[PATCH 3/5] fs: make BLKFLSBUF's wait for a superblock killable

From: Josef Bacik

Date: Wed Oct 21 2026 - 12:48:11 EST


fs_bdev_sync() syncs the filesystems on a block device for BLKFLSBUF. It
can already be killed while it waits for one which is being unmounted. For
one which is still being mounted it waits for SB_BORN, and then for
s_umount, in super_lock(), which can't be killed. If the mount is stuck on
that very device, so is the ioctl.

Use super_lock_killable() and stop the walk when the task is killed, as for
the unmount. All BLKFLSBUF does afterwards is invalidate_bdev(), which
leaves dirty pages and pages under writeback alone.

Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
---
fs/super.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index 40f92ffa39c1..ecba64ed0c2a 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1676,17 +1676,21 @@ static void fs_bdev_sync(struct block_device *bdev)

for (sb_dev = super_dev_first(dev); sb_dev; sb_dev = super_dev_next(sb_dev)) {
struct super_block *sb = sb_dev->sd_sb;
+ int ret;

- if (!super_lock_shared(sb)) {
- if (super_wait_shutdown_killable(sb)) {
- super_dev_put(sb_dev);
- return;
- }
+ ret = super_lock_killable(sb, false);
+ if (!ret) {
+ if (sb->s_root && (sb->s_flags & SB_ACTIVE))
+ sync_filesystem(sb);
+ super_unlock_shared(sb);
continue;
}
- if (sb->s_root && (sb->s_flags & SB_ACTIVE))
- sync_filesystem(sb);
- super_unlock_shared(sb);
+ if (ret == -ENOENT)
+ ret = super_wait_shutdown_killable(sb);
+ if (ret) {
+ super_dev_put(sb_dev);
+ return;
+ }
}
}


--
2.55.0