From: Olaf Kirch <okir@suse.de>
To: nfs@lists.sourceforge.net
Subject: 2.6.5-rc3 xprt_connect changes?
Date: Thu, 1 Apr 2004 16:47:40 +0200 [thread overview]
Message-ID: <20040401144740.GH20772@suse.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 1073 bytes --]
Hi,
I have a problem with the xprt_connect changes introduced
in 2.6.5-rc1. They break pmap_register, it always returns
with EIO now.
It seems the problem is this:
- xprt_connect puts the task on the pending queue
- xprt_socket_connect calls xprt_close, which in turn
calls xprt_disconnect, which wakes up all tasks on
the pending list with ENOTCONN
For transports with "soft" semantics (this includes the portmap client),
this will always cause it to fail with EIO.
For "hard" transports, it seems that after some delay (set in
xprt_connect_status) we come back to call_connect_status, which
notices the ENOTCONN status. It sets the function pointer to
call_connect. If xprt_connected() evaluates to true when we get
there (which is always the case for UDP, and which is true for
TCP igf the SYNACK has arrived in the meanwhile), the call to
xprt_connect() succeeds, and we can continue.
The attached, untested patch should hopefully fix this. I still need
to test this.
Olaf
--
Olaf Kirch | The Hardware Gods hate me.
okir@suse.de |
---------------+
[-- Attachment #2: sunrpc-xprt-connfix --]
[-- Type: text/plain, Size: 2757 bytes --]
--- linux-2.6.4/net/sunrpc/xprt.c.connfix 2004-04-01 15:57:50.000000000 +0200
+++ linux-2.6.4/net/sunrpc/xprt.c 2004-04-01 16:46:19.000000000 +0200
@@ -82,7 +82,7 @@
*/
static void xprt_request_init(struct rpc_task *, struct rpc_xprt *);
static inline void do_xprt_reserve(struct rpc_task *);
-static void xprt_disconnect(struct rpc_xprt *);
+static void xprt_disconnect(struct rpc_xprt *, int);
static void xprt_connect_status(struct rpc_task *task);
static struct rpc_xprt * xprt_setup(int proto, struct sockaddr_in *ap,
struct rpc_timeout *to);
@@ -387,7 +387,7 @@
* Close down a transport socket
*/
static void
-xprt_close(struct rpc_xprt *xprt)
+xprt_close(struct rpc_xprt *xprt, int reconnecting)
{
struct socket *sock;
struct sock *sk;
@@ -407,7 +407,7 @@
}
write_unlock_bh(&sk->sk_callback_lock);
- xprt_disconnect(xprt);
+ xprt_disconnect(xprt, reconnecting);
if (sock)
sock_release(sock);
@@ -418,7 +418,7 @@
{
struct rpc_xprt *xprt = (struct rpc_xprt *)args;
- xprt_close(xprt);
+ xprt_close(xprt, 0);
xprt_release_write(xprt, NULL);
}
@@ -426,12 +426,13 @@
* Mark a transport as disconnected
*/
static void
-xprt_disconnect(struct rpc_xprt *xprt)
+xprt_disconnect(struct rpc_xprt *xprt, int reconnecting)
{
dprintk("RPC: disconnected transport %p\n", xprt);
spin_lock_bh(&xprt->sock_lock);
xprt_clear_connected(xprt);
- rpc_wake_up_status(&xprt->pending, -ENOTCONN);
+ if (!reconnecting)
+ rpc_wake_up_status(&xprt->pending, -ENOTCONN);
spin_unlock_bh(&xprt->sock_lock);
}
@@ -471,8 +472,10 @@
/*
* Start by resetting any existing state
+ * Close any sockets, but sshhh: don't wake up the tasks
+ * on the pending queue.
*/
- xprt_close(xprt);
+ xprt_close(xprt, 1);
sock = xprt_create_socket(xprt, xprt->prot, xprt->resvport);
if (sock == NULL) {
/* couldn't create socket or bind to reserved port;
@@ -830,7 +833,7 @@
/* Sanity check of the record length */
if (xprt->tcp_reclen < 4) {
printk(KERN_ERR "RPC: Invalid TCP record fragment length\n");
- xprt_disconnect(xprt);
+ xprt_disconnect(xprt, 0);
}
dprintk("RPC: reading TCP record fragment of length %d\n",
xprt->tcp_reclen);
@@ -1046,7 +1049,7 @@
NIPQUAD(xprt->addr.sin_addr.s_addr),
xprt_connected(xprt)? "closed" : "refused");
}
- xprt_disconnect(xprt);
+ xprt_disconnect(xprt, 0);
break;
}
out:
@@ -1258,7 +1261,7 @@
return;
default:
if (xprt->stream)
- xprt_disconnect(xprt);
+ xprt_disconnect(xprt, 0);
}
xprt_release_write(xprt, task);
return;
@@ -1657,7 +1660,7 @@
{
dprintk("RPC: destroying transport %p\n", xprt);
xprt_shutdown(xprt);
- xprt_close(xprt);
+ xprt_close(xprt, 0);
kfree(xprt->slot);
kfree(xprt);
next reply other threads:[~2004-04-01 14:47 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-04-01 14:47 Olaf Kirch [this message]
2004-04-01 20:57 ` 2.6.5-rc3 xprt_connect changes? Trond Myklebust
2004-04-01 21:18 ` Trond Myklebust
2004-04-02 8:27 ` Olaf Kirch
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040401144740.GH20772@suse.de \
--to=okir@suse.de \
--cc=nfs@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.