Skip to content

Commit

Permalink
Btrfs: pin log earlier when renaming
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
fdmanana committed May 13, 2016
1 parent 3dc9e8f commit c4aba95
Showing 1 changed file with 2 additions and 9 deletions.
11 changes: 2 additions & 9 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -9479,22 +9479,15 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
/* force full log commit if subvolume involved. */
btrfs_set_log_full_commit(root->fs_info, trans);
} else {
btrfs_pin_log_trans(root);
log_pinned = true;
ret = btrfs_insert_inode_ref(trans, dest,
new_dentry->d_name.name,
new_dentry->d_name.len,
old_ino,
btrfs_ino(new_dir), index);
if (ret)
goto out_fail;
/*
* this is an ugly little race, but the rename is required
* to make sure that if we crash, the inode is either at the
* old name or the new one. pinning the log transaction lets
* us make sure we don't allow a log commit to come in after
* we unlink the name but before we add the new name back in.
*/
btrfs_pin_log_trans(root);
log_pinned = true;
}

inode_inc_iversion(old_dir);
Expand Down

0 comments on commit c4aba95

Please sign in to comment.