[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] [PATCH] set NULL to sock field of connection if listen failed



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 <yamato redhat com>

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;
 	}
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]