diff options
author | Jan Kara <jack@suse.cz> | 2012-06-12 10:20:31 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-30 17:02:50 -0400 |
commit | e24f17da3560781e274699f066fb788ad52f4402 (patch) | |
tree | 8523d7d7e6cc4d33d2cec4172fe055f104d8647d /fs/fat/file.c | |
parent | c30dabfe5d10c5fd70d882e5afb8f59f2942b194 (diff) |
fat: 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
outside of i_mutex as in other places.
CC: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fat/file.c')
-rw-r--r-- | fs/fat/file.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/fs/fat/file.c b/fs/fat/file.c index a71fe3715ee8..e007b8bd8e5e 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -43,10 +43,10 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) | |||
43 | if (err) | 43 | if (err) |
44 | goto out; | 44 | goto out; |
45 | 45 | ||
46 | mutex_lock(&inode->i_mutex); | ||
47 | err = mnt_want_write_file(file); | 46 | err = mnt_want_write_file(file); |
48 | if (err) | 47 | if (err) |
49 | goto out_unlock_inode; | 48 | goto out; |
49 | mutex_lock(&inode->i_mutex); | ||
50 | 50 | ||
51 | /* | 51 | /* |
52 | * ATTR_VOLUME and ATTR_DIR cannot be changed; this also | 52 | * ATTR_VOLUME and ATTR_DIR cannot be changed; this also |
@@ -73,14 +73,14 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) | |||
73 | /* The root directory has no attributes */ | 73 | /* The root directory has no attributes */ |
74 | if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) { | 74 | if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) { |
75 | err = -EINVAL; | 75 | err = -EINVAL; |
76 | goto out_drop_write; | 76 | goto out_unlock_inode; |
77 | } | 77 | } |
78 | 78 | ||
79 | if (sbi->options.sys_immutable && | 79 | if (sbi->options.sys_immutable && |
80 | ((attr | oldattr) & ATTR_SYS) && | 80 | ((attr | oldattr) & ATTR_SYS) && |
81 | !capable(CAP_LINUX_IMMUTABLE)) { | 81 | !capable(CAP_LINUX_IMMUTABLE)) { |
82 | err = -EPERM; | 82 | err = -EPERM; |
83 | goto out_drop_write; | 83 | goto out_unlock_inode; |
84 | } | 84 | } |
85 | 85 | ||
86 | /* | 86 | /* |
@@ -90,12 +90,12 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) | |||
90 | */ | 90 | */ |
91 | err = security_inode_setattr(file->f_path.dentry, &ia); | 91 | err = security_inode_setattr(file->f_path.dentry, &ia); |
92 | if (err) | 92 | if (err) |
93 | goto out_drop_write; | 93 | goto out_unlock_inode; |
94 | 94 | ||
95 | /* This MUST be done before doing anything irreversible... */ | 95 | /* This MUST be done before doing anything irreversible... */ |
96 | err = fat_setattr(file->f_path.dentry, &ia); | 96 | err = fat_setattr(file->f_path.dentry, &ia); |
97 | if (err) | 97 | if (err) |
98 | goto out_drop_write; | 98 | goto out_unlock_inode; |
99 | 99 | ||
100 | fsnotify_change(file->f_path.dentry, ia.ia_valid); | 100 | fsnotify_change(file->f_path.dentry, ia.ia_valid); |
101 | if (sbi->options.sys_immutable) { | 101 | if (sbi->options.sys_immutable) { |
@@ -107,10 +107,9 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) | |||
107 | 107 | ||
108 | fat_save_attrs(inode, attr); | 108 | fat_save_attrs(inode, attr); |
109 | mark_inode_dirty(inode); | 109 | mark_inode_dirty(inode); |
110 | out_drop_write: | ||
111 | mnt_drop_write_file(file); | ||
112 | out_unlock_inode: | 110 | out_unlock_inode: |
113 | mutex_unlock(&inode->i_mutex); | 111 | mutex_unlock(&inode->i_mutex); |
112 | mnt_drop_write_file(file); | ||
114 | out: | 113 | out: |
115 | return err; | 114 | return err; |
116 | } | 115 | } |