Convert mount code to use blkdev_get_handle_by_path() and propagate the handle around to blkdev_handle_put(). Signed-off-by: Jan Kara <jack@xxxxxxx> --- fs/super.c | 52 ++++++++++++++++++++++++++-------------------- include/linux/fs.h | 1 + 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/fs/super.c b/fs/super.c index e781226e2880..d35545364c5d 100644 --- a/fs/super.c +++ b/fs/super.c @@ -1228,7 +1228,8 @@ static const struct blk_holder_ops fs_holder_ops = { static int set_bdev_super(struct super_block *s, void *data) { - s->s_bdev = data; + s->s_bdev_handle = data; + s->s_bdev = s->s_bdev_handle->bdev; s->s_dev = s->s_bdev->bd_dev; s->s_bdi = bdi_get(s->s_bdev->bd_disk->bdi); @@ -1244,7 +1245,8 @@ static int set_bdev_super_fc(struct super_block *s, struct fs_context *fc) static int test_bdev_super_fc(struct super_block *s, struct fs_context *fc) { - return !(s->s_iflags & SB_I_RETIRED) && s->s_bdev == fc->sget_key; + return !(s->s_iflags & SB_I_RETIRED) && + s->s_bdev == ((struct bdev_handle *)fc->sget_key)->bdev; } /** @@ -1256,6 +1258,7 @@ int get_tree_bdev(struct fs_context *fc, int (*fill_super)(struct super_block *, struct fs_context *)) { + struct bdev_handle *bdev_handle; struct block_device *bdev; struct super_block *s; int error = 0; @@ -1263,12 +1266,14 @@ int get_tree_bdev(struct fs_context *fc, if (!fc->source) return invalf(fc, "No source specified"); - bdev = blkdev_get_by_path(fc->source, sb_open_mode(fc->sb_flags), - fc->fs_type, &fs_holder_ops); - if (IS_ERR(bdev)) { + bdev_handle = blkdev_get_handle_by_path(fc->source, + sb_open_mode(fc->sb_flags), fc->fs_type, + &fs_holder_ops); + if (IS_ERR(bdev_handle)) { errorf(fc, "%s: Can't open blockdev", fc->source); - return PTR_ERR(bdev); + return PTR_ERR(bdev_handle); } + bdev = bdev_handle->bdev; /* Once the superblock is inserted into the list by sget_fc(), s_umount * will protect the lockfs code from trying to start a snapshot while @@ -1278,16 +1283,16 @@ int get_tree_bdev(struct fs_context *fc, if (bdev->bd_fsfreeze_count > 0) { mutex_unlock(&bdev->bd_fsfreeze_mutex); warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev); - blkdev_put(bdev, fc->fs_type); + blkdev_handle_put(bdev_handle); return -EBUSY; } fc->sb_flags |= SB_NOSEC; - fc->sget_key = bdev; + fc->sget_key = bdev_handle; s = sget_fc(fc, test_bdev_super_fc, set_bdev_super_fc); mutex_unlock(&bdev->bd_fsfreeze_mutex); if (IS_ERR(s)) { - blkdev_put(bdev, fc->fs_type); + blkdev_handle_put(bdev_handle); return PTR_ERR(s); } @@ -1296,19 +1301,19 @@ int get_tree_bdev(struct fs_context *fc, if ((fc->sb_flags ^ s->s_flags) & SB_RDONLY) { warnf(fc, "%pg: Can't mount, would change RO state", bdev); deactivate_locked_super(s); - blkdev_put(bdev, fc->fs_type); + blkdev_handle_put(bdev_handle); return -EBUSY; } /* * s_umount nests inside open_mutex during - * __invalidate_device(). blkdev_put() acquires + * __invalidate_device(). blkdev_handle_put() acquires * open_mutex and can't be called under s_umount. Drop * s_umount temporarily. This is safe as we're * holding an active reference. */ up_write(&s->s_umount); - blkdev_put(bdev, fc->fs_type); + blkdev_handle_put(bdev_handle); down_write(&s->s_umount); } else { snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev); @@ -1333,21 +1338,24 @@ EXPORT_SYMBOL(get_tree_bdev); static int test_bdev_super(struct super_block *s, void *data) { - return !(s->s_iflags & SB_I_RETIRED) && (void *)s->s_bdev == data; + return !(s->s_iflags & SB_I_RETIRED) && + s->s_bdev == ((struct bdev_handle *)data)->bdev; } struct dentry *mount_bdev(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, int (*fill_super)(struct super_block *, void *, int)) { + struct bdev_handle *bdev_handle; struct block_device *bdev; struct super_block *s; int error = 0; - bdev = blkdev_get_by_path(dev_name, sb_open_mode(flags), fs_type, - &fs_holder_ops); - if (IS_ERR(bdev)) - return ERR_CAST(bdev); + bdev_handle = blkdev_get_handle_by_path(dev_name, sb_open_mode(flags), + fs_type, &fs_holder_ops); + if (IS_ERR(bdev_handle)) + return ERR_CAST(bdev_handle); + bdev = bdev_handle->bdev; /* * once the super is inserted into the list by sget, s_umount @@ -1361,7 +1369,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, goto error_bdev; } s = sget(fs_type, test_bdev_super, set_bdev_super, flags | SB_NOSEC, - bdev); + bdev_handle); mutex_unlock(&bdev->bd_fsfreeze_mutex); if (IS_ERR(s)) goto error_s; @@ -1375,13 +1383,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, /* * s_umount nests inside open_mutex during - * __invalidate_device(). blkdev_put() acquires + * __invalidate_device(). blkdev_handle_put() acquires * open_mutex and can't be called under s_umount. Drop * s_umount temporarily. This is safe as we're * holding an active reference. */ up_write(&s->s_umount); - blkdev_put(bdev, fs_type); + blkdev_handle_put(bdev_handle); down_write(&s->s_umount); } else { snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev); @@ -1403,7 +1411,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, error_s: error = PTR_ERR(s); error_bdev: - blkdev_put(bdev, fs_type); + blkdev_handle_put(bdev_handle); error: return ERR_PTR(error); } @@ -1416,7 +1424,7 @@ void kill_block_super(struct super_block *sb) bdev->bd_super = NULL; generic_shutdown_super(sb); sync_blockdev(bdev); - blkdev_put(bdev, sb->s_type); + blkdev_handle_put(sb->s_bdev_handle); } EXPORT_SYMBOL(kill_block_super); diff --git a/include/linux/fs.h b/include/linux/fs.h index 6867512907d6..44a224b91570 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1187,6 +1187,7 @@ struct super_block { struct hlist_bl_head s_roots; /* alternate root dentries for NFS */ struct list_head s_mounts; /* list of mounts; _not_ for fs use */ struct block_device *s_bdev; + struct bdev_handle *s_bdev_handle; struct backing_dev_info *s_bdi; struct mtd_info *s_mtd; struct hlist_node s_instances; -- 2.35.3