btrfs: zoned: verify device extent is aligned to zone
[linux-block.git] / fs / btrfs / zoned.h
CommitLineData
5b316468
NA
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#ifndef BTRFS_ZONED_H
4#define BTRFS_ZONED_H
5
6#include <linux/types.h>
b70f5097 7#include <linux/blkdev.h>
12659251
NA
8#include "volumes.h"
9#include "disk-io.h"
5b316468
NA
10
11struct btrfs_zoned_device_info {
12 /*
13 * Number of zones, zone size and types of zones if bdev is a
14 * zoned block device.
15 */
16 u64 zone_size;
17 u8 zone_size_shift;
862931c7 18 u64 max_zone_append_size;
5b316468
NA
19 u32 nr_zones;
20 unsigned long *seq_zones;
21 unsigned long *empty_zones;
12659251 22 struct blk_zone sb_zones[2 * BTRFS_SUPER_MIRROR_MAX];
5b316468
NA
23};
24
25#ifdef CONFIG_BLK_DEV_ZONED
26int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
27 struct blk_zone *zone);
73651042 28int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info);
5b316468
NA
29int btrfs_get_dev_zone_info(struct btrfs_device *device);
30void btrfs_destroy_dev_zone_info(struct btrfs_device *device);
b70f5097 31int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info);
5d1ab66c 32int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info);
12659251
NA
33int btrfs_sb_log_location_bdev(struct block_device *bdev, int mirror, int rw,
34 u64 *bytenr_ret);
35int btrfs_sb_log_location(struct btrfs_device *device, int mirror, int rw,
36 u64 *bytenr_ret);
37void btrfs_advance_sb_log(struct btrfs_device *device, int mirror);
38int btrfs_reset_sb_log_zones(struct block_device *bdev, int mirror);
1cd6121f
NA
39u64 btrfs_find_allocatable_zones(struct btrfs_device *device, u64 hole_start,
40 u64 hole_end, u64 num_bytes);
41int btrfs_reset_device_zone(struct btrfs_device *device, u64 physical,
42 u64 length, u64 *bytes);
43int btrfs_ensure_empty_zones(struct btrfs_device *device, u64 start, u64 size);
5b316468
NA
44#else /* CONFIG_BLK_DEV_ZONED */
45static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
46 struct blk_zone *zone)
47{
48 return 0;
49}
50
73651042
NA
51static inline int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info)
52{
53 return 0;
54}
55
5b316468
NA
56static inline int btrfs_get_dev_zone_info(struct btrfs_device *device)
57{
58 return 0;
59}
60
61static inline void btrfs_destroy_dev_zone_info(struct btrfs_device *device) { }
62
b70f5097
NA
63static inline int btrfs_check_zoned_mode(const struct btrfs_fs_info *fs_info)
64{
65 if (!btrfs_is_zoned(fs_info))
66 return 0;
67
68 btrfs_err(fs_info, "zoned block devices support is not enabled");
69 return -EOPNOTSUPP;
70}
71
5d1ab66c
NA
72static inline int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info)
73{
74 return 0;
75}
76
12659251
NA
77static inline int btrfs_sb_log_location_bdev(struct block_device *bdev,
78 int mirror, int rw, u64 *bytenr_ret)
79{
80 *bytenr_ret = btrfs_sb_offset(mirror);
81 return 0;
82}
83
84static inline int btrfs_sb_log_location(struct btrfs_device *device, int mirror,
85 int rw, u64 *bytenr_ret)
86{
87 *bytenr_ret = btrfs_sb_offset(mirror);
88 return 0;
89}
90
91static inline void btrfs_advance_sb_log(struct btrfs_device *device, int mirror)
92{ }
93
94static inline int btrfs_reset_sb_log_zones(struct block_device *bdev, int mirror)
95{
96 return 0;
97}
98
1cd6121f
NA
99static inline u64 btrfs_find_allocatable_zones(struct btrfs_device *device,
100 u64 hole_start, u64 hole_end,
101 u64 num_bytes)
102{
103 return hole_start;
104}
105
106static inline int btrfs_reset_device_zone(struct btrfs_device *device,
107 u64 physical, u64 length, u64 *bytes)
108{
109 *bytes = 0;
110 return 0;
111}
112
113static inline int btrfs_ensure_empty_zones(struct btrfs_device *device,
114 u64 start, u64 size)
115{
116 return 0;
117}
118
5b316468
NA
119#endif
120
121static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos)
122{
123 struct btrfs_zoned_device_info *zone_info = device->zone_info;
124
125 if (!zone_info)
126 return false;
127
128 return test_bit(pos >> zone_info->zone_size_shift, zone_info->seq_zones);
129}
130
131static inline bool btrfs_dev_is_empty_zone(struct btrfs_device *device, u64 pos)
132{
133 struct btrfs_zoned_device_info *zone_info = device->zone_info;
134
135 if (!zone_info)
136 return true;
137
138 return test_bit(pos >> zone_info->zone_size_shift, zone_info->empty_zones);
139}
140
141static inline void btrfs_dev_set_empty_zone_bit(struct btrfs_device *device,
142 u64 pos, bool set)
143{
144 struct btrfs_zoned_device_info *zone_info = device->zone_info;
145 unsigned int zno;
146
147 if (!zone_info)
148 return;
149
150 zno = pos >> zone_info->zone_size_shift;
151 if (set)
152 set_bit(zno, zone_info->empty_zones);
153 else
154 clear_bit(zno, zone_info->empty_zones);
155}
156
157static inline void btrfs_dev_set_zone_empty(struct btrfs_device *device, u64 pos)
158{
159 btrfs_dev_set_empty_zone_bit(device, pos, true);
160}
161
162static inline void btrfs_dev_clear_zone_empty(struct btrfs_device *device, u64 pos)
163{
164 btrfs_dev_set_empty_zone_bit(device, pos, false);
165}
166
b70f5097
NA
167static inline bool btrfs_check_device_zone_type(const struct btrfs_fs_info *fs_info,
168 struct block_device *bdev)
169{
b70f5097 170 if (btrfs_is_zoned(fs_info)) {
3c9daa09
JT
171 /*
172 * We can allow a regular device on a zoned filesystem, because
173 * we will emulate the zoned capabilities.
174 */
175 if (!bdev_is_zoned(bdev))
176 return true;
177
178 return fs_info->zone_size ==
179 (bdev_zone_sectors(bdev) << SECTOR_SHIFT);
b70f5097
NA
180 }
181
182 /* Do not allow Host Manged zoned device */
183 return bdev_zoned_model(bdev) != BLK_ZONED_HM;
184}
185
12659251
NA
186static inline bool btrfs_check_super_location(struct btrfs_device *device, u64 pos)
187{
188 /*
189 * On a non-zoned device, any address is OK. On a zoned device,
190 * non-SEQUENTIAL WRITE REQUIRED zones are capable.
191 */
192 return device->zone_info == NULL || !btrfs_dev_is_sequential(device, pos);
193}
194
5b316468 195#endif