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

Reply via email to