|
21 | 21 | /* Pseudo write pointer value for conventional zone */
|
22 | 22 | #define WP_CONVENTIONAL ((u64)-2)
|
23 | 23 |
|
| 24 | +/* |
| 25 | + * Location of the first zone of superblock logging zone pairs. |
| 26 | + * |
| 27 | + * - primary superblock: 0B (zone 0) |
| 28 | + * - first copy: 512G (zone starting at that offset) |
| 29 | + * - second copy: 4T (zone starting at that offset) |
| 30 | + */ |
| 31 | +#define BTRFS_SB_LOG_PRIMARY_OFFSET (0ULL) |
| 32 | +#define BTRFS_SB_LOG_FIRST_OFFSET (512ULL * SZ_1G) |
| 33 | +#define BTRFS_SB_LOG_SECOND_OFFSET (4096ULL * SZ_1G) |
| 34 | + |
| 35 | +#define BTRFS_SB_LOG_FIRST_SHIFT const_ilog2(BTRFS_SB_LOG_FIRST_OFFSET) |
| 36 | +#define BTRFS_SB_LOG_SECOND_SHIFT const_ilog2(BTRFS_SB_LOG_SECOND_OFFSET) |
| 37 | + |
24 | 38 | /* Number of superblock log zones */
|
25 | 39 | #define BTRFS_NR_SB_LOG_ZONES 2
|
26 | 40 |
|
| 41 | +/* |
| 42 | + * Maximum supported zone size. Currently, SMR disks have a zone size of |
| 43 | + * 256MiB, and we are expecting ZNS drives to be in the 1-4GiB range. We do not |
| 44 | + * expect the zone size to become larger than 8GiB in the near future. |
| 45 | + */ |
| 46 | +#define BTRFS_MAX_ZONE_SIZE SZ_8G |
| 47 | + |
27 | 48 | static int copy_zone_info_cb(struct blk_zone *zone, unsigned int idx, void *data)
|
28 | 49 | {
|
29 | 50 | struct blk_zone *zones = data;
|
@@ -111,23 +132,22 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
|
111 | 132 | }
|
112 | 133 |
|
113 | 134 | /*
|
114 |
| - * The following zones are reserved as the circular buffer on ZONED btrfs. |
115 |
| - * - The primary superblock: zones 0 and 1 |
116 |
| - * - The first copy: zones 16 and 17 |
117 |
| - * - The second copy: zones 1024 or zone at 256GB which is minimum, and |
118 |
| - * the following one |
| 135 | + * Get the first zone number of the superblock mirror |
119 | 136 | */
|
120 | 137 | static inline u32 sb_zone_number(int shift, int mirror)
|
121 | 138 | {
|
122 |
| - ASSERT(mirror < BTRFS_SUPER_MIRROR_MAX); |
| 139 | + u64 zone; |
123 | 140 |
|
| 141 | + ASSERT(mirror < BTRFS_SUPER_MIRROR_MAX); |
124 | 142 | switch (mirror) {
|
125 |
| - case 0: return 0; |
126 |
| - case 1: return 16; |
127 |
| - case 2: return min_t(u64, btrfs_sb_offset(mirror) >> shift, 1024); |
| 143 | + case 0: zone = 0; break; |
| 144 | + case 1: zone = 1ULL << (BTRFS_SB_LOG_FIRST_SHIFT - shift); break; |
| 145 | + case 2: zone = 1ULL << (BTRFS_SB_LOG_SECOND_SHIFT - shift); break; |
128 | 146 | }
|
129 | 147 |
|
130 |
| - return 0; |
| 148 | + ASSERT(zone <= U32_MAX); |
| 149 | + |
| 150 | + return (u32)zone; |
131 | 151 | }
|
132 | 152 |
|
133 | 153 | /*
|
@@ -300,10 +320,21 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
|
300 | 320 | zone_sectors = bdev_zone_sectors(bdev);
|
301 | 321 | }
|
302 | 322 |
|
303 |
| - nr_sectors = bdev_nr_sectors(bdev); |
304 | 323 | /* Check if it's power of 2 (see is_power_of_2) */
|
305 | 324 | ASSERT(zone_sectors != 0 && (zone_sectors & (zone_sectors - 1)) == 0);
|
306 | 325 | zone_info->zone_size = zone_sectors << SECTOR_SHIFT;
|
| 326 | + |
| 327 | + /* We reject devices with a zone size larger than 8GB */ |
| 328 | + if (zone_info->zone_size > BTRFS_MAX_ZONE_SIZE) { |
| 329 | + btrfs_err_in_rcu(fs_info, |
| 330 | + "zoned: %s: zone size %llu larger than supported maximum %llu", |
| 331 | + rcu_str_deref(device->name), |
| 332 | + zone_info->zone_size, BTRFS_MAX_ZONE_SIZE); |
| 333 | + ret = -EINVAL; |
| 334 | + goto out; |
| 335 | + } |
| 336 | + |
| 337 | + nr_sectors = bdev_nr_sectors(bdev); |
307 | 338 | zone_info->zone_size_shift = ilog2(zone_info->zone_size);
|
308 | 339 | zone_info->max_zone_append_size =
|
309 | 340 | (u64)queue_max_zone_append_sectors(queue) << SECTOR_SHIFT;
|
|
0 commit comments