15b316468SNaohiro Aota /* SPDX-License-Identifier: GPL-2.0 */ 25b316468SNaohiro Aota 35b316468SNaohiro Aota #ifndef BTRFS_ZONED_H 45b316468SNaohiro Aota #define BTRFS_ZONED_H 55b316468SNaohiro Aota 65b316468SNaohiro Aota #include <linux/types.h> 7b70f5097SNaohiro Aota #include <linux/blkdev.h> 812659251SNaohiro Aota #include "volumes.h" 912659251SNaohiro Aota #include "disk-io.h" 1040ab3be1SNaohiro Aota #include "block-group.h" 115b316468SNaohiro Aota 12*18bb8bbfSJohannes Thumshirn /* 13*18bb8bbfSJohannes Thumshirn * Block groups with more than this value (percents) of unusable space will be 14*18bb8bbfSJohannes Thumshirn * scheduled for background reclaim. 15*18bb8bbfSJohannes Thumshirn */ 16*18bb8bbfSJohannes Thumshirn #define BTRFS_DEFAULT_RECLAIM_THRESH 75 17*18bb8bbfSJohannes Thumshirn 185b316468SNaohiro Aota struct btrfs_zoned_device_info { 195b316468SNaohiro Aota /* 205b316468SNaohiro Aota * Number of zones, zone size and types of zones if bdev is a 215b316468SNaohiro Aota * zoned block device. 225b316468SNaohiro Aota */ 235b316468SNaohiro Aota u64 zone_size; 245b316468SNaohiro Aota u8 zone_size_shift; 25862931c7SNaohiro Aota u64 max_zone_append_size; 265b316468SNaohiro Aota u32 nr_zones; 275b316468SNaohiro Aota unsigned long *seq_zones; 285b316468SNaohiro Aota unsigned long *empty_zones; 2912659251SNaohiro Aota struct blk_zone sb_zones[2 * BTRFS_SUPER_MIRROR_MAX]; 305b316468SNaohiro Aota }; 315b316468SNaohiro Aota 325b316468SNaohiro Aota #ifdef CONFIG_BLK_DEV_ZONED 335b316468SNaohiro Aota int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, 345b316468SNaohiro Aota struct blk_zone *zone); 3573651042SNaohiro Aota int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info); 365b316468SNaohiro Aota int btrfs_get_dev_zone_info(struct btrfs_device *device); 375b316468SNaohiro Aota void btrfs_destroy_dev_zone_info(struct btrfs_device *device); 38b70f5097SNaohiro Aota int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info); 395d1ab66cSNaohiro Aota int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info); 4012659251SNaohiro Aota int btrfs_sb_log_location_bdev(struct block_device *bdev, int mirror, int rw, 4112659251SNaohiro Aota u64 *bytenr_ret); 4212659251SNaohiro Aota int btrfs_sb_log_location(struct btrfs_device *device, int mirror, int rw, 4312659251SNaohiro Aota u64 *bytenr_ret); 4412659251SNaohiro Aota void btrfs_advance_sb_log(struct btrfs_device *device, int mirror); 4512659251SNaohiro Aota int btrfs_reset_sb_log_zones(struct block_device *bdev, int mirror); 461cd6121fSNaohiro Aota u64 btrfs_find_allocatable_zones(struct btrfs_device *device, u64 hole_start, 471cd6121fSNaohiro Aota u64 hole_end, u64 num_bytes); 481cd6121fSNaohiro Aota int btrfs_reset_device_zone(struct btrfs_device *device, u64 physical, 491cd6121fSNaohiro Aota u64 length, u64 *bytes); 501cd6121fSNaohiro Aota int btrfs_ensure_empty_zones(struct btrfs_device *device, u64 start, u64 size); 51a94794d5SNaohiro Aota int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new); 52169e0da9SNaohiro Aota void btrfs_calc_zone_unusable(struct btrfs_block_group *cache); 53d3575156SNaohiro Aota void btrfs_redirty_list_add(struct btrfs_transaction *trans, 54d3575156SNaohiro Aota struct extent_buffer *eb); 55d3575156SNaohiro Aota void btrfs_free_redirty_list(struct btrfs_transaction *trans); 5608f45559SJohannes Thumshirn bool btrfs_use_zone_append(struct btrfs_inode *inode, struct extent_map *em); 57d8e3fb10SNaohiro Aota void btrfs_record_physical_zoned(struct inode *inode, u64 file_offset, 58d8e3fb10SNaohiro Aota struct bio *bio); 59d8e3fb10SNaohiro Aota void btrfs_rewrite_logical_zoned(struct btrfs_ordered_extent *ordered); 600bc09ca1SNaohiro Aota bool btrfs_check_meta_write_pointer(struct btrfs_fs_info *fs_info, 610bc09ca1SNaohiro Aota struct extent_buffer *eb, 620bc09ca1SNaohiro Aota struct btrfs_block_group **cache_ret); 630bc09ca1SNaohiro Aota void btrfs_revert_meta_write_pointer(struct btrfs_block_group *cache, 640bc09ca1SNaohiro Aota struct extent_buffer *eb); 65de17addcSNaohiro Aota int btrfs_zoned_issue_zeroout(struct btrfs_device *device, u64 physical, u64 length); 667db1c5d1SNaohiro Aota int btrfs_sync_zone_write_pointer(struct btrfs_device *tgt_dev, u64 logical, 677db1c5d1SNaohiro Aota u64 physical_start, u64 physical_pos); 685b316468SNaohiro Aota #else /* CONFIG_BLK_DEV_ZONED */ 695b316468SNaohiro Aota static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, 705b316468SNaohiro Aota struct blk_zone *zone) 715b316468SNaohiro Aota { 725b316468SNaohiro Aota return 0; 735b316468SNaohiro Aota } 745b316468SNaohiro Aota 7573651042SNaohiro Aota static inline int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info) 7673651042SNaohiro Aota { 7773651042SNaohiro Aota return 0; 7873651042SNaohiro Aota } 7973651042SNaohiro Aota 805b316468SNaohiro Aota static inline int btrfs_get_dev_zone_info(struct btrfs_device *device) 815b316468SNaohiro Aota { 825b316468SNaohiro Aota return 0; 835b316468SNaohiro Aota } 845b316468SNaohiro Aota 855b316468SNaohiro Aota static inline void btrfs_destroy_dev_zone_info(struct btrfs_device *device) { } 865b316468SNaohiro Aota 87b70f5097SNaohiro Aota static inline int btrfs_check_zoned_mode(const struct btrfs_fs_info *fs_info) 88b70f5097SNaohiro Aota { 89b70f5097SNaohiro Aota if (!btrfs_is_zoned(fs_info)) 90b70f5097SNaohiro Aota return 0; 91b70f5097SNaohiro Aota 92b70f5097SNaohiro Aota btrfs_err(fs_info, "zoned block devices support is not enabled"); 93b70f5097SNaohiro Aota return -EOPNOTSUPP; 94b70f5097SNaohiro Aota } 95b70f5097SNaohiro Aota 965d1ab66cSNaohiro Aota static inline int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info) 975d1ab66cSNaohiro Aota { 985d1ab66cSNaohiro Aota return 0; 995d1ab66cSNaohiro Aota } 1005d1ab66cSNaohiro Aota 10112659251SNaohiro Aota static inline int btrfs_sb_log_location_bdev(struct block_device *bdev, 10212659251SNaohiro Aota int mirror, int rw, u64 *bytenr_ret) 10312659251SNaohiro Aota { 10412659251SNaohiro Aota *bytenr_ret = btrfs_sb_offset(mirror); 10512659251SNaohiro Aota return 0; 10612659251SNaohiro Aota } 10712659251SNaohiro Aota 10812659251SNaohiro Aota static inline int btrfs_sb_log_location(struct btrfs_device *device, int mirror, 10912659251SNaohiro Aota int rw, u64 *bytenr_ret) 11012659251SNaohiro Aota { 11112659251SNaohiro Aota *bytenr_ret = btrfs_sb_offset(mirror); 11212659251SNaohiro Aota return 0; 11312659251SNaohiro Aota } 11412659251SNaohiro Aota 11512659251SNaohiro Aota static inline void btrfs_advance_sb_log(struct btrfs_device *device, int mirror) 11612659251SNaohiro Aota { } 11712659251SNaohiro Aota 11812659251SNaohiro Aota static inline int btrfs_reset_sb_log_zones(struct block_device *bdev, int mirror) 11912659251SNaohiro Aota { 12012659251SNaohiro Aota return 0; 12112659251SNaohiro Aota } 12212659251SNaohiro Aota 1231cd6121fSNaohiro Aota static inline u64 btrfs_find_allocatable_zones(struct btrfs_device *device, 1241cd6121fSNaohiro Aota u64 hole_start, u64 hole_end, 1251cd6121fSNaohiro Aota u64 num_bytes) 1261cd6121fSNaohiro Aota { 1271cd6121fSNaohiro Aota return hole_start; 1281cd6121fSNaohiro Aota } 1291cd6121fSNaohiro Aota 1301cd6121fSNaohiro Aota static inline int btrfs_reset_device_zone(struct btrfs_device *device, 1311cd6121fSNaohiro Aota u64 physical, u64 length, u64 *bytes) 1321cd6121fSNaohiro Aota { 1331cd6121fSNaohiro Aota *bytes = 0; 1341cd6121fSNaohiro Aota return 0; 1351cd6121fSNaohiro Aota } 1361cd6121fSNaohiro Aota 1371cd6121fSNaohiro Aota static inline int btrfs_ensure_empty_zones(struct btrfs_device *device, 1381cd6121fSNaohiro Aota u64 start, u64 size) 1391cd6121fSNaohiro Aota { 1401cd6121fSNaohiro Aota return 0; 1411cd6121fSNaohiro Aota } 1421cd6121fSNaohiro Aota 14308e11a3dSNaohiro Aota static inline int btrfs_load_block_group_zone_info( 144a94794d5SNaohiro Aota struct btrfs_block_group *cache, bool new) 14508e11a3dSNaohiro Aota { 14608e11a3dSNaohiro Aota return 0; 14708e11a3dSNaohiro Aota } 14808e11a3dSNaohiro Aota 149169e0da9SNaohiro Aota static inline void btrfs_calc_zone_unusable(struct btrfs_block_group *cache) { } 150169e0da9SNaohiro Aota 151d3575156SNaohiro Aota static inline void btrfs_redirty_list_add(struct btrfs_transaction *trans, 152d3575156SNaohiro Aota struct extent_buffer *eb) { } 153d3575156SNaohiro Aota static inline void btrfs_free_redirty_list(struct btrfs_transaction *trans) { } 154d3575156SNaohiro Aota 15508f45559SJohannes Thumshirn static inline bool btrfs_use_zone_append(struct btrfs_inode *inode, 15608f45559SJohannes Thumshirn struct extent_map *em) 15708f45559SJohannes Thumshirn { 15808f45559SJohannes Thumshirn return false; 15908f45559SJohannes Thumshirn } 160d8e3fb10SNaohiro Aota 161d8e3fb10SNaohiro Aota static inline void btrfs_record_physical_zoned(struct inode *inode, 162d8e3fb10SNaohiro Aota u64 file_offset, struct bio *bio) 163d8e3fb10SNaohiro Aota { 164d8e3fb10SNaohiro Aota } 165d8e3fb10SNaohiro Aota 166d8e3fb10SNaohiro Aota static inline void btrfs_rewrite_logical_zoned( 167d8e3fb10SNaohiro Aota struct btrfs_ordered_extent *ordered) { } 168d8e3fb10SNaohiro Aota 1690bc09ca1SNaohiro Aota static inline bool btrfs_check_meta_write_pointer(struct btrfs_fs_info *fs_info, 1700bc09ca1SNaohiro Aota struct extent_buffer *eb, 1710bc09ca1SNaohiro Aota struct btrfs_block_group **cache_ret) 1720bc09ca1SNaohiro Aota { 1730bc09ca1SNaohiro Aota return true; 1740bc09ca1SNaohiro Aota } 1750bc09ca1SNaohiro Aota 1760bc09ca1SNaohiro Aota static inline void btrfs_revert_meta_write_pointer( 1770bc09ca1SNaohiro Aota struct btrfs_block_group *cache, 1780bc09ca1SNaohiro Aota struct extent_buffer *eb) 1790bc09ca1SNaohiro Aota { 1800bc09ca1SNaohiro Aota } 1810bc09ca1SNaohiro Aota 182de17addcSNaohiro Aota static inline int btrfs_zoned_issue_zeroout(struct btrfs_device *device, 183de17addcSNaohiro Aota u64 physical, u64 length) 184de17addcSNaohiro Aota { 185de17addcSNaohiro Aota return -EOPNOTSUPP; 186de17addcSNaohiro Aota } 187de17addcSNaohiro Aota 1887db1c5d1SNaohiro Aota static inline int btrfs_sync_zone_write_pointer(struct btrfs_device *tgt_dev, 1897db1c5d1SNaohiro Aota u64 logical, u64 physical_start, 1907db1c5d1SNaohiro Aota u64 physical_pos) 1917db1c5d1SNaohiro Aota { 1927db1c5d1SNaohiro Aota return -EOPNOTSUPP; 1937db1c5d1SNaohiro Aota } 1947db1c5d1SNaohiro Aota 1955b316468SNaohiro Aota #endif 1965b316468SNaohiro Aota 1975b316468SNaohiro Aota static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos) 1985b316468SNaohiro Aota { 1995b316468SNaohiro Aota struct btrfs_zoned_device_info *zone_info = device->zone_info; 2005b316468SNaohiro Aota 2015b316468SNaohiro Aota if (!zone_info) 2025b316468SNaohiro Aota return false; 2035b316468SNaohiro Aota 2045b316468SNaohiro Aota return test_bit(pos >> zone_info->zone_size_shift, zone_info->seq_zones); 2055b316468SNaohiro Aota } 2065b316468SNaohiro Aota 2075b316468SNaohiro Aota static inline bool btrfs_dev_is_empty_zone(struct btrfs_device *device, u64 pos) 2085b316468SNaohiro Aota { 2095b316468SNaohiro Aota struct btrfs_zoned_device_info *zone_info = device->zone_info; 2105b316468SNaohiro Aota 2115b316468SNaohiro Aota if (!zone_info) 2125b316468SNaohiro Aota return true; 2135b316468SNaohiro Aota 2145b316468SNaohiro Aota return test_bit(pos >> zone_info->zone_size_shift, zone_info->empty_zones); 2155b316468SNaohiro Aota } 2165b316468SNaohiro Aota 2175b316468SNaohiro Aota static inline void btrfs_dev_set_empty_zone_bit(struct btrfs_device *device, 2185b316468SNaohiro Aota u64 pos, bool set) 2195b316468SNaohiro Aota { 2205b316468SNaohiro Aota struct btrfs_zoned_device_info *zone_info = device->zone_info; 2215b316468SNaohiro Aota unsigned int zno; 2225b316468SNaohiro Aota 2235b316468SNaohiro Aota if (!zone_info) 2245b316468SNaohiro Aota return; 2255b316468SNaohiro Aota 2265b316468SNaohiro Aota zno = pos >> zone_info->zone_size_shift; 2275b316468SNaohiro Aota if (set) 2285b316468SNaohiro Aota set_bit(zno, zone_info->empty_zones); 2295b316468SNaohiro Aota else 2305b316468SNaohiro Aota clear_bit(zno, zone_info->empty_zones); 2315b316468SNaohiro Aota } 2325b316468SNaohiro Aota 2335b316468SNaohiro Aota static inline void btrfs_dev_set_zone_empty(struct btrfs_device *device, u64 pos) 2345b316468SNaohiro Aota { 2355b316468SNaohiro Aota btrfs_dev_set_empty_zone_bit(device, pos, true); 2365b316468SNaohiro Aota } 2375b316468SNaohiro Aota 2385b316468SNaohiro Aota static inline void btrfs_dev_clear_zone_empty(struct btrfs_device *device, u64 pos) 2395b316468SNaohiro Aota { 2405b316468SNaohiro Aota btrfs_dev_set_empty_zone_bit(device, pos, false); 2415b316468SNaohiro Aota } 2425b316468SNaohiro Aota 243b70f5097SNaohiro Aota static inline bool btrfs_check_device_zone_type(const struct btrfs_fs_info *fs_info, 244b70f5097SNaohiro Aota struct block_device *bdev) 245b70f5097SNaohiro Aota { 246b70f5097SNaohiro Aota if (btrfs_is_zoned(fs_info)) { 2473c9daa09SJohannes Thumshirn /* 2483c9daa09SJohannes Thumshirn * We can allow a regular device on a zoned filesystem, because 2493c9daa09SJohannes Thumshirn * we will emulate the zoned capabilities. 2503c9daa09SJohannes Thumshirn */ 2513c9daa09SJohannes Thumshirn if (!bdev_is_zoned(bdev)) 2523c9daa09SJohannes Thumshirn return true; 2533c9daa09SJohannes Thumshirn 2543c9daa09SJohannes Thumshirn return fs_info->zone_size == 2553c9daa09SJohannes Thumshirn (bdev_zone_sectors(bdev) << SECTOR_SHIFT); 256b70f5097SNaohiro Aota } 257b70f5097SNaohiro Aota 258b70f5097SNaohiro Aota /* Do not allow Host Manged zoned device */ 259b70f5097SNaohiro Aota return bdev_zoned_model(bdev) != BLK_ZONED_HM; 260b70f5097SNaohiro Aota } 261b70f5097SNaohiro Aota 26212659251SNaohiro Aota static inline bool btrfs_check_super_location(struct btrfs_device *device, u64 pos) 26312659251SNaohiro Aota { 26412659251SNaohiro Aota /* 26512659251SNaohiro Aota * On a non-zoned device, any address is OK. On a zoned device, 26612659251SNaohiro Aota * non-SEQUENTIAL WRITE REQUIRED zones are capable. 26712659251SNaohiro Aota */ 26812659251SNaohiro Aota return device->zone_info == NULL || !btrfs_dev_is_sequential(device, pos); 26912659251SNaohiro Aota } 27012659251SNaohiro Aota 271dcba6e48SNaohiro Aota static inline bool btrfs_can_zone_reset(struct btrfs_device *device, 272dcba6e48SNaohiro Aota u64 physical, u64 length) 273dcba6e48SNaohiro Aota { 274dcba6e48SNaohiro Aota u64 zone_size; 275dcba6e48SNaohiro Aota 276dcba6e48SNaohiro Aota if (!btrfs_dev_is_sequential(device, physical)) 277dcba6e48SNaohiro Aota return false; 278dcba6e48SNaohiro Aota 279dcba6e48SNaohiro Aota zone_size = device->zone_info->zone_size; 280dcba6e48SNaohiro Aota if (!IS_ALIGNED(physical, zone_size) || !IS_ALIGNED(length, zone_size)) 281dcba6e48SNaohiro Aota return false; 282dcba6e48SNaohiro Aota 283dcba6e48SNaohiro Aota return true; 284dcba6e48SNaohiro Aota } 285dcba6e48SNaohiro Aota 2860bc09ca1SNaohiro Aota static inline void btrfs_zoned_meta_io_lock(struct btrfs_fs_info *fs_info) 2870bc09ca1SNaohiro Aota { 2880bc09ca1SNaohiro Aota if (!btrfs_is_zoned(fs_info)) 2890bc09ca1SNaohiro Aota return; 2900bc09ca1SNaohiro Aota mutex_lock(&fs_info->zoned_meta_io_lock); 2910bc09ca1SNaohiro Aota } 2920bc09ca1SNaohiro Aota 2930bc09ca1SNaohiro Aota static inline void btrfs_zoned_meta_io_unlock(struct btrfs_fs_info *fs_info) 2940bc09ca1SNaohiro Aota { 2950bc09ca1SNaohiro Aota if (!btrfs_is_zoned(fs_info)) 2960bc09ca1SNaohiro Aota return; 2970bc09ca1SNaohiro Aota mutex_unlock(&fs_info->zoned_meta_io_lock); 2980bc09ca1SNaohiro Aota } 2990bc09ca1SNaohiro Aota 30040ab3be1SNaohiro Aota static inline void btrfs_clear_treelog_bg(struct btrfs_block_group *bg) 30140ab3be1SNaohiro Aota { 30240ab3be1SNaohiro Aota struct btrfs_fs_info *fs_info = bg->fs_info; 30340ab3be1SNaohiro Aota 30440ab3be1SNaohiro Aota if (!btrfs_is_zoned(fs_info)) 30540ab3be1SNaohiro Aota return; 30640ab3be1SNaohiro Aota 30740ab3be1SNaohiro Aota spin_lock(&fs_info->treelog_bg_lock); 30840ab3be1SNaohiro Aota if (fs_info->treelog_bg == bg->start) 30940ab3be1SNaohiro Aota fs_info->treelog_bg = 0; 31040ab3be1SNaohiro Aota spin_unlock(&fs_info->treelog_bg_lock); 31140ab3be1SNaohiro Aota } 31240ab3be1SNaohiro Aota 3135b316468SNaohiro Aota #endif 314