Skip to content

Commit

Permalink
btrfs: record all roots for rename exchange on a subvol
Browse files Browse the repository at this point in the history
Testing with the new fsstress support for subvolumes uncovered a pretty
bad problem with rename exchange on subvolumes.  We're modifying two
different subvolumes, but we only start the transaction on one of them,
so the other one is not added to the dirty root list.  This is caught by
btrfs_cow_block() with a warning because the root has not been updated,
however if we do not modify this root again we'll end up pointing at an
invalid root because the root item is never updated.

Fix this by making sure we add the destination root to the trans list,
the same as we do with normal renames.  This fixes the corruption.

Fixes: cdd1fed ("btrfs: add support for RENAME_EXCHANGE and RENAME_WHITEOUT")
CC: stable@vger.kernel.org # 4.9+
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
Josef Bacik authored and David Sterba committed Nov 18, 2019
1 parent 042528f commit 3e17409
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -9582,6 +9582,9 @@ static int btrfs_rename_exchange(struct inode *old_dir,
goto out_notrans;
}

if (dest != root)
btrfs_record_root_in_trans(trans, dest);

/*
* We need to find a free sequence number both in the source and
* in the destination directory for the exchange.
Expand Down

0 comments on commit 3e17409

Please sign in to comment.