Skip to content

Commit 4317ff0

Browse files
adam900710kdave
authored andcommitted
btrfs: introduce btrfs_bio::fs_info member
Currently we're doing a lot of work for btrfs_bio: - Checksum verification for data read bios - Bio splits if it crosses stripe boundary - Read repair for data read bios However for the incoming scrub patches, we don't want this extra functionality at all, just plain logical + mirror -> physical mapping ability. Thus here we do the following changes: - Introduce btrfs_bio::fs_info This is for the new scrub specific btrfs_bio, which would not populate btrfs_bio::inode. Thus we need such new member to grab a fs_info This new member will always be populated. - Replace @iNode argument with @fs_info for btrfs_bio_init() and its caller Since @iNode is no longer a mandatory member, replace it with @fs_info, and let involved users populate @iNode. - Skip checksum verification and generation if @bbio->inode is NULL - Add extra ASSERT()s To make sure: * bbio->inode is properly set for involved read repair path * if @file_offset is set, bbio->inode is also populated - Grab @fs_info from @BBIO directly We can no longer go @bbio->inode->root->fs_info, as bbio->inode can be NULL. This involves: * btrfs_simple_end_io() * should_async_write() * btrfs_wq_submit_bio() * btrfs_use_zone_append() Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 2a2dc22 commit 4317ff0

6 files changed

Lines changed: 49 additions & 28 deletions

File tree

fs/btrfs/bio.c

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ struct btrfs_failed_bio {
3131
* Initialize a btrfs_bio structure. This skips the embedded bio itself as it
3232
* is already initialized by the block layer.
3333
*/
34-
void btrfs_bio_init(struct btrfs_bio *bbio, struct btrfs_inode *inode,
34+
void btrfs_bio_init(struct btrfs_bio *bbio, struct btrfs_fs_info *fs_info,
3535
btrfs_bio_end_io_t end_io, void *private)
3636
{
3737
memset(bbio, 0, offsetof(struct btrfs_bio, bio));
38-
bbio->inode = inode;
38+
bbio->fs_info = fs_info;
3939
bbio->end_io = end_io;
4040
bbio->private = private;
4141
atomic_set(&bbio->pending_ios, 1);
@@ -49,15 +49,15 @@ void btrfs_bio_init(struct btrfs_bio *bbio, struct btrfs_inode *inode,
4949
* a mempool.
5050
*/
5151
struct btrfs_bio *btrfs_bio_alloc(unsigned int nr_vecs, blk_opf_t opf,
52-
struct btrfs_inode *inode,
52+
struct btrfs_fs_info *fs_info,
5353
btrfs_bio_end_io_t end_io, void *private)
5454
{
5555
struct btrfs_bio *bbio;
5656
struct bio *bio;
5757

5858
bio = bio_alloc_bioset(NULL, nr_vecs, opf, GFP_NOFS, &btrfs_bioset);
5959
bbio = btrfs_bio(bio);
60-
btrfs_bio_init(bbio, inode, end_io, private);
60+
btrfs_bio_init(bbio, fs_info, end_io, private);
6161
return bbio;
6262
}
6363

@@ -92,8 +92,8 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info *fs_info,
9292
GFP_NOFS, &btrfs_clone_bioset);
9393
}
9494
bbio = btrfs_bio(bio);
95-
btrfs_bio_init(bbio, orig_bbio->inode, NULL, orig_bbio);
96-
95+
btrfs_bio_init(bbio, fs_info, NULL, orig_bbio);
96+
bbio->inode = orig_bbio->inode;
9797
bbio->file_offset = orig_bbio->file_offset;
9898
if (!(orig_bbio->bio.bi_opf & REQ_BTRFS_ONE_ORDERED))
9999
orig_bbio->file_offset += map_length;
@@ -244,7 +244,8 @@ static struct btrfs_failed_bio *repair_one_sector(struct btrfs_bio *failed_bbio,
244244
__bio_add_page(repair_bio, bv->bv_page, bv->bv_len, bv->bv_offset);
245245

246246
repair_bbio = btrfs_bio(repair_bio);
247-
btrfs_bio_init(repair_bbio, failed_bbio->inode, NULL, fbio);
247+
btrfs_bio_init(repair_bbio, fs_info, NULL, fbio);
248+
repair_bbio->inode = failed_bbio->inode;
248249
repair_bbio->file_offset = failed_bbio->file_offset + bio_offset;
249250

250251
mirror = next_repair_mirror(fbio, failed_bbio->mirror_num);
@@ -263,6 +264,9 @@ static void btrfs_check_read_bio(struct btrfs_bio *bbio, struct btrfs_device *de
263264
struct btrfs_failed_bio *fbio = NULL;
264265
u32 offset = 0;
265266

267+
/* Read-repair requires the inode field to be set by the submitter. */
268+
ASSERT(inode);
269+
266270
/*
267271
* Hand off repair bios to the repair code as there is no upper level
268272
* submitter for them.
@@ -323,17 +327,17 @@ static void btrfs_end_bio_work(struct work_struct *work)
323327
struct btrfs_bio *bbio = container_of(work, struct btrfs_bio, end_io_work);
324328

325329
/* Metadata reads are checked and repaired by the submitter. */
326-
if (bbio->bio.bi_opf & REQ_META)
327-
bbio->end_io(bbio);
328-
else
330+
if (bbio->inode && !(bbio->bio.bi_opf & REQ_META))
329331
btrfs_check_read_bio(bbio, bbio->bio.bi_private);
332+
else
333+
bbio->end_io(bbio);
330334
}
331335

332336
static void btrfs_simple_end_io(struct bio *bio)
333337
{
334338
struct btrfs_bio *bbio = btrfs_bio(bio);
335339
struct btrfs_device *dev = bio->bi_private;
336-
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
340+
struct btrfs_fs_info *fs_info = bbio->fs_info;
337341

338342
btrfs_bio_counter_dec(fs_info);
339343

@@ -357,7 +361,8 @@ static void btrfs_raid56_end_io(struct bio *bio)
357361

358362
btrfs_bio_counter_dec(bioc->fs_info);
359363
bbio->mirror_num = bioc->mirror_num;
360-
if (bio_op(bio) == REQ_OP_READ && !(bbio->bio.bi_opf & REQ_META))
364+
if (bio_op(bio) == REQ_OP_READ && bbio->inode &&
365+
!(bbio->bio.bi_opf & REQ_META))
361366
btrfs_check_read_bio(bbio, NULL);
362367
else
363368
btrfs_orig_bbio_end_io(bbio);
@@ -583,7 +588,7 @@ static bool should_async_write(struct btrfs_bio *bbio)
583588
* in order.
584589
*/
585590
if (bbio->bio.bi_opf & REQ_META) {
586-
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
591+
struct btrfs_fs_info *fs_info = bbio->fs_info;
587592

588593
if (btrfs_is_zoned(fs_info))
589594
return false;
@@ -603,7 +608,7 @@ static bool btrfs_wq_submit_bio(struct btrfs_bio *bbio,
603608
struct btrfs_io_context *bioc,
604609
struct btrfs_io_stripe *smap, int mirror_num)
605610
{
606-
struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info;
611+
struct btrfs_fs_info *fs_info = bbio->fs_info;
607612
struct async_submit_bio *async;
608613

609614
async = kmalloc(sizeof(*async), GFP_NOFS);
@@ -627,7 +632,7 @@ static bool btrfs_wq_submit_bio(struct btrfs_bio *bbio,
627632
static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
628633
{
629634
struct btrfs_inode *inode = bbio->inode;
630-
struct btrfs_fs_info *fs_info = inode->root->fs_info;
635+
struct btrfs_fs_info *fs_info = bbio->fs_info;
631636
struct btrfs_bio *orig_bbio = bbio;
632637
struct bio *bio = &bbio->bio;
633638
u64 logical = bio->bi_iter.bi_sector << 9;
@@ -660,7 +665,7 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
660665
* Save the iter for the end_io handler and preload the checksums for
661666
* data reads.
662667
*/
663-
if (bio_op(bio) == REQ_OP_READ && !(bio->bi_opf & REQ_META)) {
668+
if (bio_op(bio) == REQ_OP_READ && inode && !(bio->bi_opf & REQ_META)) {
664669
bbio->saved_iter = bio->bi_iter;
665670
ret = btrfs_lookup_bio_sums(bbio);
666671
if (ret)
@@ -680,7 +685,7 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
680685
* Csum items for reloc roots have already been cloned at this
681686
* point, so they are handled as part of the no-checksum case.
682687
*/
683-
if (!(inode->flags & BTRFS_INODE_NODATASUM) &&
688+
if (inode && !(inode->flags & BTRFS_INODE_NODATASUM) &&
684689
!test_bit(BTRFS_FS_STATE_NO_CSUMS, &fs_info->fs_state) &&
685690
!btrfs_is_data_reloc_root(inode->root)) {
686691
if (should_async_write(bbio) &&
@@ -709,6 +714,9 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
709714

710715
void btrfs_submit_bio(struct btrfs_bio *bbio, int mirror_num)
711716
{
717+
/* If bbio->inode is not populated, its file_offset must be 0. */
718+
ASSERT(bbio->inode || bbio->file_offset == 0);
719+
712720
while (!btrfs_submit_chunk(bbio, mirror_num))
713721
;
714722
}

fs/btrfs/bio.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ typedef void (*btrfs_bio_end_io_t)(struct btrfs_bio *bbio);
3030
* passed to btrfs_submit_bio for mapping to the physical devices.
3131
*/
3232
struct btrfs_bio {
33-
/* Inode and offset into it that this I/O operates on. */
33+
/*
34+
* Inode and offset into it that this I/O operates on.
35+
* Only set for data I/O.
36+
*/
3437
struct btrfs_inode *inode;
3538
u64 file_offset;
3639

@@ -58,6 +61,9 @@ struct btrfs_bio {
5861
atomic_t pending_ios;
5962
struct work_struct end_io_work;
6063

64+
/* File system that this I/O operates on. */
65+
struct btrfs_fs_info *fs_info;
66+
6167
/*
6268
* This member must come last, bio_alloc_bioset will allocate enough
6369
* bytes for entire btrfs_bio but relies on bio being last.
@@ -73,10 +79,10 @@ static inline struct btrfs_bio *btrfs_bio(struct bio *bio)
7379
int __init btrfs_bioset_init(void);
7480
void __cold btrfs_bioset_exit(void);
7581

76-
void btrfs_bio_init(struct btrfs_bio *bbio, struct btrfs_inode *inode,
82+
void btrfs_bio_init(struct btrfs_bio *bbio, struct btrfs_fs_info *fs_info,
7783
btrfs_bio_end_io_t end_io, void *private);
7884
struct btrfs_bio *btrfs_bio_alloc(unsigned int nr_vecs, blk_opf_t opf,
79-
struct btrfs_inode *inode,
85+
struct btrfs_fs_info *fs_info,
8086
btrfs_bio_end_io_t end_io, void *private);
8187

8288
static inline void btrfs_bio_end_io(struct btrfs_bio *bbio, blk_status_t status)

fs/btrfs/compression.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ static struct compressed_bio *alloc_compressed_bio(struct btrfs_inode *inode,
6969

7070
bbio = btrfs_bio(bio_alloc_bioset(NULL, BTRFS_MAX_COMPRESSED_PAGES, op,
7171
GFP_NOFS, &btrfs_compressed_bioset));
72-
btrfs_bio_init(bbio, inode, end_io, NULL);
72+
btrfs_bio_init(bbio, inode->root->fs_info, end_io, NULL);
73+
bbio->inode = inode;
7374
bbio->file_offset = start;
7475
return to_compressed_bio(bbio);
7576
}

fs/btrfs/extent_io.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -898,9 +898,10 @@ static void alloc_new_bio(struct btrfs_inode *inode,
898898
struct btrfs_fs_info *fs_info = inode->root->fs_info;
899899
struct btrfs_bio *bbio;
900900

901-
bbio = btrfs_bio_alloc(BIO_MAX_VECS, bio_ctrl->opf, inode,
901+
bbio = btrfs_bio_alloc(BIO_MAX_VECS, bio_ctrl->opf, fs_info,
902902
bio_ctrl->end_io_func, NULL);
903903
bbio->bio.bi_iter.bi_sector = disk_bytenr >> SECTOR_SHIFT;
904+
bbio->inode = inode;
904905
bbio->file_offset = file_offset;
905906
bio_ctrl->bbio = bbio;
906907
bio_ctrl->len_to_oe_boundary = U32_MAX;

fs/btrfs/inode.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7711,7 +7711,9 @@ static void btrfs_dio_submit_io(const struct iomap_iter *iter, struct bio *bio,
77117711
container_of(bbio, struct btrfs_dio_private, bbio);
77127712
struct btrfs_dio_data *dio_data = iter->private;
77137713

7714-
btrfs_bio_init(bbio, BTRFS_I(iter->inode), btrfs_dio_end_io, bio->bi_private);
7714+
btrfs_bio_init(bbio, BTRFS_I(iter->inode)->root->fs_info,
7715+
btrfs_dio_end_io, bio->bi_private);
7716+
bbio->inode = BTRFS_I(iter->inode);
77157717
bbio->file_offset = file_offset;
77167718

77177719
dip->file_offset = file_offset;
@@ -9899,6 +9901,7 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode,
98999901
u64 file_offset, u64 disk_bytenr,
99009902
u64 disk_io_size, struct page **pages)
99019903
{
9904+
struct btrfs_fs_info *fs_info = inode->root->fs_info;
99029905
struct btrfs_encoded_read_private priv = {
99039906
.pending = ATOMIC_INIT(1),
99049907
};
@@ -9907,9 +9910,10 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode,
99079910

99089911
init_waitqueue_head(&priv.wait);
99099912

9910-
bbio = btrfs_bio_alloc(BIO_MAX_VECS, REQ_OP_READ, inode,
9911-
btrfs_encoded_read_endio, &priv);
9913+
bbio = btrfs_bio_alloc(BIO_MAX_VECS, REQ_OP_READ, fs_info,
9914+
btrfs_encoded_read_endio, &priv);
99129915
bbio->bio.bi_iter.bi_sector = disk_bytenr >> SECTOR_SHIFT;
9916+
bbio->inode = inode;
99139917

99149918
do {
99159919
size_t bytes = min_t(u64, disk_io_size, PAGE_SIZE);
@@ -9918,9 +9922,10 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode,
99189922
atomic_inc(&priv.pending);
99199923
btrfs_submit_bio(bbio, 0);
99209924

9921-
bbio = btrfs_bio_alloc(BIO_MAX_VECS, REQ_OP_READ, inode,
9925+
bbio = btrfs_bio_alloc(BIO_MAX_VECS, REQ_OP_READ, fs_info,
99229926
btrfs_encoded_read_endio, &priv);
99239927
bbio->bio.bi_iter.bi_sector = disk_bytenr >> SECTOR_SHIFT;
9928+
bbio->inode = inode;
99249929
continue;
99259930
}
99269931

fs/btrfs/zoned.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,14 +1640,14 @@ bool btrfs_use_zone_append(struct btrfs_bio *bbio)
16401640
{
16411641
u64 start = (bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT);
16421642
struct btrfs_inode *inode = bbio->inode;
1643-
struct btrfs_fs_info *fs_info = inode->root->fs_info;
1643+
struct btrfs_fs_info *fs_info = bbio->fs_info;
16441644
struct btrfs_block_group *cache;
16451645
bool ret = false;
16461646

16471647
if (!btrfs_is_zoned(fs_info))
16481648
return false;
16491649

1650-
if (!is_data_inode(&inode->vfs_inode))
1650+
if (!inode || !is_data_inode(&inode->vfs_inode))
16511651
return false;
16521652

16531653
if (btrfs_op(&bbio->bio) != BTRFS_MAP_WRITE)

0 commit comments

Comments
 (0)