Btrfs: use dget_parent where we can UPDATED

There are lots of places where we do dentry->d_parent->d_inode without holding
the dentry->d_lock.  This could cause problems with rename.  So instead we need
to use dget_parent() and hold the reference to the parent as long as we are
going to use it's inode and then dput it at the end.

Signed-off-by: Josef Bacik <josef@redhat.com>
Cc: raven@themaw.net
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
Josef Bacik
2010-11-20 09:48:00 +00:00
committed by Chris Mason
parent 7619585390
commit 6a91221304
4 changed files with 43 additions and 12 deletions

View File

@@ -4811,10 +4811,12 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
if (err) {
drop_inode = 1;
} else {
struct dentry *parent = dget_parent(dentry);
btrfs_update_inode_block_group(trans, dir);
err = btrfs_update_inode(trans, root, inode);
BUG_ON(err);
btrfs_log_new_name(trans, inode, NULL, dentry->d_parent);
btrfs_log_new_name(trans, inode, NULL, parent);
dput(parent);
}
nr = trans->blocks_used;
@@ -6768,8 +6770,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
BUG_ON(ret);
if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) {
btrfs_log_new_name(trans, old_inode, old_dir,
new_dentry->d_parent);
struct dentry *parent = dget_parent(new_dentry);
btrfs_log_new_name(trans, old_inode, old_dir, parent);
dput(parent);
btrfs_end_log_trans(root);
}
out_fail: