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:
Liu Bo 2012-06-29 03:58:46 -06:00 committed by Chris Mason
parent 287082b0bd
commit a874a63e13
1 changed files with 11 additions and 11 deletions

View File

@ -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;
} }