Btrfs: check write access to mount earlier while creating snapshots
Move check of write access to mount into upper functions so that we can use mnt_want_write_file instead, which is faster than mnt_want_write. Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
This commit is contained in:
parent
287082b0bd
commit
a874a63e13
|
@ -652,13 +652,9 @@ static noinline int btrfs_mksubvol(struct path *parent,
|
||||||
if (dentry->d_inode)
|
if (dentry->d_inode)
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
|
|
||||||
error = mnt_want_write(parent->mnt);
|
|
||||||
if (error)
|
|
||||||
goto out_dput;
|
|
||||||
|
|
||||||
error = btrfs_may_create(dir, dentry);
|
error = btrfs_may_create(dir, dentry);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_drop_write;
|
goto out_dput;
|
||||||
|
|
||||||
down_read(&BTRFS_I(dir)->root->fs_info->subvol_sem);
|
down_read(&BTRFS_I(dir)->root->fs_info->subvol_sem);
|
||||||
|
|
||||||
|
@ -676,8 +672,6 @@ static noinline int btrfs_mksubvol(struct path *parent,
|
||||||
fsnotify_mkdir(dir, dentry);
|
fsnotify_mkdir(dir, dentry);
|
||||||
out_up_read:
|
out_up_read:
|
||||||
up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem);
|
up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem);
|
||||||
out_drop_write:
|
|
||||||
mnt_drop_write(parent->mnt);
|
|
||||||
out_dput:
|
out_dput:
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
|
@ -1395,16 +1389,20 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
|
||||||
if (root->fs_info->sb->s_flags & MS_RDONLY)
|
if (root->fs_info->sb->s_flags & MS_RDONLY)
|
||||||
return -EROFS;
|
return -EROFS;
|
||||||
|
|
||||||
|
ret = mnt_want_write_file(file);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
namelen = strlen(name);
|
namelen = strlen(name);
|
||||||
if (strchr(name, '/')) {
|
if (strchr(name, '/')) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out_drop_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name[0] == '.' &&
|
if (name[0] == '.' &&
|
||||||
(namelen == 1 || (name[1] == '.' && namelen == 2))) {
|
(namelen == 1 || (name[1] == '.' && namelen == 2))) {
|
||||||
ret = -EEXIST;
|
ret = -EEXIST;
|
||||||
goto out;
|
goto out_drop_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subvol) {
|
if (subvol) {
|
||||||
|
@ -1415,7 +1413,7 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
|
||||||
src_file = fget(fd);
|
src_file = fget(fd);
|
||||||
if (!src_file) {
|
if (!src_file) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out_drop_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
src_inode = src_file->f_path.dentry->d_inode;
|
src_inode = src_file->f_path.dentry->d_inode;
|
||||||
|
@ -1424,13 +1422,15 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
|
||||||
"another FS\n");
|
"another FS\n");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
fput(src_file);
|
fput(src_file);
|
||||||
goto out;
|
goto out_drop_write;
|
||||||
}
|
}
|
||||||
ret = btrfs_mksubvol(&file->f_path, name, namelen,
|
ret = btrfs_mksubvol(&file->f_path, name, namelen,
|
||||||
BTRFS_I(src_inode)->root,
|
BTRFS_I(src_inode)->root,
|
||||||
transid, readonly);
|
transid, readonly);
|
||||||
fput(src_file);
|
fput(src_file);
|
||||||
}
|
}
|
||||||
|
out_drop_write:
|
||||||
|
mnt_drop_write_file(file);
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue