diff options
| author | Dave Young <hidave.darkstar@gmail.com> | 2008-01-11 01:22:52 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2008-01-11 01:22:52 -0500 |
| commit | f951375d470c1a20d92c34377991197e6bf17990 (patch) | |
| tree | c479a1b80c14072a9486214f034078ab6f524471 /net/bluetooth | |
| parent | ecd2ebdea350c40e73c00d400d74c8a09c072082 (diff) | |
[BLUETOOTH]: rfcomm tty BUG_ON() code fix
1) In tty.c the BUG_ON at line 115 will never be called, because the the
before list_del_init in this same function.
115 BUG_ON(!list_empty(&dev->list));
So move the list_del_init to rfcomm_dev_del
2) The rfcomm_dev_del could be called from diffrent path
(rfcomm_tty_hangup/rfcomm_dev_state_change/rfcomm_release_dev),
So add another BUG_ON when the rfcomm_dev_del is called more than
one time.
Signed-off-by: Dave Young <hidave.darkstar@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bluetooth')
| -rw-r--r-- | net/bluetooth/rfcomm/tty.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index e447651a2dbe..a6a758dd1f7d 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
| @@ -95,9 +95,10 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev) | |||
| 95 | 95 | ||
| 96 | BT_DBG("dev %p dlc %p", dev, dlc); | 96 | BT_DBG("dev %p dlc %p", dev, dlc); |
| 97 | 97 | ||
| 98 | write_lock_bh(&rfcomm_dev_lock); | 98 | /* Refcount should only hit zero when called from rfcomm_dev_del() |
| 99 | list_del_init(&dev->list); | 99 | which will have taken us off the list. Everything else are |
| 100 | write_unlock_bh(&rfcomm_dev_lock); | 100 | refcounting bugs. */ |
| 101 | BUG_ON(!list_empty(&dev->list)); | ||
| 101 | 102 | ||
| 102 | rfcomm_dlc_lock(dlc); | 103 | rfcomm_dlc_lock(dlc); |
| 103 | /* Detach DLC if it's owned by this dev */ | 104 | /* Detach DLC if it's owned by this dev */ |
| @@ -109,11 +110,6 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev) | |||
| 109 | 110 | ||
| 110 | tty_unregister_device(rfcomm_tty_driver, dev->id); | 111 | tty_unregister_device(rfcomm_tty_driver, dev->id); |
| 111 | 112 | ||
| 112 | /* Refcount should only hit zero when called from rfcomm_dev_del() | ||
| 113 | which will have taken us off the list. Everything else are | ||
| 114 | refcounting bugs. */ | ||
| 115 | BUG_ON(!list_empty(&dev->list)); | ||
| 116 | |||
| 117 | kfree(dev); | 113 | kfree(dev); |
| 118 | 114 | ||
| 119 | /* It's safe to call module_put() here because socket still | 115 | /* It's safe to call module_put() here because socket still |
| @@ -313,7 +309,15 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev) | |||
| 313 | { | 309 | { |
| 314 | BT_DBG("dev %p", dev); | 310 | BT_DBG("dev %p", dev); |
| 315 | 311 | ||
| 316 | set_bit(RFCOMM_TTY_RELEASED, &dev->flags); | 312 | if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) |
| 313 | BUG_ON(1); | ||
| 314 | else | ||
| 315 | set_bit(RFCOMM_TTY_RELEASED, &dev->flags); | ||
| 316 | |||
| 317 | write_lock_bh(&rfcomm_dev_lock); | ||
| 318 | list_del_init(&dev->list); | ||
| 319 | write_unlock_bh(&rfcomm_dev_lock); | ||
| 320 | |||
| 317 | rfcomm_dev_put(dev); | 321 | rfcomm_dev_put(dev); |
| 318 | } | 322 | } |
| 319 | 323 | ||
