From be39d65c09dc61d91d510f262c6d096ddb88df2e Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Thu, 30 Jul 2026 14:16:55 -0400 Subject: [PATCH] btrfs: stripe_alloc: kick parked rbios before the fast fsync's writeback wait 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 | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index f23cb174561ca..00f85c9e8f18d 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -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; -- 2.53.0