btrfs: zoned: fix btrfs_can_activate_zone() to support DUP profile
authorNaohiro Aota <naohiro.aota@wdc.com>
Mon, 13 Mar 2023 07:29:49 +0000 (16:29 +0900)
committerDavid Sterba <dsterba@suse.com>
Wed, 15 Mar 2023 19:51:06 +0000 (20:51 +0100)
btrfs_can_activate_zone() returns true if at least one device has one zone
available for activation. This is OK for the single profile, but not OK for
DUP profile. We need two zones to create a DUP block group. Fix it by
properly handling the case with the profile flags.

Fixes: 265f7237dd25 ("btrfs: zoned: allow DUP on meta-data block groups")
CC: stable@vger.kernel.org # 6.1+
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/zoned.c

index f95b2c94d6199a62194d785ffa3d427c0a3fa79b..0a330d5410a02148278c3a4f4cd78cc549eb5605 100644 (file)
@@ -2086,11 +2086,21 @@ bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags)
                if (!device->bdev)
                        continue;
 
-               if (!zinfo->max_active_zones ||
-                   atomic_read(&zinfo->active_zones_left)) {
+               if (!zinfo->max_active_zones) {
                        ret = true;
                        break;
                }
+
+               switch (flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
+               case 0: /* single */
+                       ret = (atomic_read(&zinfo->active_zones_left) >= 1);
+                       break;
+               case BTRFS_BLOCK_GROUP_DUP:
+                       ret = (atomic_read(&zinfo->active_zones_left) >= 2);
+                       break;
+               }
+               if (ret)
+                       break;
        }
        mutex_unlock(&fs_info->chunk_mutex);