btrfs: handle preemptive delalloc flushing slightly differently
authorJosef Bacik <josef@toxicpanda.com>
Wed, 28 Apr 2021 17:38:48 +0000 (13:38 -0400)
committerDavid Sterba <dsterba@suse.com>
Mon, 21 Jun 2021 13:19:04 +0000 (15:19 +0200)
If we decide to flush delalloc from the preemptive flusher, we really do
not want to wait on ordered extents, as it gains us nothing.  However
there was logic to go ahead and wait on ordered extents if there was
more ordered bytes than delalloc bytes.  We do not want this behavior,
so pass through whether this flushing is for preemption, and do not wait
for ordered extents if that's the case.  Also break out of the shrink
loop after the first flushing, as we just want to one shot shrink
delalloc.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/space-info.c

index 639787b..42d0fa2 100644 (file)
@@ -495,7 +495,8 @@ static inline u64 calc_reclaim_items_nr(struct btrfs_fs_info *fs_info,
  */
 static void shrink_delalloc(struct btrfs_fs_info *fs_info,
                            struct btrfs_space_info *space_info,
-                           u64 to_reclaim, bool wait_ordered)
+                           u64 to_reclaim, bool wait_ordered,
+                           bool for_preempt)
 {
        struct btrfs_trans_handle *trans;
        u64 delalloc_bytes;
@@ -532,7 +533,7 @@ static void shrink_delalloc(struct btrfs_fs_info *fs_info,
         * ordered extents, otherwise we'll waste time trying to flush delalloc
         * that likely won't give us the space back we need.
         */
-       if (ordered_bytes > delalloc_bytes)
+       if (ordered_bytes > delalloc_bytes && !for_preempt)
                wait_ordered = true;
 
        loops = 0;
@@ -551,6 +552,14 @@ static void shrink_delalloc(struct btrfs_fs_info *fs_info,
                                break;
                }
 
+               /*
+                * If we are for preemption we just want a one-shot of delalloc
+                * flushing so we can stop flushing if we decide we don't need
+                * to anymore.
+                */
+               if (for_preempt)
+                       break;
+
                spin_lock(&space_info->lock);
                if (list_empty(&space_info->tickets) &&
                    list_empty(&space_info->priority_tickets)) {
@@ -702,7 +711,7 @@ static void flush_space(struct btrfs_fs_info *fs_info,
        case FLUSH_DELALLOC:
        case FLUSH_DELALLOC_WAIT:
                shrink_delalloc(fs_info, space_info, num_bytes,
-                               state == FLUSH_DELALLOC_WAIT);
+                               state == FLUSH_DELALLOC_WAIT, for_preempt);
                break;
        case FLUSH_DELAYED_REFS_NR:
        case FLUSH_DELAYED_REFS: