blob: af01070e185bf8b269d1e0e8108f9579b2ac5fef [file] [log] [blame]
Naohiro Aota5b316462020-11-10 20:26:07 +09001/* SPDX-License-Identifier: GPL-2.0 */
2
3#ifndef BTRFS_ZONED_H
4#define BTRFS_ZONED_H
5
6#include <linux/types.h>
Naohiro Aotab70f5092020-11-10 20:26:08 +09007#include <linux/blkdev.h>
Naohiro Aota5b316462020-11-10 20:26:07 +09008
9struct btrfs_zoned_device_info {
10 /*
11 * Number of zones, zone size and types of zones if bdev is a
12 * zoned block device.
13 */
14 u64 zone_size;
15 u8 zone_size_shift;
Naohiro Aota862931c2020-11-10 20:26:09 +090016 u64 max_zone_append_size;
Naohiro Aota5b316462020-11-10 20:26:07 +090017 u32 nr_zones;
18 unsigned long *seq_zones;
19 unsigned long *empty_zones;
20};
21
22#ifdef CONFIG_BLK_DEV_ZONED
23int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
24 struct blk_zone *zone);
25int btrfs_get_dev_zone_info(struct btrfs_device *device);
26void btrfs_destroy_dev_zone_info(struct btrfs_device *device);
Naohiro Aotab70f5092020-11-10 20:26:08 +090027int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info);
Naohiro Aota5d1ab662020-11-10 20:26:10 +090028int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info);
Naohiro Aota5b316462020-11-10 20:26:07 +090029#else /* CONFIG_BLK_DEV_ZONED */
30static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
31 struct blk_zone *zone)
32{
33 return 0;
34}
35
36static inline int btrfs_get_dev_zone_info(struct btrfs_device *device)
37{
38 return 0;
39}
40
41static inline void btrfs_destroy_dev_zone_info(struct btrfs_device *device) { }
42
Naohiro Aotab70f5092020-11-10 20:26:08 +090043static inline int btrfs_check_zoned_mode(const struct btrfs_fs_info *fs_info)
44{
45 if (!btrfs_is_zoned(fs_info))
46 return 0;
47
48 btrfs_err(fs_info, "zoned block devices support is not enabled");
49 return -EOPNOTSUPP;
50}
51
Naohiro Aota5d1ab662020-11-10 20:26:10 +090052static inline int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info)
53{
54 return 0;
55}
56
Naohiro Aota5b316462020-11-10 20:26:07 +090057#endif
58
59static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos)
60{
61 struct btrfs_zoned_device_info *zone_info = device->zone_info;
62
63 if (!zone_info)
64 return false;
65
66 return test_bit(pos >> zone_info->zone_size_shift, zone_info->seq_zones);
67}
68
69static inline bool btrfs_dev_is_empty_zone(struct btrfs_device *device, u64 pos)
70{
71 struct btrfs_zoned_device_info *zone_info = device->zone_info;
72
73 if (!zone_info)
74 return true;
75
76 return test_bit(pos >> zone_info->zone_size_shift, zone_info->empty_zones);
77}
78
79static inline void btrfs_dev_set_empty_zone_bit(struct btrfs_device *device,
80 u64 pos, bool set)
81{
82 struct btrfs_zoned_device_info *zone_info = device->zone_info;
83 unsigned int zno;
84
85 if (!zone_info)
86 return;
87
88 zno = pos >> zone_info->zone_size_shift;
89 if (set)
90 set_bit(zno, zone_info->empty_zones);
91 else
92 clear_bit(zno, zone_info->empty_zones);
93}
94
95static inline void btrfs_dev_set_zone_empty(struct btrfs_device *device, u64 pos)
96{
97 btrfs_dev_set_empty_zone_bit(device, pos, true);
98}
99
100static inline void btrfs_dev_clear_zone_empty(struct btrfs_device *device, u64 pos)
101{
102 btrfs_dev_set_empty_zone_bit(device, pos, false);
103}
104
Naohiro Aotab70f5092020-11-10 20:26:08 +0900105static inline bool btrfs_check_device_zone_type(const struct btrfs_fs_info *fs_info,
106 struct block_device *bdev)
107{
108 u64 zone_size;
109
110 if (btrfs_is_zoned(fs_info)) {
111 zone_size = bdev_zone_sectors(bdev) << SECTOR_SHIFT;
112 /* Do not allow non-zoned device */
113 return bdev_is_zoned(bdev) && fs_info->zone_size == zone_size;
114 }
115
116 /* Do not allow Host Manged zoned device */
117 return bdev_zoned_model(bdev) != BLK_ZONED_HM;
118}
119
Naohiro Aota5b316462020-11-10 20:26:07 +0900120#endif