aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2016-04-29 08:14:42 -0400
committerFilipe Manana <fdmanana@suse.com>2016-05-12 20:59:19 -0400
commitc4aba9545430ed0f842d0833072f990a42da90f0 (patch)
tree7fcde1ac6f1a1cbeea481f97dbbf79b763b40cfb
parent3dc9e8f76720fbbd9c56a11775932733fe13d214 (diff)
Btrfs: pin log earlier when renaming
We were pinning the log right after the first step in the rename operation (inserting inode ref for the new name in the destination directory) instead of doing it before. This behaviour was introduced in 2009 for some reason that was not mentioned neither on the changelog nor any comment, with the drawback of a small time window where concurrent log writers can end up logging the new inode reference for the inode we are renaming while the rename operation is in progress (so that we can end up with a log containing both the new and old references). As of today there's no reason to not pin the log before that first step anymore, so just fix this. Signed-off-by: Filipe Manana <fdmanana@suse.com>
-rw-r--r--fs/btrfs/inode.c11
1 files changed, 2 insertions, 9 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 4594a263a5f8..422833e70d00 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -9479,6 +9479,8 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
9479 /* force full log commit if subvolume involved. */ 9479 /* force full log commit if subvolume involved. */
9480 btrfs_set_log_full_commit(root->fs_info, trans); 9480 btrfs_set_log_full_commit(root->fs_info, trans);
9481 } else { 9481 } else {
9482 btrfs_pin_log_trans(root);
9483 log_pinned = true;
9482 ret = btrfs_insert_inode_ref(trans, dest, 9484 ret = btrfs_insert_inode_ref(trans, dest,
9483 new_dentry->d_name.name, 9485 new_dentry->d_name.name,
9484 new_dentry->d_name.len, 9486 new_dentry->d_name.len,
@@ -9486,15 +9488,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
9486 btrfs_ino(new_dir), index); 9488 btrfs_ino(new_dir), index);
9487 if (ret) 9489 if (ret)
9488 goto out_fail; 9490 goto out_fail;
9489 /*
9490 * this is an ugly little race, but the rename is required
9491 * to make sure that if we crash, the inode is either at the
9492 * old name or the new one. pinning the log transaction lets
9493 * us make sure we don't allow a log commit to come in after
9494 * we unlink the name but before we add the new name back in.
9495 */
9496 btrfs_pin_log_trans(root);
9497 log_pinned = true;
9498 } 9491 }
9499 9492
9500 inode_inc_iversion(old_dir); 9493 inode_inc_iversion(old_dir);