fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / net / netrom / nr_route.c
index dac2e36..8f88964 100644 (file)
 static unsigned int nr_neigh_no = 1;
 
 static HLIST_HEAD(nr_node_list);
-static spinlock_t nr_node_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nr_node_list_lock);
 static HLIST_HEAD(nr_neigh_list);
-static spinlock_t nr_neigh_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nr_neigh_list_lock);
 
-struct nr_node *nr_node_get(ax25_address *callsign)
+static struct nr_node *nr_node_get(ax25_address *callsign)
 {
        struct nr_node *found = NULL;
        struct nr_node *nr_node;
@@ -62,7 +62,8 @@ struct nr_node *nr_node_get(ax25_address *callsign)
        return found;
 }
 
-struct nr_neigh *nr_neigh_get_dev(ax25_address *callsign, struct net_device *dev)
+static struct nr_neigh *nr_neigh_get_dev(ax25_address *callsign,
+                                        struct net_device *dev)
 {
        struct nr_neigh *found = NULL;
        struct nr_neigh *nr_neigh;
@@ -86,8 +87,9 @@ static void nr_remove_neigh(struct nr_neigh *);
  *     Add a new route to a node, and in the process add the node and the
  *     neighbour if it is new.
  */
-static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax25,
-       ax25_digi *ax25_digi, struct net_device *dev, int quality, int obs_count)
+static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
+       ax25_address *ax25, ax25_digi *ax25_digi, struct net_device *dev,
+       int quality, int obs_count)
 {
        struct nr_node  *nr_node;
        struct nr_neigh *nr_neigh;
@@ -154,14 +156,15 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
                atomic_set(&nr_neigh->refcount, 1);
 
                if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
-                       if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) {
+                       nr_neigh->digipeat = kmemdup(ax25_digi,
+                                                    sizeof(*ax25_digi),
+                                                    GFP_KERNEL);
+                       if (nr_neigh->digipeat == NULL) {
                                kfree(nr_neigh);
                                if (nr_node)
                                        nr_node_put(nr_node);
                                return -ENOMEM;
                        }
-                       memcpy(nr_neigh->digipeat, ax25_digi,
-                                       sizeof(*ax25_digi));
                }
 
                spin_lock_bh(&nr_neigh_list_lock);
@@ -186,7 +189,7 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
                nr_node->which = 0;
                nr_node->count = 1;
                atomic_set(&nr_node->refcount, 1);
-               nr_node->node_lock = SPIN_LOCK_UNLOCKED;
+               spin_lock_init(&nr_node->node_lock);
 
                nr_node->routes[0].quality   = quality;
                nr_node->routes[0].obs_count = obs_count;
@@ -404,7 +407,8 @@ static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct n
 /*
  *     Lock a neighbour with a quality.
  */
-static int nr_add_neigh(ax25_address *callsign, ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
+static int __must_check nr_add_neigh(ax25_address *callsign,
+       ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
 {
        struct nr_neigh *nr_neigh;
 
@@ -431,11 +435,12 @@ static int nr_add_neigh(ax25_address *callsign, ax25_digi *ax25_digi, struct net
        atomic_set(&nr_neigh->refcount, 1);
 
        if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
-               if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) {
+               nr_neigh->digipeat = kmemdup(ax25_digi, sizeof(*ax25_digi),
+                                            GFP_KERNEL);
+               if (nr_neigh->digipeat == NULL) {
                        kfree(nr_neigh);
                        return -ENOMEM;
                }
-               memcpy(nr_neigh->digipeat, ax25_digi, sizeof(*ax25_digi));
        }
 
        spin_lock_bh(&nr_neigh_list_lock);
@@ -724,15 +729,17 @@ void nr_link_failed(ax25_cb *ax25, int reason)
        struct nr_node  *nr_node = NULL;
 
        spin_lock_bh(&nr_neigh_list_lock);
-       nr_neigh_for_each(s, node, &nr_neigh_list)
+       nr_neigh_for_each(s, node, &nr_neigh_list) {
                if (s->ax25 == ax25) {
                        nr_neigh_hold(s);
                        nr_neigh = s;
                        break;
                }
+       }
        spin_unlock_bh(&nr_neigh_list_lock);
 
-       if (nr_neigh == NULL) return;
+       if (nr_neigh == NULL)
+               return;
 
        nr_neigh->ax25 = NULL;
        ax25_cb_put(ax25);
@@ -742,11 +749,13 @@ void nr_link_failed(ax25_cb *ax25, int reason)
                return;
        }
        spin_lock_bh(&nr_node_list_lock);
-       nr_node_for_each(nr_node, node, &nr_node_list)
+       nr_node_for_each(nr_node, node, &nr_node_list) {
                nr_node_lock(nr_node);
-               if (nr_node->which < nr_node->count && nr_node->routes[nr_node->which].neighbour == nr_neigh)
+               if (nr_node->which < nr_node->count &&
+                   nr_node->routes[nr_node->which].neighbour == nr_neigh)
                        nr_node->which++;
                nr_node_unlock(nr_node);
+       }
        spin_unlock_bh(&nr_node_list_lock);
        nr_neigh_put(nr_neigh);
 }
@@ -770,9 +779,13 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
        nr_src  = (ax25_address *)(skb->data + 0);
        nr_dest = (ax25_address *)(skb->data + 7);
 
-       if (ax25 != NULL)
-               nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
-                           ax25->ax25_dev->dev, 0, sysctl_netrom_obsolescence_count_initialiser);
+       if (ax25 != NULL) {
+               ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
+                                 ax25->ax25_dev->dev, 0,
+                                 sysctl_netrom_obsolescence_count_initialiser);
+               if (ret)
+                       return ret;
+       }
 
        if ((dev = nr_dev_get(nr_dest)) != NULL) {      /* Its for me */
                if (ax25 == NULL)                       /* Its from me */
@@ -837,6 +850,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
        ret = (nr_neigh->ax25 != NULL);
        nr_node_unlock(nr_node);
        nr_node_put(nr_node);
+
        return ret;
 }
 
@@ -880,6 +894,7 @@ static void nr_node_stop(struct seq_file *seq, void *v)
 
 static int nr_node_show(struct seq_file *seq, void *v)
 {
+       char buf[11];
        int i;
 
        if (v == SEQ_START_TOKEN)
@@ -889,7 +904,7 @@ static int nr_node_show(struct seq_file *seq, void *v)
                struct nr_node *nr_node = v;
                nr_node_lock(nr_node);
                seq_printf(seq, "%-9s %-7s  %d %d",
-                       ax2asc(&nr_node->callsign),
+                       ax2asc(buf, &nr_node->callsign),
                        (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
                        nr_node->which + 1,
                        nr_node->count);
@@ -963,6 +978,7 @@ static void nr_neigh_stop(struct seq_file *seq, void *v)
 
 static int nr_neigh_show(struct seq_file *seq, void *v)
 {
+       char buf[11];
        int i;
 
        if (v == SEQ_START_TOKEN)
@@ -972,7 +988,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
 
                seq_printf(seq, "%05d %-9s %-4s  %3d    %d   %3d    %3d",
                        nr_neigh->number,
-                       ax2asc(&nr_neigh->callsign),
+                       ax2asc(buf, &nr_neigh->callsign),
                        nr_neigh->dev ? nr_neigh->dev->name : "???",
                        nr_neigh->quality,
                        nr_neigh->locked,
@@ -982,7 +998,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
                if (nr_neigh->digipeat != NULL) {
                        for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
                                seq_printf(seq, " %s", 
-                                          ax2asc(&nr_neigh->digipeat->calls[i]));
+                                          ax2asc(buf, &nr_neigh->digipeat->calls[i]));
                }
 
                seq_puts(seq, "\n");