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:
@@ -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:
|
||||
|
Reference in New Issue
Block a user