Commit e24f17da authored by Jan Kara's avatar Jan Kara Committed by Al Viro

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: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent c30dabfe
...@@ -43,10 +43,10 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) ...@@ -43,10 +43,10 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
if (err) if (err)
goto out; goto out;
mutex_lock(&inode->i_mutex);
err = mnt_want_write_file(file); err = mnt_want_write_file(file);
if (err) if (err)
goto out_unlock_inode; goto out;
mutex_lock(&inode->i_mutex);
/* /*
* ATTR_VOLUME and ATTR_DIR cannot be changed; this also * 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,14 +73,14 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
/* The root directory has no attributes */ /* The root directory has no attributes */
if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) { if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) {
err = -EINVAL; err = -EINVAL;
goto out_drop_write; goto out_unlock_inode;
} }
if (sbi->options.sys_immutable && if (sbi->options.sys_immutable &&
((attr | oldattr) & ATTR_SYS) && ((attr | oldattr) & ATTR_SYS) &&
!capable(CAP_LINUX_IMMUTABLE)) { !capable(CAP_LINUX_IMMUTABLE)) {
err = -EPERM; err = -EPERM;
goto out_drop_write; goto out_unlock_inode;
} }
/* /*
...@@ -90,12 +90,12 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) ...@@ -90,12 +90,12 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
*/ */
err = security_inode_setattr(file->f_path.dentry, &ia); err = security_inode_setattr(file->f_path.dentry, &ia);
if (err) if (err)
goto out_drop_write; goto out_unlock_inode;
/* This MUST be done before doing anything irreversible... */ /* This MUST be done before doing anything irreversible... */
err = fat_setattr(file->f_path.dentry, &ia); err = fat_setattr(file->f_path.dentry, &ia);
if (err) if (err)
goto out_drop_write; goto out_unlock_inode;
fsnotify_change(file->f_path.dentry, ia.ia_valid); fsnotify_change(file->f_path.dentry, ia.ia_valid);
if (sbi->options.sys_immutable) { if (sbi->options.sys_immutable) {
...@@ -107,10 +107,9 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr) ...@@ -107,10 +107,9 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
fat_save_attrs(inode, attr); fat_save_attrs(inode, attr);
mark_inode_dirty(inode); mark_inode_dirty(inode);
out_drop_write:
mnt_drop_write_file(file);
out_unlock_inode: out_unlock_inode:
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
mnt_drop_write_file(file);
out: out:
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment