diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 62 |
1 files changed, 38 insertions, 24 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 396cdbe249d1..12487aafaab5 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -36,8 +36,6 @@ | |||
36 | #include <linux/sunrpc/metrics.h> | 36 | #include <linux/sunrpc/metrics.h> |
37 | 37 | ||
38 | 38 | ||
39 | #define RPC_SLACK_SPACE (1024) /* total overkill */ | ||
40 | |||
41 | #ifdef RPC_DEBUG | 39 | #ifdef RPC_DEBUG |
42 | # define RPCDBG_FACILITY RPCDBG_CALL | 40 | # define RPCDBG_FACILITY RPCDBG_CALL |
43 | #endif | 41 | #endif |
@@ -747,21 +745,37 @@ call_reserveresult(struct rpc_task *task) | |||
747 | static void | 745 | static void |
748 | call_allocate(struct rpc_task *task) | 746 | call_allocate(struct rpc_task *task) |
749 | { | 747 | { |
748 | unsigned int slack = task->tk_auth->au_cslack; | ||
750 | struct rpc_rqst *req = task->tk_rqstp; | 749 | struct rpc_rqst *req = task->tk_rqstp; |
751 | struct rpc_xprt *xprt = task->tk_xprt; | 750 | struct rpc_xprt *xprt = task->tk_xprt; |
752 | unsigned int bufsiz; | 751 | struct rpc_procinfo *proc = task->tk_msg.rpc_proc; |
753 | 752 | ||
754 | dprint_status(task); | 753 | dprint_status(task); |
755 | 754 | ||
755 | task->tk_status = 0; | ||
756 | task->tk_action = call_bind; | 756 | task->tk_action = call_bind; |
757 | |||
757 | if (req->rq_buffer) | 758 | if (req->rq_buffer) |
758 | return; | 759 | return; |
759 | 760 | ||
760 | /* FIXME: compute buffer requirements more exactly using | 761 | if (proc->p_proc != 0) { |
761 | * auth->au_wslack */ | 762 | BUG_ON(proc->p_arglen == 0); |
762 | bufsiz = task->tk_msg.rpc_proc->p_bufsiz + RPC_SLACK_SPACE; | 763 | if (proc->p_decode != NULL) |
764 | BUG_ON(proc->p_replen == 0); | ||
765 | } | ||
763 | 766 | ||
764 | if (xprt->ops->buf_alloc(task, bufsiz << 1) != NULL) | 767 | /* |
768 | * Calculate the size (in quads) of the RPC call | ||
769 | * and reply headers, and convert both values | ||
770 | * to byte sizes. | ||
771 | */ | ||
772 | req->rq_callsize = RPC_CALLHDRSIZE + (slack << 1) + proc->p_arglen; | ||
773 | req->rq_callsize <<= 2; | ||
774 | req->rq_rcvsize = RPC_REPHDRSIZE + slack + proc->p_replen; | ||
775 | req->rq_rcvsize <<= 2; | ||
776 | |||
777 | xprt->ops->buf_alloc(task, req->rq_callsize + req->rq_rcvsize); | ||
778 | if (req->rq_buffer != NULL) | ||
765 | return; | 779 | return; |
766 | 780 | ||
767 | dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); | 781 | dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); |
@@ -788,6 +802,17 @@ rpc_task_force_reencode(struct rpc_task *task) | |||
788 | task->tk_rqstp->rq_snd_buf.len = 0; | 802 | task->tk_rqstp->rq_snd_buf.len = 0; |
789 | } | 803 | } |
790 | 804 | ||
805 | static inline void | ||
806 | rpc_xdr_buf_init(struct xdr_buf *buf, void *start, size_t len) | ||
807 | { | ||
808 | buf->head[0].iov_base = start; | ||
809 | buf->head[0].iov_len = len; | ||
810 | buf->tail[0].iov_len = 0; | ||
811 | buf->page_len = 0; | ||
812 | buf->len = 0; | ||
813 | buf->buflen = len; | ||
814 | } | ||
815 | |||
791 | /* | 816 | /* |
792 | * 3. Encode arguments of an RPC call | 817 | * 3. Encode arguments of an RPC call |
793 | */ | 818 | */ |
@@ -795,28 +820,17 @@ static void | |||
795 | call_encode(struct rpc_task *task) | 820 | call_encode(struct rpc_task *task) |
796 | { | 821 | { |
797 | struct rpc_rqst *req = task->tk_rqstp; | 822 | struct rpc_rqst *req = task->tk_rqstp; |
798 | struct xdr_buf *sndbuf = &req->rq_snd_buf; | ||
799 | struct xdr_buf *rcvbuf = &req->rq_rcv_buf; | ||
800 | unsigned int bufsiz; | ||
801 | kxdrproc_t encode; | 823 | kxdrproc_t encode; |
802 | __be32 *p; | 824 | __be32 *p; |
803 | 825 | ||
804 | dprint_status(task); | 826 | dprint_status(task); |
805 | 827 | ||
806 | /* Default buffer setup */ | 828 | rpc_xdr_buf_init(&req->rq_snd_buf, |
807 | bufsiz = req->rq_bufsize >> 1; | 829 | req->rq_buffer, |
808 | sndbuf->head[0].iov_base = (void *)req->rq_buffer; | 830 | req->rq_callsize); |
809 | sndbuf->head[0].iov_len = bufsiz; | 831 | rpc_xdr_buf_init(&req->rq_rcv_buf, |
810 | sndbuf->tail[0].iov_len = 0; | 832 | (char *)req->rq_buffer + req->rq_callsize, |
811 | sndbuf->page_len = 0; | 833 | req->rq_rcvsize); |
812 | sndbuf->len = 0; | ||
813 | sndbuf->buflen = bufsiz; | ||
814 | rcvbuf->head[0].iov_base = (void *)((char *)req->rq_buffer + bufsiz); | ||
815 | rcvbuf->head[0].iov_len = bufsiz; | ||
816 | rcvbuf->tail[0].iov_len = 0; | ||
817 | rcvbuf->page_len = 0; | ||
818 | rcvbuf->len = 0; | ||
819 | rcvbuf->buflen = bufsiz; | ||
820 | 834 | ||
821 | /* Encode header and provided arguments */ | 835 | /* Encode header and provided arguments */ |
822 | encode = task->tk_msg.rpc_proc->p_encode; | 836 | encode = task->tk_msg.rpc_proc->p_encode; |