Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -43,10 +43,10 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)
	if (err)
		goto out;

	mutex_lock(&inode->i_mutex);
	err = mnt_want_write_file(file);
	if (err)
		goto out_unlock_inode;
		goto out;
	mutex_lock(&inode->i_mutex);

	/*
	 * 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)
	/* The root directory has no attributes */
	if (inode->i_ino == MSDOS_ROOT_INO && attr != ATTR_DIR) {
		err = -EINVAL;
		goto out_drop_write;
		goto out_unlock_inode;
	}

	if (sbi->options.sys_immutable &&
	    ((attr | oldattr) & ATTR_SYS) &&
	    !capable(CAP_LINUX_IMMUTABLE)) {
		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)
	 */
	err = security_inode_setattr(file->f_path.dentry, &ia);
	if (err)
		goto out_drop_write;
		goto out_unlock_inode;

	/* This MUST be done before doing anything irreversible... */
	err = fat_setattr(file->f_path.dentry, &ia);
	if (err)
		goto out_drop_write;
		goto out_unlock_inode;

	fsnotify_change(file->f_path.dentry, ia.ia_valid);
	if (sbi->options.sys_immutable) {
@@ -107,10 +107,9 @@ static int fat_ioctl_set_attributes(struct file *file, u32 __user *user_attr)

	fat_save_attrs(inode, attr);
	mark_inode_dirty(inode);
out_drop_write:
	mnt_drop_write_file(file);
out_unlock_inode:
	mutex_unlock(&inode->i_mutex);
	mnt_drop_write_file(file);
out:
	return err;
}