diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
| -rw-r--r-- | fs/btrfs/tree-log.c | 21 | 
1 files changed, 17 insertions, 4 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index a29f19384a27..054744ac5719 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2869,6 +2869,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,  {  	int ret = 0;  	struct btrfs_root *root; +	struct dentry *old_parent = NULL;  	/*  	 * for regular files, if its inode is already on disk, we don't @@ -2910,10 +2911,13 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans,  		if (IS_ROOT(parent))  			break; -		parent = parent->d_parent; +		parent = dget_parent(parent); +		dput(old_parent); +		old_parent = parent;  		inode = parent->d_inode;  	} +	dput(old_parent);  out:  	return ret;  } @@ -2945,6 +2949,7 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,  {  	int inode_only = exists_only ? LOG_INODE_EXISTS : LOG_INODE_ALL;  	struct super_block *sb; +	struct dentry *old_parent = NULL;  	int ret = 0;  	u64 last_committed = root->fs_info->last_trans_committed; @@ -3016,10 +3021,13 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,  		if (IS_ROOT(parent))  			break; -		parent = parent->d_parent; +		parent = dget_parent(parent); +		dput(old_parent); +		old_parent = parent;  	}  	ret = 0;  end_trans: +	dput(old_parent);  	if (ret < 0) {  		BUG_ON(ret != -ENOSPC);  		root->fs_info->last_trans_log_full_commit = trans->transid; @@ -3039,8 +3047,13 @@ end_no_trans:  int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans,  			  struct btrfs_root *root, struct dentry *dentry)  { -	return btrfs_log_inode_parent(trans, root, dentry->d_inode, -				      dentry->d_parent, 0); +	struct dentry *parent = dget_parent(dentry); +	int ret; + +	ret = btrfs_log_inode_parent(trans, root, dentry->d_inode, parent, 0); +	dput(parent); + +	return ret;  }  /*  | 
