Commit c314fb5d authored by Ralf Bächle's avatar Ralf Bächle

Protect ax25_route_list by a spinlock.

parent 14971321
...@@ -9,4 +9,5 @@ af_ax25.c:ax25_connect: ...@@ -9,4 +9,5 @@ af_ax25.c:ax25_connect:
return sock_error(sk); /* Always set at this point */ return sock_error(sk); /* Always set at this point */
} }
Do the spinlocks ax25_list_lock and ax25_uid_lock really have to be interrupt safe? Do the spinlocks ax25_list_lock, ax25_uid_lock and ax25_route_lock really
have to be interrupt safe?
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <net/sock.h> #include <net/sock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -65,6 +66,7 @@ ...@@ -65,6 +66,7 @@
#include <linux/init.h> #include <linux/init.h>
static ax25_route *ax25_route_list; static ax25_route *ax25_route_list;
static spinlock_t ax25_route_lock = SPIN_LOCK_UNLOCKED;
static ax25_route *ax25_find_route(ax25_address *, struct net_device *); static ax25_route *ax25_find_route(ax25_address *, struct net_device *);
...@@ -86,8 +88,11 @@ static inline void ax25_route_invert(ax25_digi *in, ax25_digi *out) ...@@ -86,8 +88,11 @@ static inline void ax25_route_invert(ax25_digi *in, ax25_digi *out)
void ax25_rt_device_down(struct net_device *dev) void ax25_rt_device_down(struct net_device *dev)
{ {
ax25_route *s, *t, *ax25_rt = ax25_route_list; ax25_route *s, *t, *ax25_rt;
unsigned long flags;
spin_lock_irqsave(&ax25_route_lock, flags);
ax25_rt = ax25_route_list;
while (ax25_rt != NULL) { while (ax25_rt != NULL) {
s = ax25_rt; s = ax25_rt;
ax25_rt = ax25_rt->next; ax25_rt = ax25_rt->next;
...@@ -111,6 +116,7 @@ void ax25_rt_device_down(struct net_device *dev) ...@@ -111,6 +116,7 @@ void ax25_rt_device_down(struct net_device *dev)
} }
} }
} }
spin_unlock_irqrestore(&ax25_route_lock, flags);
} }
int ax25_rt_ioctl(unsigned int cmd, void *arg) int ax25_rt_ioctl(unsigned int cmd, void *arg)
...@@ -167,10 +173,11 @@ int ax25_rt_ioctl(unsigned int cmd, void *arg) ...@@ -167,10 +173,11 @@ int ax25_rt_ioctl(unsigned int cmd, void *arg)
ax25_rt->digipeat->calls[i] = route.digi_addr[i]; ax25_rt->digipeat->calls[i] = route.digi_addr[i];
} }
} }
save_flags(flags); cli(); spin_lock_irqsave(&ax25_route_lock, flags);
ax25_rt->next = ax25_route_list; ax25_rt->next = ax25_route_list;
ax25_route_list = ax25_rt; ax25_route_list = ax25_rt;
restore_flags(flags); spin_unlock_irqrestore(&ax25_route_lock, flags);
break; break;
case SIOCDELRT: case SIOCDELRT:
...@@ -239,13 +246,14 @@ int ax25_rt_ioctl(unsigned int cmd, void *arg) ...@@ -239,13 +246,14 @@ int ax25_rt_ioctl(unsigned int cmd, void *arg)
int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length) int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length)
{ {
ax25_route *ax25_rt; ax25_route *ax25_rt;
unsigned long flags;
int len = 0; int len = 0;
off_t pos = 0; off_t pos = 0;
off_t begin = 0; off_t begin = 0;
char *callsign; char *callsign;
int i; int i;
cli(); spin_lock_irqsave(&ax25_route_lock, flags);
len += sprintf(buffer, "callsign dev mode digipeaters\n"); len += sprintf(buffer, "callsign dev mode digipeaters\n");
...@@ -286,13 +294,13 @@ int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length) ...@@ -286,13 +294,13 @@ int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length)
if (pos > offset + length) if (pos > offset + length)
break; break;
} }
spin_unlock_irqrestore(&ax25_route_lock, flags);
sti();
*start = buffer + (offset - begin); *start = buffer + (offset - begin);
len -= (offset - begin); len -= (offset - begin);
if (len > length) len = length; if (len > length)
len = length;
return len; return len;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment