Message ID | 20190130074000.16638-2-wqu@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: Speedup chunk allocation for large fs | expand |
On 30.01.19 г. 9:39 ч., Qu Wenruo wrote: > verify_one_dev_extent() will call btrfs_find_device() for each dev > extent, this waste some CPU time just searching the devices list. > > Move the search one level up, into the btrfs_verify_dev_extents(), so > for each device we only call btrfs_find_device() once. > > Signed-off-by: Qu Wenruo <wqu@suse.com> Seems the sane thing to do, so: Reviewed-by: Nikolay Borisov <nborisov@suse.com> > --- > fs/btrfs/volumes.c | 26 ++++++++++++++++---------- > 1 file changed, 16 insertions(+), 10 deletions(-) > > diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c > index 2576b1a379c9..8e932d7d2fe6 100644 > --- a/fs/btrfs/volumes.c > +++ b/fs/btrfs/volumes.c > @@ -7761,13 +7761,14 @@ static u64 calc_stripe_length(u64 type, u64 chunk_len, int num_stripes) > } > > static int verify_one_dev_extent(struct btrfs_fs_info *fs_info, > - u64 chunk_offset, u64 devid, > - u64 physical_offset, u64 physical_len) > + struct btrfs_device *dev, > + u64 chunk_offset, u64 physical_offset, > + u64 physical_len) > { > struct extent_map_tree *em_tree = &fs_info->mapping_tree.map_tree; > struct extent_map *em; > struct map_lookup *map; > - struct btrfs_device *dev; > + u64 devid = dev->devid; > u64 stripe_len; > bool found = false; > int ret = 0; > @@ -7819,12 +7820,6 @@ static int verify_one_dev_extent(struct btrfs_fs_info *fs_info, > } > > /* Make sure no dev extent is beyond device bondary */ > - dev = btrfs_find_device(fs_info, devid, NULL, NULL); > - if (!dev) { > - btrfs_err(fs_info, "failed to find devid %llu", devid); > - ret = -EUCLEAN; > - goto out; > - } > if (physical_offset + physical_len > dev->disk_total_bytes) { > btrfs_err(fs_info, > "dev extent devid %llu physical offset %llu len %llu is beyond device boundary %llu", > @@ -7874,6 +7869,7 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info) > { > struct btrfs_path *path; > struct btrfs_root *root = fs_info->dev_root; > + struct btrfs_device *device = NULL; > struct btrfs_key key; > u64 prev_devid = 0; > u64 prev_dev_ext_end = 0; > @@ -7917,6 +7913,16 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info) > devid = key.objectid; > physical_offset = key.offset; > > + if (!device || devid != device->devid) { > + device = btrfs_find_device(fs_info, devid, NULL, NULL); > + if (!device) { > + btrfs_err(fs_info, "failed to find devid %llu", > + devid); > + ret = -EUCLEAN; > + goto out; > + } > + } > + > dext = btrfs_item_ptr(leaf, slot, struct btrfs_dev_extent); > chunk_offset = btrfs_dev_extent_chunk_offset(leaf, dext); > physical_len = btrfs_dev_extent_length(leaf, dext); > @@ -7930,7 +7936,7 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info) > goto out; > } > > - ret = verify_one_dev_extent(fs_info, chunk_offset, devid, > + ret = verify_one_dev_extent(fs_info, device, chunk_offset, > physical_offset, physical_len); > if (ret < 0) > goto out; >
On 1/30/19 3:39 PM, Qu Wenruo wrote: > verify_one_dev_extent() will call btrfs_find_device() for each dev > extent, this waste some CPU time just searching the devices list. > Move the search one level up, into the btrfs_verify_dev_extents(), so > for each device we only call btrfs_find_device() once. This does not apply on misc-next. Looks like this patch's branch is missing the seed fix. Looks good. Reviewed-by: Anand Jain <anand.jain@oracle.com> > Signed-off-by: Qu Wenruo <wqu@suse.com> > --- > fs/btrfs/volumes.c | 26 ++++++++++++++++---------- > 1 file changed, 16 insertions(+), 10 deletions(-) > > diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c > index 2576b1a379c9..8e932d7d2fe6 100644 > --- a/fs/btrfs/volumes.c > +++ b/fs/btrfs/volumes.c > @@ -7761,13 +7761,14 @@ static u64 calc_stripe_length(u64 type, u64 chunk_len, int num_stripes) > } > > static int verify_one_dev_extent(struct btrfs_fs_info *fs_info, > - u64 chunk_offset, u64 devid, > - u64 physical_offset, u64 physical_len) > + struct btrfs_device *dev, > + u64 chunk_offset, u64 physical_offset, > + u64 physical_len) > { > struct extent_map_tree *em_tree = &fs_info->mapping_tree.map_tree; > struct extent_map *em; > struct map_lookup *map; > - struct btrfs_device *dev; > + u64 devid = dev->devid; > u64 stripe_len; > bool found = false; > int ret = 0; > @@ -7819,12 +7820,6 @@ static int verify_one_dev_extent(struct btrfs_fs_info *fs_info, > } > > /* Make sure no dev extent is beyond device bondary */ > - dev = btrfs_find_device(fs_info, devid, NULL, NULL); > - if (!dev) { > - btrfs_err(fs_info, "failed to find devid %llu", devid); > - ret = -EUCLEAN; > - goto out; > - } > if (physical_offset + physical_len > dev->disk_total_bytes) { > btrfs_err(fs_info, > "dev extent devid %llu physical offset %llu len %llu is beyond device boundary %llu", > @@ -7874,6 +7869,7 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info) > { > struct btrfs_path *path; > struct btrfs_root *root = fs_info->dev_root; > + struct btrfs_device *device = NULL; > struct btrfs_key key; > u64 prev_devid = 0; > u64 prev_dev_ext_end = 0; > @@ -7917,6 +7913,16 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info) > devid = key.objectid; > physical_offset = key.offset; > > + if (!device || devid != device->devid) { > + device = btrfs_find_device(fs_info, devid, NULL, NULL); > + if (!device) { > + btrfs_err(fs_info, "failed to find devid %llu", > + devid); > + ret = -EUCLEAN; > + goto out; > + } > + } > + > dext = btrfs_item_ptr(leaf, slot, struct btrfs_dev_extent); > chunk_offset = btrfs_dev_extent_chunk_offset(leaf, dext); > physical_len = btrfs_dev_extent_length(leaf, dext); > @@ -7930,7 +7936,7 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info) > goto out; > } > > - ret = verify_one_dev_extent(fs_info, chunk_offset, devid, > + ret = verify_one_dev_extent(fs_info, device, chunk_offset, > physical_offset, physical_len); > if (ret < 0) > goto out; >
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 2576b1a379c9..8e932d7d2fe6 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -7761,13 +7761,14 @@ static u64 calc_stripe_length(u64 type, u64 chunk_len, int num_stripes) } static int verify_one_dev_extent(struct btrfs_fs_info *fs_info, - u64 chunk_offset, u64 devid, - u64 physical_offset, u64 physical_len) + struct btrfs_device *dev, + u64 chunk_offset, u64 physical_offset, + u64 physical_len) { struct extent_map_tree *em_tree = &fs_info->mapping_tree.map_tree; struct extent_map *em; struct map_lookup *map; - struct btrfs_device *dev; + u64 devid = dev->devid; u64 stripe_len; bool found = false; int ret = 0; @@ -7819,12 +7820,6 @@ static int verify_one_dev_extent(struct btrfs_fs_info *fs_info, } /* Make sure no dev extent is beyond device bondary */ - dev = btrfs_find_device(fs_info, devid, NULL, NULL); - if (!dev) { - btrfs_err(fs_info, "failed to find devid %llu", devid); - ret = -EUCLEAN; - goto out; - } if (physical_offset + physical_len > dev->disk_total_bytes) { btrfs_err(fs_info, "dev extent devid %llu physical offset %llu len %llu is beyond device boundary %llu", @@ -7874,6 +7869,7 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info) { struct btrfs_path *path; struct btrfs_root *root = fs_info->dev_root; + struct btrfs_device *device = NULL; struct btrfs_key key; u64 prev_devid = 0; u64 prev_dev_ext_end = 0; @@ -7917,6 +7913,16 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info) devid = key.objectid; physical_offset = key.offset; + if (!device || devid != device->devid) { + device = btrfs_find_device(fs_info, devid, NULL, NULL); + if (!device) { + btrfs_err(fs_info, "failed to find devid %llu", + devid); + ret = -EUCLEAN; + goto out; + } + } + dext = btrfs_item_ptr(leaf, slot, struct btrfs_dev_extent); chunk_offset = btrfs_dev_extent_chunk_offset(leaf, dext); physical_len = btrfs_dev_extent_length(leaf, dext); @@ -7930,7 +7936,7 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info) goto out; } - ret = verify_one_dev_extent(fs_info, chunk_offset, devid, + ret = verify_one_dev_extent(fs_info, device, chunk_offset, physical_offset, physical_len); if (ret < 0) goto out;
verify_one_dev_extent() will call btrfs_find_device() for each dev extent, this waste some CPU time just searching the devices list. Move the search one level up, into the btrfs_verify_dev_extents(), so for each device we only call btrfs_find_device() once. Signed-off-by: Qu Wenruo <wqu@suse.com> --- fs/btrfs/volumes.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)