]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - fs/btrfs/zoned.h
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[mirror_ubuntu-hirsute-kernel.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);
28int btrfs_get_dev_zone_info(struct btrfs_device *device);
29void btrfs_destroy_dev_zone_info(struct btrfs_device *device);
b70f5097 30int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info);
5d1ab66c 31int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info);
12659251
NA
32int btrfs_sb_log_location_bdev(struct block_device *bdev, int mirror, int rw,
33 u64 *bytenr_ret);
34int btrfs_sb_log_location(struct btrfs_device *device, int mirror, int rw,
35 u64 *bytenr_ret);
36void btrfs_advance_sb_log(struct btrfs_device *device, int mirror);
37int btrfs_reset_sb_log_zones(struct block_device *bdev, int mirror);
5b316468
NA
38#else /* CONFIG_BLK_DEV_ZONED */
39static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
40 struct blk_zone *zone)
41{
42 return 0;
43}
44
45static inline int btrfs_get_dev_zone_info(struct btrfs_device *device)
46{
47 return 0;
48}
49
50static inline void btrfs_destroy_dev_zone_info(struct btrfs_device *device) { }
51
b70f5097
NA
52static inline int btrfs_check_zoned_mode(const struct btrfs_fs_info *fs_info)
53{
54 if (!btrfs_is_zoned(fs_info))
55 return 0;
56
57 btrfs_err(fs_info, "zoned block devices support is not enabled");
58 return -EOPNOTSUPP;
59}
60
5d1ab66c
NA
61static inline int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info)
62{
63 return 0;
64}
65
12659251
NA
66static inline int btrfs_sb_log_location_bdev(struct block_device *bdev,
67 int mirror, int rw, u64 *bytenr_ret)
68{
69 *bytenr_ret = btrfs_sb_offset(mirror);
70 return 0;
71}
72
73static inline int btrfs_sb_log_location(struct btrfs_device *device, int mirror,
74 int rw, u64 *bytenr_ret)
75{
76 *bytenr_ret = btrfs_sb_offset(mirror);
77 return 0;
78}
79
80static inline void btrfs_advance_sb_log(struct btrfs_device *device, int mirror)
81{ }
82
83static inline int btrfs_reset_sb_log_zones(struct block_device *bdev, int mirror)
84{
85 return 0;
86}
87
5b316468
NA
88#endif
89
90static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos)
91{
92 struct btrfs_zoned_device_info *zone_info = device->zone_info;
93
94 if (!zone_info)
95 return false;
96
97 return test_bit(pos >> zone_info->zone_size_shift, zone_info->seq_zones);
98}
99
100static inline bool btrfs_dev_is_empty_zone(struct btrfs_device *device, u64 pos)
101{
102 struct btrfs_zoned_device_info *zone_info = device->zone_info;
103
104 if (!zone_info)
105 return true;
106
107 return test_bit(pos >> zone_info->zone_size_shift, zone_info->empty_zones);
108}
109
110static inline void btrfs_dev_set_empty_zone_bit(struct btrfs_device *device,
111 u64 pos, bool set)
112{
113 struct btrfs_zoned_device_info *zone_info = device->zone_info;
114 unsigned int zno;
115
116 if (!zone_info)
117 return;
118
119 zno = pos >> zone_info->zone_size_shift;
120 if (set)
121 set_bit(zno, zone_info->empty_zones);
122 else
123 clear_bit(zno, zone_info->empty_zones);
124}
125
126static inline void btrfs_dev_set_zone_empty(struct btrfs_device *device, u64 pos)
127{
128 btrfs_dev_set_empty_zone_bit(device, pos, true);
129}
130
131static inline void btrfs_dev_clear_zone_empty(struct btrfs_device *device, u64 pos)
132{
133 btrfs_dev_set_empty_zone_bit(device, pos, false);
134}
135
b70f5097
NA
136static inline bool btrfs_check_device_zone_type(const struct btrfs_fs_info *fs_info,
137 struct block_device *bdev)
138{
139 u64 zone_size;
140
141 if (btrfs_is_zoned(fs_info)) {
142 zone_size = bdev_zone_sectors(bdev) << SECTOR_SHIFT;
143 /* Do not allow non-zoned device */
144 return bdev_is_zoned(bdev) && fs_info->zone_size == zone_size;
145 }
146
147 /* Do not allow Host Manged zoned device */
148 return bdev_zoned_model(bdev) != BLK_ZONED_HM;
149}
150
12659251
NA
151static inline bool btrfs_check_super_location(struct btrfs_device *device, u64 pos)
152{
153 /*
154 * On a non-zoned device, any address is OK. On a zoned device,
155 * non-SEQUENTIAL WRITE REQUIRED zones are capable.
156 */
157 return device->zone_info == NULL || !btrfs_dev_is_sequential(device, pos);
158}
159
5b316468 160#endif