diff options
author | Trond Myklebust <trondmy@gmail.com> | 2019-04-07 13:58:54 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2019-04-25 14:18:13 -0400 |
commit | 5ad64b36dda962797ce3ed579a27189ec7482d0d (patch) | |
tree | 2b178ebb06b16790c1fa688ba3971eee747e124d | |
parent | 9e910bff74be819aad751e82270682f3c405d199 (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.h | 2 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 40 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 1 |
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 | ||
1514 | static 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 | |||
1521 | static void | ||
1522 | rpc_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 | ||
1937 | retry_timeout: | 1951 | retry_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; |
2031 | out_retry: | 2045 | out_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; |
2277 | out_exit: | 2291 | out_exit: |
2278 | rpc_exit(task, status); | 2292 | rpc_call_rpcerror(task, status); |
2279 | } | 2293 | } |
2280 | 2294 | ||
2281 | static bool | 2295 | static 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 | } |