aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-06-12 10:20:32 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-30 17:02:51 -0400
commite7848683ae7ded0a4a8964122a47da9104a98337 (patch)
tree7dc006d60d73c1c37b74bc4127ecfe0209517230 /fs
parente24f17da3560781e274699f066fb788ad52f4402 (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.c23
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);
677out_up_read: 677out_up_read:
678 up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); 678 up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem);
679out_drop_write:
680 mnt_drop_write(parent->mnt);
681out_dput: 679out_dput:
682 dput(dentry); 680 dput(dentry);
683out_unlock: 681out_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