Skip to content

Commit d9c37a4

Browse files
adam900710brauner
authored andcommitted
fs: add a new remove_bdev() callback
Currently all filesystems which implement super_operations::shutdown() can not afford losing a device. Thus fs_bdev_mark_dead() will just call the ->shutdown() callback for the involved filesystem. But it will no longer be the case, as multi-device filesystems like btrfs and bcachefs can handle certain device loss without the need to shutdown the whole filesystem. To allow those multi-device filesystems to be integrated to use fs_holder_ops: - Add a new super_operations::remove_bdev() callback - Try ->remove_bdev() callback first inside fs_bdev_mark_dead() If the callback returned 0, meaning the fs can handling the device loss, then exit without doing anything else. If there is no such callback or the callback returned non-zero value, continue to shutdown the filesystem as usual. This means the new remove_bdev() should only do the check on whether the operation can continue, and if so do the fs specific handlings. The shutdown handling should still be handled by the existing ->shutdown() callback. For all existing filesystems with shutdown callback, there is no change to the code nor behavior. Btrfs is going to implement both the ->remove_bdev() and ->shutdown() callbacks soon. Signed-off-by: Qu Wenruo <[email protected]> Link: https://lore.kernel.org/09909fcff7f2763cc037fec97ac2482bdc0a12cb.1752470276.git.wqu@suse.com Reviewed-by: Jan Kara <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 19272b3 commit d9c37a4

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

fs/super.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,17 @@ static void fs_bdev_mark_dead(struct block_device *bdev, bool surprise)
14571457
if (!sb)
14581458
return;
14591459

1460+
if (sb->s_op->remove_bdev) {
1461+
int ret;
1462+
1463+
ret = sb->s_op->remove_bdev(sb, bdev);
1464+
if (!ret) {
1465+
super_unlock_shared(sb);
1466+
return;
1467+
}
1468+
/* Fallback to shutdown. */
1469+
}
1470+
14601471
if (!surprise)
14611472
sync_filesystem(sb);
14621473
shrink_dcache_sb(sb);

include/linux/fs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2363,6 +2363,15 @@ struct super_operations {
23632363
struct shrink_control *);
23642364
long (*free_cached_objects)(struct super_block *,
23652365
struct shrink_control *);
2366+
/*
2367+
* If a filesystem can support graceful removal of a device and
2368+
* continue read-write operations, implement this callback.
2369+
*
2370+
* Return 0 if the filesystem can continue read-write.
2371+
* Non-zero return value or no such callback means the fs will be shutdown
2372+
* as usual.
2373+
*/
2374+
int (*remove_bdev)(struct super_block *sb, struct block_device *bdev);
23662375
void (*shutdown)(struct super_block *sb);
23672376
};
23682377

0 commit comments

Comments
 (0)