btrfs: introduce max_zone_append_size
[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>
5b316468
NA
8
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;
862931c7 16 u64 max_zone_append_size;
5b316468
NA
17 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);
b70f5097 27int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info);
5b316468
NA
28#else /* CONFIG_BLK_DEV_ZONED */
29static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
30 struct blk_zone *zone)
31{
32 return 0;
33}
34
35static inline int btrfs_get_dev_zone_info(struct btrfs_device *device)
36{
37 return 0;
38}
39
40static inline void btrfs_destroy_dev_zone_info(struct btrfs_device *device) { }
41
b70f5097
NA
42static 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
5b316468
NA
51#endif
52
53static 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
63static 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
73static 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
89static 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
94static 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
b70f5097
NA
99static 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
5b316468 114#endif