btrfs: don't double lock the subvol_sem for rename exchange

[ Upstream commit 943eb3bf25 ]

If we're rename exchanging two subvols we'll try to lock this lock
twice, which is bad.  Just lock once if either of the ino's are subvols.

Fixes: cdd1fedf82 ("btrfs: add support for RENAME_EXCHANGE and RENAME_WHITEOUT")
CC: stable@vger.kernel.org # 4.4+
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Josef Bacik
2019-11-19 13:59:20 -05:00
committed by Chris
parent c78c872062
commit dd5f8d7a5e

View File

@@ -9597,9 +9597,8 @@ static int btrfs_rename_exchange(struct inode *old_dir,
return -EXDEV;
/* close the race window with snapshot create/destroy ioctl */
if (old_ino == BTRFS_FIRST_FREE_OBJECTID)
down_read(&root->fs_info->subvol_sem);
if (new_ino == BTRFS_FIRST_FREE_OBJECTID)
if (old_ino == BTRFS_FIRST_FREE_OBJECTID ||
new_ino == BTRFS_FIRST_FREE_OBJECTID)
down_read(&dest->fs_info->subvol_sem);
/*
@@ -9785,9 +9784,8 @@ out_fail:
ret2 = btrfs_end_transaction(trans, root);
ret = ret ? ret : ret2;
out_notrans:
if (new_ino == BTRFS_FIRST_FREE_OBJECTID)
up_read(&dest->fs_info->subvol_sem);
if (old_ino == BTRFS_FIRST_FREE_OBJECTID)
if (new_ino == BTRFS_FIRST_FREE_OBJECTID ||
old_ino == BTRFS_FIRST_FREE_OBJECTID)
up_read(&root->fs_info->subvol_sem);
return ret;