aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/clnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r--net/sunrpc/clnt.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 396cdbe249d1..d8fbee40a19c 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,38 @@ call_reserveresult(struct rpc_task *task)
747static void 745static void
748call_allocate(struct rpc_task *task) 746call_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 req->rq_buffer = xprt->ops->buf_alloc(task,
778 req->rq_callsize + req->rq_rcvsize);
779 if (req->rq_buffer != NULL)
765 return; 780 return;
766 781
767 dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid); 782 dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid);
@@ -788,6 +803,17 @@ rpc_task_force_reencode(struct rpc_task *task)
788 task->tk_rqstp->rq_snd_buf.len = 0; 803 task->tk_rqstp->rq_snd_buf.len = 0;
789} 804}
790 805
806static inline void
807rpc_xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)
808{
809 buf->head[0].iov_base = start;
810 buf->head[0].iov_len = len;
811 buf->tail[0].iov_len = 0;
812 buf->page_len = 0;
813 buf->len = 0;
814 buf->buflen = len;
815}
816
791/* 817/*
792 * 3. Encode arguments of an RPC call 818 * 3. Encode arguments of an RPC call
793 */ 819 */
@@ -795,28 +821,17 @@ static void
795call_encode(struct rpc_task *task) 821call_encode(struct rpc_task *task)
796{ 822{
797 struct rpc_rqst *req = task->tk_rqstp; 823 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; 824 kxdrproc_t encode;
802 __be32 *p; 825 __be32 *p;
803 826
804 dprint_status(task); 827 dprint_status(task);
805 828
806 /* Default buffer setup */ 829 rpc_xdr_buf_init(&req->rq_snd_buf,
807 bufsiz = req->rq_bufsize >> 1; 830 req->rq_buffer,
808 sndbuf->head[0].iov_base = (void *)req->rq_buffer; 831 req->rq_callsize);
809 sndbuf->head[0].iov_len = bufsiz; 832 rpc_xdr_buf_init(&req->rq_rcv_buf,
810 sndbuf->tail[0].iov_len = 0; 833 (char *)req->rq_buffer + req->rq_callsize,
811 sndbuf->page_len = 0; 834 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 835
821 /* Encode header and provided arguments */ 836 /* Encode header and provided arguments */
822 encode = task->tk_msg.rpc_proc->p_encode; 837 encode = task->tk_msg.rpc_proc->p_encode;
@@ -887,9 +902,11 @@ call_bind_status(struct rpc_task *task)
887 task->tk_pid); 902 task->tk_pid);
888 break; 903 break;
889 case -EPROTONOSUPPORT: 904 case -EPROTONOSUPPORT:
890 dprintk("RPC: %5u remote rpcbind version 2 unavailable\n", 905 dprintk("RPC: %5u remote rpcbind version unavailable, retrying\n",
891 task->tk_pid); 906 task->tk_pid);
892 break; 907 task->tk_status = 0;
908 task->tk_action = call_bind;
909 return;
893 default: 910 default:
894 dprintk("RPC: %5u unrecognized rpcbind error (%d)\n", 911 dprintk("RPC: %5u unrecognized rpcbind error (%d)\n",
895 task->tk_pid, -task->tk_status); 912 task->tk_pid, -task->tk_status);