Bluetooth: cmtp: Fix module reference
authorDavid Herrmann <dh.herrmann@googlemail.com>
Sat, 19 Nov 2011 12:23:32 +0000 (13:23 +0100)
committerGustavo F. Padovan <padovan@profusion.mobi>
Mon, 21 Nov 2011 16:28:45 +0000 (14:28 -0200)
We cannot call module_put(THIS_MODULE) if this is our last reference. Otherwise,
this call may cleanup our module before it returns.

Gladly, the kthread API provides a simple wrapper for us. So lets use
module_put_and_exit() to avoid a race condition with the module cleanup code.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
net/bluetooth/cmtp/core.c

index 7d00ddf..5a6e634 100644 (file)
@@ -67,14 +67,12 @@ static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
 
 static void __cmtp_link_session(struct cmtp_session *session)
 {
-       __module_get(THIS_MODULE);
        list_add(&session->list, &cmtp_session_list);
 }
 
 static void __cmtp_unlink_session(struct cmtp_session *session)
 {
        list_del(&session->list);
-       module_put(THIS_MODULE);
 }
 
 static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
@@ -327,6 +325,7 @@ static int cmtp_session(void *arg)
        up_write(&cmtp_session_sem);
 
        kfree(session);
+       module_put_and_exit(0);
        return 0;
 }
 
@@ -376,9 +375,11 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
 
        __cmtp_link_session(session);
 
+       __module_get(THIS_MODULE);
        session->task = kthread_run(cmtp_session, session, "kcmtpd_ctr_%d",
                                                                session->num);
        if (IS_ERR(session->task)) {
+               module_put(THIS_MODULE);
                err = PTR_ERR(session->task);
                goto unlink;
        }