btrfs: subpage: make readahead work properly

In readahead infrastructure, we are using a lot of hard coded PAGE_SHIFT
while we're not doing anything specific to PAGE_SIZE.

One of the most affected part is the radix tree operation of
btrfs_fs_info::reada_tree.

If using PAGE_SHIFT, subpage metadata readahead is broken and does no
help reading metadata ahead.

Fix the problem by using btrfs_fs_info::sectorsize_bits so that
readahead could work for subpage.

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:
Qu Wenruo 2021-03-15 13:39:15 +08:00 коммит произвёл David Sterba
Родитель d9bb77d51e
Коммит 60484cd9d5
1 изменённых файлов: 18 добавлений и 17 удалений

Просмотреть файл

@ -209,7 +209,7 @@ int btree_readahead_hook(struct extent_buffer *eb, int err)
/* find extent */ /* find extent */
spin_lock(&fs_info->reada_lock); spin_lock(&fs_info->reada_lock);
re = radix_tree_lookup(&fs_info->reada_tree, re = radix_tree_lookup(&fs_info->reada_tree,
eb->start >> PAGE_SHIFT); eb->start >> fs_info->sectorsize_bits);
if (re) if (re)
re->refcnt++; re->refcnt++;
spin_unlock(&fs_info->reada_lock); spin_unlock(&fs_info->reada_lock);
@ -240,7 +240,7 @@ static struct reada_zone *reada_find_zone(struct btrfs_device *dev, u64 logical,
zone = NULL; zone = NULL;
spin_lock(&fs_info->reada_lock); spin_lock(&fs_info->reada_lock);
ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone,
logical >> PAGE_SHIFT, 1); logical >> fs_info->sectorsize_bits, 1);
if (ret == 1 && logical >= zone->start && logical <= zone->end) { if (ret == 1 && logical >= zone->start && logical <= zone->end) {
kref_get(&zone->refcnt); kref_get(&zone->refcnt);
spin_unlock(&fs_info->reada_lock); spin_unlock(&fs_info->reada_lock);
@ -283,13 +283,13 @@ static struct reada_zone *reada_find_zone(struct btrfs_device *dev, u64 logical,
spin_lock(&fs_info->reada_lock); spin_lock(&fs_info->reada_lock);
ret = radix_tree_insert(&dev->reada_zones, ret = radix_tree_insert(&dev->reada_zones,
(unsigned long)(zone->end >> PAGE_SHIFT), (unsigned long)(zone->end >> fs_info->sectorsize_bits),
zone); zone);
if (ret == -EEXIST) { if (ret == -EEXIST) {
kfree(zone); kfree(zone);
ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone,
logical >> PAGE_SHIFT, 1); logical >> fs_info->sectorsize_bits, 1);
if (ret == 1 && logical >= zone->start && logical <= zone->end) if (ret == 1 && logical >= zone->start && logical <= zone->end)
kref_get(&zone->refcnt); kref_get(&zone->refcnt);
else else
@ -315,7 +315,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_fs_info *fs_info,
u64 length; u64 length;
int real_stripes; int real_stripes;
int nzones = 0; int nzones = 0;
unsigned long index = logical >> PAGE_SHIFT; unsigned long index = logical >> fs_info->sectorsize_bits;
int dev_replace_is_ongoing; int dev_replace_is_ongoing;
int have_zone = 0; int have_zone = 0;
@ -497,7 +497,7 @@ static void reada_extent_put(struct btrfs_fs_info *fs_info,
struct reada_extent *re) struct reada_extent *re)
{ {
int i; int i;
unsigned long index = re->logical >> PAGE_SHIFT; unsigned long index = re->logical >> fs_info->sectorsize_bits;
spin_lock(&fs_info->reada_lock); spin_lock(&fs_info->reada_lock);
if (--re->refcnt) { if (--re->refcnt) {
@ -538,11 +538,12 @@ static void reada_extent_put(struct btrfs_fs_info *fs_info,
static void reada_zone_release(struct kref *kref) static void reada_zone_release(struct kref *kref)
{ {
struct reada_zone *zone = container_of(kref, struct reada_zone, refcnt); struct reada_zone *zone = container_of(kref, struct reada_zone, refcnt);
struct btrfs_fs_info *fs_info = zone->device->fs_info;
lockdep_assert_held(&zone->device->fs_info->reada_lock); lockdep_assert_held(&fs_info->reada_lock);
radix_tree_delete(&zone->device->reada_zones, radix_tree_delete(&zone->device->reada_zones,
zone->end >> PAGE_SHIFT); zone->end >> fs_info->sectorsize_bits);
kfree(zone); kfree(zone);
} }
@ -593,7 +594,7 @@ static int reada_add_block(struct reada_control *rc, u64 logical,
static void reada_peer_zones_set_lock(struct reada_zone *zone, int lock) static void reada_peer_zones_set_lock(struct reada_zone *zone, int lock)
{ {
int i; int i;
unsigned long index = zone->end >> PAGE_SHIFT; unsigned long index = zone->end >> zone->device->fs_info->sectorsize_bits;
for (i = 0; i < zone->ndevs; ++i) { for (i = 0; i < zone->ndevs; ++i) {
struct reada_zone *peer; struct reada_zone *peer;
@ -628,7 +629,7 @@ static int reada_pick_zone(struct btrfs_device *dev)
(void **)&zone, index, 1); (void **)&zone, index, 1);
if (ret == 0) if (ret == 0)
break; break;
index = (zone->end >> PAGE_SHIFT) + 1; index = (zone->end >> dev->fs_info->sectorsize_bits) + 1;
if (zone->locked) { if (zone->locked) {
if (zone->elems > top_locked_elems) { if (zone->elems > top_locked_elems) {
top_locked_elems = zone->elems; top_locked_elems = zone->elems;
@ -709,7 +710,7 @@ static int reada_start_machine_dev(struct btrfs_device *dev)
* plugging to speed things up * plugging to speed things up
*/ */
ret = radix_tree_gang_lookup(&dev->reada_extents, (void **)&re, ret = radix_tree_gang_lookup(&dev->reada_extents, (void **)&re,
dev->reada_next >> PAGE_SHIFT, 1); dev->reada_next >> fs_info->sectorsize_bits, 1);
if (ret == 0 || re->logical > dev->reada_curr_zone->end) { if (ret == 0 || re->logical > dev->reada_curr_zone->end) {
ret = reada_pick_zone(dev); ret = reada_pick_zone(dev);
if (!ret) { if (!ret) {
@ -718,7 +719,7 @@ static int reada_start_machine_dev(struct btrfs_device *dev)
} }
re = NULL; re = NULL;
ret = radix_tree_gang_lookup(&dev->reada_extents, (void **)&re, ret = radix_tree_gang_lookup(&dev->reada_extents, (void **)&re,
dev->reada_next >> PAGE_SHIFT, 1); dev->reada_next >> fs_info->sectorsize_bits, 1);
} }
if (ret == 0) { if (ret == 0) {
spin_unlock(&fs_info->reada_lock); spin_unlock(&fs_info->reada_lock);
@ -885,7 +886,7 @@ static void dump_devs(struct btrfs_fs_info *fs_info, int all)
pr_cont(" curr off %llu", pr_cont(" curr off %llu",
device->reada_next - zone->start); device->reada_next - zone->start);
pr_cont("\n"); pr_cont("\n");
index = (zone->end >> PAGE_SHIFT) + 1; index = (zone->end >> fs_info->sectorsize_bits) + 1;
} }
cnt = 0; cnt = 0;
index = 0; index = 0;
@ -910,7 +911,7 @@ static void dump_devs(struct btrfs_fs_info *fs_info, int all)
} }
} }
pr_cont("\n"); pr_cont("\n");
index = (re->logical >> PAGE_SHIFT) + 1; index = (re->logical >> fs_info->sectorsize_bits) + 1;
if (++cnt > 15) if (++cnt > 15)
break; break;
} }
@ -926,7 +927,7 @@ static void dump_devs(struct btrfs_fs_info *fs_info, int all)
if (ret == 0) if (ret == 0)
break; break;
if (!re->scheduled) { if (!re->scheduled) {
index = (re->logical >> PAGE_SHIFT) + 1; index = (re->logical >> fs_info->sectorsize_bits) + 1;
continue; continue;
} }
pr_debug("re: logical %llu size %u list empty %d scheduled %d", pr_debug("re: logical %llu size %u list empty %d scheduled %d",
@ -942,7 +943,7 @@ static void dump_devs(struct btrfs_fs_info *fs_info, int all)
} }
} }
pr_cont("\n"); pr_cont("\n");
index = (re->logical >> PAGE_SHIFT) + 1; index = (re->logical >> fs_info->sectorsize_bits) + 1;
} }
spin_unlock(&fs_info->reada_lock); spin_unlock(&fs_info->reada_lock);
} }