]> 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>
Wed, 16 Sep 2026 21:40:01 +0000 (17:40 -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 f23cb174561cad93a06b159e7a6b12ae040c6876..00f85c9e8f18d2250a60232397ad1d503efa7f89 100644 (file)
@@ -35,6 +35,7 @@
 #include "file-item.h"
 #include "ioctl.h"
 #include "defrag.h"
+#include "raid56.h"
 #include "file.h"
 #include "super.h"
 #include "print-tree.h"
@@ -1659,6 +1660,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;