@@ -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++];
/*
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.