summaryrefslogtreecommitdiff
path: root/net/sunrpc
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-19 01:20:11 +0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-19 01:20:11 +0400
commit5e5ce5be6f0161d2a069a4f8a1154fe639c5c02f (patch)
treefc6e0397c8e17dad5f3f038fb1b3526a114b5244 /net/sunrpc
parentea635a517e350eb03ab5f01618417f31b82a9a4d (diff)
downloadlinux-5e5ce5be6f0161d2a069a4f8a1154fe639c5c02f.tar.xz
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>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/clnt.c23
-rw-r--r--net/sunrpc/xprt.c8
2 files changed, 20 insertions, 11 deletions
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)
static void
call_encode(struct rpc_task *task)
{
- struct rpc_clnt *clnt = task->tk_client;
struct rpc_rqst *req = task->tk_rqstp;
struct xdr_buf *sndbuf = &req->rq_snd_buf;
struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
unsigned int bufsiz;
kxdrproc_t encode;
- int status;
u32 *p;
dprintk("RPC: %4d call_encode (status %d)\n",
@@ -712,12 +710,9 @@ call_encode(struct rpc_task *task)
rpc_exit(task, -EIO);
return;
}
- if (encode && (status = rpcauth_wrap_req(task, encode, req, p,
- task->tk_msg.rpc_argp)) < 0) {
- printk(KERN_WARNING "%s: can't encode arguments: %d\n",
- clnt->cl_protname, -status);
- rpc_exit(task, status);
- }
+ if (encode != NULL)
+ task->tk_status = rpcauth_wrap_req(task, encode, req, p,
+ task->tk_msg.rpc_argp);
}
/*
@@ -865,10 +860,12 @@ call_transmit(struct rpc_task *task)
if (task->tk_status != 0)
return;
/* Encode here so that rpcsec_gss can use correct sequence number. */
- if (!task->tk_rqstp->rq_bytes_sent)
+ if (task->tk_rqstp->rq_bytes_sent == 0) {
call_encode(task);
- if (task->tk_status < 0)
- return;
+ /* Did the encode result in an error condition? */
+ if (task->tk_status != 0)
+ goto out_nosend;
+ }
xprt_transmit(task);
if (task->tk_status < 0)
return;
@@ -876,6 +873,10 @@ call_transmit(struct rpc_task *task)
task->tk_action = NULL;
rpc_wake_up_task(task);
}
+ return;
+out_nosend:
+ /* release socket write lock before attempting to handle error */
+ xprt_abort_transmit(task);
}
/*
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:
return err;
}
+void
+xprt_abort_transmit(struct rpc_task *task)
+{
+ struct rpc_xprt *xprt = task->tk_xprt;
+
+ xprt_release_write(xprt, task);
+}
+
/**
* xprt_transmit - send an RPC request on a transport
* @task: controlling RPC task