diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/auth.c | 28 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 44 | ||||
-rw-r--r-- | net/sunrpc/bc_svc.c | 2 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 21 | ||||
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 2 | ||||
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 147 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 36 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 106 | ||||
-rw-r--r-- | net/sunrpc/xdr.c | 155 |
9 files changed, 345 insertions, 196 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index afe67849269f..67e31276682a 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -563,8 +563,17 @@ rpcauth_checkverf(struct rpc_task *task, __be32 *p) | |||
563 | return cred->cr_ops->crvalidate(task, p); | 563 | return cred->cr_ops->crvalidate(task, p); |
564 | } | 564 | } |
565 | 565 | ||
566 | static void rpcauth_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, | ||
567 | __be32 *data, void *obj) | ||
568 | { | ||
569 | struct xdr_stream xdr; | ||
570 | |||
571 | xdr_init_encode(&xdr, &rqstp->rq_snd_buf, data); | ||
572 | encode(rqstp, &xdr, obj); | ||
573 | } | ||
574 | |||
566 | int | 575 | int |
567 | rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, | 576 | rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, |
568 | __be32 *data, void *obj) | 577 | __be32 *data, void *obj) |
569 | { | 578 | { |
570 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 579 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
@@ -574,11 +583,22 @@ rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, | |||
574 | if (cred->cr_ops->crwrap_req) | 583 | if (cred->cr_ops->crwrap_req) |
575 | return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); | 584 | return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); |
576 | /* By default, we encode the arguments normally. */ | 585 | /* By default, we encode the arguments normally. */ |
577 | return encode(rqstp, data, obj); | 586 | rpcauth_wrap_req_encode(encode, rqstp, data, obj); |
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static int | ||
591 | rpcauth_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp, | ||
592 | __be32 *data, void *obj) | ||
593 | { | ||
594 | struct xdr_stream xdr; | ||
595 | |||
596 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, data); | ||
597 | return decode(rqstp, &xdr, obj); | ||
578 | } | 598 | } |
579 | 599 | ||
580 | int | 600 | int |
581 | rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, | 601 | rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp, |
582 | __be32 *data, void *obj) | 602 | __be32 *data, void *obj) |
583 | { | 603 | { |
584 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 604 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
@@ -589,7 +609,7 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, | |||
589 | return cred->cr_ops->crunwrap_resp(task, decode, rqstp, | 609 | return cred->cr_ops->crunwrap_resp(task, decode, rqstp, |
590 | data, obj); | 610 | data, obj); |
591 | /* By default, we decode the arguments normally. */ | 611 | /* By default, we decode the arguments normally. */ |
592 | return decode(rqstp, data, obj); | 612 | return rpcauth_unwrap_req_decode(decode, rqstp, data, obj); |
593 | } | 613 | } |
594 | 614 | ||
595 | int | 615 | int |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 3835ce35e224..45dbf1521b9a 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -1231,9 +1231,19 @@ out_bad: | |||
1231 | return NULL; | 1231 | return NULL; |
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, | ||
1235 | __be32 *p, void *obj) | ||
1236 | { | ||
1237 | struct xdr_stream xdr; | ||
1238 | |||
1239 | xdr_init_encode(&xdr, &rqstp->rq_snd_buf, p); | ||
1240 | encode(rqstp, &xdr, obj); | ||
1241 | } | ||
1242 | |||
1234 | static inline int | 1243 | static inline int |
1235 | gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | 1244 | gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, |
1236 | kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj) | 1245 | kxdreproc_t encode, struct rpc_rqst *rqstp, |
1246 | __be32 *p, void *obj) | ||
1237 | { | 1247 | { |
1238 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; | 1248 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; |
1239 | struct xdr_buf integ_buf; | 1249 | struct xdr_buf integ_buf; |
@@ -1249,9 +1259,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1249 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; | 1259 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; |
1250 | *p++ = htonl(rqstp->rq_seqno); | 1260 | *p++ = htonl(rqstp->rq_seqno); |
1251 | 1261 | ||
1252 | status = encode(rqstp, p, obj); | 1262 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1253 | if (status) | ||
1254 | return status; | ||
1255 | 1263 | ||
1256 | if (xdr_buf_subsegment(snd_buf, &integ_buf, | 1264 | if (xdr_buf_subsegment(snd_buf, &integ_buf, |
1257 | offset, snd_buf->len - offset)) | 1265 | offset, snd_buf->len - offset)) |
@@ -1325,7 +1333,8 @@ out: | |||
1325 | 1333 | ||
1326 | static inline int | 1334 | static inline int |
1327 | gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | 1335 | gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, |
1328 | kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj) | 1336 | kxdreproc_t encode, struct rpc_rqst *rqstp, |
1337 | __be32 *p, void *obj) | ||
1329 | { | 1338 | { |
1330 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; | 1339 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; |
1331 | u32 offset; | 1340 | u32 offset; |
@@ -1342,9 +1351,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1342 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; | 1351 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; |
1343 | *p++ = htonl(rqstp->rq_seqno); | 1352 | *p++ = htonl(rqstp->rq_seqno); |
1344 | 1353 | ||
1345 | status = encode(rqstp, p, obj); | 1354 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1346 | if (status) | ||
1347 | return status; | ||
1348 | 1355 | ||
1349 | status = alloc_enc_pages(rqstp); | 1356 | status = alloc_enc_pages(rqstp); |
1350 | if (status) | 1357 | if (status) |
@@ -1394,7 +1401,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1394 | 1401 | ||
1395 | static int | 1402 | static int |
1396 | gss_wrap_req(struct rpc_task *task, | 1403 | gss_wrap_req(struct rpc_task *task, |
1397 | kxdrproc_t encode, void *rqstp, __be32 *p, void *obj) | 1404 | kxdreproc_t encode, void *rqstp, __be32 *p, void *obj) |
1398 | { | 1405 | { |
1399 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 1406 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
1400 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, | 1407 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, |
@@ -1407,12 +1414,14 @@ gss_wrap_req(struct rpc_task *task, | |||
1407 | /* The spec seems a little ambiguous here, but I think that not | 1414 | /* The spec seems a little ambiguous here, but I think that not |
1408 | * wrapping context destruction requests makes the most sense. | 1415 | * wrapping context destruction requests makes the most sense. |
1409 | */ | 1416 | */ |
1410 | status = encode(rqstp, p, obj); | 1417 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1418 | status = 0; | ||
1411 | goto out; | 1419 | goto out; |
1412 | } | 1420 | } |
1413 | switch (gss_cred->gc_service) { | 1421 | switch (gss_cred->gc_service) { |
1414 | case RPC_GSS_SVC_NONE: | 1422 | case RPC_GSS_SVC_NONE: |
1415 | status = encode(rqstp, p, obj); | 1423 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1424 | status = 0; | ||
1416 | break; | 1425 | break; |
1417 | case RPC_GSS_SVC_INTEGRITY: | 1426 | case RPC_GSS_SVC_INTEGRITY: |
1418 | status = gss_wrap_req_integ(cred, ctx, encode, | 1427 | status = gss_wrap_req_integ(cred, ctx, encode, |
@@ -1494,10 +1503,19 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1494 | return 0; | 1503 | return 0; |
1495 | } | 1504 | } |
1496 | 1505 | ||
1506 | static int | ||
1507 | gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp, | ||
1508 | __be32 *p, void *obj) | ||
1509 | { | ||
1510 | struct xdr_stream xdr; | ||
1511 | |||
1512 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | ||
1513 | return decode(rqstp, &xdr, obj); | ||
1514 | } | ||
1497 | 1515 | ||
1498 | static int | 1516 | static int |
1499 | gss_unwrap_resp(struct rpc_task *task, | 1517 | gss_unwrap_resp(struct rpc_task *task, |
1500 | kxdrproc_t decode, void *rqstp, __be32 *p, void *obj) | 1518 | kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj) |
1501 | { | 1519 | { |
1502 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 1520 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
1503 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, | 1521 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, |
@@ -1528,7 +1546,7 @@ gss_unwrap_resp(struct rpc_task *task, | |||
1528 | cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) | 1546 | cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) |
1529 | + (savedlen - head->iov_len); | 1547 | + (savedlen - head->iov_len); |
1530 | out_decode: | 1548 | out_decode: |
1531 | status = decode(rqstp, p, obj); | 1549 | status = gss_unwrap_req_decode(decode, rqstp, p, obj); |
1532 | out: | 1550 | out: |
1533 | gss_put_ctx(ctx); | 1551 | gss_put_ctx(ctx); |
1534 | dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, | 1552 | dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, |
diff --git a/net/sunrpc/bc_svc.c b/net/sunrpc/bc_svc.c index 7dcfe0cc3500..1dd1a6890007 100644 --- a/net/sunrpc/bc_svc.c +++ b/net/sunrpc/bc_svc.c | |||
@@ -59,8 +59,8 @@ int bc_send(struct rpc_rqst *req) | |||
59 | ret = task->tk_status; | 59 | ret = task->tk_status; |
60 | rpc_put_task(task); | 60 | rpc_put_task(task); |
61 | } | 61 | } |
62 | return ret; | ||
63 | dprintk("RPC: bc_send ret= %d\n", ret); | 62 | dprintk("RPC: bc_send ret= %d\n", ret); |
63 | return ret; | ||
64 | } | 64 | } |
65 | 65 | ||
66 | #endif /* CONFIG_NFS_V4_1 */ | 66 | #endif /* CONFIG_NFS_V4_1 */ |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 92ce94f5146b..57d344cf2256 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -1095,7 +1095,7 @@ static void | |||
1095 | rpc_xdr_encode(struct rpc_task *task) | 1095 | rpc_xdr_encode(struct rpc_task *task) |
1096 | { | 1096 | { |
1097 | struct rpc_rqst *req = task->tk_rqstp; | 1097 | struct rpc_rqst *req = task->tk_rqstp; |
1098 | kxdrproc_t encode; | 1098 | kxdreproc_t encode; |
1099 | __be32 *p; | 1099 | __be32 *p; |
1100 | 1100 | ||
1101 | dprint_status(task); | 1101 | dprint_status(task); |
@@ -1535,7 +1535,7 @@ call_decode(struct rpc_task *task) | |||
1535 | { | 1535 | { |
1536 | struct rpc_clnt *clnt = task->tk_client; | 1536 | struct rpc_clnt *clnt = task->tk_client; |
1537 | struct rpc_rqst *req = task->tk_rqstp; | 1537 | struct rpc_rqst *req = task->tk_rqstp; |
1538 | kxdrproc_t decode = task->tk_msg.rpc_proc->p_decode; | 1538 | kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode; |
1539 | __be32 *p; | 1539 | __be32 *p; |
1540 | 1540 | ||
1541 | dprintk("RPC: %5u call_decode (status %d)\n", | 1541 | dprintk("RPC: %5u call_decode (status %d)\n", |
@@ -1776,12 +1776,11 @@ out_overflow: | |||
1776 | goto out_garbage; | 1776 | goto out_garbage; |
1777 | } | 1777 | } |
1778 | 1778 | ||
1779 | static int rpcproc_encode_null(void *rqstp, __be32 *data, void *obj) | 1779 | static void rpcproc_encode_null(void *rqstp, struct xdr_stream *xdr, void *obj) |
1780 | { | 1780 | { |
1781 | return 0; | ||
1782 | } | 1781 | } |
1783 | 1782 | ||
1784 | static int rpcproc_decode_null(void *rqstp, __be32 *data, void *obj) | 1783 | static int rpcproc_decode_null(void *rqstp, struct xdr_stream *xdr, void *obj) |
1785 | { | 1784 | { |
1786 | return 0; | 1785 | return 0; |
1787 | } | 1786 | } |
@@ -1830,23 +1829,15 @@ static void rpc_show_task(const struct rpc_clnt *clnt, | |||
1830 | const struct rpc_task *task) | 1829 | const struct rpc_task *task) |
1831 | { | 1830 | { |
1832 | const char *rpc_waitq = "none"; | 1831 | const char *rpc_waitq = "none"; |
1833 | char *p, action[KSYM_SYMBOL_LEN]; | ||
1834 | 1832 | ||
1835 | if (RPC_IS_QUEUED(task)) | 1833 | if (RPC_IS_QUEUED(task)) |
1836 | rpc_waitq = rpc_qname(task->tk_waitqueue); | 1834 | rpc_waitq = rpc_qname(task->tk_waitqueue); |
1837 | 1835 | ||
1838 | /* map tk_action pointer to a function name; then trim off | 1836 | printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%ps q:%s\n", |
1839 | * the "+0x0 [sunrpc]" */ | ||
1840 | sprint_symbol(action, (unsigned long)task->tk_action); | ||
1841 | p = strchr(action, '+'); | ||
1842 | if (p) | ||
1843 | *p = '\0'; | ||
1844 | |||
1845 | printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%s q:%s\n", | ||
1846 | task->tk_pid, task->tk_flags, task->tk_status, | 1837 | task->tk_pid, task->tk_flags, task->tk_status, |
1847 | clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, | 1838 | clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, |
1848 | clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), | 1839 | clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), |
1849 | action, rpc_waitq); | 1840 | task->tk_action, rpc_waitq); |
1850 | } | 1841 | } |
1851 | 1842 | ||
1852 | void rpc_show_tasks(void) | 1843 | void rpc_show_tasks(void) |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 09f01f41e55a..72bc53683965 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -474,7 +474,7 @@ static int __rpc_create_common(struct inode *dir, struct dentry *dentry, | |||
474 | { | 474 | { |
475 | struct inode *inode; | 475 | struct inode *inode; |
476 | 476 | ||
477 | BUG_ON(!d_unhashed(dentry)); | 477 | d_drop(dentry); |
478 | inode = rpc_get_inode(dir->i_sb, mode); | 478 | inode = rpc_get_inode(dir->i_sb, mode); |
479 | if (!inode) | 479 | if (!inode) |
480 | goto out_err; | 480 | goto out_err; |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index fa6d7ca2c851..c652e4cc9fe9 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -57,10 +57,6 @@ enum { | |||
57 | RPCBPROC_GETSTAT, | 57 | RPCBPROC_GETSTAT, |
58 | }; | 58 | }; |
59 | 59 | ||
60 | #define RPCB_HIGHPROC_2 RPCBPROC_CALLIT | ||
61 | #define RPCB_HIGHPROC_3 RPCBPROC_TADDR2UADDR | ||
62 | #define RPCB_HIGHPROC_4 RPCBPROC_GETSTAT | ||
63 | |||
64 | /* | 60 | /* |
65 | * r_owner | 61 | * r_owner |
66 | * | 62 | * |
@@ -693,46 +689,37 @@ static void rpcb_getport_done(struct rpc_task *child, void *data) | |||
693 | * XDR functions for rpcbind | 689 | * XDR functions for rpcbind |
694 | */ | 690 | */ |
695 | 691 | ||
696 | static int rpcb_enc_mapping(struct rpc_rqst *req, __be32 *p, | 692 | static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr, |
697 | const struct rpcbind_args *rpcb) | 693 | const struct rpcbind_args *rpcb) |
698 | { | 694 | { |
699 | struct rpc_task *task = req->rq_task; | 695 | struct rpc_task *task = req->rq_task; |
700 | struct xdr_stream xdr; | 696 | __be32 *p; |
701 | 697 | ||
702 | dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n", | 698 | dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n", |
703 | task->tk_pid, task->tk_msg.rpc_proc->p_name, | 699 | task->tk_pid, task->tk_msg.rpc_proc->p_name, |
704 | rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port); | 700 | rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port); |
705 | 701 | ||
706 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 702 | p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2); |
707 | 703 | *p++ = cpu_to_be32(rpcb->r_prog); | |
708 | p = xdr_reserve_space(&xdr, sizeof(__be32) * RPCB_mappingargs_sz); | 704 | *p++ = cpu_to_be32(rpcb->r_vers); |
709 | if (unlikely(p == NULL)) | 705 | *p++ = cpu_to_be32(rpcb->r_prot); |
710 | return -EIO; | 706 | *p = cpu_to_be32(rpcb->r_port); |
711 | |||
712 | *p++ = htonl(rpcb->r_prog); | ||
713 | *p++ = htonl(rpcb->r_vers); | ||
714 | *p++ = htonl(rpcb->r_prot); | ||
715 | *p = htonl(rpcb->r_port); | ||
716 | |||
717 | return 0; | ||
718 | } | 707 | } |
719 | 708 | ||
720 | static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, | 709 | static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr, |
721 | struct rpcbind_args *rpcb) | 710 | struct rpcbind_args *rpcb) |
722 | { | 711 | { |
723 | struct rpc_task *task = req->rq_task; | 712 | struct rpc_task *task = req->rq_task; |
724 | struct xdr_stream xdr; | ||
725 | unsigned long port; | 713 | unsigned long port; |
726 | 714 | __be32 *p; | |
727 | xdr_init_decode(&xdr, &req->rq_rcv_buf, p); | ||
728 | 715 | ||
729 | rpcb->r_port = 0; | 716 | rpcb->r_port = 0; |
730 | 717 | ||
731 | p = xdr_inline_decode(&xdr, sizeof(__be32)); | 718 | p = xdr_inline_decode(xdr, 4); |
732 | if (unlikely(p == NULL)) | 719 | if (unlikely(p == NULL)) |
733 | return -EIO; | 720 | return -EIO; |
734 | 721 | ||
735 | port = ntohl(*p); | 722 | port = be32_to_cpup(p); |
736 | dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid, | 723 | dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid, |
737 | task->tk_msg.rpc_proc->p_name, port); | 724 | task->tk_msg.rpc_proc->p_name, port); |
738 | if (unlikely(port > USHRT_MAX)) | 725 | if (unlikely(port > USHRT_MAX)) |
@@ -742,20 +729,18 @@ static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, | |||
742 | return 0; | 729 | return 0; |
743 | } | 730 | } |
744 | 731 | ||
745 | static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p, | 732 | static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr, |
746 | unsigned int *boolp) | 733 | unsigned int *boolp) |
747 | { | 734 | { |
748 | struct rpc_task *task = req->rq_task; | 735 | struct rpc_task *task = req->rq_task; |
749 | struct xdr_stream xdr; | 736 | __be32 *p; |
750 | |||
751 | xdr_init_decode(&xdr, &req->rq_rcv_buf, p); | ||
752 | 737 | ||
753 | p = xdr_inline_decode(&xdr, sizeof(__be32)); | 738 | p = xdr_inline_decode(xdr, 4); |
754 | if (unlikely(p == NULL)) | 739 | if (unlikely(p == NULL)) |
755 | return -EIO; | 740 | return -EIO; |
756 | 741 | ||
757 | *boolp = 0; | 742 | *boolp = 0; |
758 | if (*p) | 743 | if (*p != xdr_zero) |
759 | *boolp = 1; | 744 | *boolp = 1; |
760 | 745 | ||
761 | dprintk("RPC: %5u RPCB_%s call %s\n", | 746 | dprintk("RPC: %5u RPCB_%s call %s\n", |
@@ -764,73 +749,53 @@ static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p, | |||
764 | return 0; | 749 | return 0; |
765 | } | 750 | } |
766 | 751 | ||
767 | static int encode_rpcb_string(struct xdr_stream *xdr, const char *string, | 752 | static void encode_rpcb_string(struct xdr_stream *xdr, const char *string, |
768 | const u32 maxstrlen) | 753 | const u32 maxstrlen) |
769 | { | 754 | { |
770 | u32 len; | ||
771 | __be32 *p; | 755 | __be32 *p; |
756 | u32 len; | ||
772 | 757 | ||
773 | if (unlikely(string == NULL)) | ||
774 | return -EIO; | ||
775 | len = strlen(string); | 758 | len = strlen(string); |
776 | if (unlikely(len > maxstrlen)) | 759 | BUG_ON(len > maxstrlen); |
777 | return -EIO; | 760 | p = xdr_reserve_space(xdr, 4 + len); |
778 | |||
779 | p = xdr_reserve_space(xdr, sizeof(__be32) + len); | ||
780 | if (unlikely(p == NULL)) | ||
781 | return -EIO; | ||
782 | xdr_encode_opaque(p, string, len); | 761 | xdr_encode_opaque(p, string, len); |
783 | |||
784 | return 0; | ||
785 | } | 762 | } |
786 | 763 | ||
787 | static int rpcb_enc_getaddr(struct rpc_rqst *req, __be32 *p, | 764 | static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, |
788 | const struct rpcbind_args *rpcb) | 765 | const struct rpcbind_args *rpcb) |
789 | { | 766 | { |
790 | struct rpc_task *task = req->rq_task; | 767 | struct rpc_task *task = req->rq_task; |
791 | struct xdr_stream xdr; | 768 | __be32 *p; |
792 | 769 | ||
793 | dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n", | 770 | dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n", |
794 | task->tk_pid, task->tk_msg.rpc_proc->p_name, | 771 | task->tk_pid, task->tk_msg.rpc_proc->p_name, |
795 | rpcb->r_prog, rpcb->r_vers, | 772 | rpcb->r_prog, rpcb->r_vers, |
796 | rpcb->r_netid, rpcb->r_addr); | 773 | rpcb->r_netid, rpcb->r_addr); |
797 | 774 | ||
798 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 775 | p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2); |
799 | 776 | *p++ = cpu_to_be32(rpcb->r_prog); | |
800 | p = xdr_reserve_space(&xdr, | 777 | *p = cpu_to_be32(rpcb->r_vers); |
801 | sizeof(__be32) * (RPCB_program_sz + RPCB_version_sz)); | ||
802 | if (unlikely(p == NULL)) | ||
803 | return -EIO; | ||
804 | *p++ = htonl(rpcb->r_prog); | ||
805 | *p = htonl(rpcb->r_vers); | ||
806 | |||
807 | if (encode_rpcb_string(&xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN)) | ||
808 | return -EIO; | ||
809 | if (encode_rpcb_string(&xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN)) | ||
810 | return -EIO; | ||
811 | if (encode_rpcb_string(&xdr, rpcb->r_owner, RPCB_MAXOWNERLEN)) | ||
812 | return -EIO; | ||
813 | 778 | ||
814 | return 0; | 779 | encode_rpcb_string(xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN); |
780 | encode_rpcb_string(xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN); | ||
781 | encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN); | ||
815 | } | 782 | } |
816 | 783 | ||
817 | static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p, | 784 | static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, |
818 | struct rpcbind_args *rpcb) | 785 | struct rpcbind_args *rpcb) |
819 | { | 786 | { |
820 | struct sockaddr_storage address; | 787 | struct sockaddr_storage address; |
821 | struct sockaddr *sap = (struct sockaddr *)&address; | 788 | struct sockaddr *sap = (struct sockaddr *)&address; |
822 | struct rpc_task *task = req->rq_task; | 789 | struct rpc_task *task = req->rq_task; |
823 | struct xdr_stream xdr; | 790 | __be32 *p; |
824 | u32 len; | 791 | u32 len; |
825 | 792 | ||
826 | rpcb->r_port = 0; | 793 | rpcb->r_port = 0; |
827 | 794 | ||
828 | xdr_init_decode(&xdr, &req->rq_rcv_buf, p); | 795 | p = xdr_inline_decode(xdr, 4); |
829 | |||
830 | p = xdr_inline_decode(&xdr, sizeof(__be32)); | ||
831 | if (unlikely(p == NULL)) | 796 | if (unlikely(p == NULL)) |
832 | goto out_fail; | 797 | goto out_fail; |
833 | len = ntohl(*p); | 798 | len = be32_to_cpup(p); |
834 | 799 | ||
835 | /* | 800 | /* |
836 | * If the returned universal address is a null string, | 801 | * If the returned universal address is a null string, |
@@ -845,7 +810,7 @@ static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p, | |||
845 | if (unlikely(len > RPCBIND_MAXUADDRLEN)) | 810 | if (unlikely(len > RPCBIND_MAXUADDRLEN)) |
846 | goto out_fail; | 811 | goto out_fail; |
847 | 812 | ||
848 | p = xdr_inline_decode(&xdr, len); | 813 | p = xdr_inline_decode(xdr, len); |
849 | if (unlikely(p == NULL)) | 814 | if (unlikely(p == NULL)) |
850 | goto out_fail; | 815 | goto out_fail; |
851 | dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid, | 816 | dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid, |
@@ -871,8 +836,8 @@ out_fail: | |||
871 | static struct rpc_procinfo rpcb_procedures2[] = { | 836 | static struct rpc_procinfo rpcb_procedures2[] = { |
872 | [RPCBPROC_SET] = { | 837 | [RPCBPROC_SET] = { |
873 | .p_proc = RPCBPROC_SET, | 838 | .p_proc = RPCBPROC_SET, |
874 | .p_encode = (kxdrproc_t)rpcb_enc_mapping, | 839 | .p_encode = (kxdreproc_t)rpcb_enc_mapping, |
875 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 840 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
876 | .p_arglen = RPCB_mappingargs_sz, | 841 | .p_arglen = RPCB_mappingargs_sz, |
877 | .p_replen = RPCB_setres_sz, | 842 | .p_replen = RPCB_setres_sz, |
878 | .p_statidx = RPCBPROC_SET, | 843 | .p_statidx = RPCBPROC_SET, |
@@ -881,8 +846,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { | |||
881 | }, | 846 | }, |
882 | [RPCBPROC_UNSET] = { | 847 | [RPCBPROC_UNSET] = { |
883 | .p_proc = RPCBPROC_UNSET, | 848 | .p_proc = RPCBPROC_UNSET, |
884 | .p_encode = (kxdrproc_t)rpcb_enc_mapping, | 849 | .p_encode = (kxdreproc_t)rpcb_enc_mapping, |
885 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 850 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
886 | .p_arglen = RPCB_mappingargs_sz, | 851 | .p_arglen = RPCB_mappingargs_sz, |
887 | .p_replen = RPCB_setres_sz, | 852 | .p_replen = RPCB_setres_sz, |
888 | .p_statidx = RPCBPROC_UNSET, | 853 | .p_statidx = RPCBPROC_UNSET, |
@@ -891,8 +856,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { | |||
891 | }, | 856 | }, |
892 | [RPCBPROC_GETPORT] = { | 857 | [RPCBPROC_GETPORT] = { |
893 | .p_proc = RPCBPROC_GETPORT, | 858 | .p_proc = RPCBPROC_GETPORT, |
894 | .p_encode = (kxdrproc_t)rpcb_enc_mapping, | 859 | .p_encode = (kxdreproc_t)rpcb_enc_mapping, |
895 | .p_decode = (kxdrproc_t)rpcb_dec_getport, | 860 | .p_decode = (kxdrdproc_t)rpcb_dec_getport, |
896 | .p_arglen = RPCB_mappingargs_sz, | 861 | .p_arglen = RPCB_mappingargs_sz, |
897 | .p_replen = RPCB_getportres_sz, | 862 | .p_replen = RPCB_getportres_sz, |
898 | .p_statidx = RPCBPROC_GETPORT, | 863 | .p_statidx = RPCBPROC_GETPORT, |
@@ -904,8 +869,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { | |||
904 | static struct rpc_procinfo rpcb_procedures3[] = { | 869 | static struct rpc_procinfo rpcb_procedures3[] = { |
905 | [RPCBPROC_SET] = { | 870 | [RPCBPROC_SET] = { |
906 | .p_proc = RPCBPROC_SET, | 871 | .p_proc = RPCBPROC_SET, |
907 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 872 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
908 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 873 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
909 | .p_arglen = RPCB_getaddrargs_sz, | 874 | .p_arglen = RPCB_getaddrargs_sz, |
910 | .p_replen = RPCB_setres_sz, | 875 | .p_replen = RPCB_setres_sz, |
911 | .p_statidx = RPCBPROC_SET, | 876 | .p_statidx = RPCBPROC_SET, |
@@ -914,8 +879,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { | |||
914 | }, | 879 | }, |
915 | [RPCBPROC_UNSET] = { | 880 | [RPCBPROC_UNSET] = { |
916 | .p_proc = RPCBPROC_UNSET, | 881 | .p_proc = RPCBPROC_UNSET, |
917 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 882 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
918 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 883 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
919 | .p_arglen = RPCB_getaddrargs_sz, | 884 | .p_arglen = RPCB_getaddrargs_sz, |
920 | .p_replen = RPCB_setres_sz, | 885 | .p_replen = RPCB_setres_sz, |
921 | .p_statidx = RPCBPROC_UNSET, | 886 | .p_statidx = RPCBPROC_UNSET, |
@@ -924,8 +889,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { | |||
924 | }, | 889 | }, |
925 | [RPCBPROC_GETADDR] = { | 890 | [RPCBPROC_GETADDR] = { |
926 | .p_proc = RPCBPROC_GETADDR, | 891 | .p_proc = RPCBPROC_GETADDR, |
927 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 892 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
928 | .p_decode = (kxdrproc_t)rpcb_dec_getaddr, | 893 | .p_decode = (kxdrdproc_t)rpcb_dec_getaddr, |
929 | .p_arglen = RPCB_getaddrargs_sz, | 894 | .p_arglen = RPCB_getaddrargs_sz, |
930 | .p_replen = RPCB_getaddrres_sz, | 895 | .p_replen = RPCB_getaddrres_sz, |
931 | .p_statidx = RPCBPROC_GETADDR, | 896 | .p_statidx = RPCBPROC_GETADDR, |
@@ -937,8 +902,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { | |||
937 | static struct rpc_procinfo rpcb_procedures4[] = { | 902 | static struct rpc_procinfo rpcb_procedures4[] = { |
938 | [RPCBPROC_SET] = { | 903 | [RPCBPROC_SET] = { |
939 | .p_proc = RPCBPROC_SET, | 904 | .p_proc = RPCBPROC_SET, |
940 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 905 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
941 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 906 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
942 | .p_arglen = RPCB_getaddrargs_sz, | 907 | .p_arglen = RPCB_getaddrargs_sz, |
943 | .p_replen = RPCB_setres_sz, | 908 | .p_replen = RPCB_setres_sz, |
944 | .p_statidx = RPCBPROC_SET, | 909 | .p_statidx = RPCBPROC_SET, |
@@ -947,8 +912,8 @@ static struct rpc_procinfo rpcb_procedures4[] = { | |||
947 | }, | 912 | }, |
948 | [RPCBPROC_UNSET] = { | 913 | [RPCBPROC_UNSET] = { |
949 | .p_proc = RPCBPROC_UNSET, | 914 | .p_proc = RPCBPROC_UNSET, |
950 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 915 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
951 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 916 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
952 | .p_arglen = RPCB_getaddrargs_sz, | 917 | .p_arglen = RPCB_getaddrargs_sz, |
953 | .p_replen = RPCB_setres_sz, | 918 | .p_replen = RPCB_setres_sz, |
954 | .p_statidx = RPCBPROC_UNSET, | 919 | .p_statidx = RPCBPROC_UNSET, |
@@ -957,8 +922,8 @@ static struct rpc_procinfo rpcb_procedures4[] = { | |||
957 | }, | 922 | }, |
958 | [RPCBPROC_GETADDR] = { | 923 | [RPCBPROC_GETADDR] = { |
959 | .p_proc = RPCBPROC_GETADDR, | 924 | .p_proc = RPCBPROC_GETADDR, |
960 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 925 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
961 | .p_decode = (kxdrproc_t)rpcb_dec_getaddr, | 926 | .p_decode = (kxdrdproc_t)rpcb_dec_getaddr, |
962 | .p_arglen = RPCB_getaddrargs_sz, | 927 | .p_arglen = RPCB_getaddrargs_sz, |
963 | .p_replen = RPCB_getaddrres_sz, | 928 | .p_replen = RPCB_getaddrres_sz, |
964 | .p_statidx = RPCBPROC_GETADDR, | 929 | .p_statidx = RPCBPROC_GETADDR, |
@@ -993,19 +958,19 @@ static struct rpcb_info rpcb_next_version6[] = { | |||
993 | 958 | ||
994 | static struct rpc_version rpcb_version2 = { | 959 | static struct rpc_version rpcb_version2 = { |
995 | .number = RPCBVERS_2, | 960 | .number = RPCBVERS_2, |
996 | .nrprocs = RPCB_HIGHPROC_2, | 961 | .nrprocs = ARRAY_SIZE(rpcb_procedures2), |
997 | .procs = rpcb_procedures2 | 962 | .procs = rpcb_procedures2 |
998 | }; | 963 | }; |
999 | 964 | ||
1000 | static struct rpc_version rpcb_version3 = { | 965 | static struct rpc_version rpcb_version3 = { |
1001 | .number = RPCBVERS_3, | 966 | .number = RPCBVERS_3, |
1002 | .nrprocs = RPCB_HIGHPROC_3, | 967 | .nrprocs = ARRAY_SIZE(rpcb_procedures3), |
1003 | .procs = rpcb_procedures3 | 968 | .procs = rpcb_procedures3 |
1004 | }; | 969 | }; |
1005 | 970 | ||
1006 | static struct rpc_version rpcb_version4 = { | 971 | static struct rpc_version rpcb_version4 = { |
1007 | .number = RPCBVERS_4, | 972 | .number = RPCBVERS_4, |
1008 | .nrprocs = RPCB_HIGHPROC_4, | 973 | .nrprocs = ARRAY_SIZE(rpcb_procedures4), |
1009 | .procs = rpcb_procedures4 | 974 | .procs = rpcb_procedures4 |
1010 | }; | 975 | }; |
1011 | 976 | ||
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 6359c42c4941..0e659c665a8d 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -488,10 +488,6 @@ svc_destroy(struct svc_serv *serv) | |||
488 | if (svc_serv_is_pooled(serv)) | 488 | if (svc_serv_is_pooled(serv)) |
489 | svc_pool_map_put(); | 489 | svc_pool_map_put(); |
490 | 490 | ||
491 | #if defined(CONFIG_NFS_V4_1) | ||
492 | svc_sock_destroy(serv->bc_xprt); | ||
493 | #endif /* CONFIG_NFS_V4_1 */ | ||
494 | |||
495 | svc_unregister(serv); | 491 | svc_unregister(serv); |
496 | kfree(serv->sv_pools); | 492 | kfree(serv->sv_pools); |
497 | kfree(serv); | 493 | kfree(serv); |
@@ -1147,7 +1143,6 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) | |||
1147 | dropit: | 1143 | dropit: |
1148 | svc_authorise(rqstp); /* doesn't hurt to call this twice */ | 1144 | svc_authorise(rqstp); /* doesn't hurt to call this twice */ |
1149 | dprintk("svc: svc_process dropit\n"); | 1145 | dprintk("svc: svc_process dropit\n"); |
1150 | svc_drop(rqstp); | ||
1151 | return 0; | 1146 | return 0; |
1152 | 1147 | ||
1153 | err_short_len: | 1148 | err_short_len: |
@@ -1218,7 +1213,6 @@ svc_process(struct svc_rqst *rqstp) | |||
1218 | struct kvec *resv = &rqstp->rq_res.head[0]; | 1213 | struct kvec *resv = &rqstp->rq_res.head[0]; |
1219 | struct svc_serv *serv = rqstp->rq_server; | 1214 | struct svc_serv *serv = rqstp->rq_server; |
1220 | u32 dir; | 1215 | u32 dir; |
1221 | int error; | ||
1222 | 1216 | ||
1223 | /* | 1217 | /* |
1224 | * Setup response xdr_buf. | 1218 | * Setup response xdr_buf. |
@@ -1246,11 +1240,13 @@ svc_process(struct svc_rqst *rqstp) | |||
1246 | return 0; | 1240 | return 0; |
1247 | } | 1241 | } |
1248 | 1242 | ||
1249 | error = svc_process_common(rqstp, argv, resv); | 1243 | /* Returns 1 for send, 0 for drop */ |
1250 | if (error <= 0) | 1244 | if (svc_process_common(rqstp, argv, resv)) |
1251 | return error; | 1245 | return svc_send(rqstp); |
1252 | 1246 | else { | |
1253 | return svc_send(rqstp); | 1247 | svc_drop(rqstp); |
1248 | return 0; | ||
1249 | } | ||
1254 | } | 1250 | } |
1255 | 1251 | ||
1256 | #if defined(CONFIG_NFS_V4_1) | 1252 | #if defined(CONFIG_NFS_V4_1) |
@@ -1264,10 +1260,9 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, | |||
1264 | { | 1260 | { |
1265 | struct kvec *argv = &rqstp->rq_arg.head[0]; | 1261 | struct kvec *argv = &rqstp->rq_arg.head[0]; |
1266 | struct kvec *resv = &rqstp->rq_res.head[0]; | 1262 | struct kvec *resv = &rqstp->rq_res.head[0]; |
1267 | int error; | ||
1268 | 1263 | ||
1269 | /* Build the svc_rqst used by the common processing routine */ | 1264 | /* Build the svc_rqst used by the common processing routine */ |
1270 | rqstp->rq_xprt = serv->bc_xprt; | 1265 | rqstp->rq_xprt = serv->sv_bc_xprt; |
1271 | rqstp->rq_xid = req->rq_xid; | 1266 | rqstp->rq_xid = req->rq_xid; |
1272 | rqstp->rq_prot = req->rq_xprt->prot; | 1267 | rqstp->rq_prot = req->rq_xprt->prot; |
1273 | rqstp->rq_server = serv; | 1268 | rqstp->rq_server = serv; |
@@ -1292,12 +1287,15 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, | |||
1292 | svc_getu32(argv); /* XID */ | 1287 | svc_getu32(argv); /* XID */ |
1293 | svc_getnl(argv); /* CALLDIR */ | 1288 | svc_getnl(argv); /* CALLDIR */ |
1294 | 1289 | ||
1295 | error = svc_process_common(rqstp, argv, resv); | 1290 | /* Returns 1 for send, 0 for drop */ |
1296 | if (error <= 0) | 1291 | if (svc_process_common(rqstp, argv, resv)) { |
1297 | return error; | 1292 | memcpy(&req->rq_snd_buf, &rqstp->rq_res, |
1298 | 1293 | sizeof(req->rq_snd_buf)); | |
1299 | memcpy(&req->rq_snd_buf, &rqstp->rq_res, sizeof(req->rq_snd_buf)); | 1294 | return bc_send(req); |
1300 | return bc_send(req); | 1295 | } else { |
1296 | /* Nothing to do to drop request */ | ||
1297 | return 0; | ||
1298 | } | ||
1301 | } | 1299 | } |
1302 | EXPORT_SYMBOL(bc_svc_process); | 1300 | EXPORT_SYMBOL(bc_svc_process); |
1303 | #endif /* CONFIG_NFS_V4_1 */ | 1301 | #endif /* CONFIG_NFS_V4_1 */ |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 07919e16be3e..d265aa700bb3 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -66,6 +66,13 @@ static void svc_sock_free(struct svc_xprt *); | |||
66 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, | 66 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, |
67 | struct net *, struct sockaddr *, | 67 | struct net *, struct sockaddr *, |
68 | int, int); | 68 | int, int); |
69 | #if defined(CONFIG_NFS_V4_1) | ||
70 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, | ||
71 | struct net *, struct sockaddr *, | ||
72 | int, int); | ||
73 | static void svc_bc_sock_free(struct svc_xprt *xprt); | ||
74 | #endif /* CONFIG_NFS_V4_1 */ | ||
75 | |||
69 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 76 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
70 | static struct lock_class_key svc_key[2]; | 77 | static struct lock_class_key svc_key[2]; |
71 | static struct lock_class_key svc_slock_key[2]; | 78 | static struct lock_class_key svc_slock_key[2]; |
@@ -1184,6 +1191,57 @@ static struct svc_xprt *svc_tcp_create(struct svc_serv *serv, | |||
1184 | return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags); | 1191 | return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags); |
1185 | } | 1192 | } |
1186 | 1193 | ||
1194 | #if defined(CONFIG_NFS_V4_1) | ||
1195 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, | ||
1196 | struct net *, struct sockaddr *, | ||
1197 | int, int); | ||
1198 | static void svc_bc_sock_free(struct svc_xprt *xprt); | ||
1199 | |||
1200 | static struct svc_xprt *svc_bc_tcp_create(struct svc_serv *serv, | ||
1201 | struct net *net, | ||
1202 | struct sockaddr *sa, int salen, | ||
1203 | int flags) | ||
1204 | { | ||
1205 | return svc_bc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags); | ||
1206 | } | ||
1207 | |||
1208 | static void svc_bc_tcp_sock_detach(struct svc_xprt *xprt) | ||
1209 | { | ||
1210 | } | ||
1211 | |||
1212 | static struct svc_xprt_ops svc_tcp_bc_ops = { | ||
1213 | .xpo_create = svc_bc_tcp_create, | ||
1214 | .xpo_detach = svc_bc_tcp_sock_detach, | ||
1215 | .xpo_free = svc_bc_sock_free, | ||
1216 | .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr, | ||
1217 | }; | ||
1218 | |||
1219 | static struct svc_xprt_class svc_tcp_bc_class = { | ||
1220 | .xcl_name = "tcp-bc", | ||
1221 | .xcl_owner = THIS_MODULE, | ||
1222 | .xcl_ops = &svc_tcp_bc_ops, | ||
1223 | .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP, | ||
1224 | }; | ||
1225 | |||
1226 | static void svc_init_bc_xprt_sock(void) | ||
1227 | { | ||
1228 | svc_reg_xprt_class(&svc_tcp_bc_class); | ||
1229 | } | ||
1230 | |||
1231 | static void svc_cleanup_bc_xprt_sock(void) | ||
1232 | { | ||
1233 | svc_unreg_xprt_class(&svc_tcp_bc_class); | ||
1234 | } | ||
1235 | #else /* CONFIG_NFS_V4_1 */ | ||
1236 | static void svc_init_bc_xprt_sock(void) | ||
1237 | { | ||
1238 | } | ||
1239 | |||
1240 | static void svc_cleanup_bc_xprt_sock(void) | ||
1241 | { | ||
1242 | } | ||
1243 | #endif /* CONFIG_NFS_V4_1 */ | ||
1244 | |||
1187 | static struct svc_xprt_ops svc_tcp_ops = { | 1245 | static struct svc_xprt_ops svc_tcp_ops = { |
1188 | .xpo_create = svc_tcp_create, | 1246 | .xpo_create = svc_tcp_create, |
1189 | .xpo_recvfrom = svc_tcp_recvfrom, | 1247 | .xpo_recvfrom = svc_tcp_recvfrom, |
@@ -1207,12 +1265,14 @@ void svc_init_xprt_sock(void) | |||
1207 | { | 1265 | { |
1208 | svc_reg_xprt_class(&svc_tcp_class); | 1266 | svc_reg_xprt_class(&svc_tcp_class); |
1209 | svc_reg_xprt_class(&svc_udp_class); | 1267 | svc_reg_xprt_class(&svc_udp_class); |
1268 | svc_init_bc_xprt_sock(); | ||
1210 | } | 1269 | } |
1211 | 1270 | ||
1212 | void svc_cleanup_xprt_sock(void) | 1271 | void svc_cleanup_xprt_sock(void) |
1213 | { | 1272 | { |
1214 | svc_unreg_xprt_class(&svc_tcp_class); | 1273 | svc_unreg_xprt_class(&svc_tcp_class); |
1215 | svc_unreg_xprt_class(&svc_udp_class); | 1274 | svc_unreg_xprt_class(&svc_udp_class); |
1275 | svc_cleanup_bc_xprt_sock(); | ||
1216 | } | 1276 | } |
1217 | 1277 | ||
1218 | static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) | 1278 | static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) |
@@ -1509,41 +1569,45 @@ static void svc_sock_free(struct svc_xprt *xprt) | |||
1509 | kfree(svsk); | 1569 | kfree(svsk); |
1510 | } | 1570 | } |
1511 | 1571 | ||
1572 | #if defined(CONFIG_NFS_V4_1) | ||
1512 | /* | 1573 | /* |
1513 | * Create a svc_xprt. | 1574 | * Create a back channel svc_xprt which shares the fore channel socket. |
1514 | * | ||
1515 | * For internal use only (e.g. nfsv4.1 backchannel). | ||
1516 | * Callers should typically use the xpo_create() method. | ||
1517 | */ | 1575 | */ |
1518 | struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot) | 1576 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv, |
1577 | int protocol, | ||
1578 | struct net *net, | ||
1579 | struct sockaddr *sin, int len, | ||
1580 | int flags) | ||
1519 | { | 1581 | { |
1520 | struct svc_sock *svsk; | 1582 | struct svc_sock *svsk; |
1521 | struct svc_xprt *xprt = NULL; | 1583 | struct svc_xprt *xprt; |
1584 | |||
1585 | if (protocol != IPPROTO_TCP) { | ||
1586 | printk(KERN_WARNING "svc: only TCP sockets" | ||
1587 | " supported on shared back channel\n"); | ||
1588 | return ERR_PTR(-EINVAL); | ||
1589 | } | ||
1522 | 1590 | ||
1523 | dprintk("svc: %s\n", __func__); | ||
1524 | svsk = kzalloc(sizeof(*svsk), GFP_KERNEL); | 1591 | svsk = kzalloc(sizeof(*svsk), GFP_KERNEL); |
1525 | if (!svsk) | 1592 | if (!svsk) |
1526 | goto out; | 1593 | return ERR_PTR(-ENOMEM); |
1527 | 1594 | ||
1528 | xprt = &svsk->sk_xprt; | 1595 | xprt = &svsk->sk_xprt; |
1529 | if (prot == IPPROTO_TCP) | 1596 | svc_xprt_init(&svc_tcp_bc_class, xprt, serv); |
1530 | svc_xprt_init(&svc_tcp_class, xprt, serv); | 1597 | |
1531 | else if (prot == IPPROTO_UDP) | 1598 | serv->sv_bc_xprt = xprt; |
1532 | svc_xprt_init(&svc_udp_class, xprt, serv); | 1599 | |
1533 | else | ||
1534 | BUG(); | ||
1535 | out: | ||
1536 | dprintk("svc: %s return %p\n", __func__, xprt); | ||
1537 | return xprt; | 1600 | return xprt; |
1538 | } | 1601 | } |
1539 | EXPORT_SYMBOL_GPL(svc_sock_create); | ||
1540 | 1602 | ||
1541 | /* | 1603 | /* |
1542 | * Destroy a svc_sock. | 1604 | * Free a back channel svc_sock. |
1543 | */ | 1605 | */ |
1544 | void svc_sock_destroy(struct svc_xprt *xprt) | 1606 | static void svc_bc_sock_free(struct svc_xprt *xprt) |
1545 | { | 1607 | { |
1546 | if (xprt) | 1608 | if (xprt) { |
1609 | kfree(xprt->xpt_bc_sid); | ||
1547 | kfree(container_of(xprt, struct svc_sock, sk_xprt)); | 1610 | kfree(container_of(xprt, struct svc_sock, sk_xprt)); |
1611 | } | ||
1548 | } | 1612 | } |
1549 | EXPORT_SYMBOL_GPL(svc_sock_destroy); | 1613 | #endif /* CONFIG_NFS_V4_1 */ |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index cd9e841e7492..679cd674b81d 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -552,6 +552,74 @@ void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int b | |||
552 | } | 552 | } |
553 | EXPORT_SYMBOL_GPL(xdr_write_pages); | 553 | EXPORT_SYMBOL_GPL(xdr_write_pages); |
554 | 554 | ||
555 | static void xdr_set_iov(struct xdr_stream *xdr, struct kvec *iov, | ||
556 | __be32 *p, unsigned int len) | ||
557 | { | ||
558 | if (len > iov->iov_len) | ||
559 | len = iov->iov_len; | ||
560 | if (p == NULL) | ||
561 | p = (__be32*)iov->iov_base; | ||
562 | xdr->p = p; | ||
563 | xdr->end = (__be32*)(iov->iov_base + len); | ||
564 | xdr->iov = iov; | ||
565 | xdr->page_ptr = NULL; | ||
566 | } | ||
567 | |||
568 | static int xdr_set_page_base(struct xdr_stream *xdr, | ||
569 | unsigned int base, unsigned int len) | ||
570 | { | ||
571 | unsigned int pgnr; | ||
572 | unsigned int maxlen; | ||
573 | unsigned int pgoff; | ||
574 | unsigned int pgend; | ||
575 | void *kaddr; | ||
576 | |||
577 | maxlen = xdr->buf->page_len; | ||
578 | if (base >= maxlen) | ||
579 | return -EINVAL; | ||
580 | maxlen -= base; | ||
581 | if (len > maxlen) | ||
582 | len = maxlen; | ||
583 | |||
584 | base += xdr->buf->page_base; | ||
585 | |||
586 | pgnr = base >> PAGE_SHIFT; | ||
587 | xdr->page_ptr = &xdr->buf->pages[pgnr]; | ||
588 | kaddr = page_address(*xdr->page_ptr); | ||
589 | |||
590 | pgoff = base & ~PAGE_MASK; | ||
591 | xdr->p = (__be32*)(kaddr + pgoff); | ||
592 | |||
593 | pgend = pgoff + len; | ||
594 | if (pgend > PAGE_SIZE) | ||
595 | pgend = PAGE_SIZE; | ||
596 | xdr->end = (__be32*)(kaddr + pgend); | ||
597 | xdr->iov = NULL; | ||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | static void xdr_set_next_page(struct xdr_stream *xdr) | ||
602 | { | ||
603 | unsigned int newbase; | ||
604 | |||
605 | newbase = (1 + xdr->page_ptr - xdr->buf->pages) << PAGE_SHIFT; | ||
606 | newbase -= xdr->buf->page_base; | ||
607 | |||
608 | if (xdr_set_page_base(xdr, newbase, PAGE_SIZE) < 0) | ||
609 | xdr_set_iov(xdr, xdr->buf->tail, NULL, xdr->buf->len); | ||
610 | } | ||
611 | |||
612 | static bool xdr_set_next_buffer(struct xdr_stream *xdr) | ||
613 | { | ||
614 | if (xdr->page_ptr != NULL) | ||
615 | xdr_set_next_page(xdr); | ||
616 | else if (xdr->iov == xdr->buf->head) { | ||
617 | if (xdr_set_page_base(xdr, 0, PAGE_SIZE) < 0) | ||
618 | xdr_set_iov(xdr, xdr->buf->tail, NULL, xdr->buf->len); | ||
619 | } | ||
620 | return xdr->p != xdr->end; | ||
621 | } | ||
622 | |||
555 | /** | 623 | /** |
556 | * xdr_init_decode - Initialize an xdr_stream for decoding data. | 624 | * xdr_init_decode - Initialize an xdr_stream for decoding data. |
557 | * @xdr: pointer to xdr_stream struct | 625 | * @xdr: pointer to xdr_stream struct |
@@ -560,41 +628,67 @@ EXPORT_SYMBOL_GPL(xdr_write_pages); | |||
560 | */ | 628 | */ |
561 | void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) | 629 | void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) |
562 | { | 630 | { |
563 | struct kvec *iov = buf->head; | ||
564 | unsigned int len = iov->iov_len; | ||
565 | |||
566 | if (len > buf->len) | ||
567 | len = buf->len; | ||
568 | xdr->buf = buf; | 631 | xdr->buf = buf; |
569 | xdr->iov = iov; | 632 | xdr->scratch.iov_base = NULL; |
570 | xdr->p = p; | 633 | xdr->scratch.iov_len = 0; |
571 | xdr->end = (__be32 *)((char *)iov->iov_base + len); | 634 | if (buf->head[0].iov_len != 0) |
635 | xdr_set_iov(xdr, buf->head, p, buf->len); | ||
636 | else if (buf->page_len != 0) | ||
637 | xdr_set_page_base(xdr, 0, buf->len); | ||
572 | } | 638 | } |
573 | EXPORT_SYMBOL_GPL(xdr_init_decode); | 639 | EXPORT_SYMBOL_GPL(xdr_init_decode); |
574 | 640 | ||
575 | /** | 641 | static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) |
576 | * xdr_inline_peek - Allow read-ahead in the XDR data stream | ||
577 | * @xdr: pointer to xdr_stream struct | ||
578 | * @nbytes: number of bytes of data to decode | ||
579 | * | ||
580 | * Check if the input buffer is long enough to enable us to decode | ||
581 | * 'nbytes' more bytes of data starting at the current position. | ||
582 | * If so return the current pointer without updating the current | ||
583 | * pointer position. | ||
584 | */ | ||
585 | __be32 * xdr_inline_peek(struct xdr_stream *xdr, size_t nbytes) | ||
586 | { | 642 | { |
587 | __be32 *p = xdr->p; | 643 | __be32 *p = xdr->p; |
588 | __be32 *q = p + XDR_QUADLEN(nbytes); | 644 | __be32 *q = p + XDR_QUADLEN(nbytes); |
589 | 645 | ||
590 | if (unlikely(q > xdr->end || q < p)) | 646 | if (unlikely(q > xdr->end || q < p)) |
591 | return NULL; | 647 | return NULL; |
648 | xdr->p = q; | ||
592 | return p; | 649 | return p; |
593 | } | 650 | } |
594 | EXPORT_SYMBOL_GPL(xdr_inline_peek); | ||
595 | 651 | ||
596 | /** | 652 | /** |
597 | * xdr_inline_decode - Retrieve non-page XDR data to decode | 653 | * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data. |
654 | * @xdr: pointer to xdr_stream struct | ||
655 | * @buf: pointer to an empty buffer | ||
656 | * @buflen: size of 'buf' | ||
657 | * | ||
658 | * The scratch buffer is used when decoding from an array of pages. | ||
659 | * If an xdr_inline_decode() call spans across page boundaries, then | ||
660 | * we copy the data into the scratch buffer in order to allow linear | ||
661 | * access. | ||
662 | */ | ||
663 | void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen) | ||
664 | { | ||
665 | xdr->scratch.iov_base = buf; | ||
666 | xdr->scratch.iov_len = buflen; | ||
667 | } | ||
668 | EXPORT_SYMBOL_GPL(xdr_set_scratch_buffer); | ||
669 | |||
670 | static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes) | ||
671 | { | ||
672 | __be32 *p; | ||
673 | void *cpdest = xdr->scratch.iov_base; | ||
674 | size_t cplen = (char *)xdr->end - (char *)xdr->p; | ||
675 | |||
676 | if (nbytes > xdr->scratch.iov_len) | ||
677 | return NULL; | ||
678 | memcpy(cpdest, xdr->p, cplen); | ||
679 | cpdest += cplen; | ||
680 | nbytes -= cplen; | ||
681 | if (!xdr_set_next_buffer(xdr)) | ||
682 | return NULL; | ||
683 | p = __xdr_inline_decode(xdr, nbytes); | ||
684 | if (p == NULL) | ||
685 | return NULL; | ||
686 | memcpy(cpdest, p, nbytes); | ||
687 | return xdr->scratch.iov_base; | ||
688 | } | ||
689 | |||
690 | /** | ||
691 | * xdr_inline_decode - Retrieve XDR data to decode | ||
598 | * @xdr: pointer to xdr_stream struct | 692 | * @xdr: pointer to xdr_stream struct |
599 | * @nbytes: number of bytes of data to decode | 693 | * @nbytes: number of bytes of data to decode |
600 | * | 694 | * |
@@ -605,13 +699,16 @@ EXPORT_SYMBOL_GPL(xdr_inline_peek); | |||
605 | */ | 699 | */ |
606 | __be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) | 700 | __be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) |
607 | { | 701 | { |
608 | __be32 *p = xdr->p; | 702 | __be32 *p; |
609 | __be32 *q = p + XDR_QUADLEN(nbytes); | ||
610 | 703 | ||
611 | if (unlikely(q > xdr->end || q < p)) | 704 | if (nbytes == 0) |
705 | return xdr->p; | ||
706 | if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr)) | ||
612 | return NULL; | 707 | return NULL; |
613 | xdr->p = q; | 708 | p = __xdr_inline_decode(xdr, nbytes); |
614 | return p; | 709 | if (p != NULL) |
710 | return p; | ||
711 | return xdr_copy_to_scratch(xdr, nbytes); | ||
615 | } | 712 | } |
616 | EXPORT_SYMBOL_GPL(xdr_inline_decode); | 713 | EXPORT_SYMBOL_GPL(xdr_inline_decode); |
617 | 714 | ||
@@ -671,16 +768,12 @@ EXPORT_SYMBOL_GPL(xdr_read_pages); | |||
671 | */ | 768 | */ |
672 | void xdr_enter_page(struct xdr_stream *xdr, unsigned int len) | 769 | void xdr_enter_page(struct xdr_stream *xdr, unsigned int len) |
673 | { | 770 | { |
674 | char * kaddr = page_address(xdr->buf->pages[0]); | ||
675 | xdr_read_pages(xdr, len); | 771 | xdr_read_pages(xdr, len); |
676 | /* | 772 | /* |
677 | * Position current pointer at beginning of tail, and | 773 | * Position current pointer at beginning of tail, and |
678 | * set remaining message length. | 774 | * set remaining message length. |
679 | */ | 775 | */ |
680 | if (len > PAGE_CACHE_SIZE - xdr->buf->page_base) | 776 | xdr_set_page_base(xdr, 0, len); |
681 | len = PAGE_CACHE_SIZE - xdr->buf->page_base; | ||
682 | xdr->p = (__be32 *)(kaddr + xdr->buf->page_base); | ||
683 | xdr->end = (__be32 *)((char *)xdr->p + len); | ||
684 | } | 777 | } |
685 | EXPORT_SYMBOL_GPL(xdr_enter_page); | 778 | EXPORT_SYMBOL_GPL(xdr_enter_page); |
686 | 779 | ||