Instead of calculating the superblock location every time, cache the
superblock zone location in btrfs_zoned_device_info struct and use it to
locate the zone index.

The functions such as btrfs_sb_log_location_bdev() and
btrfs_reset_sb_log_zones() which work directly on block_device shall
continue to use the sb_zone_number because btrfs_zoned_device_info
struct might not have been initialized at that point.

This patch will enable non power-of-2 zoned devices to not perform
division to lookup superblock and its mirror location.

Reviewed-by: Luis Chamberlain <mcg...@kernel.org>
Signed-off-by: Pankaj Raghav <p.rag...@samsung.com>
---
 fs/btrfs/zoned.c | 13 +++++++++----
 fs/btrfs/zoned.h |  1 +
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index 1b1b310c3c51..6f76942d0ea5 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -512,6 +512,11 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, 
bool populate_cache)
                           max_active_zones - nactive);
        }
 
+       /* Cache the sb zone number */
+       for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; ++i) {
+               zone_info->sb_zone_location[i] =
+                       sb_zone_number(zone_info->zone_size_shift, i);
+       }
        /* Validate superblock log */
        nr_zones = BTRFS_NR_SB_LOG_ZONES;
        for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
@@ -519,7 +524,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, 
bool populate_cache)
                u64 sb_wp;
                int sb_pos = BTRFS_NR_SB_LOG_ZONES * i;
 
-               sb_zone = sb_zone_number(zone_info->zone_size_shift, i);
+               sb_zone = zone_info->sb_zone_location[i];
                if (sb_zone + 1 >= zone_info->nr_zones)
                        continue;
 
@@ -867,7 +872,7 @@ int btrfs_sb_log_location(struct btrfs_device *device, int 
mirror, int rw,
                return 0;
        }
 
-       zone_num = sb_zone_number(zinfo->zone_size_shift, mirror);
+       zone_num = zinfo->sb_zone_location[mirror];
        if (zone_num + 1 >= zinfo->nr_zones)
                return -ENOENT;
 
@@ -884,7 +889,7 @@ static inline bool is_sb_log_zone(struct 
btrfs_zoned_device_info *zinfo,
        if (!zinfo)
                return false;
 
-       zone_num = sb_zone_number(zinfo->zone_size_shift, mirror);
+       zone_num = zinfo->sb_zone_location[mirror];
        if (zone_num + 1 >= zinfo->nr_zones)
                return false;
 
@@ -1012,7 +1017,7 @@ u64 btrfs_find_allocatable_zones(struct btrfs_device 
*device, u64 hole_start,
                        u32 sb_zone;
                        u64 sb_pos;
 
-                       sb_zone = sb_zone_number(shift, i);
+                       sb_zone = zinfo->sb_zone_location[i];
                        if (!(end <= sb_zone ||
                              sb_zone + BTRFS_NR_SB_LOG_ZONES <= begin)) {
                                have_sb = true;
diff --git a/fs/btrfs/zoned.h b/fs/btrfs/zoned.h
index cbf016a7bb5d..49317524e9a6 100644
--- a/fs/btrfs/zoned.h
+++ b/fs/btrfs/zoned.h
@@ -31,6 +31,7 @@ struct btrfs_zoned_device_info {
        unsigned long *active_zones;
        struct blk_zone *zone_cache;
        struct blk_zone sb_zones[2 * BTRFS_SUPER_MIRROR_MAX];
+       u32 sb_zone_location[BTRFS_SUPER_MIRROR_MAX];
 };
 
 #ifdef CONFIG_BLK_DEV_ZONED
-- 
2.25.1

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel

Reply via email to