aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-18 17:20:11 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-18 17:20:11 -0400
commit5e5ce5be6f0161d2a069a4f8a1154fe639c5c02f (patch)
treefc6e0397c8e17dad5f3f038fb1b3526a114b5244
parentea635a517e350eb03ab5f01618417f31b82a9a4d (diff)
RPC: allow call_encode() to delay transmission of an RPC call.
Currently, call_encode will cause the entire RPC call to abort if it returns an error. This is unnecessarily rigid, and gets in the way of attempts to allow the NFSv4 layer to order RPC calls that carry sequence ids. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--include/linux/sunrpc/xprt.h1
-rw-r--r--net/sunrpc/clnt.c23
-rw-r--r--net/sunrpc/xprt.c8
3 files changed, 21 insertions, 11 deletions
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 99cad3ead81d..068e1fb0868b 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -211,6 +211,7 @@ int xprt_reserve_xprt(struct rpc_task *task);
211int xprt_reserve_xprt_cong(struct rpc_task *task); 211int xprt_reserve_xprt_cong(struct rpc_task *task);
212int xprt_prepare_transmit(struct rpc_task *task); 212int xprt_prepare_transmit(struct rpc_task *task);
213void xprt_transmit(struct rpc_task *task); 213void xprt_transmit(struct rpc_task *task);
214void xprt_abort_transmit(struct rpc_task *task);
214int xprt_adjust_timeout(struct rpc_rqst *req); 215int xprt_adjust_timeout(struct rpc_rqst *req);
215void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task); 216void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
216void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); 217void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index a5f7029b1daa..534274056329 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -678,13 +678,11 @@ call_allocate(struct rpc_task *task)
678static void 678static void
679call_encode(struct rpc_task *task) 679call_encode(struct rpc_task *task)
680{ 680{
681 struct rpc_clnt *clnt = task->tk_client;
682 struct rpc_rqst *req = task->tk_rqstp; 681 struct rpc_rqst *req = task->tk_rqstp;
683 struct xdr_buf *sndbuf = &req->rq_snd_buf; 682 struct xdr_buf *sndbuf = &req->rq_snd_buf;
684 struct xdr_buf *rcvbuf = &req->rq_rcv_buf; 683 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
685 unsigned int bufsiz; 684 unsigned int bufsiz;
686 kxdrproc_t encode; 685 kxdrproc_t encode;
687 int status;
688 u32 *p; 686 u32 *p;
689 687
690 dprintk("RPC: %4d call_encode (status %d)\n", 688 dprintk("RPC: %4d call_encode (status %d)\n",
@@ -712,12 +710,9 @@ call_encode(struct rpc_task *task)
712 rpc_exit(task, -EIO); 710 rpc_exit(task, -EIO);
713 return; 711 return;
714 } 712 }
715 if (encode && (status = rpcauth_wrap_req(task, encode, req, p, 713 if (encode != NULL)
716 task->tk_msg.rpc_argp)) < 0) { 714 task->tk_status = rpcauth_wrap_req(task, encode, req, p,
717 printk(KERN_WARNING "%s: can't encode arguments: %d\n", 715 task->tk_msg.rpc_argp);
718 clnt->cl_protname, -status);
719 rpc_exit(task, status);
720 }
721} 716}
722 717
723/* 718/*
@@ -865,10 +860,12 @@ call_transmit(struct rpc_task *task)
865 if (task->tk_status != 0) 860 if (task->tk_status != 0)
866 return; 861 return;
867 /* Encode here so that rpcsec_gss can use correct sequence number. */ 862 /* Encode here so that rpcsec_gss can use correct sequence number. */
868 if (!task->tk_rqstp->rq_bytes_sent) 863 if (task->tk_rqstp->rq_bytes_sent == 0) {
869 call_encode(task); 864 call_encode(task);
870 if (task->tk_status < 0) 865 /* Did the encode result in an error condition? */
871 return; 866 if (task->tk_status != 0)
867 goto out_nosend;
868 }
872 xprt_transmit(task); 869 xprt_transmit(task);
873 if (task->tk_status < 0) 870 if (task->tk_status < 0)
874 return; 871 return;
@@ -876,6 +873,10 @@ call_transmit(struct rpc_task *task)
876 task->tk_action = NULL; 873 task->tk_action = NULL;
877 rpc_wake_up_task(task); 874 rpc_wake_up_task(task);
878 } 875 }
876 return;
877out_nosend:
878 /* release socket write lock before attempting to handle error */
879 xprt_abort_transmit(task);
879} 880}
880 881
881/* 882/*
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 215be0d0ef6b..1ba55dc38b7a 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -709,6 +709,14 @@ out_unlock:
709 return err; 709 return err;
710} 710}
711 711
712void
713xprt_abort_transmit(struct rpc_task *task)
714{
715 struct rpc_xprt *xprt = task->tk_xprt;
716
717 xprt_release_write(xprt, task);
718}
719
712/** 720/**
713 * xprt_transmit - send an RPC request on a transport 721 * xprt_transmit - send an RPC request on a transport
714 * @task: controlling RPC task 722 * @task: controlling RPC task