diff options
Diffstat (limited to 'fs/btrfs/inode.c')
| -rw-r--r-- | fs/btrfs/inode.c | 18 | 
1 files changed, 14 insertions, 4 deletions
| diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4d14de6d121b..b2d004ad66a0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4018,7 +4018,8 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)  		memcpy(&location, dentry->d_fsdata, sizeof(struct btrfs_key));  		kfree(dentry->d_fsdata);  		dentry->d_fsdata = NULL; -		d_clear_need_lookup(dentry); +		/* This thing is hashed, drop it for now */ +		d_drop(dentry);  	} else {  		ret = btrfs_inode_by_name(dir, dentry, &location);  	} @@ -4085,7 +4086,15 @@ static void btrfs_dentry_release(struct dentry *dentry)  static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,  				   struct nameidata *nd)  { -	return d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry); +	struct dentry *ret; + +	ret = d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry); +	if (unlikely(d_need_lookup(dentry))) { +		spin_lock(&dentry->d_lock); +		dentry->d_flags &= ~DCACHE_NEED_LOOKUP; +		spin_unlock(&dentry->d_lock); +	} +	return ret;  }  unsigned char btrfs_filetype_table[] = { @@ -4125,7 +4134,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,  	/* special case for "." */  	if (filp->f_pos == 0) { -		over = filldir(dirent, ".", 1, 1, btrfs_ino(inode), DT_DIR); +		over = filldir(dirent, ".", 1, +			       filp->f_pos, btrfs_ino(inode), DT_DIR);  		if (over)  			return 0;  		filp->f_pos = 1; @@ -4134,7 +4144,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,  	if (filp->f_pos == 1) {  		u64 pino = parent_ino(filp->f_path.dentry);  		over = filldir(dirent, "..", 2, -			       2, pino, DT_DIR); +			       filp->f_pos, pino, DT_DIR);  		if (over)  			return 0;  		filp->f_pos = 2; | 
