bool do_chunk_alloc)
 {
        struct btrfs_fs_info *fs_info = cache->fs_info;
+       struct btrfs_space_info *space_info = cache->space_info;
        struct btrfs_trans_handle *trans;
        struct btrfs_root *root = btrfs_block_group_root(fs_info);
        u64 alloc_flags;
                 */
                alloc_flags = btrfs_get_alloc_profile(fs_info, cache->flags);
                if (alloc_flags != cache->flags) {
-                       ret = btrfs_chunk_alloc(trans, alloc_flags,
+                       ret = btrfs_chunk_alloc(trans, space_info, alloc_flags,
                                                CHUNK_ALLOC_FORCE);
                        /*
                         * ENOSPC is allowed here, we may have enough space
            (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM))
                goto unlock_out;
 
-       alloc_flags = btrfs_get_alloc_profile(fs_info, cache->space_info->flags);
-       ret = btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE);
+       alloc_flags = btrfs_get_alloc_profile(fs_info, space_info->flags);
+       ret = btrfs_chunk_alloc(trans, space_info, alloc_flags, CHUNK_ALLOC_FORCE);
        if (ret < 0)
                goto out;
        /*
         * We have allocated a new chunk. We also need to activate that chunk to
         * grant metadata tickets for zoned filesystem.
         */
-       ret = btrfs_zoned_activate_one_bg(fs_info, cache->space_info, true);
+       ret = btrfs_zoned_activate_one_bg(fs_info, space_info, true);
        if (ret < 0)
                goto out;
 
 int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, u64 type)
 {
        u64 alloc_flags = btrfs_get_alloc_profile(trans->fs_info, type);
+       struct btrfs_space_info *space_info;
+
+       space_info = btrfs_find_space_info(trans->fs_info, type);
+       if (!space_info) {
+               DEBUG_WARN();
+               return -EINVAL;
+       }
 
-       return btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE);
+       return btrfs_chunk_alloc(trans, space_info, alloc_flags, CHUNK_ALLOC_FORCE);
 }
 
 static struct btrfs_block_group *do_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags)
  *
  * This function, btrfs_chunk_alloc(), belongs to phase 1.
  *
+ * @space_info: specify which space_info the new chunk should belong to.
+ *
  * If @force is CHUNK_ALLOC_FORCE:
  *    - return 1 if it successfully allocates a chunk,
  *    - return errors including -ENOSPC otherwise.
  *    - return 1 if it successfully allocates a chunk,
  *    - return errors including -ENOSPC otherwise.
  */
-int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,
+int btrfs_chunk_alloc(struct btrfs_trans_handle *trans,
+                     struct btrfs_space_info *space_info, u64 flags,
                      enum btrfs_chunk_alloc_enum force)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
-       struct btrfs_space_info *space_info;
        struct btrfs_block_group *ret_bg;
        bool wait_for_alloc = false;
        bool should_alloc = false;
        if (flags & BTRFS_BLOCK_GROUP_SYSTEM)
                return -ENOSPC;
 
-       space_info = btrfs_find_space_info(fs_info, flags);
-       ASSERT(space_info);
-
        do {
                spin_lock(&space_info->lock);
                if (force < space_info->force_alloc)
 
                             bool force_wrong_size_class);
 void btrfs_free_reserved_bytes(struct btrfs_block_group *cache,
                               u64 num_bytes, int delalloc);
-int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,
+int btrfs_chunk_alloc(struct btrfs_trans_handle *trans,
+                     struct btrfs_space_info *space_info, u64 flags,
                      enum btrfs_chunk_alloc_enum force);
 int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, u64 type);
 void check_system_chunk(struct btrfs_trans_handle *trans, const u64 type);
 
 static int find_free_extent_update_loop(struct btrfs_fs_info *fs_info,
                                        struct btrfs_key *ins,
                                        struct find_free_extent_ctl *ffe_ctl,
+                                       struct btrfs_space_info *space_info,
                                        bool full_search)
 {
        struct btrfs_root *root = fs_info->chunk_root;
                                return ret;
                        }
 
-                       ret = btrfs_chunk_alloc(trans, ffe_ctl->flags,
+                       ret = btrfs_chunk_alloc(trans, space_info, ffe_ctl->flags,
                                                CHUNK_ALLOC_FORCE_FOR_EXTENT);
 
                        /* Do not bail out on ENOSPC since we can do more. */
        }
        up_read(&space_info->groups_sem);
 
-       ret = find_free_extent_update_loop(fs_info, ins, ffe_ctl, full_search);
+       ret = find_free_extent_update_loop(fs_info, ins, ffe_ctl, space_info,
+                                          full_search);
        if (ret > 0)
                goto search;