diff options
author | J. Bruce Fields <bfields@redhat.com> | 2014-05-12 18:10:58 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-05-30 17:32:17 -0400 |
commit | a5cddc885b99458df963a75abbe0b40cbef56c48 (patch) | |
tree | b7f200949823f98207aa2d2fd72c112fa3e6ee8e | |
parent | d05d5744ef67879877dbe2e3d0fb9fcc27ee44e5 (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.c | 4 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 5 | ||||
-rw-r--r-- | include/linux/sunrpc/svc.h | 11 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 2 | ||||
-rw-r--r-- | net/sunrpc/svcauth.c | 2 |
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 | */ |
457 | static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space) | 460 | static 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 | } |