Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2010-07-26 16:03:58 +04:00
Родитель f7442b3be6
Коммит 8bcbbf0009
1 изменённых файлов: 22 добавлений и 29 удалений

Просмотреть файл

@ -1250,12 +1250,11 @@ static int test_gfs2_super(struct super_block *s, void *ptr)
} }
/** /**
* gfs2_get_sb - Get the GFS2 superblock * gfs2_mount - Get the GFS2 superblock
* @fs_type: The GFS2 filesystem type * @fs_type: The GFS2 filesystem type
* @flags: Mount flags * @flags: Mount flags
* @dev_name: The name of the device * @dev_name: The name of the device
* @data: The mount arguments * @data: The mount arguments
* @mnt: The vfsmnt for this mount
* *
* Q. Why not use get_sb_bdev() ? * Q. Why not use get_sb_bdev() ?
* A. We need to select one of two root directories to mount, independent * A. We need to select one of two root directories to mount, independent
@ -1264,8 +1263,8 @@ static int test_gfs2_super(struct super_block *s, void *ptr)
* Returns: 0 or -ve on error * Returns: 0 or -ve on error
*/ */
static int gfs2_get_sb(struct file_system_type *fs_type, int flags, static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data, struct vfsmount *mnt) const char *dev_name, void *data)
{ {
struct block_device *bdev; struct block_device *bdev;
struct super_block *s; struct super_block *s;
@ -1279,7 +1278,7 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
bdev = open_bdev_exclusive(dev_name, mode, fs_type); bdev = open_bdev_exclusive(dev_name, mode, fs_type);
if (IS_ERR(bdev)) if (IS_ERR(bdev))
return PTR_ERR(bdev); return ERR_CAST(bdev);
/* /*
* once the super is inserted into the list by sget, s_umount * once the super is inserted into the list by sget, s_umount
@ -1298,6 +1297,9 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
if (IS_ERR(s)) if (IS_ERR(s))
goto error_bdev; goto error_bdev;
if (s->s_root)
close_bdev_exclusive(bdev, mode);
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.ar_quota = GFS2_QUOTA_DEFAULT; args.ar_quota = GFS2_QUOTA_DEFAULT;
args.ar_data = GFS2_DATA_DEFAULT; args.ar_data = GFS2_DATA_DEFAULT;
@ -1309,17 +1311,13 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
error = gfs2_mount_args(&args, data); error = gfs2_mount_args(&args, data);
if (error) { if (error) {
printk(KERN_WARNING "GFS2: can't parse mount arguments\n"); printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
if (s->s_root) goto error_super;
goto error_super;
deactivate_locked_super(s);
return error;
} }
if (s->s_root) { if (s->s_root) {
error = -EBUSY; error = -EBUSY;
if ((flags ^ s->s_flags) & MS_RDONLY) if ((flags ^ s->s_flags) & MS_RDONLY)
goto error_super; goto error_super;
close_bdev_exclusive(bdev, mode);
} else { } else {
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
@ -1328,27 +1326,24 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
sb_set_blocksize(s, block_size(bdev)); sb_set_blocksize(s, block_size(bdev));
error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0); error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0);
if (error) { if (error)
deactivate_locked_super(s); goto error_super;
return error;
}
s->s_flags |= MS_ACTIVE; s->s_flags |= MS_ACTIVE;
bdev->bd_super = s; bdev->bd_super = s;
} }
sdp = s->s_fs_info; sdp = s->s_fs_info;
mnt->mnt_sb = s;
if (args.ar_meta) if (args.ar_meta)
mnt->mnt_root = dget(sdp->sd_master_dir); return dget(sdp->sd_master_dir);
else else
mnt->mnt_root = dget(sdp->sd_root_dir); return dget(sdp->sd_root_dir);
return 0;
error_super: error_super:
deactivate_locked_super(s); deactivate_locked_super(s);
return ERR_PTR(error);
error_bdev: error_bdev:
close_bdev_exclusive(bdev, mode); close_bdev_exclusive(bdev, mode);
return error; return ERR_PTR(error);
} }
static int set_meta_super(struct super_block *s, void *ptr) static int set_meta_super(struct super_block *s, void *ptr)
@ -1356,8 +1351,8 @@ static int set_meta_super(struct super_block *s, void *ptr)
return -EINVAL; return -EINVAL;
} }
static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags, static struct dentry *gfs2_mount_meta(struct file_system_type *fs_type,
const char *dev_name, void *data, struct vfsmount *mnt) int flags, const char *dev_name, void *data)
{ {
struct super_block *s; struct super_block *s;
struct gfs2_sbd *sdp; struct gfs2_sbd *sdp;
@ -1368,23 +1363,21 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
if (error) { if (error) {
printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n", printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n",
dev_name, error); dev_name, error);
return error; return ERR_PTR(error);
} }
s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super, s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super,
path.dentry->d_inode->i_sb->s_bdev); path.dentry->d_inode->i_sb->s_bdev);
path_put(&path); path_put(&path);
if (IS_ERR(s)) { if (IS_ERR(s)) {
printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n"); printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
return PTR_ERR(s); return ERR_CAST(s);
} }
if ((flags ^ s->s_flags) & MS_RDONLY) { if ((flags ^ s->s_flags) & MS_RDONLY) {
deactivate_locked_super(s); deactivate_locked_super(s);
return -EBUSY; return ERR_PTR(-EBUSY);
} }
sdp = s->s_fs_info; sdp = s->s_fs_info;
mnt->mnt_sb = s; return dget(sdp->sd_master_dir);
mnt->mnt_root = dget(sdp->sd_master_dir);
return 0;
} }
static void gfs2_kill_sb(struct super_block *sb) static void gfs2_kill_sb(struct super_block *sb)
@ -1410,7 +1403,7 @@ static void gfs2_kill_sb(struct super_block *sb)
struct file_system_type gfs2_fs_type = { struct file_system_type gfs2_fs_type = {
.name = "gfs2", .name = "gfs2",
.fs_flags = FS_REQUIRES_DEV, .fs_flags = FS_REQUIRES_DEV,
.get_sb = gfs2_get_sb, .mount = gfs2_mount,
.kill_sb = gfs2_kill_sb, .kill_sb = gfs2_kill_sb,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
@ -1418,7 +1411,7 @@ struct file_system_type gfs2_fs_type = {
struct file_system_type gfs2meta_fs_type = { struct file_system_type gfs2meta_fs_type = {
.name = "gfs2meta", .name = "gfs2meta",
.fs_flags = FS_REQUIRES_DEV, .fs_flags = FS_REQUIRES_DEV,
.get_sb = gfs2_get_sb_meta, .mount = gfs2_mount_meta,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };