]> git.neil.brown.name Git - history.git/commitdiff
[irda] LAP close race
authorJean Tourrilhes <jt@bougret.hpl.hp.com>
Fri, 5 Sep 2003 17:08:50 +0000 (13:08 -0400)
committerLinus Torvalds <torvalds@home.osdl.org>
Fri, 5 Sep 2003 17:08:50 +0000 (13:08 -0400)
o [CRITICA] Fix a race condition when closing the LAP
prevent the stack to open new LSAPs while we are killing them.

net/irda/irlap.c
net/irda/irlmp.c

index f662327dfb3df0de1842146e13c50a22ee479d43..99aeaa2df601c165c9f9130f2fa19da880802277 100644 (file)
@@ -221,8 +221,11 @@ void irlap_close(struct irlap_cb *self)
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == LAP_MAGIC, return;);
 
-       irlap_disconnect_indication(self, LAP_DISC_INDICATION);
+       /* We used to send a LAP_DISC_INDICATION here, but this was
+        * racy. This has been move within irlmp_unregister_link()
+        * itself. Jean II */
 
+       /* Kill the LAP and all LSAPs on top of it */
        irlmp_unregister_link(self->saddr);
        self->notify.instance = NULL;
 
index b6d41fc2772fb4db348f75502613f13ae4b7600e..f5866514a1cb318c4c418ea957d9f20ce8411c2f 100644 (file)
@@ -321,15 +321,23 @@ void irlmp_unregister_link(__u32 saddr)
 
        IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 
+       /* We must remove ourselves from the hashbin *first*. This ensure
+        * that no more LSAPs will be open on this link and no discovery
+        * will be triggered anymore. Jean II */
        link = hashbin_remove(irlmp->links, saddr, NULL);
        if (link) {
                ASSERT(link->magic == LMP_LAP_MAGIC, return;);
 
+               /* Kill all the LSAPs on this link. Jean II */
+               link->reason = LAP_DISC_INDICATION;
+               link->daddr = DEV_ADDR_ANY;
+               irlmp_do_lap_event(link, LM_LAP_DISCONNECT_INDICATION, NULL);
+
                /* Remove all discoveries discovered at this link */
                irlmp_expire_discoveries(irlmp->cachelog, link->saddr, TRUE);
 
+               /* Final cleanup */
                del_timer(&link->idle_timer);
-
                link->magic = 0;
                kfree(link);
        }