mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
btrfs: scrub: implement calc_sector_number() in a faster way
Currently calc_sector_number() is implemented by comparing the first
bvec of the bbio against all blocks inside a scrub_stripe.
This implementation is a little inefficient, and depends on how the
scrub buffer is implemented.
One of the reason implementing such complex function is that, we do not
save the original bvec_iter inside a write btrfs_bio.
Although a read bbio has btrfs_bio::saved_iter to get the original
logical bytenr, it's not implemented for write bios.
On the other hand, since commit 81cea6cd70 ("btrfs: remove
btrfs_bio::fs_info by extracting it from btrfs_bio::inode"), we always
set the btrfs_bio::file_offset as the logical bytenr for scrub, and that
member will not be modified during IO.
So this means we have a stable way to determine the logical bytenr for a
scrub bio, now calc_sector_number() is just as simple as:
return (bbio->file_offset - stripe->logical) >> sectorsize_bits;
Since we're here, also add an ASSERT() to make sure the bbio is inside
the stripe, and change the return type to unsigned int to be extra safe.
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
1462637d55
commit
36c9fddcf8
|
|
@ -864,16 +864,19 @@ static void scrub_verify_one_stripe(struct scrub_stripe *stripe, unsigned long b
|
|||
}
|
||||
}
|
||||
|
||||
static int calc_sector_number(struct scrub_stripe *stripe, struct bio_vec *first_bvec)
|
||||
static unsigned int calc_sector_number(const struct btrfs_bio *bbio)
|
||||
{
|
||||
int i;
|
||||
const struct scrub_stripe *stripe = bbio->private;
|
||||
const struct btrfs_fs_info *fs_info = stripe->bg->fs_info;
|
||||
|
||||
for (i = 0; i < stripe->nr_sectors; i++) {
|
||||
if (scrub_stripe_get_kaddr(stripe, i) == bvec_virt(first_bvec))
|
||||
break;
|
||||
}
|
||||
ASSERT(i < stripe->nr_sectors);
|
||||
return i;
|
||||
/* Scrub bbios all have their @file_offset set to the logical bytenr. */
|
||||
ASSERT(bbio->file_offset >= stripe->logical &&
|
||||
bbio->file_offset < stripe->logical + (stripe->nr_sectors <<
|
||||
fs_info->sectorsize_bits),
|
||||
"scrub bio logical=%llu stripe logical=%llu stripe len=%u",
|
||||
bbio->file_offset, stripe->logical,
|
||||
stripe->nr_sectors << fs_info->sectorsize_bits);
|
||||
return (bbio->file_offset - stripe->logical) >> fs_info->sectorsize_bits;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -885,12 +888,10 @@ static void scrub_read_endio_common(struct btrfs_bio *bbio)
|
|||
{
|
||||
struct scrub_stripe *stripe = bbio->private;
|
||||
struct btrfs_fs_info *fs_info = stripe->bg->fs_info;
|
||||
int sector_nr = calc_sector_number(stripe, bio_first_bvec_all(&bbio->bio));
|
||||
unsigned int sector_nr = calc_sector_number(bbio);
|
||||
const u32 bio_size = bio_get_size(&bbio->bio);
|
||||
const u32 sectors = bio_size >> fs_info->sectorsize_bits;
|
||||
|
||||
ASSERT(sector_nr < stripe->nr_sectors);
|
||||
|
||||
if (bbio->bio.bi_status) {
|
||||
scrub_bitmap_set_io_error(stripe, sector_nr, sectors);
|
||||
scrub_bitmap_set_error(stripe, sector_nr, sectors);
|
||||
|
|
@ -1264,7 +1265,7 @@ static void scrub_write_endio(struct btrfs_bio *bbio)
|
|||
{
|
||||
struct scrub_stripe *stripe = bbio->private;
|
||||
struct btrfs_fs_info *fs_info = stripe->bg->fs_info;
|
||||
int sector_nr = calc_sector_number(stripe, bio_first_bvec_all(&bbio->bio));
|
||||
unsigned int sector_nr = calc_sector_number(bbio);
|
||||
const u32 bio_size = bio_get_size(&bbio->bio);
|
||||
|
||||
if (bbio->bio.bi_status) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user