diff options
Diffstat (limited to 'net/mac80211/mesh.c')
| -rw-r--r-- | net/mac80211/mesh.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 697ef67f96b6..b5933b271491 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
| @@ -315,6 +315,13 @@ struct mesh_table *mesh_table_alloc(int size_order) | |||
| 315 | return newtbl; | 315 | return newtbl; |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | static void __mesh_table_free(struct mesh_table *tbl) | ||
| 319 | { | ||
| 320 | kfree(tbl->hash_buckets); | ||
| 321 | kfree(tbl->hashwlock); | ||
| 322 | kfree(tbl); | ||
| 323 | } | ||
| 324 | |||
| 318 | void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | 325 | void mesh_table_free(struct mesh_table *tbl, bool free_leafs) |
| 319 | { | 326 | { |
| 320 | struct hlist_head *mesh_hash; | 327 | struct hlist_head *mesh_hash; |
| @@ -330,9 +337,7 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | |||
| 330 | } | 337 | } |
| 331 | spin_unlock(&tbl->hashwlock[i]); | 338 | spin_unlock(&tbl->hashwlock[i]); |
| 332 | } | 339 | } |
| 333 | kfree(tbl->hash_buckets); | 340 | __mesh_table_free(tbl); |
| 334 | kfree(tbl->hashwlock); | ||
| 335 | kfree(tbl); | ||
| 336 | } | 341 | } |
| 337 | 342 | ||
| 338 | static void ieee80211_mesh_path_timer(unsigned long data) | 343 | static void ieee80211_mesh_path_timer(unsigned long data) |
| @@ -349,21 +354,16 @@ struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | |||
| 349 | { | 354 | { |
| 350 | struct mesh_table *newtbl; | 355 | struct mesh_table *newtbl; |
| 351 | struct hlist_head *oldhash; | 356 | struct hlist_head *oldhash; |
| 352 | struct hlist_node *p; | 357 | struct hlist_node *p, *q; |
| 353 | int err = 0; | ||
| 354 | int i; | 358 | int i; |
| 355 | 359 | ||
| 356 | if (atomic_read(&tbl->entries) | 360 | if (atomic_read(&tbl->entries) |
| 357 | < tbl->mean_chain_len * (tbl->hash_mask + 1)) { | 361 | < tbl->mean_chain_len * (tbl->hash_mask + 1)) |
| 358 | err = -EPERM; | ||
| 359 | goto endgrow; | 362 | goto endgrow; |
| 360 | } | ||
| 361 | 363 | ||
| 362 | newtbl = mesh_table_alloc(tbl->size_order + 1); | 364 | newtbl = mesh_table_alloc(tbl->size_order + 1); |
| 363 | if (!newtbl) { | 365 | if (!newtbl) |
| 364 | err = -ENOMEM; | ||
| 365 | goto endgrow; | 366 | goto endgrow; |
| 366 | } | ||
| 367 | 367 | ||
| 368 | newtbl->free_node = tbl->free_node; | 368 | newtbl->free_node = tbl->free_node; |
| 369 | newtbl->mean_chain_len = tbl->mean_chain_len; | 369 | newtbl->mean_chain_len = tbl->mean_chain_len; |
| @@ -373,13 +373,19 @@ 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 | ||
| 379 | return newtbl; | ||
| 380 | |||
| 381 | errcopy: | ||
| 382 | for (i = 0; i <= newtbl->hash_mask; i++) { | ||
| 383 | hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) | ||
| 384 | tbl->free_node(p, 0); | ||
| 385 | } | ||
| 386 | __mesh_table_free(tbl); | ||
| 378 | endgrow: | 387 | endgrow: |
| 379 | if (err) | 388 | return NULL; |
| 380 | return NULL; | ||
| 381 | else | ||
| 382 | return newtbl; | ||
| 383 | } | 389 | } |
| 384 | 390 | ||
| 385 | /** | 391 | /** |
