On Wed 02-08-23 17:41:26, Christoph Hellwig wrote: > fs_mark_dead currently uses get_super to find the superblock for the > block device that is going away. This means it is limited to the > main device stored in sb->s_dev, leading to a lot of code duplication > for file systems that can use multiple block devices. > > Now that the holder for all block devices used by file systems is set > to the super_block, we can instead look at that holder and then check > if the file system is born and active, so do that instead. > > Signed-off-by: Christoph Hellwig <hch@xxxxxx> Looks good. Feel free to add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza > --- > fs/super.c | 30 ++++++++++++++++++++++++++---- > 1 file changed, 26 insertions(+), 4 deletions(-) > > diff --git a/fs/super.c b/fs/super.c > index 09b65ee1a8b737..0cda4af0a7e16c 100644 > --- a/fs/super.c > +++ b/fs/super.c > @@ -1209,17 +1209,39 @@ int get_tree_keyed(struct fs_context *fc, > EXPORT_SYMBOL(get_tree_keyed); > > #ifdef CONFIG_BLOCK > +/* > + * Lock a super block that the callers holds a reference to. > + * > + * The caller needs to ensure that the super_block isn't being freed while > + * calling this function, e.g. by holding a lock over the call to this function > + * and the place that clears the pointer to the superblock used by this function > + * before freeing the superblock. > + */ > +static bool lock_active_super(struct super_block *sb) > +{ > + down_read(&sb->s_umount); > + if (!sb->s_root || > + (sb->s_flags & (SB_ACTIVE | SB_BORN)) != (SB_ACTIVE | SB_BORN)) { > + up_read(&sb->s_umount); > + return false; > + } > + return true; > +} > + > static void fs_mark_dead(struct block_device *bdev) > { > - struct super_block *sb; > + struct super_block *sb = bdev->bd_holder; > > - sb = get_super(bdev); > - if (!sb) > + /* bd_holder_lock ensures that the sb isn't freed */ > + lockdep_assert_held(&bdev->bd_holder_lock); > + > + if (!lock_active_super(sb)) > return; > > if (sb->s_op->shutdown) > sb->s_op->shutdown(sb); > - drop_super(sb); > + > + up_read(&sb->s_umount); > } > > static const struct blk_holder_ops fs_holder_ops = { > -- > 2.39.2 > -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR