diff options
author | David Sterba <dsterba@suse.cz> | 2013-12-06 11:51:32 -0500 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2013-12-12 10:11:38 -0500 |
commit | e43f998e47bae27e37e159915625e8d4b130153b (patch) | |
tree | 03a1788ff0601554fca2c0fce2476548c80c78bd /fs | |
parent | a7e252af5a819eb71c9494e62b2bfca982e92f84 (diff) |
btrfs: call mnt_drop_write after interrupted subvol deletion
If btrfs_ioctl_snap_destroy blocks on the mutex and the process is
killed, mnt_write count is unbalanced and leads to unmountable
filesystem.
CC: stable@vger.kernel.org
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ioctl.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index a111622598b0..21da5762b0b1 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -2121,7 +2121,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
2121 | 2121 | ||
2122 | err = mutex_lock_killable_nested(&dir->i_mutex, I_MUTEX_PARENT); | 2122 | err = mutex_lock_killable_nested(&dir->i_mutex, I_MUTEX_PARENT); |
2123 | if (err == -EINTR) | 2123 | if (err == -EINTR) |
2124 | goto out; | 2124 | goto out_drop_write; |
2125 | dentry = lookup_one_len(vol_args->name, parent, namelen); | 2125 | dentry = lookup_one_len(vol_args->name, parent, namelen); |
2126 | if (IS_ERR(dentry)) { | 2126 | if (IS_ERR(dentry)) { |
2127 | err = PTR_ERR(dentry); | 2127 | err = PTR_ERR(dentry); |
@@ -2284,6 +2284,7 @@ out_dput: | |||
2284 | dput(dentry); | 2284 | dput(dentry); |
2285 | out_unlock_dir: | 2285 | out_unlock_dir: |
2286 | mutex_unlock(&dir->i_mutex); | 2286 | mutex_unlock(&dir->i_mutex); |
2287 | out_drop_write: | ||
2287 | mnt_drop_write_file(file); | 2288 | mnt_drop_write_file(file); |
2288 | out: | 2289 | out: |
2289 | kfree(vol_args); | 2290 | kfree(vol_args); |