aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2019-04-07 13:58:54 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2019-04-25 14:18:13 -0400
commit5ad64b36dda962797ce3ed579a27189ec7482d0d (patch)
tree2b178ebb06b16790c1fa688ba3971eee747e124d
parent9e910bff74be819aad751e82270682f3c405d199 (diff)
SUNRPC: Add tracking of RPC level errors
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>
-rw-r--r--include/linux/sunrpc/sched.h2
-rw-r--r--net/sunrpc/clnt.c40
-rw-r--r--net/sunrpc/xprtsock.c1
3 files changed, 30 insertions, 13 deletions
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index bf9d6ee7f00f..d0e451868f02 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -61,6 +61,8 @@ struct rpc_task {
61 struct rpc_wait tk_wait; /* RPC wait */ 61 struct rpc_wait tk_wait; /* RPC wait */
62 } u; 62 } u;
63 63
64 int tk_rpc_status; /* Result of last RPC operation */
65
64 /* 66 /*
65 * RPC call state 67 * RPC call state
66 */ 68 */
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index b25f317d0ee2..315f9c9cb72d 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1468,6 +1468,7 @@ static int
1468__rpc_restart_call(struct rpc_task *task, void (*action)(struct rpc_task *)) 1468__rpc_restart_call(struct rpc_task *task, void (*action)(struct rpc_task *))
1469{ 1469{
1470 task->tk_status = 0; 1470 task->tk_status = 0;
1471 task->tk_rpc_status = 0;
1471 task->tk_action = action; 1472 task->tk_action = action;
1472 return 1; 1473 return 1;
1473} 1474}
@@ -1510,6 +1511,19 @@ const char
1510 return "no proc"; 1511 return "no proc";
1511} 1512}
1512 1513
1514static void
1515__rpc_call_rpcerror(struct rpc_task *task, int tk_status, int rpc_status)
1516{
1517 task->tk_rpc_status = rpc_status;
1518 rpc_exit(task, tk_status);
1519}
1520
1521static void
1522rpc_call_rpcerror(struct rpc_task *task, int status)
1523{
1524 __rpc_call_rpcerror(task, status, status);
1525}
1526
1513/* 1527/*
1514 * 0. Initial state 1528 * 0. Initial state
1515 * 1529 *
@@ -1574,7 +1588,7 @@ call_reserveresult(struct rpc_task *task)
1574 1588
1575 printk(KERN_ERR "%s: status=%d, but no request slot, exiting\n", 1589 printk(KERN_ERR "%s: status=%d, but no request slot, exiting\n",
1576 __func__, status); 1590 __func__, status);
1577 rpc_exit(task, -EIO); 1591 rpc_call_rpcerror(task, -EIO);
1578 return; 1592 return;
1579 } 1593 }
1580 1594
@@ -1602,7 +1616,7 @@ call_reserveresult(struct rpc_task *task)
1602 __func__, status); 1616 __func__, status);
1603 break; 1617 break;
1604 } 1618 }
1605 rpc_exit(task, status); 1619 rpc_call_rpcerror(task, status);
1606} 1620}
1607 1621
1608/* 1622/*
@@ -1670,7 +1684,7 @@ call_refreshresult(struct rpc_task *task)
1670 } 1684 }
1671 dprintk("RPC: %5u %s: refresh creds failed with error %d\n", 1685 dprintk("RPC: %5u %s: refresh creds failed with error %d\n",
1672 task->tk_pid, __func__, status); 1686 task->tk_pid, __func__, status);
1673 rpc_exit(task, status); 1687 rpc_call_rpcerror(task, status);
1674} 1688}
1675 1689
1676/* 1690/*
@@ -1721,7 +1735,7 @@ call_allocate(struct rpc_task *task)
1721 if (status == 0) 1735 if (status == 0)
1722 return; 1736 return;
1723 if (status != -ENOMEM) { 1737 if (status != -ENOMEM) {
1724 rpc_exit(task, status); 1738 rpc_call_rpcerror(task, status);
1725 return; 1739 return;
1726 } 1740 }
1727 1741
@@ -1790,7 +1804,7 @@ call_encode(struct rpc_task *task)
1790 task->tk_action = call_refresh; 1804 task->tk_action = call_refresh;
1791 break; 1805 break;
1792 default: 1806 default:
1793 rpc_exit(task, task->tk_status); 1807 rpc_call_rpcerror(task, task->tk_status);
1794 } 1808 }
1795 return; 1809 return;
1796 } else { 1810 } else {
@@ -1931,7 +1945,7 @@ call_bind_status(struct rpc_task *task)
1931 task->tk_pid, -task->tk_status); 1945 task->tk_pid, -task->tk_status);
1932 } 1946 }
1933 1947
1934 rpc_exit(task, status); 1948 rpc_call_rpcerror(task, status);
1935 return; 1949 return;
1936 1950
1937retry_timeout: 1951retry_timeout:
@@ -1966,7 +1980,7 @@ call_connect(struct rpc_task *task)
1966 if (task->tk_status < 0) 1980 if (task->tk_status < 0)
1967 return; 1981 return;
1968 if (task->tk_flags & RPC_TASK_NOCONNECT) { 1982 if (task->tk_flags & RPC_TASK_NOCONNECT) {
1969 rpc_exit(task, -ENOTCONN); 1983 rpc_call_rpcerror(task, -ENOTCONN);
1970 return; 1984 return;
1971 } 1985 }
1972 if (!xprt_prepare_transmit(task)) 1986 if (!xprt_prepare_transmit(task))
@@ -2026,7 +2040,7 @@ call_connect_status(struct rpc_task *task)
2026 task->tk_action = call_transmit; 2040 task->tk_action = call_transmit;
2027 return; 2041 return;
2028 } 2042 }
2029 rpc_exit(task, status); 2043 rpc_call_rpcerror(task, status);
2030 return; 2044 return;
2031out_retry: 2045out_retry:
2032 /* Check for timeouts before looping back to call_bind */ 2046 /* Check for timeouts before looping back to call_bind */
@@ -2111,7 +2125,7 @@ call_transmit_status(struct rpc_task *task)
2111 if (!task->tk_msg.rpc_proc->p_proc) 2125 if (!task->tk_msg.rpc_proc->p_proc)
2112 trace_xprt_ping(task->tk_xprt, 2126 trace_xprt_ping(task->tk_xprt,
2113 task->tk_status); 2127 task->tk_status);
2114 rpc_exit(task, task->tk_status); 2128 rpc_call_rpcerror(task, task->tk_status);
2115 return; 2129 return;
2116 } 2130 }
2117 /* fall through */ 2131 /* fall through */
@@ -2275,7 +2289,7 @@ call_status(struct rpc_task *task)
2275 rpc_check_timeout(task); 2289 rpc_check_timeout(task);
2276 return; 2290 return;
2277out_exit: 2291out_exit:
2278 rpc_exit(task, status); 2292 rpc_call_rpcerror(task, status);
2279} 2293}
2280 2294
2281static bool 2295static bool
@@ -2299,7 +2313,7 @@ rpc_check_timeout(struct rpc_task *task)
2299 task->tk_timeouts++; 2313 task->tk_timeouts++;
2300 2314
2301 if (RPC_IS_SOFTCONN(task) && !rpc_check_connected(task->tk_rqstp)) { 2315 if (RPC_IS_SOFTCONN(task) && !rpc_check_connected(task->tk_rqstp)) {
2302 rpc_exit(task, -ETIMEDOUT); 2316 rpc_call_rpcerror(task, -ETIMEDOUT);
2303 return; 2317 return;
2304 } 2318 }
2305 2319
@@ -2310,9 +2324,9 @@ rpc_check_timeout(struct rpc_task *task)
2310 task->tk_xprt->servername); 2324 task->tk_xprt->servername);
2311 } 2325 }
2312 if (task->tk_flags & RPC_TASK_TIMEOUT) 2326 if (task->tk_flags & RPC_TASK_TIMEOUT)
2313 rpc_exit(task, -ETIMEDOUT); 2327 rpc_call_rpcerror(task, -ETIMEDOUT);
2314 else 2328 else
2315 rpc_exit(task, -EIO); 2329 __rpc_call_rpcerror(task, -EIO, -ETIMEDOUT);
2316 return; 2330 return;
2317 } 2331 }
2318 2332
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index b4b4b8db143c..c69951ed2ebc 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2017,6 +2017,7 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task)
2017 * we'll need to figure out how to pass a namespace to 2017 * we'll need to figure out how to pass a namespace to
2018 * connect. 2018 * connect.
2019 */ 2019 */
2020 task->tk_rpc_status = -ENOTCONN;
2020 rpc_exit(task, -ENOTCONN); 2021 rpc_exit(task, -ENOTCONN);
2021 return; 2022 return;
2022 } 2023 }