Currently we already have the super_operations::shutdown() callback, which is called when the block device of a filesystem is marked dead. However this is mostly for single(ish) block device filesystems. For multi-device filesystems, they may afford a missing device, thus may continue work without fully shutdown the filesystem. So add a new super_operation::shutdown_bdev() callback, for mutli-device filesystems like btrfs and bcachefs. For now the only user is fs_holder_ops::mark_dead(), which will call shutdown_bdev() if supported. If not supported then fallback to the original shutdown() callback. Btrfs is going to add the usage of shutdown_bdev() soon. Signed-off-by: Qu Wenruo <wqu@xxxxxxxx> --- fs/super.c | 4 +++- include/linux/fs.h | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/super.c b/fs/super.c index 21799e213fd7..8242a03bd5ce 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1461,7 +1461,9 @@ static void fs_bdev_mark_dead(struct block_device *bdev, bool surprise) sync_filesystem(sb); shrink_dcache_sb(sb); evict_inodes(sb); - if (sb->s_op->shutdown) + if (sb->s_op->shutdown_bdev) + sb->s_op->shutdown_bdev(sb, bdev); + else if (sb->s_op->shutdown) sb->s_op->shutdown(sb); super_unlock_shared(sb); diff --git a/include/linux/fs.h b/include/linux/fs.h index 96c7925a6551..4f6b4b3cbe22 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2363,7 +2363,17 @@ struct super_operations { struct shrink_control *); long (*free_cached_objects)(struct super_block *, struct shrink_control *); + /* + * For single-device filesystems. Called when the only block device is + * marked dead. + */ void (*shutdown)(struct super_block *sb); + + /* + * For multi-device filesystems. Called when any of its block device is + * marked dead. + */ + void (*shutdown_bdev)(struct super_block *sb, struct block_device *bdev); }; /* -- 2.49.0