]> git.hungrycats.org Git - linux/commitdiff
btrfs: stripe_alloc: kick parked rbios before the fast fsync's writeback wait
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Thu, 30 Jul 2026 18:16:55 +0000 (14:16 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Fri, 18 Sep 2026 21:36:22 +0000 (17:36 -0400)
The fast fsync path waits for page writeback, which completes only when
the raid56 layer writes the data -- but a partial-stripe rbio parks to
collect merges until its sync deadline, and on this path nothing unparks
it before the wait: the stripes are settled only later, in the logging
itself.  The full-sync path does not have this problem because the
ordered extent wait already flushes parked rbios before sleeping.

All of the fsync's writes are submitted before the wait, so nothing more
can merge into its stripes; flush the parked rbios covering the attached
ordered extents instead of sleeping out their deadline.  Removes the
sync park timeout from the fast fsync critical path.

Assisted-by: Claude:claude-fable-5
fs/btrfs/file.c

index d927b559aa327742cf01308799a298d8337c6080..577d2c0f6b73cd92cde763a26559aca594300606 100644 (file)
@@ -36,6 +36,7 @@
 #include "file-item.h"
 #include "ioctl.h"
 #include "defrag.h"
+#include "raid56.h"
 #include "file.h"
 #include "super.h"
 #include "print-tree.h"
@@ -1656,6 +1657,28 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
                 * checksums attached to the ordered extents.
                 */
                btrfs_get_ordered_extents_for_logging(inode, &ctx.ordered_extents);
+
+               /*
+                * The writeback wait below completes only when the raid56
+                * layer writes this fsync's data, but a partial-stripe rbio
+                * parks (collecting merges) until its sync deadline, and on
+                * this path nothing else unparks it before the wait -- the
+                * stripes are settled only later, in the logging itself.  All
+                * of this fsync's writes are submitted by now, so nothing
+                * more can merge; kick the parked rbios covering our ordered
+                * extents instead of sleeping out their deadline.
+                */
+               if (btrfs_test_opt(fs_info, STRIPE_ALLOC)) {
+                       struct btrfs_ordered_extent *tmp_oe;
+
+                       list_for_each_entry(tmp_oe, &ctx.ordered_extents,
+                                           log_list)
+                               if (tmp_oe->disk_num_bytes)
+                                       btrfs_flush_parked_rbios(fs_info,
+                                                       tmp_oe->disk_bytenr,
+                                                       tmp_oe->disk_num_bytes);
+               }
+
                ret = filemap_fdatawait_range(inode->vfs_inode.i_mapping, start, end);
                if (ret)
                        goto out_release_extents;