diff options
| -rw-r--r-- | net/sunrpc/clnt.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 9cf63e6339f4..67c955d8b21b 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -1812,6 +1812,24 @@ out: | |||
| 1812 | } | 1812 | } |
| 1813 | 1813 | ||
| 1814 | /* | 1814 | /* |
| 1815 | * Helpers to check if the task was already transmitted, and | ||
| 1816 | * to take action when that is the case. | ||
| 1817 | */ | ||
| 1818 | static bool | ||
| 1819 | rpc_task_transmitted(struct rpc_task *task) | ||
| 1820 | { | ||
| 1821 | return !test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate); | ||
| 1822 | } | ||
| 1823 | |||
| 1824 | static void | ||
| 1825 | rpc_task_handle_transmitted(struct rpc_task *task) | ||
| 1826 | { | ||
| 1827 | xprt_end_transmit(task); | ||
| 1828 | task->tk_action = call_transmit_status; | ||
| 1829 | call_transmit_status(task); | ||
| 1830 | } | ||
| 1831 | |||
| 1832 | /* | ||
| 1815 | * 4. Get the server port number if not yet set | 1833 | * 4. Get the server port number if not yet set |
| 1816 | */ | 1834 | */ |
| 1817 | static void | 1835 | static void |
| @@ -1819,6 +1837,11 @@ call_bind(struct rpc_task *task) | |||
| 1819 | { | 1837 | { |
| 1820 | struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; | 1838 | struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; |
| 1821 | 1839 | ||
| 1840 | if (rpc_task_transmitted(task)) { | ||
| 1841 | rpc_task_handle_transmitted(task); | ||
| 1842 | return; | ||
| 1843 | } | ||
| 1844 | |||
| 1822 | dprint_status(task); | 1845 | dprint_status(task); |
| 1823 | 1846 | ||
| 1824 | task->tk_action = call_connect; | 1847 | task->tk_action = call_connect; |
| @@ -1837,6 +1860,11 @@ call_bind_status(struct rpc_task *task) | |||
| 1837 | { | 1860 | { |
| 1838 | int status = -EIO; | 1861 | int status = -EIO; |
| 1839 | 1862 | ||
| 1863 | if (rpc_task_transmitted(task)) { | ||
| 1864 | rpc_task_handle_transmitted(task); | ||
| 1865 | return; | ||
| 1866 | } | ||
| 1867 | |||
| 1840 | if (task->tk_status >= 0) { | 1868 | if (task->tk_status >= 0) { |
| 1841 | dprint_status(task); | 1869 | dprint_status(task); |
| 1842 | task->tk_status = 0; | 1870 | task->tk_status = 0; |
| @@ -1916,6 +1944,11 @@ call_connect(struct rpc_task *task) | |||
| 1916 | { | 1944 | { |
| 1917 | struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; | 1945 | struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; |
| 1918 | 1946 | ||
| 1947 | if (rpc_task_transmitted(task)) { | ||
| 1948 | rpc_task_handle_transmitted(task); | ||
| 1949 | return; | ||
| 1950 | } | ||
| 1951 | |||
| 1919 | dprintk("RPC: %5u call_connect xprt %p %s connected\n", | 1952 | dprintk("RPC: %5u call_connect xprt %p %s connected\n", |
| 1920 | task->tk_pid, xprt, | 1953 | task->tk_pid, xprt, |
| 1921 | (xprt_connected(xprt) ? "is" : "is not")); | 1954 | (xprt_connected(xprt) ? "is" : "is not")); |
| @@ -1942,10 +1975,8 @@ call_connect_status(struct rpc_task *task) | |||
| 1942 | struct rpc_clnt *clnt = task->tk_client; | 1975 | struct rpc_clnt *clnt = task->tk_client; |
| 1943 | int status = task->tk_status; | 1976 | int status = task->tk_status; |
| 1944 | 1977 | ||
| 1945 | /* Check if the task was already transmitted */ | 1978 | if (rpc_task_transmitted(task)) { |
| 1946 | if (!test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) { | 1979 | rpc_task_handle_transmitted(task); |
| 1947 | xprt_end_transmit(task); | ||
| 1948 | task->tk_action = call_transmit_status; | ||
| 1949 | return; | 1980 | return; |
| 1950 | } | 1981 | } |
| 1951 | 1982 | ||
| @@ -2001,6 +2032,11 @@ out_retry: | |||
| 2001 | static void | 2032 | static void |
| 2002 | call_transmit(struct rpc_task *task) | 2033 | call_transmit(struct rpc_task *task) |
| 2003 | { | 2034 | { |
| 2035 | if (rpc_task_transmitted(task)) { | ||
| 2036 | rpc_task_handle_transmitted(task); | ||
| 2037 | return; | ||
| 2038 | } | ||
| 2039 | |||
| 2004 | dprint_status(task); | 2040 | dprint_status(task); |
| 2005 | 2041 | ||
| 2006 | task->tk_action = call_transmit_status; | 2042 | task->tk_action = call_transmit_status; |
