On Mon 14-07-25 14:55:57, Qu Wenruo wrote: > 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 ^^^ handle > 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 ^^^^ I'd remove this word. > ->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 <wqu@xxxxxxxx> Besides the spelling fixes looks good to me. Feel free to add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza > --- > fs/super.c | 11 +++++++++++ > include/linux/fs.h | 9 +++++++++ > 2 files changed, 20 insertions(+) > > diff --git a/fs/super.c b/fs/super.c > index 80418ca8e215..7f876f32343a 100644 > --- a/fs/super.c > +++ b/fs/super.c > @@ -1459,6 +1459,17 @@ static void fs_bdev_mark_dead(struct block_device *bdev, bool surprise) > if (!sb) > return; > > + if (sb->s_op->remove_bdev) { > + int ret; > + > + ret = sb->s_op->remove_bdev(sb, bdev); > + if (!ret) { > + super_unlock_shared(sb); > + return; > + } > + /* Fallback to shutdown. */ > + } > + > if (!surprise) > sync_filesystem(sb); > shrink_dcache_sb(sb); > diff --git a/include/linux/fs.h b/include/linux/fs.h > index b085f161ed22..6a8a5e63a5d4 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -2367,6 +2367,15 @@ struct super_operations { > struct shrink_control *); > long (*free_cached_objects)(struct super_block *, > struct shrink_control *); > + /* > + * If a filesystem can support graceful removal of a device and > + * continue read-write operations, implement this callback. > + * > + * Return 0 if the filesystem can continue read-write. > + * Non-zero return value or no such callback means the fs will be shutdown > + * as usual. > + */ > + int (*remove_bdev)(struct super_block *sb, struct block_device *bdev); > void (*shutdown)(struct super_block *sb); > }; > > -- > 2.50.0 > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR