44#include <linux/slab.h>
55#include <linux/blkdev.h>
66#include <linux/sched/mm.h>
7+ #include <linux/atomic.h>
78#include "ctree.h"
89#include "volumes.h"
910#include "zoned.h"
3839/* Number of superblock log zones */
3940#define BTRFS_NR_SB_LOG_ZONES 2
4041
42+ /*
43+ * Minimum of active zones we need:
44+ *
45+ * - BTRFS_SUPER_MIRROR_MAX zones for superblock mirrors
46+ * - 3 zones to ensure at least one zone per SYSTEM, META and DATA block group
47+ * - 1 zone for tree-log dedicated block group
48+ * - 1 zone for relocation
49+ */
50+ #define BTRFS_MIN_ACTIVE_ZONES (BTRFS_SUPER_MIRROR_MAX + 5)
51+
4152/*
4253 * Maximum supported zone size. Currently, SMR disks have a zone size of
4354 * 256MiB, and we are expecting ZNS drives to be in the 1-4GiB range. We do not
@@ -303,6 +314,9 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
303314 struct btrfs_fs_info * fs_info = device -> fs_info ;
304315 struct btrfs_zoned_device_info * zone_info = NULL ;
305316 struct block_device * bdev = device -> bdev ;
317+ struct request_queue * queue = bdev_get_queue (bdev );
318+ unsigned int max_active_zones ;
319+ unsigned int nactive ;
306320 sector_t nr_sectors ;
307321 sector_t sector = 0 ;
308322 struct blk_zone * zones = NULL ;
@@ -358,6 +372,17 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
358372 if (!IS_ALIGNED (nr_sectors , zone_sectors ))
359373 zone_info -> nr_zones ++ ;
360374
375+ max_active_zones = queue_max_active_zones (queue );
376+ if (max_active_zones && max_active_zones < BTRFS_MIN_ACTIVE_ZONES ) {
377+ btrfs_err_in_rcu (fs_info ,
378+ "zoned: %s: max active zones %u is too small, need at least %u active zones" ,
379+ rcu_str_deref (device -> name ), max_active_zones ,
380+ BTRFS_MIN_ACTIVE_ZONES );
381+ ret = - EINVAL ;
382+ goto out ;
383+ }
384+ zone_info -> max_active_zones = max_active_zones ;
385+
361386 zone_info -> seq_zones = bitmap_zalloc (zone_info -> nr_zones , GFP_KERNEL );
362387 if (!zone_info -> seq_zones ) {
363388 ret = - ENOMEM ;
@@ -370,13 +395,20 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
370395 goto out ;
371396 }
372397
398+ zone_info -> active_zones = bitmap_zalloc (zone_info -> nr_zones , GFP_KERNEL );
399+ if (!zone_info -> active_zones ) {
400+ ret = - ENOMEM ;
401+ goto out ;
402+ }
403+
373404 zones = kcalloc (BTRFS_REPORT_NR_ZONES , sizeof (struct blk_zone ), GFP_KERNEL );
374405 if (!zones ) {
375406 ret = - ENOMEM ;
376407 goto out ;
377408 }
378409
379410 /* Get zones type */
411+ nactive = 0 ;
380412 while (sector < nr_sectors ) {
381413 nr_zones = BTRFS_REPORT_NR_ZONES ;
382414 ret = btrfs_get_dev_zones (device , sector << SECTOR_SHIFT , zones ,
@@ -387,8 +419,17 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
387419 for (i = 0 ; i < nr_zones ; i ++ ) {
388420 if (zones [i ].type == BLK_ZONE_TYPE_SEQWRITE_REQ )
389421 __set_bit (nreported , zone_info -> seq_zones );
390- if (zones [i ].cond == BLK_ZONE_COND_EMPTY )
422+ switch (zones [i ].cond ) {
423+ case BLK_ZONE_COND_EMPTY :
391424 __set_bit (nreported , zone_info -> empty_zones );
425+ break ;
426+ case BLK_ZONE_COND_IMP_OPEN :
427+ case BLK_ZONE_COND_EXP_OPEN :
428+ case BLK_ZONE_COND_CLOSED :
429+ __set_bit (nreported , zone_info -> active_zones );
430+ nactive ++ ;
431+ break ;
432+ }
392433 nreported ++ ;
393434 }
394435 sector = zones [nr_zones - 1 ].start + zones [nr_zones - 1 ].len ;
@@ -403,6 +444,19 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
403444 goto out ;
404445 }
405446
447+ if (max_active_zones ) {
448+ if (nactive > max_active_zones ) {
449+ btrfs_err_in_rcu (device -> fs_info ,
450+ "zoned: %u active zones on %s exceeds max_active_zones %u" ,
451+ nactive , rcu_str_deref (device -> name ),
452+ max_active_zones );
453+ ret = - EIO ;
454+ goto out ;
455+ }
456+ atomic_set (& zone_info -> active_zones_left ,
457+ max_active_zones - nactive );
458+ }
459+
406460 /* Validate superblock log */
407461 nr_zones = BTRFS_NR_SB_LOG_ZONES ;
408462 for (i = 0 ; i < BTRFS_SUPER_MIRROR_MAX ; i ++ ) {
@@ -485,6 +539,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device)
485539out :
486540 kfree (zones );
487541out_free_zone_info :
542+ bitmap_free (zone_info -> active_zones );
488543 bitmap_free (zone_info -> empty_zones );
489544 bitmap_free (zone_info -> seq_zones );
490545 kfree (zone_info );
@@ -500,6 +555,7 @@ void btrfs_destroy_dev_zone_info(struct btrfs_device *device)
500555 if (!zone_info )
501556 return ;
502557
558+ bitmap_free (zone_info -> active_zones );
503559 bitmap_free (zone_info -> seq_zones );
504560 bitmap_free (zone_info -> empty_zones );
505561 kfree (zone_info );
0 commit comments