SUNRPC: Yet more RPC cleanups
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 3 Jan 2006 08:55:03 +0000 (09:55 +0100)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 6 Jan 2006 19:58:39 +0000 (14:58 -0500)
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
include/linux/sunrpc/sched.h
net/sunrpc/clnt.c
net/sunrpc/pmap_clnt.c
net/sunrpc/sched.c

index 4d77e90..4c4b2dc 100644 (file)
@@ -233,6 +233,7 @@ struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent);
 void           rpc_init_task(struct rpc_task *, struct rpc_clnt *,
                                        rpc_action exitfunc, int flags);
 void           rpc_release_task(struct rpc_task *);
+void           rpc_exit_task(struct rpc_task *);
 void           rpc_killall_tasks(struct rpc_clnt *);
 int            rpc_execute(struct rpc_task *);
 void           rpc_run_child(struct rpc_task *parent, struct rpc_task *child,
@@ -259,7 +260,7 @@ void                rpc_destroy_mempool(void);
 static inline void rpc_exit(struct rpc_task *task, int status)
 {
        task->tk_status = status;
-       task->tk_action = NULL;
+       task->tk_action = rpc_exit_task;
 }
 
 #ifdef RPC_DEBUG
index 61c3abe..6ab4cbd 100644 (file)
@@ -511,7 +511,7 @@ rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags)
        if (task->tk_status == 0)
                task->tk_action = call_start;
        else
-               task->tk_action = NULL;
+               task->tk_action = rpc_exit_task;
 }
 
 void
@@ -892,7 +892,7 @@ call_transmit(struct rpc_task *task)
        if (task->tk_status < 0)
                return;
        if (!task->tk_msg.rpc_proc->p_decode) {
-               task->tk_action = NULL;
+               task->tk_action = rpc_exit_task;
                rpc_wake_up_task(task);
        }
        return;
@@ -1039,13 +1039,14 @@ call_decode(struct rpc_task *task)
                                sizeof(req->rq_rcv_buf)) != 0);
 
        /* Verify the RPC header */
-       if (!(p = call_verify(task))) {
-               if (task->tk_action == NULL)
-                       return;
-               goto out_retry;
+       p = call_verify(task);
+       if (IS_ERR(p)) {
+               if (p == ERR_PTR(-EAGAIN))
+                       goto out_retry;
+               return;
        }
 
-       task->tk_action = NULL;
+       task->tk_action = rpc_exit_task;
 
        if (decode)
                task->tk_status = rpcauth_unwrap_resp(task, decode, req, p,
@@ -1138,7 +1139,7 @@ call_verify(struct rpc_task *task)
 
        if ((n = ntohl(*p++)) != RPC_REPLY) {
                printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n);
-               goto out_retry;
+               goto out_garbage;
        }
        if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
                if (--len < 0)
@@ -1168,7 +1169,7 @@ call_verify(struct rpc_task *task)
                                                        task->tk_pid);
                        rpcauth_invalcred(task);
                        task->tk_action = call_refresh;
-                       return NULL;
+                       goto out_retry;
                case RPC_AUTH_BADCRED:
                case RPC_AUTH_BADVERF:
                        /* possibly garbled cred/verf? */
@@ -1178,7 +1179,7 @@ call_verify(struct rpc_task *task)
                        dprintk("RPC: %4d call_verify: retry garbled creds\n",
                                                        task->tk_pid);
                        task->tk_action = call_bind;
-                       return NULL;
+                       goto out_retry;
                case RPC_AUTH_TOOWEAK:
                        printk(KERN_NOTICE "call_verify: server requires stronger "
                               "authentication.\n");
@@ -1193,7 +1194,7 @@ call_verify(struct rpc_task *task)
        }
        if (!(p = rpcauth_checkverf(task, p))) {
                printk(KERN_WARNING "call_verify: auth check failed\n");
-               goto out_retry;         /* bad verifier, retry */
+               goto out_garbage;               /* bad verifier, retry */
        }
        len = p - (u32 *)iov->iov_base - 1;
        if (len < 0)
@@ -1230,23 +1231,24 @@ call_verify(struct rpc_task *task)
                /* Also retry */
        }
 
-out_retry:
+out_garbage:
        task->tk_client->cl_stats->rpcgarbage++;
        if (task->tk_garb_retry) {
                task->tk_garb_retry--;
                dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid);
                task->tk_action = call_bind;
-               return NULL;
+out_retry:
+               return ERR_PTR(-EAGAIN);
        }
        printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__);
 out_eio:
        error = -EIO;
 out_err:
        rpc_exit(task, error);
-       return NULL;
+       return ERR_PTR(error);
 out_overflow:
        printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__);
-       goto out_retry;
+       goto out_garbage;
 }
 
 static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj)
index a398575..cad4568 100644 (file)
@@ -90,8 +90,7 @@ bailout:
        map->pm_binding = 0;
        rpc_wake_up(&map->pm_bindwait);
        spin_unlock(&pmap_lock);
-       task->tk_status = -EIO;
-       task->tk_action = NULL;
+       rpc_exit(task, -EIO);
 }
 
 #ifdef CONFIG_ROOT_NFS
@@ -138,11 +137,10 @@ pmap_getport_done(struct rpc_task *task)
                        task->tk_pid, task->tk_status, clnt->cl_port);
        if (task->tk_status < 0) {
                /* Make the calling task exit with an error */
-               task->tk_action = NULL;
+               task->tk_action = rpc_exit_task;
        } else if (clnt->cl_port == 0) {
                /* Program not registered */
-               task->tk_status = -EACCES;
-               task->tk_action = NULL;
+               rpc_exit(task, -EACCES);
        } else {
                /* byte-swap port number first */
                clnt->cl_port = htons(clnt->cl_port);
index 54e60a6..3fcf7b0 100644 (file)
@@ -555,28 +555,22 @@ __rpc_atrun(struct rpc_task *task)
 }
 
 /*
- * Helper that calls task->tk_exit if it exists and then returns
- * true if we should exit __rpc_execute.
+ * Helper that calls task->tk_exit if it exists
  */
-static inline int __rpc_do_exit(struct rpc_task *task)
+void rpc_exit_task(struct rpc_task *task)
 {
+       task->tk_action = NULL;
        if (task->tk_exit != NULL) {
-               lock_kernel();
                task->tk_exit(task);
-               unlock_kernel();
-               /* If tk_action is non-null, we should restart the call */
                if (task->tk_action != NULL) {
-                       if (!RPC_ASSASSINATED(task)) {
-                               /* Release RPC slot and buffer memory */
-                               xprt_release(task);
-                               rpc_free(task);
-                               return 0;
-                       }
-                       printk(KERN_ERR "RPC: dead task tried to walk away.\n");
+                       WARN_ON(RPC_ASSASSINATED(task));
+                       /* Always release the RPC slot and buffer memory */
+                       xprt_release(task);
+                       rpc_free(task);
                }
        }
-       return 1;
 }
+EXPORT_SYMBOL(rpc_exit_task);
 
 static int rpc_wait_bit_interruptible(void *word)
 {
@@ -631,12 +625,11 @@ static int __rpc_execute(struct rpc_task *task)
                 * by someone else.
                 */
                if (!RPC_IS_QUEUED(task)) {
-                       if (task->tk_action != NULL) {
-                               lock_kernel();
-                               task->tk_action(task);
-                               unlock_kernel();
-                       } else if (__rpc_do_exit(task))
+                       if (task->tk_action == NULL)
                                break;
+                       lock_kernel();
+                       task->tk_action(task);
+                       unlock_kernel();
                }
 
                /*