summaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfsproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfsproc.c')
-rw-r--r--fs/nfsd/nfsproc.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 7d570299f..6f69225cc 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -195,6 +195,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
svc_fh *newfhp = &resp->fh;
struct iattr *attr = &argp->attrs;
struct inode *inode;
+ struct dentry *dchild;
int nfserr, type, mode, rdonly = 0;
dev_t rdev = NODEV;
@@ -214,14 +215,24 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
} else if (nfserr)
goto done;
- /*
- * Do a lookup to verify the new file handle.
- */
+ nfserr = nfserr_acces;
+ if (!argp->len)
+ goto done;
+ nfserr = nfserr_exist;
+ if (isdotent(argp->name, argp->len))
+ goto done;
+ fh_lock(dirfhp);
+ dchild = lookup_one(argp->name, dget(dirfhp->fh_dentry));
+ nfserr = nfserrno(PTR_ERR(dchild));
+ if (IS_ERR(dchild))
+ goto out_unlock;
fh_init(newfhp, NFS_FHSIZE);
- nfserr = nfsd_lookup(rqstp, dirfhp, argp->name, argp->len, newfhp);
+ nfserr = fh_compose(newfhp, dirfhp->fh_export, dchild);
+ if (!nfserr && !dchild->d_inode)
+ nfserr = nfserr_noent;
if (nfserr) {
if (nfserr != nfserr_noent)
- goto done;
+ goto out_unlock;
/*
* If the new file handle wasn't verified, we can't tell
* whether the file exists or not. Time to bail ...
@@ -230,22 +241,11 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
if (!newfhp->fh_dverified) {
printk(KERN_WARNING
"nfsd_proc_create: file handle not verified\n");
- goto done;
+ goto out_unlock;
}
}
- /*
- * Lock the parent directory and check for existence.
- */
- nfserr = fh_lock_parent(dirfhp, newfhp->fh_dentry);
- if (nfserr)
- goto done;
inode = newfhp->fh_dentry->d_inode;
- if (inode && newfhp->fh_handle.fh_fileid_type == 0)
- /* inode might have been instantiated while we slept */
- nfserr = fh_update(newfhp);
- if (nfserr)
- goto done;
/* Unfudge the mode bits */
if (attr->ia_valid & ATTR_MODE) {