aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-05-07 11:47:01 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:47:42 -0400
commit4caf86c6928cfaca270327bc944f901c2e2a8f50 (patch)
tree6f6a1ecac1a4399c6597510f4076e19b1e30f10e /net/mac80211
parent5194ee82b4aafc35b32c96db11bdacea9bf548be (diff)
mac80211: Prepare mesh_table_grow to failing copy_node callback.
The mesh_path_node_copy() performs kmalloc() and thus - may fail (well, it does not now, but I'm fixing this right now). Its caller - the mesh_table_grow() - isn't prepared for such a trick yet. This preparation is just flush the new hash and make copy_node() return an int value. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/mesh.c15
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_pathtbl.c3
3 files changed, 16 insertions, 4 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 697ef67f96b6..ca81d0065eb8 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -349,7 +349,7 @@ struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
349{ 349{
350 struct mesh_table *newtbl; 350 struct mesh_table *newtbl;
351 struct hlist_head *oldhash; 351 struct hlist_head *oldhash;
352 struct hlist_node *p; 352 struct hlist_node *p, *q;
353 int err = 0; 353 int err = 0;
354 int i; 354 int i;
355 355
@@ -373,13 +373,24 @@ struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
373 oldhash = tbl->hash_buckets; 373 oldhash = tbl->hash_buckets;
374 for (i = 0; i <= tbl->hash_mask; i++) 374 for (i = 0; i <= tbl->hash_mask; i++)
375 hlist_for_each(p, &oldhash[i]) 375 hlist_for_each(p, &oldhash[i])
376 tbl->copy_node(p, newtbl); 376 if (tbl->copy_node(p, newtbl) < 0)
377 goto errcopy;
377 378
378endgrow: 379endgrow:
379 if (err) 380 if (err)
380 return NULL; 381 return NULL;
381 else 382 else
382 return newtbl; 383 return newtbl;
384
385errcopy:
386 for (i = 0; i <= newtbl->hash_mask; i++) {
387 hlist_for_each_safe(p, q, &newtbl->hash_buckets[i])
388 tbl->free_node(p, 0);
389 }
390 kfree(newtbl->hash_buckets);
391 kfree(newtbl->hashwlock);
392 kfree(newtbl);
393 return NULL;
383} 394}
384 395
385/** 396/**
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 2e161f6d8288..669eafafe497 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -109,7 +109,7 @@ struct mesh_table {
109 __u32 hash_rnd; /* Used for hash generation */ 109 __u32 hash_rnd; /* Used for hash generation */
110 atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ 110 atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */
111 void (*free_node) (struct hlist_node *p, bool free_leafs); 111 void (*free_node) (struct hlist_node *p, bool free_leafs);
112 void (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); 112 int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
113 int size_order; 113 int size_order;
114 int mean_chain_len; 114 int mean_chain_len;
115}; 115};
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 0b6c4bfe3e78..512bfa112c6a 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -463,7 +463,7 @@ static void mesh_path_node_free(struct hlist_node *p, bool free_leafs)
463 kfree(node); 463 kfree(node);
464} 464}
465 465
466static void mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl) 466static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl)
467{ 467{
468 struct mesh_path *mpath; 468 struct mesh_path *mpath;
469 struct mpath_node *node, *new_node; 469 struct mpath_node *node, *new_node;
@@ -476,6 +476,7 @@ static void mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl)
476 hash_idx = mesh_table_hash(mpath->dst, mpath->dev, newtbl); 476 hash_idx = mesh_table_hash(mpath->dst, mpath->dev, newtbl);
477 hlist_add_head(&new_node->list, 477 hlist_add_head(&new_node->list,
478 &newtbl->hash_buckets[hash_idx]); 478 &newtbl->hash_buckets[hash_idx]);
479 return 0;
479} 480}
480 481
481int mesh_pathtbl_init(void) 482int mesh_pathtbl_init(void)