Add helpers to calculate alignment, round up and round down for zoned devices. These helpers encapsulates the necessary handling for power_of_2 and non-power_of_2 zone sizes. Optimized calculations are performed for zone sizes that are power_of_2 with log and shifts. btrfs_zoned_is_aligned() is added instead of reusing bdev_zone_aligned() helper is due to some use cases in btrfs where zone alignment is checked before having access to the underlying block device such as in this function: btrfs_load_block_group_zone_info(). Reviewed-by: Luis Chamberlain <mcgrof@xxxxxxxxxx> Signed-off-by: Pankaj Raghav <p.raghav@xxxxxxxxxxx> --- fs/btrfs/zoned.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/fs/btrfs/zoned.h b/fs/btrfs/zoned.h index 49317524e9a6..b9c435961361 100644 --- a/fs/btrfs/zoned.h +++ b/fs/btrfs/zoned.h @@ -9,6 +9,7 @@ #include "disk-io.h" #include "block-group.h" #include "btrfs_inode.h" +#include "misc.h" /* * Block groups with more than this value (percents) of unusable space will be @@ -34,6 +35,33 @@ struct btrfs_zoned_device_info { u32 sb_zone_location[BTRFS_SUPER_MIRROR_MAX]; }; +static inline bool btrfs_zoned_is_aligned(u64 pos, u64 zone_size) +{ + u64 remainder = 0; + + if (is_power_of_two_u64(zone_size)) + return IS_ALIGNED(pos, zone_size); + + div64_u64_rem(pos, zone_size, &remainder); + return remainder == 0; +} + +static inline u64 btrfs_zoned_roundup(u64 pos, u64 zone_size) +{ + if (is_power_of_two_u64(zone_size)) + return ALIGN(pos, zone_size); + + return roundup(pos, zone_size); +} + +static inline u64 btrfs_zoned_rounddown(u64 pos, u64 zone_size) +{ + if (is_power_of_two_u64(zone_size)) + return round_down(pos, zone_size); + + return rounddown(pos, zone_size); +} + #ifdef CONFIG_BLK_DEV_ZONED int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, struct blk_zone *zone); -- 2.25.1