Hi,
I found lines where a `sock' is released twice in dlm
unexpectedly.
See tcp_create_listen_sock() of gfs2-2.6-nmw/fs/dlm/lowcomms.c:
result = sock->ops->listen(sock, 5);
if (result < 0) {
log_print("Can't listen on port %d", dlm_config.ci_tcp_port);
sock_release(sock);
sock = NULL;
goto create_out;
}
When listen is failed, sock is released by calling sock_release.
This is ok. However, the sock still occupies con->sock.
See dlm_lowcomms_start() of the file:
if (dlm_config.ci_protocol == 0)
error = tcp_listen_for_all();
else
error = sctp_listen_for_all();
if (error)
goto fail_unlisten;
error = work_start();
if (error)
goto fail_unlisten;
return 0;
fail_unlisten:
con = nodeid2con(0,0);
if (con) {
close_connection(con, false);
kmem_cache_free(con_cache, con);
}
When tcp_listen_for_all returns an error, close_connection is
called. The failure of listen call causes tcp_listen_for_all returns
an error.
See close_connection:
static void close_connection(struct connection *con, bool and_other)
{
mutex_lock(&con->sock_mutex);
if (con->sock) {
sock_release(con->sock);
con->sock = NULL;
}
If con->sock is not NULL, sock_release is called again on con->sock.
Attached patch fixes this.
Signed-off-by: Masatake YAMATO <[EMAIL PROTECTED]>
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 637018c..9ff9c5c 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -994,6 +994,7 @@ static struct socket *tcp_create_listen_sock(struct
connection *con,
log_print("Can't listen on port %d", dlm_config.ci_tcp_port);
sock_release(sock);
sock = NULL;
+ con->sock = NULL;
goto create_out;
}