FAILED: patch "[PATCH] NFSD: COMMIT operations must not return NFS?ERR_INVAL" failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 3f965021c8bc38965ecb1924f570c4842b33d408 Mon Sep 17 00:00:00 2001
From: Chuck Lever <[email protected]>
Date: Mon, 24 Jan 2022 15:50:31 -0500
Subject: [PATCH] NFSD: COMMIT operations must not return NFS?ERR_INVAL
Since, well, forever, the Linux NFS server's nfsd_commit() function has returned nfserr_inval when the passed-in byte range arguments were non-sensical.
However, according to RFC 1813 section 3.3.21, NFSv3 COMMIT requests are permitted to return only the following non-zero status codes:
NFS3ERR_IO
NFS3ERR_STALE
NFS3ERR_BADHANDLE
NFS3ERR_SERVERFAULT
NFS3ERR_INVAL is not included in that list. Likewise, NFS4ERR_INVAL is not listed in the COMMIT row of Table 6 in RFC 8881.
RFC 7530 does permit COMMIT to return NFS4ERR_INVAL, but does not specify when it can or should be used.
Instead of dropping or failing a COMMIT request in a byte range that is not supported, turn it into a valid request by treating one or both arguments as zero. Offset zero means start-of-file, count zero means until-end-of-file, so we only ever extend the commit range. NFS servers are always allowed to commit more and sooner than requested.
The range check is no longer bounded by NFS_OFFSET_MAX, but rather by the value that is returned in the maxfilesize field of the NFSv3 FSINFO procedure or the NFSv4 maxfilesize file attribute.
Note that this change results in a new pynfs failure:
CMT4 st_commit.testCommitOverflow : RUNNING CMT4 st_commit.testCommitOverflow : FAILURE
COMMIT with offset + count overflow should return NFS4ERR_INVAL, instead got NFS4_OK
IMO the test is not correct as written: RFC 8881 does not allow the COMMIT operation to return NFS4ERR_INVAL.
fs/nfsd/nfs3proc.c +0 -6
@@ -663,15 +663,9 @@ nfsd3_proc_commit(struct svc_rqst *rqstp) argp->count, (unsigned long long) argp->offset); -if (argp->offset >NFS_OFFSET_MAX ) { - resp->status = nfserr_inval; - goto out; - } -fh_copy (&resp->fh, &argp->fh); resp->status =nfsd_commit (rqstp, &resp->fh, argp->offset, argp->count, resp->verf); -out:return rpc_success; }
fs/nfsd/vfs.c +36 -17
78 lines not on this page · raw message
fs/nfsd/vfs.h +2 -2
@@ -74,8 +74,8 @@ __be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *, char *name, int len, struct iattr *attrs, struct svc_fh *res, int createmode, u32 *verifier, bool *truncp, bool *created); -__be32 nfsd_commit (struct svc_rqst *,struct svc_fh *, -loff_t ,unsigned long ,__be32 *verf); +__be32 nfsd_commit (struct svc_rqst *rqst,struct svc_fh *fhp, +u64 offset,u32 count,__be32 *verf);#endif /* CONFIG_NFSD_V3 */ #ifdef CONFIG_NFSD_V4 __be32 nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp,