new helper: lookup_positive_unlocked()
[ Upstream commit 6c2d4798a8d16cf4f3a28c3cd4af4f1dcbbb4d04 ] Most of the callers of lookup_one_len_unlocked() treat negatives are ERR_PTR(-ENOENT). Provide a helper that would do just that. Note that a pinned positive dentry remains positive - it's ->d_inode is stable, etc.; a pinned _negative_ dentry can become positive at any point as long as you are not holding its parent at least shared. So using lookup_one_len_unlocked() needs to be careful; lookup_positive_unlocked() is safer and that's what the callers end up open-coding anyway. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Stable-dep-of: 0d5a4f8f775f ("fs: Fix error checking for d_hash_and_lookup()") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5701502619
commit
3c70569e17
@@ -855,13 +855,11 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
|
||||
} else
|
||||
dchild = dget(dparent);
|
||||
} else
|
||||
dchild = lookup_one_len_unlocked(name, dparent, namlen);
|
||||
dchild = lookup_positive_unlocked(name, dparent, namlen);
|
||||
if (IS_ERR(dchild))
|
||||
return rv;
|
||||
if (d_mountpoint(dchild))
|
||||
goto out;
|
||||
if (d_really_is_negative(dchild))
|
||||
goto out;
|
||||
if (dchild->d_inode->i_ino != ino)
|
||||
goto out;
|
||||
rv = fh_compose(fhp, exp, dchild, &cd->fh);
|
||||
|
||||
@@ -2984,18 +2984,9 @@ nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
|
||||
__be32 nfserr;
|
||||
int ignore_crossmnt = 0;
|
||||
|
||||
dentry = lookup_one_len_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
|
||||
dentry = lookup_positive_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
|
||||
if (IS_ERR(dentry))
|
||||
return nfserrno(PTR_ERR(dentry));
|
||||
if (d_really_is_negative(dentry)) {
|
||||
/*
|
||||
* we're not holding the i_mutex here, so there's
|
||||
* a window where this directory entry could have gone
|
||||
* away.
|
||||
*/
|
||||
dput(dentry);
|
||||
return nfserr_noent;
|
||||
}
|
||||
|
||||
exp_get(exp);
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user