[PATCH] uml: balance list_add and list_del in the network driver
The network driver added an interface to the "opened" list when it was configured, not when it was brought up, and removed it when it was taken down. A sequence of ifconfig up, ifconfig down, ... caused it to be removed multiple times from the list without being added in between, resulting in a crash. This patch moves the add to when the interface is brought up. Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
1d2ddcfb19
commit
14d9ead05e
1 changed files with 19 additions and 10 deletions
|
@ -131,9 +131,8 @@ static int uml_net_open(struct net_device *dev)
|
|||
SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
|
||||
if(err != 0){
|
||||
printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
|
||||
if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
|
||||
lp->fd = -1;
|
||||
err = -ENETUNREACH;
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
lp->tl.data = (unsigned long) &lp->user;
|
||||
|
@ -145,9 +144,19 @@ static int uml_net_open(struct net_device *dev)
|
|||
*/
|
||||
while((err = uml_net_rx(dev)) > 0) ;
|
||||
|
||||
out:
|
||||
spin_unlock(&lp->lock);
|
||||
return(err);
|
||||
|
||||
spin_lock(&opened_lock);
|
||||
list_add(&lp->list, &opened);
|
||||
spin_unlock(&opened_lock);
|
||||
|
||||
return 0;
|
||||
out_close:
|
||||
if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
|
||||
lp->fd = -1;
|
||||
out:
|
||||
spin_unlock(&lp->lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int uml_net_close(struct net_device *dev)
|
||||
|
@ -161,9 +170,13 @@ static int uml_net_close(struct net_device *dev)
|
|||
if(lp->close != NULL)
|
||||
(*lp->close)(lp->fd, &lp->user);
|
||||
lp->fd = -1;
|
||||
list_del(&lp->list);
|
||||
|
||||
spin_unlock(&lp->lock);
|
||||
|
||||
spin_lock(&opened_lock);
|
||||
list_del(&lp->list);
|
||||
spin_unlock(&opened_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -410,11 +423,7 @@ static int eth_configure(int n, void *init, char *mac,
|
|||
if (device->have_mac)
|
||||
set_ether_mac(dev, device->mac);
|
||||
|
||||
spin_lock(&opened_lock);
|
||||
list_add(&lp->list, &opened);
|
||||
spin_unlock(&opened_lock);
|
||||
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct uml_net *find_device(int n)
|
||||
|
|
Loading…
Reference in a new issue