Commit 0a496096 authored by Trond Myklebust's avatar Trond Myklebust

RPC: Fix a bug introduced by trond.myklebust@fys.uio.no|ChangeSet|20040314024328|33542.

  portmap can fail due to the call to xprt_close() in xprt_connect():
    xprt_disconnect() wakes up xprt->snd_task, and sets -ENOTCONN,
    which again gets converted to EIO by xprt_connect_status()

  Fix is to remove call to xprt_disconnect(). We don't need it in the
  case when we are reconnecting. However we do need to ensure that we
  wake up xprt->snd_task if reconnection fails.

  Diagnosis & proposed solution by Olaf Kirch
parent 4e2cf619
...@@ -405,7 +405,6 @@ xprt_close(struct rpc_xprt *xprt) ...@@ -405,7 +405,6 @@ xprt_close(struct rpc_xprt *xprt)
sk->sk_write_space = xprt->old_write_space; sk->sk_write_space = xprt->old_write_space;
write_unlock_bh(&sk->sk_callback_lock); write_unlock_bh(&sk->sk_callback_lock);
xprt_disconnect(xprt);
sk->sk_no_check = 0; sk->sk_no_check = 0;
sock_release(sock); sock_release(sock);
...@@ -416,6 +415,7 @@ xprt_socket_autoclose(void *args) ...@@ -416,6 +415,7 @@ xprt_socket_autoclose(void *args)
{ {
struct rpc_xprt *xprt = (struct rpc_xprt *)args; struct rpc_xprt *xprt = (struct rpc_xprt *)args;
xprt_disconnect(xprt);
xprt_close(xprt); xprt_close(xprt);
xprt_release_write(xprt, NULL); xprt_release_write(xprt, NULL);
} }
...@@ -511,7 +511,8 @@ static void xprt_socket_connect(void *args) ...@@ -511,7 +511,8 @@ static void xprt_socket_connect(void *args)
if (xprt->snd_task) { if (xprt->snd_task) {
xprt->snd_task->tk_status = status; xprt->snd_task->tk_status = status;
rpc_wake_up_task(xprt->snd_task); rpc_wake_up_task(xprt->snd_task);
} } else
rpc_wake_up_status(&xprt->pending, -ENOTCONN);
spin_unlock_bh(&xprt->sock_lock); spin_unlock_bh(&xprt->sock_lock);
} }
...@@ -1642,6 +1643,7 @@ xprt_destroy(struct rpc_xprt *xprt) ...@@ -1642,6 +1643,7 @@ xprt_destroy(struct rpc_xprt *xprt)
{ {
dprintk("RPC: destroying transport %p\n", xprt); dprintk("RPC: destroying transport %p\n", xprt);
xprt_shutdown(xprt); xprt_shutdown(xprt);
xprt_disconnect(xprt);
xprt_close(xprt); xprt_close(xprt);
kfree(xprt->slot); kfree(xprt->slot);
kfree(xprt); kfree(xprt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment