Commit 36920044 authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba

btrfs: raid56: avoid double for loop inside finish_rmw()

We can easily calculate the stripe number and sector number inside the
stripe.  Thus there is not much need for a double for loop.

For the only case we want to skip the whole stripe, we can manually
increase @total_sector_nr.
This is not a recommended behavior, thus every time the iterator gets
modified there will be a comment along with an ASSERT() for it.
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent f31f09f6
...@@ -1182,7 +1182,10 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) ...@@ -1182,7 +1182,10 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
const u32 sectorsize = bioc->fs_info->sectorsize; const u32 sectorsize = bioc->fs_info->sectorsize;
void **pointers = rbio->finish_pointers; void **pointers = rbio->finish_pointers;
int nr_data = rbio->nr_data; int nr_data = rbio->nr_data;
/* The total sector number inside the full stripe. */
int total_sector_nr;
int stripe; int stripe;
/* Sector number inside a stripe. */
int sectornr; int sectornr;
bool has_qstripe; bool has_qstripe;
struct bio_list bio_list; struct bio_list bio_list;
...@@ -1267,63 +1270,73 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) ...@@ -1267,63 +1270,73 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
} }
/* /*
* time to start writing. Make bios for everything from the * Start writing. Make bios for everything from the higher layers (the
* higher layers (the bio_list in our rbio) and our p/q. Ignore * bio_list in our rbio) and our P/Q. Ignore everything else.
* everything else.
*/ */
for (stripe = 0; stripe < rbio->real_stripes; stripe++) { for (total_sector_nr = 0; total_sector_nr < rbio->nr_sectors;
for (sectornr = 0; sectornr < rbio->stripe_nsectors; sectornr++) { total_sector_nr++) {
struct sector_ptr *sector; struct sector_ptr *sector;
/* This vertical stripe has no data, skip it. */ stripe = total_sector_nr / rbio->stripe_nsectors;
if (!test_bit(sectornr, &rbio->dbitmap)) sectornr = total_sector_nr % rbio->stripe_nsectors;
continue;
if (stripe < rbio->nr_data) { /* This vertical stripe has no data, skip it. */
sector = sector_in_rbio(rbio, stripe, sectornr, 1); if (!test_bit(sectornr, &rbio->dbitmap))
if (!sector) continue;
continue;
} else {
sector = rbio_stripe_sector(rbio, stripe, sectornr);
}
ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe, if (stripe < rbio->nr_data) {
sectornr, rbio->stripe_len, sector = sector_in_rbio(rbio, stripe, sectornr, 1);
REQ_OP_WRITE); if (!sector)
if (ret) continue;
goto cleanup; } else {
sector = rbio_stripe_sector(rbio, stripe, sectornr);
} }
ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe,
sectornr, rbio->stripe_len,
REQ_OP_WRITE);
if (ret)
goto cleanup;
} }
if (likely(!bioc->num_tgtdevs)) if (likely(!bioc->num_tgtdevs))
goto write_data; goto write_data;
for (stripe = 0; stripe < rbio->real_stripes; stripe++) { for (total_sector_nr = 0; total_sector_nr < rbio->nr_sectors;
if (!bioc->tgtdev_map[stripe]) total_sector_nr++) {
continue; struct sector_ptr *sector;
for (sectornr = 0; sectornr < rbio->stripe_nsectors; sectornr++) { stripe = total_sector_nr / rbio->stripe_nsectors;
struct sector_ptr *sector; sectornr = total_sector_nr % rbio->stripe_nsectors;
/* This vertical stripe has no data, skip it. */ if (!bioc->tgtdev_map[stripe]) {
if (!test_bit(sectornr, &rbio->dbitmap)) /*
continue; * We can skip the whole stripe completely, note
* total_sector_nr will be increased by one anyway.
*/
ASSERT(sectornr == 0);
total_sector_nr += rbio->stripe_nsectors - 1;
continue;
}
if (stripe < rbio->nr_data) { /* This vertical stripe has no data, skip it. */
sector = sector_in_rbio(rbio, stripe, sectornr, 1); if (!test_bit(sectornr, &rbio->dbitmap))
if (!sector) continue;
continue;
} else {
sector = rbio_stripe_sector(rbio, stripe, sectornr);
}
ret = rbio_add_io_sector(rbio, &bio_list, sector, if (stripe < rbio->nr_data) {
rbio->bioc->tgtdev_map[stripe], sector = sector_in_rbio(rbio, stripe, sectornr, 1);
sectornr, rbio->stripe_len, if (!sector)
REQ_OP_WRITE); continue;
if (ret) } else {
goto cleanup; sector = rbio_stripe_sector(rbio, stripe, sectornr);
} }
ret = rbio_add_io_sector(rbio, &bio_list, sector,
rbio->bioc->tgtdev_map[stripe],
sectornr, rbio->stripe_len,
REQ_OP_WRITE);
if (ret)
goto cleanup;
} }
write_data: write_data:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment