aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2014-05-12 18:10:58 -0400
committerJ. Bruce Fields <bfields@redhat.com>2014-05-30 17:32:17 -0400
commita5cddc885b99458df963a75abbe0b40cbef56c48 (patch)
treeb7f200949823f98207aa2d2fd72c112fa3e6ee8e
parentd05d5744ef67879877dbe2e3d0fb9fcc27ee44e5 (diff)
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>
-rw-r--r--fs/nfsd/nfs4proc.c4
-rw-r--r--fs/nfsd/nfs4state.c2
-rw-r--r--fs/nfsd/nfs4xdr.c5
-rw-r--r--include/linux/sunrpc/svc.h11
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c2
-rw-r--r--net/sunrpc/svcauth.c2
6 files changed, 15 insertions, 11 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 2d786b813c7e..16e71d033ea5 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1261,13 +1261,13 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp,
1261 xdr->buf = buf; 1261 xdr->buf = buf;
1262 xdr->iov = head; 1262 xdr->iov = head;
1263 xdr->p = head->iov_base + head->iov_len; 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 /* Tail and page_len should be zero at this point: */ 1265 /* Tail and page_len should be zero at this point: */
1266 buf->len = buf->head[0].iov_len; 1266 buf->len = buf->head[0].iov_len;
1267 xdr->scratch.iov_len = 0; 1267 xdr->scratch.iov_len = 0;
1268 xdr->page_ptr = buf->pages; 1268 xdr->page_ptr = buf->pages;
1269 buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages) 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/*
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 62b882dc48ec..d0a016a502be 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2288,7 +2288,7 @@ nfsd4_sequence(struct svc_rqst *rqstp,
2288 session->se_fchannel.maxresp_sz; 2288 session->se_fchannel.maxresp_sz;
2289 status = (seq->cachethis) ? nfserr_rep_too_big_to_cache : 2289 status = (seq->cachethis) ? nfserr_rep_too_big_to_cache :
2290 nfserr_rep_too_big; 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 goto out_put_session; 2292 goto out_put_session;
2293 svc_reserve(rqstp, buflen); 2293 svc_reserve(rqstp, buflen);
2294 2294
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 3e347a1caec4..470fe8998c9b 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1611,7 +1611,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1611 DECODE_HEAD; 1611 DECODE_HEAD;
1612 struct nfsd4_op *op; 1612 struct nfsd4_op *op;
1613 bool cachethis = false; 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 int readcount = 0; 1616 int readcount = 0;
1616 int readbytes = 0; 1617 int readbytes = 0;
1617 int i; 1618 int i;
@@ -1677,7 +1678,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1677 svc_reserve(argp->rqstp, max_reply + readbytes); 1678 svc_reserve(argp->rqstp, max_reply + readbytes);
1678 argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE; 1679 argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
1679 1680
1680 if (readcount > 1 || max_reply > PAGE_SIZE - 2*RPC_MAX_AUTH_SIZE) 1681 if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
1681 argp->rqstp->rq_splice_ok = false; 1682 argp->rqstp->rq_splice_ok = false;
1682 1683
1683 DECODE_TAIL; 1684 DECODE_TAIL;
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 85cb6472a423..1bc7cd05b22e 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -260,7 +260,10 @@ struct svc_rqst {
260 void * rq_argp; /* decoded arguments */ 260 void * rq_argp; /* decoded arguments */
261 void * rq_resp; /* xdr'd results */ 261 void * rq_resp; /* xdr'd results */
262 void * rq_auth_data; /* flavor-specific data */ 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 int rq_reserved; /* space on socket outq 267 int rq_reserved; /* space on socket outq
265 * reserved for this request 268 * reserved for this request
266 */ 269 */
@@ -456,11 +459,7 @@ char * svc_print_addr(struct svc_rqst *, char *, size_t);
456 */ 459 */
457static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space) 460static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
458{ 461{
459 int added_space = 0; 462 svc_reserve(rqstp, space + rqstp->rq_auth_slack);
460
461 if (rqstp->rq_authop->flavour)
462 added_space = RPC_MAX_AUTH_SIZE;
463 svc_reserve(rqstp, space + added_space);
464} 463}
465 464
466#endif /* SUNRPC_SVC_H */ 465#endif /* SUNRPC_SVC_H */
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 0f73f4507746..4ce5eccec1f6 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1503,6 +1503,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1503 if (unwrap_integ_data(rqstp, &rqstp->rq_arg, 1503 if (unwrap_integ_data(rqstp, &rqstp->rq_arg,
1504 gc->gc_seq, rsci->mechctx)) 1504 gc->gc_seq, rsci->mechctx))
1505 goto garbage_args; 1505 goto garbage_args;
1506 rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE;
1506 break; 1507 break;
1507 case RPC_GSS_SVC_PRIVACY: 1508 case RPC_GSS_SVC_PRIVACY:
1508 /* placeholders for length and seq. number: */ 1509 /* placeholders for length and seq. number: */
@@ -1511,6 +1512,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1511 if (unwrap_priv_data(rqstp, &rqstp->rq_arg, 1512 if (unwrap_priv_data(rqstp, &rqstp->rq_arg,
1512 gc->gc_seq, rsci->mechctx)) 1513 gc->gc_seq, rsci->mechctx))
1513 goto garbage_args; 1514 goto garbage_args;
1515 rqstp->rq_auth_slack = RPC_MAX_AUTH_SIZE * 2;
1514 break; 1516 break;
1515 default: 1517 default:
1516 goto auth_err; 1518 goto auth_err;
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index 2af7b0cba43a..79c0f3459b5c 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -54,6 +54,8 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
54 } 54 }
55 spin_unlock(&authtab_lock); 55 spin_unlock(&authtab_lock);
56 56
57 rqstp->rq_auth_slack = 0;
58
57 rqstp->rq_authop = aops; 59 rqstp->rq_authop = aops;
58 return aops->accept(rqstp, authp); 60 return aops->accept(rqstp, authp);
59} 61}