btrfs: introduce max_zone_append_size
[linux-2.6-block.git] / fs / btrfs / zoned.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #ifndef BTRFS_ZONED_H
4 #define BTRFS_ZONED_H
5
6 #include <linux/types.h>
7 #include <linux/blkdev.h>
8
9 struct 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;
16         u64 max_zone_append_size;
17         u32 nr_zones;
18         unsigned long *seq_zones;
19         unsigned long *empty_zones;
20 };
21
22 #ifdef CONFIG_BLK_DEV_ZONED
23 int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
24                        struct blk_zone *zone);
25 int btrfs_get_dev_zone_info(struct btrfs_device *device);
26 void btrfs_destroy_dev_zone_info(struct btrfs_device *device);
27 int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info);
28 #else /* CONFIG_BLK_DEV_ZONED */
29 static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
30                                      struct blk_zone *zone)
31 {
32         return 0;
33 }
34
35 static inline int btrfs_get_dev_zone_info(struct btrfs_device *device)
36 {
37         return 0;
38 }
39
40 static inline void btrfs_destroy_dev_zone_info(struct btrfs_device *device) { }
41
42 static inline int btrfs_check_zoned_mode(const struct btrfs_fs_info *fs_info)
43 {
44         if (!btrfs_is_zoned(fs_info))
45                 return 0;
46
47         btrfs_err(fs_info, "zoned block devices support is not enabled");
48         return -EOPNOTSUPP;
49 }
50
51 #endif
52
53 static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos)
54 {
55         struct btrfs_zoned_device_info *zone_info = device->zone_info;
56
57         if (!zone_info)
58                 return false;
59
60         return test_bit(pos >> zone_info->zone_size_shift, zone_info->seq_zones);
61 }
62
63 static inline bool btrfs_dev_is_empty_zone(struct btrfs_device *device, u64 pos)
64 {
65         struct btrfs_zoned_device_info *zone_info = device->zone_info;
66
67         if (!zone_info)
68                 return true;
69
70         return test_bit(pos >> zone_info->zone_size_shift, zone_info->empty_zones);
71 }
72
73 static inline void btrfs_dev_set_empty_zone_bit(struct btrfs_device *device,
74                                                 u64 pos, bool set)
75 {
76         struct btrfs_zoned_device_info *zone_info = device->zone_info;
77         unsigned int zno;
78
79         if (!zone_info)
80                 return;
81
82         zno = pos >> zone_info->zone_size_shift;
83         if (set)
84                 set_bit(zno, zone_info->empty_zones);
85         else
86                 clear_bit(zno, zone_info->empty_zones);
87 }
88
89 static inline void btrfs_dev_set_zone_empty(struct btrfs_device *device, u64 pos)
90 {
91         btrfs_dev_set_empty_zone_bit(device, pos, true);
92 }
93
94 static inline void btrfs_dev_clear_zone_empty(struct btrfs_device *device, u64 pos)
95 {
96         btrfs_dev_set_empty_zone_bit(device, pos, false);
97 }
98
99 static inline bool btrfs_check_device_zone_type(const struct btrfs_fs_info *fs_info,
100                                                 struct block_device *bdev)
101 {
102         u64 zone_size;
103
104         if (btrfs_is_zoned(fs_info)) {
105                 zone_size = bdev_zone_sectors(bdev) << SECTOR_SHIFT;
106                 /* Do not allow non-zoned device */
107                 return bdev_is_zoned(bdev) && fs_info->zone_size == zone_size;
108         }
109
110         /* Do not allow Host Manged zoned device */
111         return bdev_zoned_model(bdev) != BLK_ZONED_HM;
112 }
113
114 #endif