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.

Merge tag 'nfsd-6.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux

Pull nfsd fixes from Chuck Lever:
"Regression fixes:

- Revert the patch that removed the cap on MAX_OPS_PER_COMPOUND

- Address a kernel build issue

Stable fixes:

- Fix crash when a client queries new attributes on forechannel

- Fix rare NFSD crash when tracing is enabled"

* tag 'nfsd-6.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
Revert "NFSD: Remove the cap on number of operations per NFSv4 COMPOUND"
nfsd: Avoid strlen conflict in nfsd4_encode_components_esc()
NFSD: Fix crash in nfsd4_read_release()
NFSD: Define actions for the new time_deleg FATTR4 attributes

+35 -12
+16 -5
fs/nfsd/nfs4proc.c
··· 988 988 static void 989 989 nfsd4_read_release(union nfsd4_op_u *u) 990 990 { 991 - if (u->read.rd_nf) 991 + if (u->read.rd_nf) { 992 + trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp, 993 + u->read.rd_offset, u->read.rd_length); 992 994 nfsd_file_put(u->read.rd_nf); 993 - trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp, 994 - u->read.rd_offset, u->read.rd_length); 995 + } 995 996 } 996 997 997 998 static __be32 ··· 2893 2892 2894 2893 rqstp->rq_lease_breaker = (void **)&cstate->clp; 2895 2894 2896 - trace_nfsd_compound(rqstp, args->tag, args->taglen, args->opcnt); 2895 + trace_nfsd_compound(rqstp, args->tag, args->taglen, args->client_opcnt); 2897 2896 while (!status && resp->opcnt < args->opcnt) { 2898 2897 op = &args->ops[resp->opcnt++]; 2898 + 2899 + if (unlikely(resp->opcnt == NFSD_MAX_OPS_PER_COMPOUND)) { 2900 + /* If there are still more operations to process, 2901 + * stop here and report NFS4ERR_RESOURCE. */ 2902 + if (cstate->minorversion == 0 && 2903 + args->client_opcnt > resp->opcnt) { 2904 + op->status = nfserr_resource; 2905 + goto encode_op; 2906 + } 2907 + } 2899 2908 2900 2909 /* 2901 2910 * The XDR decode routines may have pre-set op->status; ··· 2983 2972 status = op->status; 2984 2973 } 2985 2974 2986 - trace_nfsd_compound_status(args->opcnt, resp->opcnt, 2975 + trace_nfsd_compound_status(args->client_opcnt, resp->opcnt, 2987 2976 status, nfsd4_op_name(op->opnum)); 2988 2977 2989 2978 nfsd4_cstate_clear_replay(cstate);
+1
fs/nfsd/nfs4state.c
··· 3902 3902 ca->headerpadsz = 0; 3903 3903 ca->maxreq_sz = min_t(u32, ca->maxreq_sz, maxrpc); 3904 3904 ca->maxresp_sz = min_t(u32, ca->maxresp_sz, maxrpc); 3905 + ca->maxops = min_t(u32, ca->maxops, NFSD_MAX_OPS_PER_COMPOUND); 3905 3906 ca->maxresp_cached = min_t(u32, ca->maxresp_cached, 3906 3907 NFSD_SLOT_CACHE_SIZE + NFSD_MIN_HDR_SEQ_SZ); 3907 3908 ca->maxreqs = min_t(u32, ca->maxreqs, NFSD_MAX_SLOTS_PER_SESSION);
+14 -7
fs/nfsd/nfs4xdr.c
··· 2488 2488 2489 2489 if (xdr_stream_decode_u32(argp->xdr, &argp->minorversion) < 0) 2490 2490 return false; 2491 - if (xdr_stream_decode_u32(argp->xdr, &argp->opcnt) < 0) 2491 + if (xdr_stream_decode_u32(argp->xdr, &argp->client_opcnt) < 0) 2492 2492 return false; 2493 + argp->opcnt = min_t(u32, argp->client_opcnt, 2494 + NFSD_MAX_OPS_PER_COMPOUND); 2493 2495 2494 2496 if (argp->opcnt > ARRAY_SIZE(argp->iops)) { 2495 2497 argp->ops = vcalloc(argp->opcnt, sizeof(*argp->ops)); ··· 2630 2628 __be32 *p; 2631 2629 __be32 pathlen; 2632 2630 int pathlen_offset; 2633 - int strlen, count=0; 2634 2631 char *str, *end, *next; 2635 - 2636 - dprintk("nfsd4_encode_components(%s)\n", components); 2632 + int count = 0; 2637 2633 2638 2634 pathlen_offset = xdr->buf->len; 2639 2635 p = xdr_reserve_space(xdr, 4); ··· 2658 2658 for (; *end && (*end != sep); end++) 2659 2659 /* find sep or end of string */; 2660 2660 2661 - strlen = end - str; 2662 - if (strlen) { 2663 - if (xdr_stream_encode_opaque(xdr, str, strlen) < 0) 2661 + if (end > str) { 2662 + if (xdr_stream_encode_opaque(xdr, str, end - str) < 0) 2664 2663 return nfserr_resource; 2665 2664 count++; 2666 2665 } else ··· 2937 2938 2938 2939 typedef __be32(*nfsd4_enc_attr)(struct xdr_stream *xdr, 2939 2940 const struct nfsd4_fattr_args *args); 2941 + 2942 + static __be32 nfsd4_encode_fattr4__inval(struct xdr_stream *xdr, 2943 + const struct nfsd4_fattr_args *args) 2944 + { 2945 + return nfserr_inval; 2946 + } 2940 2947 2941 2948 static __be32 nfsd4_encode_fattr4__noop(struct xdr_stream *xdr, 2942 2949 const struct nfsd4_fattr_args *args) ··· 3565 3560 3566 3561 [FATTR4_MODE_UMASK] = nfsd4_encode_fattr4__noop, 3567 3562 [FATTR4_XATTR_SUPPORT] = nfsd4_encode_fattr4_xattr_support, 3563 + [FATTR4_TIME_DELEG_ACCESS] = nfsd4_encode_fattr4__inval, 3564 + [FATTR4_TIME_DELEG_MODIFY] = nfsd4_encode_fattr4__inval, 3568 3565 [FATTR4_OPEN_ARGUMENTS] = nfsd4_encode_fattr4_open_arguments, 3569 3566 }; 3570 3567
+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 200 62 + 60 63 struct nfsd_genl_rqstp { 61 64 struct sockaddr rq_daddr; 62 65 struct sockaddr rq_saddr;
+1
fs/nfsd/xdr4.h
··· 903 903 char * tag; 904 904 u32 taglen; 905 905 u32 minorversion; 906 + u32 client_opcnt; 906 907 u32 opcnt; 907 908 bool splice_ok; 908 909 struct nfsd4_op *ops;