summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-21 00:11:10 +0100
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-21 00:11:10 +0100
commit7a1218a277c45cba1fb8d7089407a1769c645c43 (patch)
treec59634979c53606696993ef06297045015791d6e /net
parentSUNRPC: Fix memory barriers for req->rq_received (diff)
downloadlinux-7a1218a277c45cba1fb8d7089407a1769c645c43.tar.xz
linux-7a1218a277c45cba1fb8d7089407a1769c645c43.zip
SUNRPC: Ensure rpc_call_async() always calls tk_ops->rpc_release()
Currently this will not happen if we exit before rpc_new_task() was called. Also fix up rpc_run_task() to do the same (for consistency). Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/clnt.c10
-rw-r--r--net/sunrpc/sched.c5
2 files changed, 11 insertions, 4 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 6e71d6ace5a3..aa8965e9d307 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -495,15 +495,16 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
int status;
/* If this client is slain all further I/O fails */
+ status = -EIO;
if (clnt->cl_dead)
- return -EIO;
+ goto out_release;
flags |= RPC_TASK_ASYNC;
/* Create/initialize a new RPC task */
status = -ENOMEM;
if (!(task = rpc_new_task(clnt, flags, tk_ops, data)))
- goto out;
+ goto out_release;
/* Mask signals on GSS_AUTH upcalls */
rpc_task_sigmask(task, &oldset);
@@ -518,7 +519,10 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
rpc_release_task(task);
rpc_restore_sigmask(&oldset);
-out:
+ return status;
+out_release:
+ if (tk_ops->rpc_release != NULL)
+ tk_ops->rpc_release(data);
return status;
}
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index cd51b5468332..3fc13bea302d 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -921,8 +921,11 @@ struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
{
struct rpc_task *task;
task = rpc_new_task(clnt, flags, ops, data);
- if (task == NULL)
+ if (task == NULL) {
+ if (ops->rpc_release != NULL)
+ ops->rpc_release(data);
return ERR_PTR(-ENOMEM);
+ }
atomic_inc(&task->tk_count);
rpc_execute(task);
return task;