@@ -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);
@@ -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;
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@suse.cz> --- fs/super.c | 52 ++++++++++++++++++++++++++-------------------- include/linux/fs.h | 1 + 2 files changed, 31 insertions(+), 22 deletions(-)