Skip to content

Commit

Permalink
btrfs: raid56: use fixed stripe length everywhere
Browse files Browse the repository at this point in the history
The raid56 code assumes a fixed stripe length BTRFS_STRIPE_LEN but there
are functions passing it as arguments, this is not necessary. The fixed
value has been used for a long time and though the stripe length should
be configurable by super block member stripesize, this hasn't been
implemented and would require more changes so we don't need to keep this
code around until then.

Partially based on a patch from Qu Wenruo.

Reviewed-by: Nikolay Borisov <[email protected]>
Tested-by: Nikolay Borisov <[email protected]>
Reviewed-by: Johannes Thumshirn <[email protected]>
Reviewed-by: Qu Wenruo <[email protected]>
Signed-off-by: Christoph Hellwig <[email protected]>
[ update changelog ]
Reviewed-by: David Sterba <[email protected]>
Signed-off-by: David Sterba <[email protected]>
  • Loading branch information
Christoph Hellwig authored and kdave committed Jul 25, 2022
1 parent 0201fce commit ff18a4a
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 56 deletions.
61 changes: 27 additions & 34 deletions fs/btrfs/raid56.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,9 +474,9 @@ static int rbio_is_full(struct btrfs_raid_bio *rbio)
int ret = 1;

spin_lock_irqsave(&rbio->bio_list_lock, flags);
if (size != rbio->nr_data * rbio->stripe_len)
if (size != rbio->nr_data * BTRFS_STRIPE_LEN)
ret = 0;
BUG_ON(size > rbio->nr_data * rbio->stripe_len);
BUG_ON(size > rbio->nr_data * BTRFS_STRIPE_LEN);
spin_unlock_irqrestore(&rbio->bio_list_lock, flags);

return ret;
Expand Down Expand Up @@ -913,18 +913,17 @@ static struct sector_ptr *sector_in_rbio(struct btrfs_raid_bio *rbio,
* this does not allocate any pages for rbio->pages.
*/
static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info,
struct btrfs_io_context *bioc,
u32 stripe_len)
struct btrfs_io_context *bioc)
{
const unsigned int real_stripes = bioc->num_stripes - bioc->num_tgtdevs;
const unsigned int stripe_npages = stripe_len >> PAGE_SHIFT;
const unsigned int stripe_npages = BTRFS_STRIPE_LEN >> PAGE_SHIFT;
const unsigned int num_pages = stripe_npages * real_stripes;
const unsigned int stripe_nsectors = stripe_len >> fs_info->sectorsize_bits;
const unsigned int stripe_nsectors =
BTRFS_STRIPE_LEN >> fs_info->sectorsize_bits;
const unsigned int num_sectors = stripe_nsectors * real_stripes;
struct btrfs_raid_bio *rbio;
void *p;

ASSERT(IS_ALIGNED(stripe_len, PAGE_SIZE));
/* PAGE_SIZE must also be aligned to sectorsize for subpage support */
ASSERT(IS_ALIGNED(PAGE_SIZE, fs_info->sectorsize));
/*
Expand All @@ -948,7 +947,6 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info,
INIT_LIST_HEAD(&rbio->stripe_cache);
INIT_LIST_HEAD(&rbio->hash_list);
rbio->bioc = bioc;
rbio->stripe_len = stripe_len;
rbio->nr_pages = num_pages;
rbio->nr_sectors = num_sectors;
rbio->real_stripes = real_stripes;
Expand Down Expand Up @@ -1020,7 +1018,6 @@ static int rbio_add_io_sector(struct btrfs_raid_bio *rbio,
struct sector_ptr *sector,
unsigned int stripe_nr,
unsigned int sector_nr,
unsigned long bio_max_len,
unsigned int opf)
{
const u32 sectorsize = rbio->bioc->fs_info->sectorsize;
Expand Down Expand Up @@ -1065,7 +1062,8 @@ static int rbio_add_io_sector(struct btrfs_raid_bio *rbio,
}

/* put a new bio on the list */
bio = bio_alloc(stripe->dev->bdev, max(bio_max_len >> PAGE_SHIFT, 1UL),
bio = bio_alloc(stripe->dev->bdev,
max(BTRFS_STRIPE_LEN >> PAGE_SHIFT, 1),
opf, GFP_NOFS);
bio->bi_iter.bi_sector = disk_start >> 9;
bio->bi_private = rbio;
Expand Down Expand Up @@ -1287,8 +1285,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
}

ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe,
sectornr, rbio->stripe_len,
REQ_OP_WRITE);
sectornr, REQ_OP_WRITE);
if (ret)
goto cleanup;
}
Expand Down Expand Up @@ -1327,8 +1324,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)

ret = rbio_add_io_sector(rbio, &bio_list, sector,
rbio->bioc->tgtdev_map[stripe],
sectornr, rbio->stripe_len,
REQ_OP_WRITE);
sectornr, REQ_OP_WRITE);
if (ret)
goto cleanup;
}
Expand Down Expand Up @@ -1373,7 +1369,7 @@ static int find_bio_stripe(struct btrfs_raid_bio *rbio,

for (i = 0; i < rbio->bioc->num_stripes; i++) {
stripe = &rbio->bioc->stripes[i];
if (in_range(physical, stripe->physical, rbio->stripe_len) &&
if (in_range(physical, stripe->physical, BTRFS_STRIPE_LEN) &&
stripe->dev->bdev && bio->bi_bdev == stripe->dev->bdev) {
return i;
}
Expand All @@ -1395,7 +1391,7 @@ static int find_logical_bio_stripe(struct btrfs_raid_bio *rbio,
for (i = 0; i < rbio->nr_data; i++) {
u64 stripe_start = rbio->bioc->raid_map[i];

if (in_range(logical, stripe_start, rbio->stripe_len))
if (in_range(logical, stripe_start, BTRFS_STRIPE_LEN))
return i;
}
return -1;
Expand Down Expand Up @@ -1580,8 +1576,7 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio)
continue;

ret = rbio_add_io_sector(rbio, &bio_list, sector,
stripe, sectornr, rbio->stripe_len,
REQ_OP_READ);
stripe, sectornr, REQ_OP_READ);
if (ret)
goto cleanup;
}
Expand Down Expand Up @@ -1790,7 +1785,7 @@ static void rbio_add_bio(struct btrfs_raid_bio *rbio, struct bio *orig_bio)

ASSERT(orig_logical >= full_stripe_start &&
orig_logical + orig_len <= full_stripe_start +
rbio->nr_data * rbio->stripe_len);
rbio->nr_data * BTRFS_STRIPE_LEN);

bio_list_add(&rbio->bio_list, orig_bio);
rbio->bio_list_bytes += orig_bio->bi_iter.bi_size;
Expand All @@ -1808,15 +1803,15 @@ static void rbio_add_bio(struct btrfs_raid_bio *rbio, struct bio *orig_bio)
/*
* our main entry point for writes from the rest of the FS.
*/
int raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc, u32 stripe_len)
int raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc)
{
struct btrfs_fs_info *fs_info = bioc->fs_info;
struct btrfs_raid_bio *rbio;
struct btrfs_plug_cb *plug = NULL;
struct blk_plug_cb *cb;
int ret;

rbio = alloc_rbio(fs_info, bioc, stripe_len);
rbio = alloc_rbio(fs_info, bioc);
if (IS_ERR(rbio)) {
btrfs_put_bioc(bioc);
return PTR_ERR(rbio);
Expand Down Expand Up @@ -2140,8 +2135,7 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
}
sector = rbio_stripe_sector(rbio, stripe, sectornr);
ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe,
sectornr, rbio->stripe_len,
REQ_OP_READ);
sectornr, REQ_OP_READ);
if (ret < 0)
goto cleanup;
}
Expand Down Expand Up @@ -2199,7 +2193,7 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
* of the drive.
*/
int raid56_parity_recover(struct bio *bio, struct btrfs_io_context *bioc,
u32 stripe_len, int mirror_num, int generic_io)
int mirror_num, int generic_io)
{
struct btrfs_fs_info *fs_info = bioc->fs_info;
struct btrfs_raid_bio *rbio;
Expand All @@ -2210,7 +2204,7 @@ int raid56_parity_recover(struct bio *bio, struct btrfs_io_context *bioc,
btrfs_bio(bio)->mirror_num = mirror_num;
}

rbio = alloc_rbio(fs_info, bioc, stripe_len);
rbio = alloc_rbio(fs_info, bioc);
if (IS_ERR(rbio)) {
if (generic_io)
btrfs_put_bioc(bioc);
Expand Down Expand Up @@ -2304,14 +2298,14 @@ static void read_rebuild_work(struct work_struct *work)

struct btrfs_raid_bio *raid56_parity_alloc_scrub_rbio(struct bio *bio,
struct btrfs_io_context *bioc,
u32 stripe_len, struct btrfs_device *scrub_dev,
struct btrfs_device *scrub_dev,
unsigned long *dbitmap, int stripe_nsectors)
{
struct btrfs_fs_info *fs_info = bioc->fs_info;
struct btrfs_raid_bio *rbio;
int i;

rbio = alloc_rbio(fs_info, bioc, stripe_len);
rbio = alloc_rbio(fs_info, bioc);
if (IS_ERR(rbio))
return NULL;
bio_list_add(&rbio->bio_list, bio);
Expand Down Expand Up @@ -2356,7 +2350,7 @@ void raid56_add_scrub_pages(struct btrfs_raid_bio *rbio, struct page *page,

ASSERT(logical >= rbio->bioc->raid_map[0]);
ASSERT(logical + sectorsize <= rbio->bioc->raid_map[0] +
rbio->stripe_len * rbio->nr_data);
BTRFS_STRIPE_LEN * rbio->nr_data);
stripe_offset = (int)(logical - rbio->bioc->raid_map[0]);
index = stripe_offset / sectorsize;
rbio->bio_sectors[index].page = page;
Expand Down Expand Up @@ -2512,7 +2506,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,

sector = rbio_stripe_sector(rbio, rbio->scrubp, sectornr);
ret = rbio_add_io_sector(rbio, &bio_list, sector, rbio->scrubp,
sectornr, rbio->stripe_len, REQ_OP_WRITE);
sectornr, REQ_OP_WRITE);
if (ret)
goto cleanup;
}
Expand All @@ -2526,7 +2520,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
sector = rbio_stripe_sector(rbio, rbio->scrubp, sectornr);
ret = rbio_add_io_sector(rbio, &bio_list, sector,
bioc->tgtdev_map[rbio->scrubp],
sectornr, rbio->stripe_len, REQ_OP_WRITE);
sectornr, REQ_OP_WRITE);
if (ret)
goto cleanup;
}
Expand Down Expand Up @@ -2693,7 +2687,7 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
continue;

ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe,
sectornr, rbio->stripe_len, REQ_OP_READ);
sectornr, REQ_OP_READ);
if (ret)
goto cleanup;
}
Expand Down Expand Up @@ -2758,13 +2752,12 @@ void raid56_parity_submit_scrub_rbio(struct btrfs_raid_bio *rbio)
/* The following code is used for dev replace of a missing RAID 5/6 device. */

struct btrfs_raid_bio *
raid56_alloc_missing_rbio(struct bio *bio, struct btrfs_io_context *bioc,
u64 length)
raid56_alloc_missing_rbio(struct bio *bio, struct btrfs_io_context *bioc)
{
struct btrfs_fs_info *fs_info = bioc->fs_info;
struct btrfs_raid_bio *rbio;

rbio = alloc_rbio(fs_info, bioc, length);
rbio = alloc_rbio(fs_info, bioc);
if (IS_ERR(rbio))
return NULL;

Expand Down
12 changes: 4 additions & 8 deletions fs/btrfs/raid56.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ struct btrfs_raid_bio {
*/
enum btrfs_rbio_ops operation;

/* Size of each individual stripe on disk */
u32 stripe_len;

/* How many pages there are for the full stripe including P/Q */
u16 nr_pages;

Expand Down Expand Up @@ -169,21 +166,20 @@ static inline int nr_data_stripes(const struct map_lookup *map)
struct btrfs_device;

int raid56_parity_recover(struct bio *bio, struct btrfs_io_context *bioc,
u32 stripe_len, int mirror_num, int generic_io);
int raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc, u32 stripe_len);
int mirror_num, int generic_io);
int raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc);

void raid56_add_scrub_pages(struct btrfs_raid_bio *rbio, struct page *page,
unsigned int pgoff, u64 logical);

struct btrfs_raid_bio *raid56_parity_alloc_scrub_rbio(struct bio *bio,
struct btrfs_io_context *bioc, u32 stripe_len,
struct btrfs_io_context *bioc,
struct btrfs_device *scrub_dev,
unsigned long *dbitmap, int stripe_nsectors);
void raid56_parity_submit_scrub_rbio(struct btrfs_raid_bio *rbio);

struct btrfs_raid_bio *
raid56_alloc_missing_rbio(struct bio *bio, struct btrfs_io_context *bioc,
u64 length);
raid56_alloc_missing_rbio(struct bio *bio, struct btrfs_io_context *bioc);
void raid56_submit_missing_rbio(struct btrfs_raid_bio *rbio);

int btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info);
Expand Down
9 changes: 3 additions & 6 deletions fs/btrfs/scrub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1216,7 +1216,6 @@ static inline int scrub_nr_raid_mirrors(struct btrfs_io_context *bioc)

static inline void scrub_stripe_index_and_offset(u64 logical, u64 map_type,
u64 *raid_map,
u64 mapped_length,
int nstripes, int mirror,
int *stripe_index,
u64 *stripe_offset)
Expand All @@ -1231,7 +1230,7 @@ static inline void scrub_stripe_index_and_offset(u64 logical, u64 map_type,
continue;

if (logical >= raid_map[i] &&
logical < raid_map[i] + mapped_length)
logical < raid_map[i] + BTRFS_STRIPE_LEN)
break;
}

Expand Down Expand Up @@ -1335,7 +1334,6 @@ static int scrub_setup_recheck_block(struct scrub_block *original_sblock,
scrub_stripe_index_and_offset(logical,
bioc->map_type,
bioc->raid_map,
mapped_length,
bioc->num_stripes -
bioc->num_tgtdevs,
mirror_index,
Expand Down Expand Up @@ -1387,7 +1385,6 @@ static int scrub_submit_raid56_bio_wait(struct btrfs_fs_info *fs_info,

mirror_num = sector->sblock->sectors[0]->mirror_num;
ret = raid56_parity_recover(bio, sector->recover->bioc,
sector->recover->map_length,
mirror_num, 0);
if (ret)
return ret;
Expand Down Expand Up @@ -2195,7 +2192,7 @@ static void scrub_missing_raid56_pages(struct scrub_block *sblock)
bio->bi_private = sblock;
bio->bi_end_io = scrub_missing_raid56_end_io;

rbio = raid56_alloc_missing_rbio(bio, bioc, length);
rbio = raid56_alloc_missing_rbio(bio, bioc);
if (!rbio)
goto rbio_out;

Expand Down Expand Up @@ -2829,7 +2826,7 @@ static void scrub_parity_check_and_repair(struct scrub_parity *sparity)
bio->bi_private = sparity;
bio->bi_end_io = scrub_parity_bio_endio;

rbio = raid56_parity_alloc_scrub_rbio(bio, bioc, length,
rbio = raid56_parity_alloc_scrub_rbio(bio, bioc,
sparity->scrub_dev,
&sparity->dbitmap,
sparity->nsectors);
Expand Down
13 changes: 5 additions & 8 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -6461,6 +6461,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info,
}

} else if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
ASSERT(map->stripe_len == BTRFS_STRIPE_LEN);
if (need_raid_map && (need_full_stripe(op) || mirror_num > 1)) {
/* push stripe_nr back to the start of the full stripe */
stripe_nr = div64_u64(raid56_full_stripe_start,
Expand Down Expand Up @@ -6758,14 +6759,10 @@ blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,

if ((bioc->map_type & BTRFS_BLOCK_GROUP_RAID56_MASK) &&
((btrfs_op(bio) == BTRFS_MAP_WRITE) || (mirror_num > 1))) {
/* In this case, map_length has been set to the length of
a single stripe; not the whole write */
if (btrfs_op(bio) == BTRFS_MAP_WRITE) {
ret = raid56_parity_write(bio, bioc, map_length);
} else {
ret = raid56_parity_recover(bio, bioc, map_length,
mirror_num, 1);
}
if (btrfs_op(bio) == BTRFS_MAP_WRITE)
ret = raid56_parity_write(bio, bioc);
else
ret = raid56_parity_recover(bio, bioc, mirror_num, 1);
goto out_dec;
}

Expand Down

0 comments on commit ff18a4a

Please sign in to comment.