Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

NFSD: Remove the cap on number of operations per NFSv4 COMPOUND

This limit has always been a sanity check; in nearly all cases a
large COMPOUND is a sign of a malfunctioning client. The only real
limit on COMPOUND size and complexity is the size of NFSD's send
and receive buffers.

However, there are a few cases where a large COMPOUND is sane. For
example, when a client implementation wants to walk down a long file
pathname in a single round trip.

A small risk is that now a client can construct a COMPOUND request
that can keep a single nfsd thread busy for quite some time.

Suggested-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

Chuck Lever 48aab160 a2d61427

+3 -20
+2 -12
fs/nfsd/nfs4proc.c
··· 2842 2842 2843 2843 rqstp->rq_lease_breaker = (void **)&cstate->clp; 2844 2844 2845 - trace_nfsd_compound(rqstp, args->tag, args->taglen, args->client_opcnt); 2845 + trace_nfsd_compound(rqstp, args->tag, args->taglen, args->opcnt); 2846 2846 while (!status && resp->opcnt < args->opcnt) { 2847 2847 op = &args->ops[resp->opcnt++]; 2848 - 2849 - if (unlikely(resp->opcnt == NFSD_MAX_OPS_PER_COMPOUND)) { 2850 - /* If there are still more operations to process, 2851 - * stop here and report NFS4ERR_RESOURCE. */ 2852 - if (cstate->minorversion == 0 && 2853 - args->client_opcnt > resp->opcnt) { 2854 - op->status = nfserr_resource; 2855 - goto encode_op; 2856 - } 2857 - } 2858 2848 2859 2849 /* 2860 2850 * The XDR decode routines may have pre-set op->status; ··· 2922 2932 status = op->status; 2923 2933 } 2924 2934 2925 - trace_nfsd_compound_status(args->client_opcnt, resp->opcnt, 2935 + trace_nfsd_compound_status(args->opcnt, resp->opcnt, 2926 2936 status, nfsd4_op_name(op->opnum)); 2927 2937 2928 2938 nfsd4_cstate_clear_replay(cstate);
-1
fs/nfsd/nfs4state.c
··· 3865 3865 ca->headerpadsz = 0; 3866 3866 ca->maxreq_sz = min_t(u32, ca->maxreq_sz, maxrpc); 3867 3867 ca->maxresp_sz = min_t(u32, ca->maxresp_sz, maxrpc); 3868 - ca->maxops = min_t(u32, ca->maxops, NFSD_MAX_OPS_PER_COMPOUND); 3869 3868 ca->maxresp_cached = min_t(u32, ca->maxresp_cached, 3870 3869 NFSD_SLOT_CACHE_SIZE + NFSD_MIN_HDR_SEQ_SZ); 3871 3870 ca->maxreqs = min_t(u32, ca->maxreqs, NFSD_MAX_SLOTS_PER_SESSION);
+1 -3
fs/nfsd/nfs4xdr.c
··· 2500 2500 2501 2501 if (xdr_stream_decode_u32(argp->xdr, &argp->minorversion) < 0) 2502 2502 return false; 2503 - if (xdr_stream_decode_u32(argp->xdr, &argp->client_opcnt) < 0) 2503 + if (xdr_stream_decode_u32(argp->xdr, &argp->opcnt) < 0) 2504 2504 return false; 2505 - argp->opcnt = min_t(u32, argp->client_opcnt, 2506 - NFSD_MAX_OPS_PER_COMPOUND); 2507 2505 2508 2506 if (argp->opcnt > ARRAY_SIZE(argp->iops)) { 2509 2507 argp->ops = vcalloc(argp->opcnt, sizeof(*argp->ops));
-3
fs/nfsd/nfsd.h
··· 57 57 __be32 err; /* 0, nfserr, or nfserr_eof */ 58 58 }; 59 59 60 - /* Maximum number of operations per session compound */ 61 - #define NFSD_MAX_OPS_PER_COMPOUND 50 62 - 63 60 struct nfsd_genl_rqstp { 64 61 struct sockaddr rq_daddr; 65 62 struct sockaddr rq_saddr;
-1
fs/nfsd/xdr4.h
··· 870 870 char * tag; 871 871 u32 taglen; 872 872 u32 minorversion; 873 - u32 client_opcnt; 874 873 u32 opcnt; 875 874 bool splice_ok; 876 875 struct nfsd4_op *ops;