Merge ../linux-2.6-watchdog-mm
[pandora-kernel.git] / net / netrom / nr_route.c
index b3b9097..8f88964 100644 (file)
@@ -87,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;
@@ -155,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);
@@ -405,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;
 
@@ -432,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);
@@ -725,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);
@@ -743,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);
 }
@@ -771,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 */
@@ -838,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;
 }