[PATCH v5 09/18] nfsd: nfsd4_create_file(): Move NFSD_MAY_CREATE check earlier
NeilBrown <[email protected]> Fri, 17 Jul 2026 19:27:57 +1000
| Newsgroups | gmane.linux.nfs |
|---|---|
| Message-ID | <[email protected]> |
From: NeilBrown <neil-+NVA1uvv1dVBDLzU/[email protected]> We only need NFS_MAY_CREATE check if the file doesn't exist, but it is nfsd-specific code as it needs to check NFSEXP_READONLY and I want that to be separate from vfs-specific code, which eventually all be provided by the VFS. So move that check earlier, but hold the error status until needed. The if/else chain here looks a bit clumsy, but it will make a later patch cleaner. Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: NeilBrown <neil-+NVA1uvv1dVBDLzU/[email protected]> --- fs/nfsd/nfs4proc.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 8840f6dd8a0a..5e56bf6e6bd9 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -261,7 +261,7 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, struct dentry *parent, *child = ERR_PTR(-EINVAL); __u32 v_mtime, v_atime; struct inode *inode; - __be32 status; + __be32 status, create_status; int host_err; if (name_is_dot_dotdot(open->op_fname, open->op_fnamelen)) @@ -347,6 +347,8 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, iap->ia_atime.tv_nsec = 0; } + create_status = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + host_err = fh_want_write(fhp); if (host_err) { status = nfserrno(host_err); @@ -360,16 +362,17 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; } - if (d_really_is_negative(child)) { - status = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); - if (status != nfs_ok) - goto out; - + if (d_really_is_positive(child)) { + /* No creation needed */ + } else if (create_status) { + status = create_status; + } else { status = nfsd4_vfs_create(fhp, &child, open); - if (status != nfs_ok) - goto out; - open->op_created = open->op_filp->f_mode & FMODE_CREATED; + if (status == nfs_ok) + open->op_created = open->op_filp->f_mode & FMODE_CREATED; } + if (status != nfs_ok) + goto out; status = fh_compose(resfhp, fhp->fh_export, child, fhp); if (status != nfs_ok) -- 2.50.0.107.gf914562f5916.dirty