bbio
struct bbio *b = container_of(bio, struct bbio, bio);
struct bbio *b = container_of(bio, struct bbio, bio);
struct bbio *b = mempool_alloc(&c->bio_meta, GFP_NOIO);
struct bbio *b = container_of(bio, struct bbio, bio);
struct bbio *b = container_of(bio, struct bbio, bio);
struct bbio bio;
struct bbio *b = container_of(bio, struct bbio, bio);
struct bbio bio;
struct bbio *b = container_of(bio, struct bbio, bio);
bio_key = &container_of(n, struct bbio, bio)->key;
sizeof(struct bbio) +
if (bioset_init(&c->bio_split, 4, offsetof(struct bbio, bio),
if (bioset_init(&d->bio_split, 4, offsetof(struct bbio, bio),
void btrfs_submit_repair_write(struct btrfs_bio *bbio, int mirror_num, bool dev_replace)
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
u64 logical = bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT;
u64 length = bbio->bio.bi_iter.bi_size;
bbio->csum_search_commit_root = orig_bbio->csum_search_commit_root;
ASSERT(btrfs_op(&bbio->bio) == BTRFS_MAP_WRITE);
ASSERT(!is_data_inode(bbio->inode));
ASSERT(bbio->is_scrub);
bbio->can_use_append = orig_bbio->can_use_append;
btrfs_submit_bio(&bbio->bio, NULL, &smap, mirror_num);
bbio->is_scrub = orig_bbio->is_scrub;
btrfs_bio_end_io(bbio, errno_to_blk_status(ret));
bbio->is_remap = orig_bbio->is_remap;
bbio->async_csum = orig_bbio->async_csum;
return bbio;
void btrfs_bio_end_io(struct btrfs_bio *bbio, blk_status_t status)
if (bbio->async_csum)
wait_for_completion(&bbio->csum_done);
bbio->bio.bi_status = status;
if (bbio->bio.bi_pool == &btrfs_clone_bioset) {
struct btrfs_bio *orig_bbio = bbio->private;
if (bbio_has_ordered_extent(bbio))
btrfs_put_ordered_extent(bbio->ordered);
bio_put(&bbio->bio);
bbio = orig_bbio;
cmpxchg(&bbio->status, BLK_STS_OK, status);
if (atomic_dec_and_test(&bbio->pending_ios)) {
bbio->bio.bi_status = READ_ONCE(bbio->status);
if (bbio_has_ordered_extent(bbio)) {
struct btrfs_ordered_extent *ordered = bbio->ordered;
bbio->end_io(bbio);
bbio->end_io(bbio);
btrfs_bio_end_io(fbio->bbio, fbio->bbio->bio.bi_status);
if (mirror == fbio->bbio->mirror_num) {
fbio->bbio->bio.bi_status = BLK_STS_IOERR;
} while (mirror != fbio->bbio->mirror_num);
struct btrfs_bio *bbio;
fbio->bbio = failed_bbio;
static void btrfs_check_read_bio(struct btrfs_bio *bbio, struct btrfs_device *dev)
struct btrfs_inode *inode = bbio->inode;
static inline bool is_data_bbio(const struct btrfs_bio *bbio)
struct bvec_iter *iter = &bbio->saved_iter;
blk_status_t status = bbio->bio.bi_status;
if (bbio->bio.bi_pool == &btrfs_repair_bioset) {
btrfs_end_repair_bio(bbio, dev);
return bbio->inode && is_data_inode(bbio->inode);
bbio->bio.bi_status = BLK_STS_OK;
btrfs_bio_for_each_block(paddr, &bbio->bio, iter, step) {
!btrfs_data_csum_ok(bbio, dev, offset - sectorsize, paddrs))
fbio = repair_one_sector(bbio, offset - sectorsize,
if (bbio->csum != bbio->csum_inline)
kvfree(bbio->csum);
btrfs_bio_end_io(bbio, bbio->bio.bi_status);
static bool bbio_has_ordered_extent(const struct btrfs_bio *bbio)
return is_data_bbio(bbio) && btrfs_op(&bbio->bio) == BTRFS_MAP_WRITE;
struct btrfs_bio *bbio = container_of(work, struct btrfs_bio, end_io_work);
struct bio *bio = &bbio->bio;
if (is_data_bbio(bbio))
return btrfs_check_read_bio(bbio, bbio->bio.bi_private);
return btrfs_bio_end_io(bbio, bbio->bio.bi_status);
btrfs_record_physical_zoned(bbio);
btrfs_bio_end_io(bbio, bbio->bio.bi_status);
struct btrfs_bio *bbio = btrfs_bio(bio);
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
INIT_WORK(&bbio->end_io_work, simple_end_io_work);
queue_work(btrfs_end_io_wq(fs_info, bio), &bbio->end_io_work);
struct btrfs_bio *bbio = btrfs_bio(bio);
bbio->mirror_num = bioc->mirror_num;
if (bio_op(bio) == REQ_OP_READ && is_data_bbio(bbio))
btrfs_check_read_bio(bbio, NULL);
btrfs_bio_end_io(bbio, bbio->bio.bi_status);
struct btrfs_bio *bbio = container_of(work, struct btrfs_bio, end_io_work);
struct bio *bio = &bbio->bio;
void btrfs_bio_init(struct btrfs_bio *bbio, struct btrfs_inode *inode, u64 file_offset,
btrfs_bio_end_io(bbio, bbio->bio.bi_status);
struct btrfs_bio *bbio = btrfs_bio(bio);
INIT_WORK(&bbio->end_io_work, orig_write_end_io_work);
queue_work(btrfs_end_io_wq(bbio->inode->root->fs_info, bio), &bbio->end_io_work);
struct btrfs_bio *bbio = container_of(work, struct btrfs_bio, end_io_work);
struct bio *bio = &bbio->bio;
struct btrfs_bio *bbio = btrfs_bio(bio);
INIT_WORK(&bbio->end_io_work, clone_write_end_io_work);
queue_work(btrfs_end_io_wq(bbio->inode->root->fs_info, bio), &bbio->end_io_work);
memset(bbio, 0, offsetof(struct btrfs_bio, bio));
bbio->inode = inode;
bbio->end_io = end_io;
bbio->private = private;
bbio->file_offset = file_offset;
atomic_set(&bbio->pending_ios, 1);
WRITE_ONCE(bbio->status, BLK_STS_OK);
static int btrfs_bio_csum(struct btrfs_bio *bbio)
if (bbio->bio.bi_opf & REQ_META)
return btree_csum_one_bio(bbio);
return btrfs_csum_one_bio(bbio, true);
return btrfs_csum_one_bio(bbio, false);
struct btrfs_bio *bbio;
ret = btrfs_bio_csum(async->bbio);
async->bbio->bio.bi_status = errno_to_blk_status(ret);
struct bio *bio = &async->bbio->bio;
btrfs_bio_end_io(async->bbio, bio->bi_status);
static bool should_async_write(struct btrfs_bio *bbio)
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
if (op_is_sync(bbio->bio.bi_opf))
if ((bbio->bio.bi_opf & REQ_META) && btrfs_is_zoned(fs_info))
struct btrfs_bio *bbio;
static bool btrfs_wq_submit_bio(struct btrfs_bio *bbio,
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
async->bbio = bbio;
static u64 btrfs_append_map_length(struct btrfs_bio *bbio, u64 map_length)
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
sector_offset = bio_split_rw_at(&bbio->bio, &fs_info->limits,
bbio = btrfs_bio(bio);
static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
struct btrfs_inode *inode = bbio->inode;
struct bio *bio = &bbio->bio;
btrfs_bio_init(bbio, inode, file_offset, end_io, private);
if (bbio->is_scrub || btrfs_is_data_reloc_root(inode->root))
return bbio;
if (bio_op(bio) == REQ_OP_WRITE && is_data_bbio(bbio))
bbio->orig_logical = logical;
bbio->can_use_append = btrfs_use_zone_append(bbio);
if (bbio->can_use_append)
map_length = btrfs_append_map_length(bbio, map_length);
split = btrfs_split_bio(fs_info, bbio, map_length);
bbio = split;
bio = &bbio->bio;
if (bio_op(bio) == REQ_OP_READ && is_data_bbio(bbio)) {
bbio->saved_iter = bio->bi_iter;
ret = btrfs_lookup_bio_sums(bbio);
if (is_data_bbio(bbio) && bioc && bioc->use_rst) {
list_add_tail(&bioc->rst_ordered_entry, &bbio->ordered->bioc_list);
!btrfs_is_data_reloc_root(inode->root) && !bbio->is_remap) {
if (should_async_write(bbio) &&
struct btrfs_bio *bbio;
btrfs_wq_submit_bio(bbio, bioc, &smap, mirror_num))
ret = btrfs_bio_csum(bbio);
} else if (bbio->can_use_append ||
ret = btrfs_alloc_dummy_sum(bbio);
struct btrfs_bio *remaining = bbio->private;
ASSERT(bbio->bio.bi_pool == &btrfs_clone_bioset);
btrfs_bio_end_io(bbio, status);
static void assert_bbio_alignment(struct btrfs_bio *bbio)
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
const u64 logical = bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT;
const u32 length = bbio->bio.bi_iter.bi_size;
btrfs_root_id(bbio->inode->root),
btrfs_ino(bbio->inode), logical, length);
bio_for_each_bvec(bvec, &bbio->bio, iter)
btrfs_root_id(bbio->inode->root),
btrfs_ino(bbio->inode), logical, length, iter.bi_idx,
void btrfs_submit_bbio(struct btrfs_bio *bbio, int mirror_num)
ASSERT(bbio->inode || bbio->file_offset == 0);
assert_bbio_alignment(bbio);
while (!btrfs_submit_chunk(bbio, mirror_num))
bbio = btrfs_bio(bio);
btrfs_bio_init(bbio, orig_bbio->inode, orig_bbio->file_offset, NULL, orig_bbio);
if (bbio_has_ordered_extent(bbio)) {
bbio->ordered = orig_bbio->ordered;
bbio->orig_logical = orig_bbio->orig_logical;
void btrfs_bio_init(struct btrfs_bio *bbio, struct btrfs_inode *inode, u64 file_offset,
void btrfs_bio_end_io(struct btrfs_bio *bbio, blk_status_t status);
void btrfs_submit_bbio(struct btrfs_bio *bbio, int mirror_num);
void btrfs_submit_repair_write(struct btrfs_bio *bbio, int mirror_num, bool dev_replace);
typedef void (*btrfs_bio_end_io_t)(struct btrfs_bio *bbio);
bool btrfs_data_csum_ok(struct btrfs_bio *bbio, struct btrfs_device *dev,
offsetof(struct compressed_bio, bbio.bio),
static void end_bbio_compressed_read(struct btrfs_bio *bbio)
struct compressed_bio *cb = to_compressed_bio(bbio);
blk_status_t status = bbio->bio.bi_status;
bio_for_each_folio_all(fi, &bbio->bio)
bio_put(&bbio->bio);
struct inode *inode = &cb->bbio.inode->vfs_inode;
ret = blk_status_to_errno(cb->bbio.bio.bi_status);
static void end_bbio_compressed_write(struct btrfs_bio *bbio)
struct compressed_bio *cb = to_compressed_bio(bbio);
btrfs_finish_ordered_extent(cb->bbio.ordered, cb->start, cb->len,
cb->bbio.bio.bi_status == BLK_STS_OK);
bio_for_each_folio_all(fi, &bbio->bio)
bio_put(&cb->bbio.bio);
ASSERT(cb->bbio.bio.bi_iter.bi_size == ordered->disk_num_bytes);
cb->bbio.bio.bi_iter.bi_sector = ordered->disk_bytenr >> SECTOR_SHIFT;
cb->bbio.ordered = ordered;
btrfs_submit_bbio(&cb->bbio, 0);
void btrfs_submit_compressed_read(struct btrfs_bio *bbio)
struct btrfs_inode *inode = bbio->inode;
u64 file_offset = bbio->file_offset;
if (bbio->bio.bi_opf & REQ_RAHEAD)
static inline struct compressed_bio *to_compressed_bio(struct btrfs_bio *bbio)
cb->len = bbio->bio.bi_iter.bi_size;
cb->orig_bbio = bbio;
cb->bbio.csum_search_commit_root = bbio->csum_search_commit_root;
return container_of(bbio, struct compressed_bio, bbio);
ret = bio_add_folio(&cb->bbio.bio, folio, cur_len, 0);
ASSERT(cb->bbio.bio.bi_iter.bi_size == compressed_len);
&pflags, !(bbio->bio.bi_opf & REQ_RAHEAD));
cb->len = bbio->bio.bi_iter.bi_size;
cb->bbio.bio.bi_iter.bi_sector = bbio->bio.bi_iter.bi_sector;
btrfs_submit_bbio(&cb->bbio, 0);
btrfs_bio_end_io(bbio, errno_to_blk_status(ret));
struct btrfs_bio *bbio;
bbio = btrfs_bio(bio_alloc_bioset(NULL, BTRFS_MAX_COMPRESSED_PAGES, op,
btrfs_bio_init(bbio, inode, start, end_io, NULL);
return to_compressed_bio(bbio);
struct bio *bio = &cb->bbio.bio;
struct btrfs_bio bbio;
return cb->bbio.inode->root->fs_info;
void btrfs_submit_compressed_read(struct btrfs_bio *bbio);
offsetof(struct btrfs_dio_private, bbio.bio),
struct btrfs_bio bbio;
static void btrfs_dio_end_io(struct btrfs_bio *bbio)
container_of(bbio, struct btrfs_dio_private, bbio);
struct btrfs_inode *inode = bbio->inode;
struct bio *bio = &bbio->bio;
btrfs_finish_ordered_extent(bbio->ordered, dip->file_offset,
bbio->bio.bi_private = bbio->private;
static int btrfs_extract_ordered_extent(struct btrfs_bio *bbio,
u64 start = (u64)bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT;
u64 len = bbio->bio.bi_iter.bi_size;
bbio->ordered = ordered;
ret = btrfs_split_extent_map(bbio->inode, bbio->file_offset,
bbio->ordered = new;
struct btrfs_bio *bbio = btrfs_bio(bio);
container_of(bbio, struct btrfs_dio_private, bbio);
btrfs_bio_init(bbio, BTRFS_I(iter->inode), file_offset,
ret = btrfs_extract_ordered_extent(bbio, dio_data->ordered);
btrfs_submit_bbio(bbio, 0);
int btree_csum_one_bio(struct btrfs_bio *bbio)
struct extent_buffer *eb = bbio->private;
if (WARN_ON_ONCE(bbio->file_offset != eb->start))
if (WARN_ON_ONCE(bbio->bio.bi_iter.bi_size != eb->len))
int btree_csum_one_bio(struct btrfs_bio *bbio);
struct btrfs_bio *bbio = bio_ctrl->bbio;
ASSERT(bbio);
if (!(btrfs_op(&bbio->bio) == BTRFS_MAP_READ && is_data_inode(bbio->inode)))
bio_ctrl->bbio->csum_search_commit_root =
bio_ctrl->generation < btrfs_get_fs_generation(bbio->inode->root->fs_info));
struct btrfs_bio *bbio = bio_ctrl->bbio;
if (!bbio)
ASSERT(bbio->bio.bi_iter.bi_size);
if (btrfs_op(&bbio->bio) == BTRFS_MAP_READ &&
btrfs_submit_compressed_read(bbio);
btrfs_submit_bbio(bbio, 0);
bio_ctrl->bbio = NULL;
struct btrfs_bio *bbio = bio_ctrl->bbio;
if (!bbio)
btrfs_bio_end_io(bbio, errno_to_blk_status(ret));
bio_ctrl->bbio = NULL;
static void end_bbio_meta_write(struct btrfs_bio *bbio)
struct extent_buffer *eb = bbio->private;
if (bbio->bio.bi_status != BLK_STS_OK)
bio_for_each_folio_all(fi, &bbio->bio) {
bio_put(&bbio->bio);
struct btrfs_bio *bbio;
bbio = btrfs_bio_alloc(INLINE_EXTENT_BUFFER_PAGES,
bbio->bio.bi_iter.bi_sector = eb->start >> SECTOR_SHIFT;
bio_set_dev(&bbio->bio, fs_info->fs_devices->latest_dev->bdev);
wbc_init_bio(wbc, &bbio->bio);
bio_add_folio_nofail(&bbio->bio, folio, range_len,
btrfs_bio_end_io(bbio, errno_to_blk_status(BTRFS_FS_ERROR(fs_info)));
btrfs_submit_bbio(bbio, 0);
static void end_bbio_meta_read(struct btrfs_bio *bbio)
struct extent_buffer *eb = bbio->private;
bool uptodate = !bbio->bio.bi_status;
eb->read_mirror = bbio->mirror_num;
btrfs_validate_extent_buffer(eb, &bbio->parent_check) < 0)
bio_put(&bbio->bio);
struct btrfs_bio *bbio;
bbio = btrfs_bio_alloc(INLINE_EXTENT_BUFFER_PAGES,
bbio->bio.bi_iter.bi_sector = eb->start >> SECTOR_SHIFT;
memcpy(&bbio->parent_check, check, sizeof(*check));
bio_add_folio_nofail(&bbio->bio, folio, range_len,
btrfs_submit_bbio(bbio, mirror_num);
static void end_bbio_data_write(struct btrfs_bio *bbio)
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
struct bio *bio = &bbio->bio;
mapping_set_error(bbio->inode->vfs_inode.i_mapping, error);
btrfs_finish_ordered_extent(bbio->ordered, bbio->file_offset, bio_size, !error);
static void end_bbio_data_read(struct btrfs_bio *bbio)
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
struct inode *inode = &bbio->inode->vfs_inode;
struct bio *bio = &bbio->bio;
if (bbio->file_offset < i_size_read(inode))
bio_for_each_folio_all(fi, &bbio->bio) {
bbio->mirror_num);
struct bio *bio = &bio_ctrl->bbio->bio;
struct btrfs_bio *bbio;
bbio = btrfs_bio_alloc(BIO_MAX_VECS, bio_ctrl->opf, inode,
bbio->bio.bi_iter.bi_sector = disk_bytenr >> SECTOR_SHIFT;
bbio->bio.bi_write_hint = inode->vfs_inode.i_write_hint;
bio_ctrl->bbio = bbio;
ASSERT(btrfs_op(&bio_ctrl->bbio->bio) == BTRFS_MAP_WRITE);
bio_ctrl->bbio = NULL;
bio_put(&bbio->bio);
bbio->ordered = ordered;
bio_set_dev(&bbio->bio, fs_info->fs_devices->latest_dev->bdev);
wbc_init_bio(bio_ctrl->wbc, &bbio->bio);
if (bio_ctrl->bbio &&
if (!bio_ctrl->bbio) {
if (!bio_add_folio(&bio_ctrl->bbio->bio, folio, len, pg_offset)) {
bio_ctrl->bbio->bio.bi_iter.bi_size >=
struct btrfs_bio *bbio;
int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
struct btrfs_inode *inode = bbio->inode;
struct bio *bio = &bbio->bio;
bbio->csum = kvcalloc(nblocks, csum_size, GFP_NOFS);
if (!bbio->csum)
bbio->csum = bbio->csum_inline;
if (bbio->csum_search_commit_root) {
u8 *csum_dst = bbio->csum +
if (bbio->csum != bbio->csum_inline)
kvfree(bbio->csum);
bbio->csum = NULL;
u64 file_offset = bbio->file_offset + bio_offset;
static void csum_one_bio(struct btrfs_bio *bbio, struct bvec_iter *src)
struct btrfs_inode *inode = bbio->inode;
struct bio *bio = &bbio->bio;
struct btrfs_ordered_sum *sums = bbio->sums;
struct btrfs_bio *bbio = container_of(work, struct btrfs_bio, csum_work);
ASSERT(btrfs_op(&bbio->bio) == BTRFS_MAP_WRITE);
ASSERT(bbio->async_csum == true);
csum_one_bio(bbio, &bbio->csum_saved_iter);
complete(&bbio->csum_done);
int btrfs_csum_one_bio(struct btrfs_bio *bbio, bool async)
struct btrfs_ordered_extent *ordered = bbio->ordered;
struct btrfs_inode *inode = bbio->inode;
struct bio *bio = &bbio->bio;
sums->logical = bbio->orig_logical;
bbio->sums = sums;
csum_one_bio(bbio, &bbio->bio.bi_iter);
init_completion(&bbio->csum_done);
bbio->async_csum = true;
bbio->csum_saved_iter = bbio->bio.bi_iter;
INIT_WORK(&bbio->csum_work, csum_one_bio_work);
schedule_work(&bbio->csum_work);
int btrfs_alloc_dummy_sum(struct btrfs_bio *bbio)
bbio->sums = kmalloc_obj(*bbio->sums, GFP_NOFS);
if (!bbio->sums)
bbio->sums->len = bbio->bio.bi_iter.bi_size;
bbio->sums->logical = bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT;
btrfs_add_ordered_sum(bbio->ordered, bbio->sums);
int btrfs_lookup_bio_sums(struct btrfs_bio *bbio);
int btrfs_csum_one_bio(struct btrfs_bio *bbio, bool async);
int btrfs_alloc_dummy_sum(struct btrfs_bio *bbio);
compressed_size = async_extent->cb->bbio.bio.bi_iter.bi_size;
async_extent->cb->bbio.bio.bi_iter.bi_sector = ins.objectid >> SECTOR_SHIFT;
async_extent->cb->bbio.ordered = ordered;
btrfs_submit_bbio(&async_extent->cb->bbio, 0);
compressed_size = cb->bbio.bio.bi_iter.bi_size;
bio_first_folio_all(&cb->bbio.bio), false);
bool btrfs_data_csum_ok(struct btrfs_bio *bbio, struct btrfs_device *dev,
struct btrfs_inode *inode = bbio->inode;
u64 file_offset = bbio->file_offset + bio_offset;
if (!bbio->csum)
csum_expected = bbio->csum + (bio_offset >> fs_info->sectorsize_bits) *
bbio->mirror_num);
struct bio *bio = &cb->bbio.bio;
struct bio *bio = &cb->bbio.bio;
static void btrfs_encoded_read_endio(struct btrfs_bio *bbio)
struct btrfs_encoded_read_private *priv = bbio->private;
if (bbio->bio.bi_status) {
WRITE_ONCE(priv->status, bbio->bio.bi_status);
bio_put(&bbio->bio);
struct btrfs_bio *bbio;
bbio = btrfs_bio_alloc(BIO_MAX_VECS, REQ_OP_READ, inode, 0,
bbio->bio.bi_iter.bi_sector = disk_bytenr >> SECTOR_SHIFT;
if (bio_add_page(&bbio->bio, pages[i], bytes, 0) < bytes) {
btrfs_submit_bbio(bbio, 0);
bbio = btrfs_bio_alloc(BIO_MAX_VECS, REQ_OP_READ, inode, 0,
bbio->bio.bi_iter.bi_sector = disk_bytenr >> SECTOR_SHIFT;
btrfs_submit_bbio(bbio, 0);
total_compressed = cb->bbio.bio.bi_iter.bi_size;
total_compressed = cb->bbio.bio.bi_iter.bi_size;
ret = bio_add_folio(&cb->bbio.bio, folio, round_up(bytes, blocksize), 0);
ASSERT(cb->bbio.bio.bi_iter.bi_size == disk_num_bytes);
bio_first_folio_all(&cb->bbio.bio),
struct btrfs_inode *inode = cb->bbio.inode;
struct bio *bio = &cb->bbio.bio;
bio_next_folio(fi, &cb->bbio.bio);
struct btrfs_fs_info *fs_info = cb->bbio.inode->root->fs_info;
const u32 compressed_len = bio_get_size(&cb->bbio.bio);
bio_first_folio(&fi, &cb->bbio.bio, 0);
struct btrfs_inode *inode = cb->bbio.inode;
struct btrfs_inode *inode = cb->bbio.inode;
struct btrfs_inode *inode = cb->bbio.inode;
struct btrfs_inode *inode = cb->bbio.inode;
static void reloc_endio(struct btrfs_bio *bbio)
struct reloc_io_private *priv = bbio->private;
if (bbio->bio.bi_status)
WRITE_ONCE(priv->status, bbio->bio.bi_status);
bio_put(&bbio->bio);
struct btrfs_bio *bbio;
bbio = btrfs_bio_alloc(BIO_MAX_VECS, op, BTRFS_I(fs_info->btree_inode),
bbio->bio.bi_iter.bi_sector = (addr >> SECTOR_SHIFT);
bbio->is_remap = true;
if (bio_add_page(&bbio->bio, pages[i], bytes, 0) < bytes) {
btrfs_submit_bbio(bbio, 0);
bbio = btrfs_bio_alloc(BIO_MAX_VECS, op,
bbio->bio.bi_iter.bi_sector = (addr >> SECTOR_SHIFT);
bbio->is_remap = true;
btrfs_submit_bbio(bbio, 0);
static void scrub_read_endio(struct btrfs_bio *bbio)
struct scrub_stripe *stripe = bbio->private;
int sector_nr = calc_sector_number(stripe, bio_first_bvec_all(&bbio->bio));
const u32 bio_size = bio_get_size(&bbio->bio);
if (bbio->bio.bi_status) {
bio_put(&bbio->bio);
static void scrub_write_endio(struct btrfs_bio *bbio)
struct scrub_stripe *stripe = bbio->private;
int sector_nr = calc_sector_number(stripe, bio_first_bvec_all(&bbio->bio));
const u32 bio_size = bio_get_size(&bbio->bio);
if (bbio->bio.bi_status) {
bio_put(&bbio->bio);
struct btrfs_bio *bbio, bool dev_replace)
u32 bio_len = bbio->bio.bi_iter.bi_size;
u32 bio_off = (bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT) -
btrfs_submit_repair_write(bbio, stripe->mirror_num, dev_replace);
struct btrfs_bio *bbio = NULL;
if (bbio && sector_nr && !test_bit(sector_nr - 1, &write_bitmap)) {
scrub_submit_write_bio(sctx, stripe, bbio, dev_replace);
bbio = NULL;
if (!bbio)
bbio = alloc_scrub_bbio(fs_info, stripe->nr_sectors, REQ_OP_WRITE,
scrub_bio_add_sector(bbio, stripe, sector_nr);
if (bbio)
scrub_submit_write_bio(sctx, stripe, bbio, dev_replace);
struct btrfs_bio *bbio = NULL;
if (bbio &&
bbio->bio.bi_iter.bi_size >= stripe_len)) {
ASSERT(bbio->bio.bi_iter.bi_size);
btrfs_submit_bbio(bbio, mirror);
bbio = NULL;
if (!bbio) {
bbio = alloc_scrub_bbio(fs_info, stripe->nr_sectors, REQ_OP_READ,
scrub_bio_add_sector(bbio, stripe, i);
if (bbio) {
ASSERT(bbio->bio.bi_iter.bi_size);
btrfs_submit_bbio(bbio, mirror);
struct btrfs_bio *bbio;
bbio = alloc_scrub_bbio(fs_info, BTRFS_STRIPE_LEN >> min_folio_shift, REQ_OP_READ,
scrub_bio_add_sector(bbio, stripe, cur);
btrfs_submit_bbio(bbio, mirror);
static void scrub_repair_read_endio(struct btrfs_bio *bbio)
struct scrub_stripe *stripe = bbio->private;
int sector_nr = calc_sector_number(stripe, bio_first_bvec_all(&bbio->bio));
const u32 bio_size = bio_get_size(&bbio->bio);
if (bbio->bio.bi_status) {
bio_put(&bbio->bio);
static void scrub_bio_add_sector(struct btrfs_bio *bbio, struct scrub_stripe *stripe,
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
ret = bio_add_page(&bbio->bio, virt_to_page(kaddr), fs_info->sectorsize,
struct btrfs_bio *bbio;
bbio = btrfs_bio_alloc(nr_vecs, opf, BTRFS_I(fs_info->btree_inode),
bbio->is_scrub = true;
bbio->bio.bi_iter.bi_sector = logical >> SECTOR_SHIFT;
return bbio;
struct btrfs_bio *bbio = NULL;
if (bbio && ((i > 0 && !test_bit(i - 1, &old_error_bitmap)) ||
bbio->bio.bi_iter.bi_size >= blocksize)) {
ASSERT(bbio->bio.bi_iter.bi_size);
btrfs_submit_bbio(bbio, mirror);
bbio = NULL;
if (!bbio)
bbio = alloc_scrub_bbio(fs_info, stripe->nr_sectors, REQ_OP_READ,
scrub_bio_add_sector(bbio, stripe, i);
if (bbio) {
ASSERT(bbio->bio.bi_iter.bi_size);
btrfs_submit_bbio(bbio, mirror);
struct btrfs_inode *inode = cb->bbio.inode;
struct bio *bio = &cb->bbio.bio;
const size_t srclen = bio_get_size(&cb->bbio.bio);
bio_first_folio(&fi, &cb->bbio.bio, 0);
struct btrfs_inode *inode = cb->bbio.inode;
bio_next_folio(&fi, &cb->bbio.bio);
btrfs_err(cb->bbio.inode->root->fs_info,
ret, btrfs_root_id(cb->bbio.inode->root),
btrfs_ino(cb->bbio.inode), cb->start);
bool btrfs_use_zone_append(struct btrfs_bio *bbio)
u64 start = (bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT);
struct btrfs_inode *inode = bbio->inode;
if (btrfs_op(&bbio->bio) != BTRFS_MAP_WRITE)
void btrfs_record_physical_zoned(struct btrfs_bio *bbio)
const u64 physical = bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT;
struct btrfs_ordered_sum *sum = bbio->sums;
if (physical < bbio->orig_physical)
sum->logical -= bbio->orig_physical - physical;
sum->logical += physical - bbio->orig_physical;
static inline bool btrfs_use_zone_append(struct btrfs_bio *bbio)
static inline void btrfs_record_physical_zoned(struct btrfs_bio *bbio)
bool btrfs_use_zone_append(struct btrfs_bio *bbio);
void btrfs_record_physical_zoned(struct btrfs_bio *bbio);
struct btrfs_inode *inode = cb->bbio.inode;
struct bio *bio = &cb->bbio.bio;
size_t srclen = bio_get_size(&cb->bbio.bio);
bio_first_folio(&fi, &cb->bbio.bio, 0);
struct btrfs_inode *inode = cb->bbio.inode;
struct btrfs_inode *inode = cb->bbio.inode;
bio_next_folio(&fi, &cb->bbio.bio);