struct btrfs_block_rsv *rsv)
 {
        struct btrfs_fs_info *fs_info = root->fs_info;
-       struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
        struct btrfs_trans_handle *trans;
        u64 delayed_refs_extra = btrfs_calc_insert_metadata_size(fs_info, 1);
        int ret;
         * above.  We reserve our extra bit here because we generate a ton of
         * delayed refs activity by truncating.
         *
-        * If we cannot make our reservation we'll attempt to steal from the
-        * global reserve, because we really want to be able to free up space.
+        * BTRFS_RESERVE_FLUSH_EVICT will steal from the global_rsv if it can,
+        * if we fail to make this reservation we can re-try without the
+        * delayed_refs_extra so we can make some forward progress.
         */
        ret = btrfs_block_rsv_refill(root, rsv, rsv->size + delayed_refs_extra,
                                     BTRFS_RESERVE_FLUSH_EVICT);
        if (ret) {
-               /*
-                * Try to steal from the global reserve if there is space for
-                * it.
-                */
-               if (btrfs_check_space_for_delayed_refs(fs_info) ||
-                   btrfs_block_rsv_migrate(global_rsv, rsv, rsv->size, 0)) {
+               ret = btrfs_block_rsv_refill(root, rsv, rsv->size,
+                                            BTRFS_RESERVE_FLUSH_EVICT);
+               if (ret) {
                        btrfs_warn(fs_info,
                                   "could not allocate space for delete; will truncate on mount");
                        return ERR_PTR(-ENOSPC);
 
                }
        }
 
+       /* Attempt to steal from the global rsv if we can. */
+       if (!steal_from_global_rsv(fs_info, space_info, ticket)) {
+               ticket->error = -ENOSPC;
+               remove_ticket(space_info, ticket);
+       }
+
        /*
         * We must run try_granting_tickets here because we could be a large
         * ticket in front of a smaller ticket that can now be satisfied with
         * the available space.
         */
-       ticket->error = -ENOSPC;
-       remove_ticket(space_info, ticket);
        btrfs_try_granting_tickets(fs_info, space_info);
        spin_unlock(&space_info->lock);
 }
                space_info->clamp = min(space_info->clamp + 1, 8);
 }
 
+static inline bool can_steal(enum btrfs_reserve_flush_enum flush)
+{
+       return (flush == BTRFS_RESERVE_FLUSH_ALL_STEAL ||
+               flush == BTRFS_RESERVE_FLUSH_EVICT);
+}
+
 /**
  * Try to reserve bytes from the block_rsv's space
  *
                ticket.error = 0;
                space_info->reclaim_size += ticket.bytes;
                init_waitqueue_head(&ticket.wait);
-               ticket.steal = (flush == BTRFS_RESERVE_FLUSH_ALL_STEAL);
+               ticket.steal = can_steal(flush);
                if (trace_btrfs_reserve_ticket_enabled())
                        start_ns = ktime_get_ns();