]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
SUNRPC: Add tracking of RPC level errors
authorTrond Myklebust <trondmy@gmail.com>
Sun, 7 Apr 2019 17:58:54 +0000 (13:58 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Thu, 25 Apr 2019 18:18:13 +0000 (14:18 -0400)
Add variables to track RPC level errors so that we can distinguish
between issue that arose in the RPC transport layer as opposed to
those arising from the reply message.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
include/linux/sunrpc/sched.h
net/sunrpc/clnt.c
net/sunrpc/xprtsock.c

index bf9d6ee7f00fff9a0f5d6f58ad01dc76bd0156f0..d0e451868f02b1d0288e9ce106e27c3d87c614e1 100644 (file)
@@ -61,6 +61,8 @@ struct rpc_task {
                struct rpc_wait         tk_wait;        /* RPC wait */
        } u;
 
+       int                     tk_rpc_status;  /* Result of last RPC operation */
+
        /*
         * RPC call state
         */
index b25f317d0ee213b56cd64e3664200213400e9537..315f9c9cb72de4588f43271b6e6aaf6f15c2880a 100644 (file)
@@ -1468,6 +1468,7 @@ static int
 __rpc_restart_call(struct rpc_task *task, void (*action)(struct rpc_task *))
 {
        task->tk_status = 0;
+       task->tk_rpc_status = 0;
        task->tk_action = action;
        return 1;
 }
@@ -1510,6 +1511,19 @@ const char
                return "no proc";
 }
 
+static void
+__rpc_call_rpcerror(struct rpc_task *task, int tk_status, int rpc_status)
+{
+       task->tk_rpc_status = rpc_status;
+       rpc_exit(task, tk_status);
+}
+
+static void
+rpc_call_rpcerror(struct rpc_task *task, int status)
+{
+       __rpc_call_rpcerror(task, status, status);
+}
+
 /*
  * 0.  Initial state
  *
@@ -1574,7 +1588,7 @@ call_reserveresult(struct rpc_task *task)
 
                printk(KERN_ERR "%s: status=%d, but no request slot, exiting\n",
                                __func__, status);
-               rpc_exit(task, -EIO);
+               rpc_call_rpcerror(task, -EIO);
                return;
        }
 
@@ -1602,7 +1616,7 @@ call_reserveresult(struct rpc_task *task)
                                __func__, status);
                break;
        }
-       rpc_exit(task, status);
+       rpc_call_rpcerror(task, status);
 }
 
 /*
@@ -1670,7 +1684,7 @@ call_refreshresult(struct rpc_task *task)
        }
        dprintk("RPC: %5u %s: refresh creds failed with error %d\n",
                                task->tk_pid, __func__, status);
-       rpc_exit(task, status);
+       rpc_call_rpcerror(task, status);
 }
 
 /*
@@ -1721,7 +1735,7 @@ call_allocate(struct rpc_task *task)
        if (status == 0)
                return;
        if (status != -ENOMEM) {
-               rpc_exit(task, status);
+               rpc_call_rpcerror(task, status);
                return;
        }
 
@@ -1790,7 +1804,7 @@ call_encode(struct rpc_task *task)
                        task->tk_action = call_refresh;
                        break;
                default:
-                       rpc_exit(task, task->tk_status);
+                       rpc_call_rpcerror(task, task->tk_status);
                }
                return;
        } else {
@@ -1931,7 +1945,7 @@ call_bind_status(struct rpc_task *task)
                                task->tk_pid, -task->tk_status);
        }
 
-       rpc_exit(task, status);
+       rpc_call_rpcerror(task, status);
        return;
 
 retry_timeout:
@@ -1966,7 +1980,7 @@ call_connect(struct rpc_task *task)
        if (task->tk_status < 0)
                return;
        if (task->tk_flags & RPC_TASK_NOCONNECT) {
-               rpc_exit(task, -ENOTCONN);
+               rpc_call_rpcerror(task, -ENOTCONN);
                return;
        }
        if (!xprt_prepare_transmit(task))
@@ -2026,7 +2040,7 @@ call_connect_status(struct rpc_task *task)
                task->tk_action = call_transmit;
                return;
        }
-       rpc_exit(task, status);
+       rpc_call_rpcerror(task, status);
        return;
 out_retry:
        /* Check for timeouts before looping back to call_bind */
@@ -2111,7 +2125,7 @@ call_transmit_status(struct rpc_task *task)
                        if (!task->tk_msg.rpc_proc->p_proc)
                                trace_xprt_ping(task->tk_xprt,
                                                task->tk_status);
-                       rpc_exit(task, task->tk_status);
+                       rpc_call_rpcerror(task, task->tk_status);
                        return;
                }
                /* fall through */
@@ -2275,7 +2289,7 @@ call_status(struct rpc_task *task)
        rpc_check_timeout(task);
        return;
 out_exit:
-       rpc_exit(task, status);
+       rpc_call_rpcerror(task, status);
 }
 
 static bool
@@ -2299,7 +2313,7 @@ rpc_check_timeout(struct rpc_task *task)
        task->tk_timeouts++;
 
        if (RPC_IS_SOFTCONN(task) && !rpc_check_connected(task->tk_rqstp)) {
-               rpc_exit(task, -ETIMEDOUT);
+               rpc_call_rpcerror(task, -ETIMEDOUT);
                return;
        }
 
@@ -2310,9 +2324,9 @@ rpc_check_timeout(struct rpc_task *task)
                                task->tk_xprt->servername);
                }
                if (task->tk_flags & RPC_TASK_TIMEOUT)
-                       rpc_exit(task, -ETIMEDOUT);
+                       rpc_call_rpcerror(task, -ETIMEDOUT);
                else
-                       rpc_exit(task, -EIO);
+                       __rpc_call_rpcerror(task, -EIO, -ETIMEDOUT);
                return;
        }
 
index b4b4b8db143cbec8d3049652fd66d30c09782af4..c69951ed2ebc184a83db59983e856fb333de5b96 100644 (file)
@@ -2017,6 +2017,7 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task)
                 * we'll need to figure out how to pass a namespace to
                 * connect.
                 */
+               task->tk_rpc_status = -ENOTCONN;
                rpc_exit(task, -ENOTCONN);
                return;
        }