patch-2.4.22 linux-2.4.22/net/atm/addr.c
Next file: linux-2.4.22/net/atm/atm_misc.c
Previous file: linux-2.4.22/net/atm/Makefile
Back to the patch index
Back to the overall index
- Lines: 132
- Date:
2003-08-25 04:44:44.000000000 -0700
- Orig file:
linux-2.4.21/net/atm/addr.c
- Orig date:
2001-04-06 10:51:19.000000000 -0700
diff -urN linux-2.4.21/net/atm/addr.c linux-2.4.22/net/atm/addr.c
@@ -36,14 +36,6 @@
}
-/*
- * Avoid modification of any list of local interfaces while reading it
- * (which may involve page faults and therefore rescheduling)
- */
-
-static DECLARE_MUTEX(local_lock);
-extern spinlock_t atm_dev_lock;
-
static void notify_sigd(struct atm_dev *dev)
{
struct sockaddr_atmpvc pvc;
@@ -52,46 +44,46 @@
sigd_enq(NULL,as_itf_notify,NULL,&pvc,NULL);
}
-/*
- * This is called from atm_ioctl only. You must hold the lock as a caller
- */
void atm_reset_addr(struct atm_dev *dev)
{
+ unsigned long flags;
struct atm_dev_addr *this;
- down(&local_lock);
+ spin_lock_irqsave(&dev->lock, flags);
while (dev->local) {
this = dev->local;
dev->local = this->next;
kfree(this);
}
- up(&local_lock);
+ spin_unlock_irqrestore(&dev->lock, flags);
notify_sigd(dev);
}
int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
{
+ unsigned long flags;
struct atm_dev_addr **walk;
int error;
error = check_addr(addr);
- if (error) return error;
- down(&local_lock);
+ if (error)
+ return error;
+ spin_lock_irqsave(&dev->lock, flags);
for (walk = &dev->local; *walk; walk = &(*walk)->next)
if (identical(&(*walk)->addr,addr)) {
- up(&local_lock);
+ spin_unlock_irqrestore(&dev->lock, flags);
return -EEXIST;
}
- *walk = kmalloc(sizeof(struct atm_dev_addr),GFP_KERNEL);
+ *walk = kmalloc(sizeof(struct atm_dev_addr), GFP_ATOMIC);
if (!*walk) {
- up(&local_lock);
+ spin_unlock_irqrestore(&dev->lock, flags);
return -ENOMEM;
}
(*walk)->addr = *addr;
(*walk)->next = NULL;
- up(&local_lock);
+ spin_unlock_irqrestore(&dev->lock, flags);
notify_sigd(dev);
return 0;
}
@@ -99,22 +91,24 @@
int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
{
+ unsigned long flags;
struct atm_dev_addr **walk,*this;
int error;
error = check_addr(addr);
- if (error) return error;
- down(&local_lock);
+ if (error)
+ return error;
+ spin_lock_irqsave(&dev->lock, flags);
for (walk = &dev->local; *walk; walk = &(*walk)->next)
if (identical(&(*walk)->addr,addr)) break;
if (!*walk) {
- up(&local_lock);
+ spin_unlock_irqrestore(&dev->lock, flags);
return -ENOENT;
}
this = *walk;
*walk = this->next;
kfree(this);
- up(&local_lock);
+ spin_unlock_irqrestore(&dev->lock, flags);
notify_sigd(dev);
return 0;
}
@@ -122,24 +116,25 @@
int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size)
{
+ unsigned long flags;
struct atm_dev_addr *walk;
int total;
- down(&local_lock);
+ spin_lock_irqsave(&dev->lock, flags);
total = 0;
for (walk = dev->local; walk; walk = walk->next) {
total += sizeof(struct sockaddr_atmsvc);
if (total > size) {
- up(&local_lock);
+ spin_unlock_irqrestore(&dev->lock, flags);
return -E2BIG;
}
if (copy_to_user(u_buf,&walk->addr,
sizeof(struct sockaddr_atmsvc))) {
- up(&local_lock);
+ spin_unlock_irqrestore(&dev->lock, flags);
return -EFAULT;
}
u_buf++;
}
- up(&local_lock);
+ spin_unlock_irqrestore(&dev->lock, flags);
return total;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)