summaryrefslogtreecommitdiff
path: root/include/linux/fs/super.h
AgeCommit message (Collapse)Author
2026-06-29fs: look up superblocks via the device table in fs_holder_opsChristian Brauner
Switch the fs_holder_ops callbacks from recovering the single owning superblock out of bdev->bd_holder to walking the device-to-superblock table and acting on every superblock registered for the device. The holder argument becomes purely the block layer's exclusivity token and is no longer needed by the fs specific callbacks. All devices opened with fs_holder_ops are registered by now: the main device since setup_bdev_super() switched to fs_bdev_file_open_by_dev() and the extra devices (xfs log and realtime devices, btrfs member devices, the ext4 external journal) since the preceding per-filesystem conversions. So no event is lost in the switchover. The walk uses a refcount-pinning cursor: each step takes a reference on the entry via sd_ref and resumes from its sd_node. Unlinking an entry is deferred to the last unpin, so a cursor never resumes from a removed node. mark_dead and sync only need the passive reference the entry holds plus s_umount, which they take with super_lock_shared(). freeze and thaw additionally need an active reference and acquire it with get_active_super(), which waits for the superblock to be born before taking s_active. Taking s_active before the superblock is born would pin a still-mounting superblock so a racing mount that aborts could never drop s_active to zero and reach SB_DYING, deadlocking the wait for SB_BORN. This is how filesystems_freeze() and filesystems_thaw() acquire it too. One semantic change: when no live superblock uses the device anymore (the holder is dying or was never registered), fs_bdev_freeze() and fs_bdev_thaw() now return 0 - freeze after syncing the block device - where they used to return -EINVAL. The freeze-deny release path moves to the table in the same switchover. A device made unfreezable for a btrfs membership change must drop its table entry before re-allowing freezing; otherwise a freeze racing the release reaches the superblock through the still-registered entry and is stranded once the release unlinks it. Split fs_bdev_unregister() out of fs_bdev_file_release() - the inverse of fs_bdev_register() - so btrfs_release_device_allow_freeze() can drop the {dev, sb} entry, re-allow freezing on the still-open device, then close it. Re-allowing only after the entry is gone keeps a racing freeze from reaching the superblock, and doing it while the file is still open avoids touching the block device after the close. btrfs previously yielded bd_holder before re-allowing, which this commit makes irrelevant to freeze resolution. Link: https://patch.msgid.link/20260616-work-super-bdev_holder_global-v2-12-7df6b864028e@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-29fs: add dedicated block device open helpers for filesystemsChristian Brauner
Add fs_bdev_file_open_by_{dev,path}() and fs_bdev_file_release(). They open the device with fs_holder_ops and register a claim in the device-to-superblock table. Claims on the same (device, superblock) pair share one entry, so when a filesystem claims a device it already uses (xfs with its log on the data device), no second entry is added and each superblock will be acted on once. The holder argument remains purely the block layer's exclusivity token: a superblock, or a file_system_type for a device shared by several superblocks of that type. The shared case only becomes usable once the fs_holder_ops callbacks resolve superblocks through the table instead of bdev->bd_holder. Convert the main device, setup_bdev_super() and kill_block_super(), over: the open finds the entry registered by sget_fc() and claims it again. cramfs and romfs bypass kill_block_super() so they can handle MTD mounts and release the main device with a plain bdev_fput(), which would leave the claim behind: the (dev, sb) entry would never be unregistered and the passive reference it holds would keep the superblock alive forever. Convert their release paths in the same step. The frozen-device check stays in setup_bdev_super() for the primary device and is added to fs_bdev_register() for new claims, i.e. every additional device a filesystem opens through the helpers. Only a (device, superblock) pair the superblock claimed earlier may be reopened while frozen (xfs with its log on the data device): the freeze already covers that superblock through the existing claim, so nothing escapes it. Without the setup_bdev_super() check a device frozen before the mount even started (dm lock_fs, loop) could be mounted and written to (journal replay) under an active freeze, because the primary open reuses the entry registered by sget_fc() and never takes the new-claim path. Both checks read bd_fsfreeze_count only after the entry is published (by sget_fc() for the primary, by fs_bdev_register() for new claims) and pair with bdev_freeze() incrementing the count before walking the table: either the mount sees the elevated freeze count and fails with EBUSY, or the freeze finds the published entry and converges once SB_BORN is set. Link: https://patch.msgid.link/20260616-work-super-bdev_holder_global-v2-8-7df6b864028e@kernel.org Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-06-15fuse: invalidate page cache after DIO and async DIO writesCheng Ding
This fixe does page cache invalidation after DIO and async DIO writes for both O_DIRECT and FOPEN_DIRECT_IO cases. Commit b359af8275a9 ("fuse: Invalidate the page cache after FOPEN_DIRECT_IO write") fixed xfstests generic/209 for DIO writes in the FOPEN_DIRECT_IO path. DIO writes without FOPEN_DIRECT_IO are already handled by generic_file_direct_write(). However, async DIO writes (xfstests generic/451) remain unhandled. After this fix: - Async write with FUSE_ASYNC_DIO: invalidate in fuse_aio_invalidate_worker() - Otherwise (Sync or async write without FUSE_ASYNC_DIO): - With FOPEN_DIRECT_IO: invalidate in fuse_direct_write_iter() - Without FOPEN_DIRECT_IO: invalidate in generic_file_direct_write() Workqueue is required for async write invalidation to prevent deadlock: calling it directly in the I/O end routine (which is in fuse worker thread context) can block on a folio lock held by a buffered I/O thread waiting for the same fuse worker thread. Co-developed-by: Jingbo Xu <jefflexu@linux.alibaba.com> Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com> Signed-off-by: Cheng Ding <cding@ddn.com> Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2025-12-01Merge tag 'vfs-6.19-rc1.guards' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull superblock lock guard updates from Christian Brauner: "This starts the work of introducing guards for superblock related locks. Introduce super_write_guard for scoped superblock write protection. This provides a guard-based alternative to the manual sb_start_write() and sb_end_write() pattern, allowing the compiler to automatically handle the cleanup" * tag 'vfs-6.19-rc1.guards' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: xfs: use super write guard in xfs_file_ioctl() open: use super write guard in do_ftruncate() btrfs: use super write guard in relocating_repair_kthread() ext4: use super write guard in write_mmp_block() btrfs: use super write guard in sb_start_write() btrfs: use super write guard btrfs_run_defrag_inode() btrfs: use super write guard in btrfs_reclaim_bgs_work() fs: add super_write_guard
2025-12-01Merge tag 'vfs-6.19-rc1.fs_header' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull fs header updates from Christian Brauner: "This contains initial work to start splitting up fs.h. Begin the long-overdue work of splitting up the monolithic fs.h header. The header has grown to over 3000 lines and includes types and functions for many different subsystems, making it difficult to navigate and causing excessive compilation dependencies. This series introduces new focused headers for superblock-related code: - Rename fs_types.h to fs_dirent.h to better reflect its actual content (directory entry types) - Add fs/super_types.h containing superblock type definitions - Add fs/super.h containing superblock function declarations This is the first step in a longer effort to modularize the VFS headers. Cleanups: - Inode Field Layout Optimization (Mateusz Guzik) Move inode fields used during fast path lookup closer together to improve cache locality during path resolution. - current_umask() Optimization (Mateusz Guzik) Inline current_umask() and move it to fs_struct.h. This improves performance by avoiding function call overhead for this frequently-used function, and places it in a more appropriate header since it operates on fs_struct" * tag 'vfs-6.19-rc1.fs_header' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fs: move inode fields used during fast path lookup closer together fs: inline current_umask() and move it to fs_struct.h fs: add fs/super.h header fs: add fs/super_types.h header fs: rename fs_types.h to fs_dirent.h
2025-11-05fs: add super_write_guardChristian Brauner
Link: https://patch.msgid.link/20251104-work-guards-v1-1-5108ac78a171@kernel.org Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-11-05fs: add fs/super.h headerChristian Brauner
Split out super block associated functions into a separate header. Link: https://patch.msgid.link/20251104-work-fs-header-v1-3-fb39a2efe39e@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>