diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-05-07 17:47:01 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-22 03:47:42 +0200 |
commit | 4caf86c6928cfaca270327bc944f901c2e2a8f50 (patch) | |
tree | 6f6a1ecac1a4399c6597510f4076e19b1e30f10e /net/mac80211/mesh.c | |
parent | mac80211: Fix one more call to synchronize_rcu in atomic context. (diff) | |
download | linux-4caf86c6928cfaca270327bc944f901c2e2a8f50.tar.xz linux-4caf86c6928cfaca270327bc944f901c2e2a8f50.zip |
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/mesh.c')
-rw-r--r-- | net/mac80211/mesh.c | 15 |
1 files changed, 13 insertions, 2 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) { struct mesh_table *newtbl; struct hlist_head *oldhash; - struct hlist_node *p; + struct hlist_node *p, *q; int err = 0; int i; @@ -373,13 +373,24 @@ struct mesh_table *mesh_table_grow(struct mesh_table *tbl) oldhash = tbl->hash_buckets; for (i = 0; i <= tbl->hash_mask; i++) hlist_for_each(p, &oldhash[i]) - tbl->copy_node(p, newtbl); + if (tbl->copy_node(p, newtbl) < 0) + goto errcopy; endgrow: if (err) return NULL; else return newtbl; + +errcopy: + for (i = 0; i <= newtbl->hash_mask; i++) { + hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) + tbl->free_node(p, 0); + } + kfree(newtbl->hash_buckets); + kfree(newtbl->hashwlock); + kfree(newtbl); + return NULL; } /** |