return (global->size << 1);
 }
 
-int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
-                        struct btrfs_space_info *space_info, u64 bytes,
-                        enum btrfs_reserve_flush_enum flush)
+static u64 calc_available_free_space(struct btrfs_fs_info *fs_info,
+                         struct btrfs_space_info *space_info,
+                         enum btrfs_reserve_flush_enum flush)
 {
        u64 profile;
        u64 avail;
-       u64 used;
        int factor;
 
-       /* Don't overcommit when in mixed mode. */
-       if (space_info->flags & BTRFS_BLOCK_GROUP_DATA)
-               return 0;
-
        if (space_info->flags & BTRFS_BLOCK_GROUP_SYSTEM)
                profile = btrfs_system_alloc_profile(fs_info);
        else
                profile = btrfs_metadata_alloc_profile(fs_info);
 
-       used = btrfs_space_info_used(space_info, true);
        avail = atomic64_read(&fs_info->free_chunk_space);
 
        /*
                avail >>= 3;
        else
                avail >>= 1;
+       return avail;
+}
+
+int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
+                        struct btrfs_space_info *space_info, u64 bytes,
+                        enum btrfs_reserve_flush_enum flush)
+{
+       u64 avail;
+       u64 used;
+
+       /* Don't overcommit when in mixed mode */
+       if (space_info->flags & BTRFS_BLOCK_GROUP_DATA)
+               return 0;
+
+       used = btrfs_space_info_used(space_info, true);
+       avail = calc_available_free_space(fs_info, space_info, flush);
 
        if (used + bytes < space_info->total_bytes + avail)
                return 1;
 {
        struct reserve_ticket *ticket;
        u64 used;
+       u64 avail;
        u64 expected;
        u64 to_reclaim = 0;
 
                to_reclaim += ticket->bytes;
        list_for_each_entry(ticket, &space_info->priority_tickets, list)
                to_reclaim += ticket->bytes;
+
+       avail = calc_available_free_space(fs_info, space_info,
+                                         BTRFS_RESERVE_FLUSH_ALL);
+       used = btrfs_space_info_used(space_info, true);
+
+       /*
+        * We may be flushing because suddenly we have less space than we had
+        * before, and now we're well over-committed based on our current free
+        * space.  If that's the case add in our overage so we make sure to put
+        * appropriate pressure on the flushing state machine.
+        */
+       if (space_info->total_bytes + avail < used)
+               to_reclaim += used - (space_info->total_bytes + avail);
+
        if (to_reclaim)
                return to_reclaim;