btrfs: add extent allocator hook to decide to allocate chunk or not
authorNaohiro Aota <naohiro.aota@wdc.com>
Tue, 7 Dec 2021 15:35:48 +0000 (00:35 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jan 2022 11:02:48 +0000 (12:02 +0100)
commit 50475cd57706359d6cc652be88369dace7a4c2eb upstream.

Introduce a new hook for an extent allocator policy. With the new
hook, a policy can decide to allocate a new block group or not. If
not, it will return -ENOSPC, so btrfs_reserve_extent() will cut the
allocation size in half and retry the allocation if min_alloc_size is
large enough.

The hook has a place holder and will be replaced with the real
implementation in the next patch.

CC: stable@vger.kernel.org # 5.16
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/btrfs/extent-tree.c

index 25ef6e3fd3069f7b113be393fac05bc83c9c8295..5cb44931e62fa90c31a2f4a0ba30c55f81083e4c 100644 (file)
@@ -3947,6 +3947,19 @@ static void found_extent(struct find_free_extent_ctl *ffe_ctl,
        }
 }
 
+static bool can_allocate_chunk(struct btrfs_fs_info *fs_info,
+                              struct find_free_extent_ctl *ffe_ctl)
+{
+       switch (ffe_ctl->policy) {
+       case BTRFS_EXTENT_ALLOC_CLUSTERED:
+               return true;
+       case BTRFS_EXTENT_ALLOC_ZONED:
+               return true;
+       default:
+               BUG();
+       }
+}
+
 static int chunk_allocation_failed(struct find_free_extent_ctl *ffe_ctl)
 {
        switch (ffe_ctl->policy) {
@@ -4034,6 +4047,10 @@ static int find_free_extent_update_loop(struct btrfs_fs_info *fs_info,
                        struct btrfs_trans_handle *trans;
                        int exist = 0;
 
+                       /*Check if allocation policy allows to create a new chunk */
+                       if (!can_allocate_chunk(fs_info, ffe_ctl))
+                               return -ENOSPC;
+
                        trans = current->journal_info;
                        if (trans)
                                exist = 1;