]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/sunrpc/clnt.c
SUNRPC: Use soft connects for autobinding over TCP
[mv-sheeva.git] / net / sunrpc / clnt.c
index 38829e20500bf787aa59189501aaf7ce323a113c..4b76ef9336c7abb420560f09327e4d6bd57edb66 100644 (file)
@@ -1060,7 +1060,7 @@ call_bind_status(struct rpc_task *task)
                goto retry_timeout;
        case -EPFNOSUPPORT:
                /* server doesn't support any rpcbind version we know of */
-               dprintk("RPC: %5u remote rpcbind service unavailable\n",
+               dprintk("RPC: %5u unrecognized remote rpcbind service\n",
                                task->tk_pid);
                break;
        case -EPROTONOSUPPORT:
@@ -1069,6 +1069,21 @@ call_bind_status(struct rpc_task *task)
                task->tk_status = 0;
                task->tk_action = call_bind;
                return;
+       case -ECONNREFUSED:             /* connection problems */
+       case -ECONNRESET:
+       case -ENOTCONN:
+       case -EHOSTDOWN:
+       case -EHOSTUNREACH:
+       case -ENETUNREACH:
+       case -EPIPE:
+               dprintk("RPC: %5u remote rpcbind unreachable: %d\n",
+                               task->tk_pid, task->tk_status);
+               if (!RPC_IS_SOFTCONN(task)) {
+                       rpc_delay(task, 5*HZ);
+                       goto retry_timeout;
+               }
+               status = task->tk_status;
+               break;
        default:
                dprintk("RPC: %5u unrecognized rpcbind error (%d)\n",
                                task->tk_pid, -task->tk_status);
@@ -1180,11 +1195,25 @@ static void
 call_transmit_status(struct rpc_task *task)
 {
        task->tk_action = call_status;
+
+       /*
+        * Common case: success.  Force the compiler to put this
+        * test first.
+        */
+       if (task->tk_status == 0) {
+               xprt_end_transmit(task);
+               rpc_task_force_reencode(task);
+               return;
+       }
+
        switch (task->tk_status) {
        case -EAGAIN:
                break;
        default:
+               dprint_status(task);
                xprt_end_transmit(task);
+               rpc_task_force_reencode(task);
+               break;
                /*
                 * Special cases: if we've been waiting on the
                 * socket's write_space() callback, or if the
@@ -1192,11 +1221,16 @@ call_transmit_status(struct rpc_task *task)
                 * then hold onto the transport lock.
                 */
        case -ECONNREFUSED:
-       case -ECONNRESET:
-       case -ENOTCONN:
        case -EHOSTDOWN:
        case -EHOSTUNREACH:
        case -ENETUNREACH:
+               if (RPC_IS_SOFTCONN(task)) {
+                       xprt_end_transmit(task);
+                       rpc_exit(task, task->tk_status);
+                       break;
+               }
+       case -ECONNRESET:
+       case -ENOTCONN:
        case -EPIPE:
                rpc_task_force_reencode(task);
        }