diff options
-rw-r--r-- | net/bluetooth/rfcomm/tty.c | 27 |
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 | */ | ||
86 | static void rfcomm_dev_destruct(struct tty_port *port) | 79 | static 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 | ||