|
@@ -1605,40 +1605,13 @@ nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Return a rough estimate of the maximum possible reply size. Note the
|
|
|
- * estimate includes rpc headers so is meant to be passed to
|
|
|
- * svc_reserve, not svc_reserve_auth.
|
|
|
- *
|
|
|
- * Also note the current compound encoding permits only one operation to
|
|
|
- * use pages beyond the first one, so the maximum possible length is the
|
|
|
- * maximum over these values, not the sum.
|
|
|
- */
|
|
|
-static int nfsd4_max_reply(u32 opnum)
|
|
|
-{
|
|
|
- switch (opnum) {
|
|
|
- case OP_READLINK:
|
|
|
- case OP_READDIR:
|
|
|
- /*
|
|
|
- * Both of these ops take a single page for data and put
|
|
|
- * the head and tail in another page:
|
|
|
- */
|
|
|
- return 2 * PAGE_SIZE;
|
|
|
- case OP_GETATTR:
|
|
|
- case OP_READ:
|
|
|
- return INT_MAX;
|
|
|
- default:
|
|
|
- return PAGE_SIZE;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static __be32
|
|
|
nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
|
|
{
|
|
|
DECODE_HEAD;
|
|
|
struct nfsd4_op *op;
|
|
|
bool cachethis = false;
|
|
|
- int max_reply = PAGE_SIZE;
|
|
|
+ int max_reply = 2 * RPC_MAX_AUTH_SIZE + 8; /* opcnt, status */
|
|
|
int i;
|
|
|
|
|
|
READ_BUF(4);
|
|
@@ -1647,6 +1620,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
|
|
SAVEMEM(argp->tag, argp->taglen);
|
|
|
READ32(argp->minorversion);
|
|
|
READ32(argp->opcnt);
|
|
|
+ max_reply += 4 + (XDR_QUADLEN(argp->taglen) << 2);
|
|
|
|
|
|
if (argp->taglen > NFSD4_MAX_TAGLEN)
|
|
|
goto xdr_error;
|
|
@@ -1684,7 +1658,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
|
|
*/
|
|
|
cachethis |= nfsd4_cache_this_op(op);
|
|
|
|
|
|
- max_reply = max(max_reply, nfsd4_max_reply(op->opnum));
|
|
|
+ max_reply += nfsd4_max_reply(argp->rqstp, op);
|
|
|
|
|
|
if (op->status) {
|
|
|
argp->opcnt = i+1;
|
|
@@ -1694,8 +1668,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
|
|
/* Sessions make the DRC unnecessary: */
|
|
|
if (argp->minorversion)
|
|
|
cachethis = false;
|
|
|
- if (max_reply != INT_MAX)
|
|
|
- svc_reserve(argp->rqstp, max_reply);
|
|
|
+ svc_reserve(argp->rqstp, max_reply);
|
|
|
argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
|
|
|
|
|
|
DECODE_TAIL;
|