diff options
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 35 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 27 |
2 files changed, 46 insertions, 16 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index afb292cd797d..53ed8d3f8897 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -1353,6 +1353,7 @@ gss_stringify_acceptor(struct rpc_cred *cred) | |||
1353 | char *string = NULL; | 1353 | char *string = NULL; |
1354 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); | 1354 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); |
1355 | struct gss_cl_ctx *ctx; | 1355 | struct gss_cl_ctx *ctx; |
1356 | unsigned int len; | ||
1356 | struct xdr_netobj *acceptor; | 1357 | struct xdr_netobj *acceptor; |
1357 | 1358 | ||
1358 | rcu_read_lock(); | 1359 | rcu_read_lock(); |
@@ -1360,15 +1361,39 @@ gss_stringify_acceptor(struct rpc_cred *cred) | |||
1360 | if (!ctx) | 1361 | if (!ctx) |
1361 | goto out; | 1362 | goto out; |
1362 | 1363 | ||
1363 | acceptor = &ctx->gc_acceptor; | 1364 | len = ctx->gc_acceptor.len; |
1365 | rcu_read_unlock(); | ||
1364 | 1366 | ||
1365 | /* no point if there's no string */ | 1367 | /* no point if there's no string */ |
1366 | if (!acceptor->len) | 1368 | if (!len) |
1367 | goto out; | 1369 | return NULL; |
1368 | 1370 | realloc: | |
1369 | string = kmalloc(acceptor->len + 1, GFP_KERNEL); | 1371 | string = kmalloc(len + 1, GFP_KERNEL); |
1370 | if (!string) | 1372 | if (!string) |
1373 | return NULL; | ||
1374 | |||
1375 | rcu_read_lock(); | ||
1376 | ctx = rcu_dereference(gss_cred->gc_ctx); | ||
1377 | |||
1378 | /* did the ctx disappear or was it replaced by one with no acceptor? */ | ||
1379 | if (!ctx || !ctx->gc_acceptor.len) { | ||
1380 | kfree(string); | ||
1381 | string = NULL; | ||
1371 | goto out; | 1382 | goto out; |
1383 | } | ||
1384 | |||
1385 | acceptor = &ctx->gc_acceptor; | ||
1386 | |||
1387 | /* | ||
1388 | * Did we find a new acceptor that's longer than the original? Allocate | ||
1389 | * a longer buffer and try again. | ||
1390 | */ | ||
1391 | if (len < acceptor->len) { | ||
1392 | len = acceptor->len; | ||
1393 | rcu_read_unlock(); | ||
1394 | kfree(string); | ||
1395 | goto realloc; | ||
1396 | } | ||
1372 | 1397 | ||
1373 | memcpy(string, acceptor->data, acceptor->len); | 1398 | memcpy(string, acceptor->data, acceptor->len); |
1374 | string[acceptor->len] = '\0'; | 1399 | string[acceptor->len] = '\0'; |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 3f959c681885..f9c052d508f0 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -1019,17 +1019,12 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
1019 | xid = *p++; | 1019 | xid = *p++; |
1020 | calldir = *p; | 1020 | calldir = *p; |
1021 | 1021 | ||
1022 | if (bc_xprt) | 1022 | if (!bc_xprt) |
1023 | req = xprt_lookup_rqst(bc_xprt, xid); | ||
1024 | |||
1025 | if (!req) { | ||
1026 | printk(KERN_NOTICE | ||
1027 | "%s: Got unrecognized reply: " | ||
1028 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", | ||
1029 | __func__, ntohl(calldir), | ||
1030 | bc_xprt, ntohl(xid)); | ||
1031 | return -EAGAIN; | 1023 | return -EAGAIN; |
1032 | } | 1024 | spin_lock_bh(&bc_xprt->transport_lock); |
1025 | req = xprt_lookup_rqst(bc_xprt, xid); | ||
1026 | if (!req) | ||
1027 | goto unlock_notfound; | ||
1033 | 1028 | ||
1034 | memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf)); | 1029 | memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf)); |
1035 | /* | 1030 | /* |
@@ -1040,11 +1035,21 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
1040 | dst = &req->rq_private_buf.head[0]; | 1035 | dst = &req->rq_private_buf.head[0]; |
1041 | src = &rqstp->rq_arg.head[0]; | 1036 | src = &rqstp->rq_arg.head[0]; |
1042 | if (dst->iov_len < src->iov_len) | 1037 | if (dst->iov_len < src->iov_len) |
1043 | return -EAGAIN; /* whatever; just giving up. */ | 1038 | goto unlock_eagain; /* whatever; just giving up. */ |
1044 | memcpy(dst->iov_base, src->iov_base, src->iov_len); | 1039 | memcpy(dst->iov_base, src->iov_base, src->iov_len); |
1045 | xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len); | 1040 | xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len); |
1046 | rqstp->rq_arg.len = 0; | 1041 | rqstp->rq_arg.len = 0; |
1042 | spin_unlock_bh(&bc_xprt->transport_lock); | ||
1047 | return 0; | 1043 | return 0; |
1044 | unlock_notfound: | ||
1045 | printk(KERN_NOTICE | ||
1046 | "%s: Got unrecognized reply: " | ||
1047 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", | ||
1048 | __func__, ntohl(calldir), | ||
1049 | bc_xprt, ntohl(xid)); | ||
1050 | unlock_eagain: | ||
1051 | spin_unlock_bh(&bc_xprt->transport_lock); | ||
1052 | return -EAGAIN; | ||
1048 | } | 1053 | } |
1049 | 1054 | ||
1050 | static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len) | 1055 | static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len) |