mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00:00
nfsd-6.18 fixes:
Issues reported with v6.18-rc: - Revert the patch that removed the cap on MAX_OPS_PER_COMPOUND - Address a kernel build issue Issues that need expedient stable backports: - Fix crash when a client queries new attributes on forechannel - Fix rare NFSD crash when tracing is enabled -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEKLLlsBKG3yQ88j7+M2qzM29mf5cFAmj/uZAACgkQM2qzM29m f5fj5Q//cMu68pn3+TOjOb6N1v0SBLLfjg6ailkHV4IX8lK5Kt9MhXSmBUzkjwX/ YDl4NYnLR5dG4vrw0Vx4xynnIg45EjbZkjHLDeeTB2knC8EFi0Ij1Cml0fM8RSyP cgv7Z5Pg6QD9BVa6tBvgPh9+We1yHEip/FE0T9mADF3qrj4wqOhmf4JKNauaDsGH 2Lj0SSuN36AHv30+Yuur4saSFxpDKQyAVgrGqq8V247mIrI0BGAH6uIHentVXqIk WdHVD9biPJ1bhpILOiGWH/yeF2/eG6WimWuCnw7uosyc+AI6pW00Mg/1cJDIQvc+ yMQLj8b0Nnt4QzF7BEu6TUof8yg8UKZLYQ34ch4E8uqYCy9VUSCYrB/Frb64HkqV 3/nC+IqX91SmGCa/5DHCJauWCjkNKkNbgzRceu+BfCpC9aCAuos05U/OP0E8doqM yBPYBiULDcQNN8DmXKWyqJn6h+ZOMcBAMAj2cBYDcaxLI9HGbM8eTBXlC0/8G8Bc gRc00/7D3Y4KazLDCc/2v+Y/vR/P4f44rGVdDOdDrPjCy4EVfe30eINLsy2Ng3Z9 ulenzTNaz1wjKIkxcg4SBF0QDfWpRRPw4YY7Gc+/T70zoTPNZHVpsRsWR3Auxs6w wBWcE4al7Q9iWE+jmm+pIL64QNDyAkDJrU2FCT7SqaAOBiP/xw0= =4PHG -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
8eefed8f65
@ -988,10 +988,11 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
static void
|
||||
nfsd4_read_release(union nfsd4_op_u *u)
|
||||
{
|
||||
if (u->read.rd_nf)
|
||||
if (u->read.rd_nf) {
|
||||
trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp,
|
||||
u->read.rd_offset, u->read.rd_length);
|
||||
nfsd_file_put(u->read.rd_nf);
|
||||
trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp,
|
||||
u->read.rd_offset, u->read.rd_length);
|
||||
}
|
||||
}
|
||||
|
||||
static __be32
|
||||
@ -2892,10 +2893,20 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
|
||||
|
||||
rqstp->rq_lease_breaker = (void **)&cstate->clp;
|
||||
|
||||
trace_nfsd_compound(rqstp, args->tag, args->taglen, args->opcnt);
|
||||
trace_nfsd_compound(rqstp, args->tag, args->taglen, args->client_opcnt);
|
||||
while (!status && resp->opcnt < args->opcnt) {
|
||||
op = &args->ops[resp->opcnt++];
|
||||
|
||||
if (unlikely(resp->opcnt == NFSD_MAX_OPS_PER_COMPOUND)) {
|
||||
/* If there are still more operations to process,
|
||||
* stop here and report NFS4ERR_RESOURCE. */
|
||||
if (cstate->minorversion == 0 &&
|
||||
args->client_opcnt > resp->opcnt) {
|
||||
op->status = nfserr_resource;
|
||||
goto encode_op;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The XDR decode routines may have pre-set op->status;
|
||||
* for example, if there is a miscellaneous XDR error
|
||||
@ -2972,7 +2983,7 @@ encode_op:
|
||||
status = op->status;
|
||||
}
|
||||
|
||||
trace_nfsd_compound_status(args->opcnt, resp->opcnt,
|
||||
trace_nfsd_compound_status(args->client_opcnt, resp->opcnt,
|
||||
status, nfsd4_op_name(op->opnum));
|
||||
|
||||
nfsd4_cstate_clear_replay(cstate);
|
||||
|
||||
@ -3902,6 +3902,7 @@ static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs *ca, struct nfs
|
||||
ca->headerpadsz = 0;
|
||||
ca->maxreq_sz = min_t(u32, ca->maxreq_sz, maxrpc);
|
||||
ca->maxresp_sz = min_t(u32, ca->maxresp_sz, maxrpc);
|
||||
ca->maxops = min_t(u32, ca->maxops, NFSD_MAX_OPS_PER_COMPOUND);
|
||||
ca->maxresp_cached = min_t(u32, ca->maxresp_cached,
|
||||
NFSD_SLOT_CACHE_SIZE + NFSD_MIN_HDR_SEQ_SZ);
|
||||
ca->maxreqs = min_t(u32, ca->maxreqs, NFSD_MAX_SLOTS_PER_SESSION);
|
||||
|
||||
@ -2488,8 +2488,10 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
||||
|
||||
if (xdr_stream_decode_u32(argp->xdr, &argp->minorversion) < 0)
|
||||
return false;
|
||||
if (xdr_stream_decode_u32(argp->xdr, &argp->opcnt) < 0)
|
||||
if (xdr_stream_decode_u32(argp->xdr, &argp->client_opcnt) < 0)
|
||||
return false;
|
||||
argp->opcnt = min_t(u32, argp->client_opcnt,
|
||||
NFSD_MAX_OPS_PER_COMPOUND);
|
||||
|
||||
if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
|
||||
argp->ops = vcalloc(argp->opcnt, sizeof(*argp->ops));
|
||||
@ -2628,10 +2630,8 @@ static __be32 nfsd4_encode_components_esc(struct xdr_stream *xdr, char sep,
|
||||
__be32 *p;
|
||||
__be32 pathlen;
|
||||
int pathlen_offset;
|
||||
int strlen, count=0;
|
||||
char *str, *end, *next;
|
||||
|
||||
dprintk("nfsd4_encode_components(%s)\n", components);
|
||||
int count = 0;
|
||||
|
||||
pathlen_offset = xdr->buf->len;
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
@ -2658,9 +2658,8 @@ static __be32 nfsd4_encode_components_esc(struct xdr_stream *xdr, char sep,
|
||||
for (; *end && (*end != sep); end++)
|
||||
/* find sep or end of string */;
|
||||
|
||||
strlen = end - str;
|
||||
if (strlen) {
|
||||
if (xdr_stream_encode_opaque(xdr, str, strlen) < 0)
|
||||
if (end > str) {
|
||||
if (xdr_stream_encode_opaque(xdr, str, end - str) < 0)
|
||||
return nfserr_resource;
|
||||
count++;
|
||||
} else
|
||||
@ -2939,6 +2938,12 @@ struct nfsd4_fattr_args {
|
||||
typedef __be32(*nfsd4_enc_attr)(struct xdr_stream *xdr,
|
||||
const struct nfsd4_fattr_args *args);
|
||||
|
||||
static __be32 nfsd4_encode_fattr4__inval(struct xdr_stream *xdr,
|
||||
const struct nfsd4_fattr_args *args)
|
||||
{
|
||||
return nfserr_inval;
|
||||
}
|
||||
|
||||
static __be32 nfsd4_encode_fattr4__noop(struct xdr_stream *xdr,
|
||||
const struct nfsd4_fattr_args *args)
|
||||
{
|
||||
@ -3560,6 +3565,8 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = {
|
||||
|
||||
[FATTR4_MODE_UMASK] = nfsd4_encode_fattr4__noop,
|
||||
[FATTR4_XATTR_SUPPORT] = nfsd4_encode_fattr4_xattr_support,
|
||||
[FATTR4_TIME_DELEG_ACCESS] = nfsd4_encode_fattr4__inval,
|
||||
[FATTR4_TIME_DELEG_MODIFY] = nfsd4_encode_fattr4__inval,
|
||||
[FATTR4_OPEN_ARGUMENTS] = nfsd4_encode_fattr4_open_arguments,
|
||||
};
|
||||
|
||||
|
||||
@ -57,6 +57,9 @@ struct readdir_cd {
|
||||
__be32 err; /* 0, nfserr, or nfserr_eof */
|
||||
};
|
||||
|
||||
/* Maximum number of operations per session compound */
|
||||
#define NFSD_MAX_OPS_PER_COMPOUND 200
|
||||
|
||||
struct nfsd_genl_rqstp {
|
||||
struct sockaddr rq_daddr;
|
||||
struct sockaddr rq_saddr;
|
||||
|
||||
@ -903,6 +903,7 @@ struct nfsd4_compoundargs {
|
||||
char * tag;
|
||||
u32 taglen;
|
||||
u32 minorversion;
|
||||
u32 client_opcnt;
|
||||
u32 opcnt;
|
||||
bool splice_ok;
|
||||
struct nfsd4_op *ops;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user