aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorGianluca Anzolin <gianluca@sottospazio.it>2013-07-29 11:08:09 -0400
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-08-21 10:47:06 -0400
commitebe937f74b8a72cf3ceeae5c2194a160bb092901 (patch)
treea5da8a08933923db90297ca5a02ed6d02606f593 /net/bluetooth
parent396dc223dd36edd218650d042a07c5e61f022c5b (diff)
Bluetooth: Remove the device from the list in the destructor
The current code removes the device from the device list in several places. Do it only in the destructor instead and in the error path of rfcomm_add_dev() if the device couldn't be initialized. Signed-off-by: Gianluca Anzolin <gianluca@sottospazio.it> Reviewed-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/rfcomm/tty.c27
1 files changed, 6 insertions, 21 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index cd7ff370be38..9c0e142041bd 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -76,13 +76,6 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
76 76
77/* ---- Device functions ---- */ 77/* ---- Device functions ---- */
78 78
79/*
80 * The reason this isn't actually a race, as you no doubt have a little voice
81 * screaming at you in your head, is that the refcount should never actually
82 * reach zero unless the device has already been taken off the list, in
83 * rfcomm_dev_del(). And if that's not true, we'll hit the BUG() in
84 * rfcomm_dev_destruct() anyway.
85 */
86static void rfcomm_dev_destruct(struct tty_port *port) 79static void rfcomm_dev_destruct(struct tty_port *port)
87{ 80{
88 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); 81 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
@@ -90,10 +83,9 @@ static void rfcomm_dev_destruct(struct tty_port *port)
90 83
91 BT_DBG("dev %p dlc %p", dev, dlc); 84 BT_DBG("dev %p dlc %p", dev, dlc);
92 85
93 /* Refcount should only hit zero when called from rfcomm_dev_del() 86 spin_lock(&rfcomm_dev_lock);
94 which will have taken us off the list. Everything else are 87 list_del(&dev->list);
95 refcounting bugs. */ 88 spin_unlock(&rfcomm_dev_lock);
96 BUG_ON(!list_empty(&dev->list));
97 89
98 rfcomm_dlc_lock(dlc); 90 rfcomm_dlc_lock(dlc);
99 /* Detach DLC if it's owned by this dev */ 91 /* Detach DLC if it's owned by this dev */
@@ -282,7 +274,9 @@ out:
282 dev->id, NULL); 274 dev->id, NULL);
283 if (IS_ERR(dev->tty_dev)) { 275 if (IS_ERR(dev->tty_dev)) {
284 err = PTR_ERR(dev->tty_dev); 276 err = PTR_ERR(dev->tty_dev);
277 spin_lock(&rfcomm_dev_lock);
285 list_del(&dev->list); 278 list_del(&dev->list);
279 spin_unlock(&rfcomm_dev_lock);
286 goto free; 280 goto free;
287 } 281 }
288 282
@@ -315,10 +309,6 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
315 } 309 }
316 spin_unlock_irqrestore(&dev->port.lock, flags); 310 spin_unlock_irqrestore(&dev->port.lock, flags);
317 311
318 spin_lock(&rfcomm_dev_lock);
319 list_del_init(&dev->list);
320 spin_unlock(&rfcomm_dev_lock);
321
322 tty_port_put(&dev->port); 312 tty_port_put(&dev->port);
323} 313}
324 314
@@ -750,13 +740,8 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
750 dev->port.tty = NULL; 740 dev->port.tty = NULL;
751 rfcomm_dlc_unlock(dev->dlc); 741 rfcomm_dlc_unlock(dev->dlc);
752 742
753 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) { 743 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
754 spin_lock(&rfcomm_dev_lock);
755 list_del_init(&dev->list);
756 spin_unlock(&rfcomm_dev_lock);
757
758 tty_port_put(&dev->port); 744 tty_port_put(&dev->port);
759 }
760 } else 745 } else
761 spin_unlock_irqrestore(&dev->port.lock, flags); 746 spin_unlock_irqrestore(&dev->port.lock, flags);
762 747