提交 f6fbcc1d 编写于 作者: B Benjamin Coddington 提交者: Yang Yingliang

NFS: Refactor nfs_instantiate() for dentry referencing callers

mainline inclusion
from mainline-v5.4-rc1
commit 406cd915
category: bugfix
bugzilla: NA
CVE: NA

--------------------------------

Since commit b0c6108e ("nfs_instantiate(): prevent multiple aliases for
directory inode"), nfs_instantiate() may succeed without actually
instantiating the dentry that was passed in.  That can be problematic for
some callers in NFSv3, so this patch breaks things up so we can get the
actual dentry obtained.
Signed-off-by: NBenjamin Coddington <bcodding@redhat.com>
Signed-off-by: NAnna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: NZhang Xiaoxu <zhangxiaoxu5@huawei.com>
Reviewed-by: NZhang Yi <yi.zhang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 3a01d1b5
...@@ -1692,24 +1692,23 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags) ...@@ -1692,24 +1692,23 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
#endif /* CONFIG_NFSV4 */ #endif /* CONFIG_NFSV4 */
/* struct dentry *
* Code common to create, mkdir, and mknod. nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
*/
int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
struct nfs_fattr *fattr, struct nfs_fattr *fattr,
struct nfs4_label *label) struct nfs4_label *label)
{ {
struct dentry *parent = dget_parent(dentry); struct dentry *parent = dget_parent(dentry);
struct inode *dir = d_inode(parent); struct inode *dir = d_inode(parent);
struct inode *inode; struct inode *inode;
struct dentry *d; struct dentry *d = NULL;
int error = -EACCES; int error;
d_drop(dentry); d_drop(dentry);
/* We may have been initialized further down */ /* We may have been initialized further down */
if (d_really_is_positive(dentry)) if (d_really_is_positive(dentry))
goto out; goto out;
if (fhandle->size == 0) { if (fhandle->size == 0) {
error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, NULL); error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, NULL);
if (error) if (error)
...@@ -1725,18 +1724,32 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, ...@@ -1725,18 +1724,32 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
} }
inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label); inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
d = d_splice_alias(inode, dentry); d = d_splice_alias(inode, dentry);
if (IS_ERR(d)) {
error = PTR_ERR(d);
goto out_error;
}
dput(d);
out: out:
dput(parent); dput(parent);
return 0; return d;
out_error: out_error:
nfs_mark_for_revalidate(dir); nfs_mark_for_revalidate(dir);
dput(parent); d = ERR_PTR(error);
return error; goto out;
}
EXPORT_SYMBOL_GPL(nfs_add_or_obtain);
/*
* Code common to create, mkdir, and mknod.
*/
int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
struct nfs_fattr *fattr,
struct nfs4_label *label)
{
struct dentry *d;
d = nfs_add_or_obtain(dentry, fhandle, fattr, label);
if (IS_ERR(d))
return PTR_ERR(d);
/* Callers don't care */
dput(d);
return 0;
} }
EXPORT_SYMBOL_GPL(nfs_instantiate); EXPORT_SYMBOL_GPL(nfs_instantiate);
......
...@@ -487,6 +487,9 @@ extern const struct file_operations nfs_dir_operations; ...@@ -487,6 +487,9 @@ extern const struct file_operations nfs_dir_operations;
extern const struct dentry_operations nfs_dentry_operations; extern const struct dentry_operations nfs_dentry_operations;
extern void nfs_force_lookup_revalidate(struct inode *dir); extern void nfs_force_lookup_revalidate(struct inode *dir);
extern struct dentry *nfs_add_or_obtain(struct dentry *dentry,
struct nfs_fh *fh, struct nfs_fattr *fattr,
struct nfs4_label *label);
extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh,
struct nfs_fattr *fattr, struct nfs4_label *label); struct nfs_fattr *fattr, struct nfs4_label *label);
extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags); extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册