[PATCH v5 10/18] nfsd: fh_want_write) failure need not be immediately fatal for nfsd4_create_file()
NeilBrown <[email protected]> Fri, 17 Jul 2026 19:27:58 +1000
| Newsgroups | gmane.linux.nfs |
|---|---|
| Message-ID | <[email protected]> |
From: NeilBrown <neil-+NVA1uvv1dVBDLzU/[email protected]> If nfsd4_create_file() is asked to create a file, then failure to get write access to the mount need not be fatal if the file already exists. So we can delay handling the error until it is known if creation was needed, just like with the error from testing for write permission in parent. This is similar to want_write error handling in lookup_open() in fs/namei.c. Note that getting mnt write access to support O_RDWR is handled separately in do_dentry_open(), and op_truncate is handled in do_open_permission(), so nfsd doesn't need to be concerned with these. It only needs to be concerned with creation, and setattr. Signed-off-by: NeilBrown <neil-+NVA1uvv1dVBDLzU/[email protected]> --- fs/nfsd/nfs4proc.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 5e56bf6e6bd9..a4838d36885b 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -262,7 +262,7 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, __u32 v_mtime, v_atime; struct inode *inode; __be32 status, create_status; - int host_err; + int want_write_err; if (name_is_dot_dotdot(open->op_fname, open->op_fnamelen)) return nfserr_exist; @@ -349,11 +349,10 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, create_status = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); - host_err = fh_want_write(fhp); - if (host_err) { - status = nfserrno(host_err); - goto out_free; - } + want_write_err = fh_want_write(fhp); + if (want_write_err) + /* Might still succeed if no create is needed */ + create_status = nfserrno(want_write_err); child = start_creating(&nop_mnt_idmap, parent, &QSTR_LEN(open->op_fname, open->op_fnamelen)); @@ -424,8 +423,8 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, open->op_bmval[2] &= ~FATTR4_WORD2_POSIX_ACCESS_ACL; out: end_creating(child); - fh_drop_write(fhp); -out_free: + if (!want_write_err) + fh_drop_write(fhp); nfsd_attrs_free(&attrs); return status; } -- 2.50.0.107.gf914562f5916.dirty