diff options
author | Jan Kara <jack@suse.cz> | 2012-06-12 10:20:32 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-30 17:02:51 -0400 |
commit | e7848683ae7ded0a4a8964122a47da9104a98337 (patch) | |
tree | 7dc006d60d73c1c37b74bc4127ecfe0209517230 /fs | |
parent | e24f17da3560781e274699f066fb788ad52f4402 (diff) |
btrfs: Push mnt_want_write() outside of i_mutex
When mnt_want_write() starts to handle freezing it will get a full lock
semantics requiring proper lock ordering. So push mnt_want_write() call
consistently outside of i_mutex.
CC: Chris Mason <chris.mason@oracle.com>
CC: linux-btrfs@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ioctl.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 1e9f6c019ad0..cd93eb530b74 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -193,6 +193,10 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) | |||
193 | if (!inode_owner_or_capable(inode)) | 193 | if (!inode_owner_or_capable(inode)) |
194 | return -EACCES; | 194 | return -EACCES; |
195 | 195 | ||
196 | ret = mnt_want_write_file(file); | ||
197 | if (ret) | ||
198 | return ret; | ||
199 | |||
196 | mutex_lock(&inode->i_mutex); | 200 | mutex_lock(&inode->i_mutex); |
197 | 201 | ||
198 | ip_oldflags = ip->flags; | 202 | ip_oldflags = ip->flags; |
@@ -207,10 +211,6 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) | |||
207 | } | 211 | } |
208 | } | 212 | } |
209 | 213 | ||
210 | ret = mnt_want_write_file(file); | ||
211 | if (ret) | ||
212 | goto out_unlock; | ||
213 | |||
214 | if (flags & FS_SYNC_FL) | 214 | if (flags & FS_SYNC_FL) |
215 | ip->flags |= BTRFS_INODE_SYNC; | 215 | ip->flags |= BTRFS_INODE_SYNC; |
216 | else | 216 | else |
@@ -273,9 +273,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) | |||
273 | inode->i_flags = i_oldflags; | 273 | inode->i_flags = i_oldflags; |
274 | } | 274 | } |
275 | 275 | ||
276 | mnt_drop_write_file(file); | ||
277 | out_unlock: | 276 | out_unlock: |
278 | mutex_unlock(&inode->i_mutex); | 277 | mutex_unlock(&inode->i_mutex); |
278 | mnt_drop_write_file(file); | ||
279 | return ret; | 279 | return ret; |
280 | } | 280 | } |
281 | 281 | ||
@@ -641,6 +641,10 @@ static noinline int btrfs_mksubvol(struct path *parent, | |||
641 | struct dentry *dentry; | 641 | struct dentry *dentry; |
642 | int error; | 642 | int error; |
643 | 643 | ||
644 | error = mnt_want_write(parent->mnt); | ||
645 | if (error) | ||
646 | return error; | ||
647 | |||
644 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); | 648 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
645 | 649 | ||
646 | dentry = lookup_one_len(name, parent->dentry, namelen); | 650 | dentry = lookup_one_len(name, parent->dentry, namelen); |
@@ -652,13 +656,9 @@ static noinline int btrfs_mksubvol(struct path *parent, | |||
652 | if (dentry->d_inode) | 656 | if (dentry->d_inode) |
653 | goto out_dput; | 657 | goto out_dput; |
654 | 658 | ||
655 | error = mnt_want_write(parent->mnt); | ||
656 | if (error) | ||
657 | goto out_dput; | ||
658 | |||
659 | error = btrfs_may_create(dir, dentry); | 659 | error = btrfs_may_create(dir, dentry); |
660 | if (error) | 660 | if (error) |
661 | goto out_drop_write; | 661 | goto out_dput; |
662 | 662 | ||
663 | down_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); | 663 | down_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); |
664 | 664 | ||
@@ -676,12 +676,11 @@ static noinline int btrfs_mksubvol(struct path *parent, | |||
676 | fsnotify_mkdir(dir, dentry); | 676 | fsnotify_mkdir(dir, dentry); |
677 | out_up_read: | 677 | out_up_read: |
678 | up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); | 678 | up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); |
679 | out_drop_write: | ||
680 | mnt_drop_write(parent->mnt); | ||
681 | out_dput: | 679 | out_dput: |
682 | dput(dentry); | 680 | dput(dentry); |
683 | out_unlock: | 681 | out_unlock: |
684 | mutex_unlock(&dir->i_mutex); | 682 | mutex_unlock(&dir->i_mutex); |
683 | mnt_drop_write(parent->mnt); | ||
685 | return error; | 684 | return error; |
686 | } | 685 | } |
687 | 686 | ||