]> err.no Git - linux-2.6/blobdiff - net/sunrpc/clnt.c
Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville...
[linux-2.6] / net / sunrpc / clnt.c
index 9f775302d1dff946969f366ca74f39416c703d35..aa8965e9d30770cec269d1dfe6cd0bccb490dfa1 100644 (file)
@@ -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;
 }
 
@@ -1069,6 +1073,11 @@ call_decode(struct rpc_task *task)
                return;
        }
 
+       /*
+        * Ensure that we see all writes made by xprt_complete_rqst()
+        * before it changed req->rq_received.
+        */
+       smp_rmb();
        req->rq_rcv_buf.len = req->rq_private_buf.len;
 
        /* Check that the softirq receive buffer is valid */