diff mbox series

[RFC] NFSD: Process some operations before returning NFS4ERR_RESOURCE

Message ID 166110487595.12503.10743719436399570590.stgit@manet.1015granger.net (mailing list archive)
State New, archived
Headers show
Series [RFC] NFSD: Process some operations before returning NFS4ERR_RESOURCE | expand

Commit Message

Chuck Lever Aug. 21, 2022, 6:03 p.m. UTC
If an NFS server returns RESOURCE on the first operation in an NFSv4
COMPOUND, there's no way for a client to make forward progress.
Instead, make the server process as many operations in a large
COMPOUND as it can before returning NFS4ERR_RESOURCE on the first
operation it did not process.

Suggested-by: Bruce Fields <bfields@fieldses.org>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216383
Fixes: 0078117c6d91 ("nfsd: return RESOURCE not GARBAGE_ARGS on too many ops")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4proc.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

Hi-

Request for comments, compile-tested only.
diff mbox series

Patch

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index a72ab97f77ef..094cf4520931 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -2633,9 +2633,6 @@  nfsd4_proc_compound(struct svc_rqst *rqstp)
 	status = nfserr_minor_vers_mismatch;
 	if (nfsd_minorversion(nn, args->minorversion, NFSD_TEST) <= 0)
 		goto out;
-	status = nfserr_resource;
-	if (args->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
-		goto out;
 
 	status = nfs41_check_op_ordering(args);
 	if (status) {
@@ -2650,6 +2647,11 @@  nfsd4_proc_compound(struct svc_rqst *rqstp)
 
 	trace_nfsd_compound(rqstp, args->opcnt);
 	while (!status && resp->opcnt < args->opcnt) {
+		if (unlikely(resp->opcnt > NFSD_MAX_OPS_PER_COMPOUND)) {
+			status = nfserr_resource;
+			break;
+		}
+
 		op = &args->ops[resp->opcnt++];
 
 		/*