forked from Minki/linux
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>
This commit is contained in:
parent
396dc223dd
commit
ebe937f74b
@ -76,13 +76,6 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
|
||||
|
||||
/* ---- Device functions ---- */
|
||||
|
||||
/*
|
||||
* The reason this isn't actually a race, as you no doubt have a little voice
|
||||
* screaming at you in your head, is that the refcount should never actually
|
||||
* reach zero unless the device has already been taken off the list, in
|
||||
* rfcomm_dev_del(). And if that's not true, we'll hit the BUG() in
|
||||
* rfcomm_dev_destruct() anyway.
|
||||
*/
|
||||
static void rfcomm_dev_destruct(struct tty_port *port)
|
||||
{
|
||||
struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
|
||||
@ -90,10 +83,9 @@ static void rfcomm_dev_destruct(struct tty_port *port)
|
||||
|
||||
BT_DBG("dev %p dlc %p", dev, dlc);
|
||||
|
||||
/* Refcount should only hit zero when called from rfcomm_dev_del()
|
||||
which will have taken us off the list. Everything else are
|
||||
refcounting bugs. */
|
||||
BUG_ON(!list_empty(&dev->list));
|
||||
spin_lock(&rfcomm_dev_lock);
|
||||
list_del(&dev->list);
|
||||
spin_unlock(&rfcomm_dev_lock);
|
||||
|
||||
rfcomm_dlc_lock(dlc);
|
||||
/* Detach DLC if it's owned by this dev */
|
||||
@ -282,7 +274,9 @@ out:
|
||||
dev->id, NULL);
|
||||
if (IS_ERR(dev->tty_dev)) {
|
||||
err = PTR_ERR(dev->tty_dev);
|
||||
spin_lock(&rfcomm_dev_lock);
|
||||
list_del(&dev->list);
|
||||
spin_unlock(&rfcomm_dev_lock);
|
||||
goto free;
|
||||
}
|
||||
|
||||
@ -315,10 +309,6 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->port.lock, flags);
|
||||
|
||||
spin_lock(&rfcomm_dev_lock);
|
||||
list_del_init(&dev->list);
|
||||
spin_unlock(&rfcomm_dev_lock);
|
||||
|
||||
tty_port_put(&dev->port);
|
||||
}
|
||||
|
||||
@ -750,13 +740,8 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
|
||||
dev->port.tty = NULL;
|
||||
rfcomm_dlc_unlock(dev->dlc);
|
||||
|
||||
if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) {
|
||||
spin_lock(&rfcomm_dev_lock);
|
||||
list_del_init(&dev->list);
|
||||
spin_unlock(&rfcomm_dev_lock);
|
||||
|
||||
if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
|
||||
tty_port_put(&dev->port);
|
||||
}
|
||||
} else
|
||||
spin_unlock_irqrestore(&dev->port.lock, flags);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user