linux/fs/fuse
Joanne Koong 76f9377cd2
writeback: don't block sync for filesystems with no data integrity guarantees
Add a SB_I_NO_DATA_INTEGRITY superblock flag for filesystems that cannot
guarantee data persistence on sync (eg fuse). For superblocks with this
flag set, sync kicks off writeback of dirty inodes but does not wait
for the flusher threads to complete the writeback.

This replaces the per-inode AS_NO_DATA_INTEGRITY mapping flag added in
commit f9a49aa302 ("fs/writeback: skip AS_NO_DATA_INTEGRITY mappings
in wait_sb_inodes()"). The flag belongs at the superblock level because
data integrity is a filesystem-wide property, not a per-inode one.
Having this flag at the superblock level also allows us to skip having
to iterate every dirty inode in wait_sb_inodes() only to skip each inode
individually.

Prior to this commit, mappings with no data integrity guarantees skipped
waiting on writeback completion but still waited on the flusher threads
to finish initiating the writeback. Waiting on the flusher threads is
unnecessary. This commit kicks off writeback but does not wait on the
flusher threads. This change properly addresses a recent report [1] for
a suspend-to-RAM hang seen on fuse-overlayfs that was caused by waiting
on the flusher threads to finish:

Workqueue: pm_fs_sync pm_fs_sync_work_fn
Call Trace:
 <TASK>
 __schedule+0x457/0x1720
 schedule+0x27/0xd0
 wb_wait_for_completion+0x97/0xe0
 sync_inodes_sb+0xf8/0x2e0
 __iterate_supers+0xdc/0x160
 ksys_sync+0x43/0xb0
 pm_fs_sync_work_fn+0x17/0xa0
 process_one_work+0x193/0x350
 worker_thread+0x1a1/0x310
 kthread+0xfc/0x240
 ret_from_fork+0x243/0x280
 ret_from_fork_asm+0x1a/0x30
 </TASK>

On fuse this is problematic because there are paths that may cause the
flusher thread to block (eg if systemd freezes the user session cgroups
first, which freezes the fuse daemon, before invoking the kernel
suspend. The kernel suspend triggers ->write_node() which on fuse issues
a synchronous setattr request, which cannot be processed since the
daemon is frozen. Or if the daemon is buggy and cannot properly complete
writeback, initiating writeback on a dirty folio already under writeback
leads to writeback_get_folio() -> folio_prepare_writeback() ->
unconditional wait on writeback to finish, which will cause a hang).
This commit restores fuse to its prior behavior before tmp folios were
removed, where sync was essentially a no-op.

[1] https://lore.kernel.org/linux-fsdevel/CAJnrk1a-asuvfrbKXbEwwDSctvemF+6zfhdnuzO65Pt8HsFSRw@mail.gmail.com/T/#m632c4648e9cafc4239299887109ebd880ac6c5c1

Fixes: 0c58a97f91 ("fuse: remove tmp folio for writebacks and internal rb tree")
Reported-by: John <therealgraysky@proton.me>
Cc: stable@vger.kernel.org
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Link: https://patch.msgid.link/20260320005145.2483161-2-joannelkoong@gmail.com
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-03-20 14:18:56 +01:00
..
Kconfig fuse: fix references to fuse.rst -> fuse/fuse.rst 2025-09-02 11:14:15 +02:00
Makefile fuse: move CREATE_TRACE_POINTS to a separate file 2025-09-25 16:22:18 +02:00
acl.c posix_acl: make posix_acl_to_xattr() alloc the buffer 2026-01-16 10:51:12 +01:00
backing.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
control.c convert fuse_ctl 2025-11-16 01:35:03 -05:00
cuse.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
dax.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
dev.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
dev_uring.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
dev_uring_i.h fuse: add kernel-enforced timeout option for requests 2025-03-31 14:59:25 +02:00
dir.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
file.c writeback: don't block sync for filesystems with no data integrity guarantees 2026-03-20 14:18:56 +01:00
fuse_dev_i.h fuse: missing copy_finish in fuse-over-io-uring argument copies 2025-11-12 11:45:03 +01:00
fuse_i.h fuse update for 6.19 2025-12-05 15:25:13 -08:00
fuse_trace.h fuse: add simple request tracepoints 2024-08-29 11:43:13 +02:00
inode.c writeback: don't block sync for filesystems with no data integrity guarantees 2026-03-20 14:18:56 +01:00
ioctl.c Revert "fs: make vfs_fileattr_[get|set] return -EOPNOTSUPP" 2025-10-10 13:44:03 +02:00
iomode.c fuse: remove unused 'inode' parameter in fuse_passthrough_open 2025-08-27 14:29:44 +02:00
passthrough.c fuse: move the backing file idr and code into a new source file 2025-09-25 16:06:02 +02:00
readdir.c fuse: increase readdir buffer size 2025-05-29 12:31:24 +02:00
sysctl.c fuse: add default_request_timeout and max_request_timeout sysctls 2025-03-31 14:59:27 +02:00
trace.c fuse: move CREATE_TRACE_POINTS to a separate file 2025-09-25 16:22:18 +02:00
virtio_fs.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
xattr.c fuse: make args->in_args[0] to be always the header 2025-01-24 11:54:02 +01:00