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

nfsd4: better reservation of head space for krb5

RPC_MAX_AUTH_SIZE is scattered around several places. Better to set it
once in the auth code, where this kind of estimate should be made. And
while we're at it we can leave it zero when we're not using krb5i or
krb5p.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>

+15 -11
+2 -2
fs/nfsd/nfs4proc.c
··· 1261 1261 xdr->buf = buf; 1262 1262 xdr->iov = head; 1263 1263 xdr->p = head->iov_base + head->iov_len; 1264 - xdr->end = head->iov_base + PAGE_SIZE - 2 * RPC_MAX_AUTH_SIZE; 1264 + xdr->end = head->iov_base + PAGE_SIZE - rqstp->rq_auth_slack; 1265 1265 /* Tail and page_len should be zero at this point: */ 1266 1266 buf->len = buf->head[0].iov_len; 1267 1267 xdr->scratch.iov_len = 0; 1268 1268 xdr->page_ptr = buf->pages; 1269 1269 buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages) 1270 - - 2 * RPC_MAX_AUTH_SIZE; 1270 + - rqstp->rq_auth_slack; 1271 1271 } 1272 1272 1273 1273 /*
+1 -1
fs/nfsd/nfs4state.c
··· 2288 2288 session->se_fchannel.maxresp_sz; 2289 2289 status = (seq->cachethis) ? nfserr_rep_too_big_to_cache : 2290 2290 nfserr_rep_too_big; 2291 - if (xdr_restrict_buflen(xdr, buflen - 2 * RPC_MAX_AUTH_SIZE)) 2291 + if (xdr_restrict_buflen(xdr, buflen - rqstp->rq_auth_slack)) 2292 2292 goto out_put_session; 2293 2293 svc_reserve(rqstp, buflen); 2294 2294
+3 -2
fs/nfsd/nfs4xdr.c
··· 1611 1611 DECODE_HEAD; 1612 1612 struct nfsd4_op *op; 1613 1613 bool cachethis = false; 1614 - int max_reply = 2 * RPC_MAX_AUTH_SIZE + 8; /* opcnt, status */ 1614 + int auth_slack= argp->rqstp->rq_auth_slack; 1615 + int max_reply = auth_slack + 8; /* opcnt, status */ 1615 1616 int readcount = 0; 1616 1617 int readbytes = 0; 1617 1618 int i; ··· 1678 1677 svc_reserve(argp->rqstp, max_reply + readbytes); 1679 1678 argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE; 1680 1679 1681 - if (readcount > 1 || max_reply > PAGE_SIZE - 2*RPC_MAX_AUTH_SIZE) 1680 + if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack) 1682 1681 argp->rqstp->rq_splice_ok = false; 1683 1682 1684 1683 DECODE_TAIL;
+5 -6
include/linux/sunrpc/svc.h
··· 260 260 void * rq_argp; /* decoded arguments */ 261 261 void * rq_resp; /* xdr'd results */ 262 262 void * rq_auth_data; /* flavor-specific data */ 263 - 263 + int rq_auth_slack; /* extra space xdr code 264 + * should leave in head 265 + * for krb5i, krb5p. 266 + */ 264 267 int rq_reserved; /* space on socket outq 265 268 * reserved for this request 266 269 */ ··· 459 456 */ 460 457 static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space) 461 458 { 462 - int added_space = 0; 463 - 464 - if (rqstp->rq_authop->flavour) 465 - added_space = RPC_MAX_AUTH_SIZE; 466 - svc_reserve(rqstp, space + added_space); 459 + svc_reserve(rqstp, space + rqstp->rq_auth_slack); 467 460 } 468 461 469 462 #endif /* SUNRPC_SVC_H */
+2
net/sunrpc/auth_gss/svcauth_gss.c
··· 1503 1503 if (unwrap_integ_data(rqstp, &rqstp->rq_arg, 1504 1504 gc->gc_seq, rsci->mechctx)) 1505 1505 goto garbage_args; 1506 + rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE; 1506 1507 break; 1507 1508 case RPC_GSS_SVC_PRIVACY: 1508 1509 /* placeholders for length and seq. number: */ ··· 1512 1511 if (unwrap_priv_data(rqstp, &rqstp->rq_arg, 1513 1512 gc->gc_seq, rsci->mechctx)) 1514 1513 goto garbage_args; 1514 + rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE * 2; 1515 1515 break; 1516 1516 default: 1517 1517 goto auth_err;
+2
net/sunrpc/svcauth.c
··· 54 54 } 55 55 spin_unlock(&authtab_lock); 56 56 57 + rqstp->rq_auth_slack = 0; 58 + 57 59 rqstp->rq_authop = aops; 58 60 return aops->accept(rqstp, authp); 59 61 }