]> err.no Git - linux-2.6/blobdiff - net/mac80211/mesh_pathtbl.c
[ARM] 5117/1: pxafb: fix __devinit/exit annotations
[linux-2.6] / net / mac80211 / mesh_pathtbl.c
index f74e4ce40ec74f45fa51041a6a0c2450d9d2cbaf..99c2d360888ef30cc7f0e8637b7aea9af0d474a4 100644 (file)
@@ -98,7 +98,7 @@ struct mesh_path *mesh_path_lookup(u8 *dst, struct net_device *dev)
 /**
  * mesh_path_lookup_by_idx - look up a path in the mesh path table by its index
  * @idx: index
- * @dev: local interface
+ * @dev: local interface, or NULL for all entries
  *
  * Returns: pointer to the mesh path structure, or NULL if not found.
  *
@@ -111,7 +111,9 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct net_device *dev)
        int i;
        int j = 0;
 
-       for_each_mesh_entry(mesh_paths, p, node, i)
+       for_each_mesh_entry(mesh_paths, p, node, i) {
+               if (dev && node->mpath->dev != dev)
+                       continue;
                if (j++ == idx) {
                        if (MPATH_EXPIRED(node->mpath)) {
                                spin_lock_bh(&node->mpath->state_lock);
@@ -121,6 +123,7 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct net_device *dev)
                        }
                        return node->mpath;
                }
+       }
 
        return NULL;
 }
@@ -155,19 +158,25 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
        if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0)
                return -ENOSPC;
 
-       read_lock(&pathtbl_resize_lock);
-
        new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL);
        if (!new_mpath) {
                atomic_dec(&sdata->u.sta.mpaths);
                err = -ENOMEM;
                goto endadd2;
        }
+       new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
+       if (!new_node) {
+               kfree(new_mpath);
+               atomic_dec(&sdata->u.sta.mpaths);
+               err = -ENOMEM;
+               goto endadd2;
+       }
+
+       read_lock(&pathtbl_resize_lock);
        memcpy(new_mpath->dst, dst, ETH_ALEN);
        new_mpath->dev = dev;
        new_mpath->flags = 0;
        skb_queue_head_init(&new_mpath->frame_queue);
-       new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
        new_node->mpath = new_mpath;
        new_mpath->timer.data = (unsigned long) new_mpath;
        new_mpath->timer.function = mesh_path_timer;
@@ -199,7 +208,6 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
 
 endadd:
        spin_unlock(&mesh_paths->hashwlock[hash_idx]);
-endadd2:
        read_unlock(&pathtbl_resize_lock);
        if (!err && grow) {
                struct mesh_table *oldtbl, *newtbl;
@@ -212,10 +220,12 @@ endadd2:
                        return -ENOMEM;
                }
                rcu_assign_pointer(mesh_paths, newtbl);
+               write_unlock(&pathtbl_resize_lock);
+
                synchronize_rcu();
                mesh_table_free(oldtbl, false);
-               write_unlock(&pathtbl_resize_lock);
        }
+endadd2:
        return err;
 }
 
@@ -261,9 +271,9 @@ EXPORT_SYMBOL(mesh_plink_broken);
  *
  * @sta - mesh peer to match
  *
- * RCU notes: this function is called when a mesh plink transitions from ESTAB
- * to any other state, since ESTAB state is the only one that allows path
- * creation. This will happen before the sta can be freed (because
+ * RCU notes: this function is called when a mesh plink transitions from
+ * PLINK_ESTAB to any other state, since PLINK_ESTAB state is the only one that
+ * allows path creation. This will happen before the sta can be freed (because
  * sta_info_destroy() calls this) so any reader in a rcu read block will be
  * protected against the plink disappearing.
  */