btrfs: on unknown chunk allocation policy fallback to regular
authorDavid Sterba <dsterba@suse.com>
Wed, 23 Apr 2025 06:29:14 +0000 (08:29 +0200)
committerDavid Sterba <dsterba@suse.com>
Thu, 15 May 2025 12:30:49 +0000 (14:30 +0200)
We have only two chunk allocation policies right now and the
switch/cases don't handle an unknown one properly. The error is in the
impossible category (the policy is stored only in memory), we don't have
to BUG(), falling back to regular policy should be safe.

Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/volumes.c
fs/btrfs/volumes.h

index 85fa73b32eb040992c5590b4234e6815d88a35d0..12260592d37fd400ae5bc373f8b68f546c1c214a 100644 (file)
@@ -1528,6 +1528,9 @@ static bool contains_pending_extent(struct btrfs_device *device, u64 *start,
 static u64 dev_extent_search_start(struct btrfs_device *device)
 {
        switch (device->fs_devices->chunk_alloc_policy) {
+       default:
+               btrfs_warn_unknown_chunk_allocation(device->fs_devices->chunk_alloc_policy);
+               fallthrough;
        case BTRFS_CHUNK_ALLOC_REGULAR:
                return BTRFS_DEVICE_RANGE_RESERVED;
        case BTRFS_CHUNK_ALLOC_ZONED:
@@ -1537,8 +1540,6 @@ static u64 dev_extent_search_start(struct btrfs_device *device)
                 * for superblock logging.
                 */
                return 0;
-       default:
-               BUG();
        }
 }
 
@@ -1618,6 +1619,9 @@ static bool dev_extent_hole_check(struct btrfs_device *device, u64 *hole_start,
                }
 
                switch (device->fs_devices->chunk_alloc_policy) {
+               default:
+                       btrfs_warn_unknown_chunk_allocation(device->fs_devices->chunk_alloc_policy);
+                       fallthrough;
                case BTRFS_CHUNK_ALLOC_REGULAR:
                        /* No extra check */
                        break;
@@ -1632,8 +1636,6 @@ static bool dev_extent_hole_check(struct btrfs_device *device, u64 *hole_start,
                                continue;
                        }
                        break;
-               default:
-                       BUG();
                }
 
                break;
@@ -5199,14 +5201,15 @@ static void init_alloc_chunk_ctl(struct btrfs_fs_devices *fs_devices,
        ctl->ndevs = 0;
 
        switch (fs_devices->chunk_alloc_policy) {
+       default:
+               btrfs_warn_unknown_chunk_allocation(fs_devices->chunk_alloc_policy);
+               fallthrough;
        case BTRFS_CHUNK_ALLOC_REGULAR:
                init_alloc_chunk_ctl_policy_regular(fs_devices, ctl);
                break;
        case BTRFS_CHUNK_ALLOC_ZONED:
                init_alloc_chunk_ctl_policy_zoned(fs_devices, ctl);
                break;
-       default:
-               BUG();
        }
 }
 
@@ -5395,12 +5398,13 @@ static int decide_stripe_size(struct btrfs_fs_devices *fs_devices,
        ctl->ndevs = min(ctl->ndevs, ctl->devs_max);
 
        switch (fs_devices->chunk_alloc_policy) {
+       default:
+               btrfs_warn_unknown_chunk_allocation(fs_devices->chunk_alloc_policy);
+               fallthrough;
        case BTRFS_CHUNK_ALLOC_REGULAR:
                return decide_stripe_size_regular(ctl, devices_info);
        case BTRFS_CHUNK_ALLOC_ZONED:
                return decide_stripe_size_zoned(ctl, devices_info);
-       default:
-               BUG();
        }
 }
 
index 72b8122938eb7555325aca008663b5c89d1ceaad..b043c285c409656e6d6eb247a41e3524ce509d10 100644 (file)
@@ -846,6 +846,11 @@ static inline const char *btrfs_dev_name(const struct btrfs_device *device)
                return rcu_str_deref(device->name);
 }
 
+static inline void btrfs_warn_unknown_chunk_allocation(enum btrfs_chunk_allocation_policy pol)
+{
+       WARN_ONCE(1, "unknown allocation policy %d, fallback to regular", pol);
+}
+
 void btrfs_commit_device_sizes(struct btrfs_transaction *trans);
 
 struct list_head * __attribute_const__ btrfs_get_fs_uuids(void);