|
@@ -65,42 +65,37 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
|
|
__mesh_table_free(tbl);
|
|
__mesh_table_free(tbl);
|
|
}
|
|
}
|
|
|
|
|
|
-static struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
|
|
|
|
|
|
+static int mesh_table_grow(struct mesh_table *oldtbl,
|
|
|
|
+ struct mesh_table *newtbl)
|
|
{
|
|
{
|
|
- struct mesh_table *newtbl;
|
|
|
|
struct hlist_head *oldhash;
|
|
struct hlist_head *oldhash;
|
|
struct hlist_node *p, *q;
|
|
struct hlist_node *p, *q;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- if (atomic_read(&tbl->entries)
|
|
|
|
- < tbl->mean_chain_len * (tbl->hash_mask + 1))
|
|
|
|
- goto endgrow;
|
|
|
|
|
|
+ if (atomic_read(&oldtbl->entries)
|
|
|
|
+ < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1))
|
|
|
|
+ return -EAGAIN;
|
|
|
|
|
|
- newtbl = mesh_table_alloc(tbl->size_order + 1);
|
|
|
|
- if (!newtbl)
|
|
|
|
- goto endgrow;
|
|
|
|
|
|
|
|
- newtbl->free_node = tbl->free_node;
|
|
|
|
- newtbl->mean_chain_len = tbl->mean_chain_len;
|
|
|
|
- newtbl->copy_node = tbl->copy_node;
|
|
|
|
- atomic_set(&newtbl->entries, atomic_read(&tbl->entries));
|
|
|
|
|
|
+ newtbl->free_node = oldtbl->free_node;
|
|
|
|
+ newtbl->mean_chain_len = oldtbl->mean_chain_len;
|
|
|
|
+ newtbl->copy_node = oldtbl->copy_node;
|
|
|
|
+ atomic_set(&newtbl->entries, atomic_read(&oldtbl->entries));
|
|
|
|
|
|
- oldhash = tbl->hash_buckets;
|
|
|
|
- for (i = 0; i <= tbl->hash_mask; i++)
|
|
|
|
|
|
+ oldhash = oldtbl->hash_buckets;
|
|
|
|
+ for (i = 0; i <= oldtbl->hash_mask; i++)
|
|
hlist_for_each(p, &oldhash[i])
|
|
hlist_for_each(p, &oldhash[i])
|
|
- if (tbl->copy_node(p, newtbl) < 0)
|
|
|
|
|
|
+ if (oldtbl->copy_node(p, newtbl) < 0)
|
|
goto errcopy;
|
|
goto errcopy;
|
|
|
|
|
|
- return newtbl;
|
|
|
|
|
|
+ return 0;
|
|
|
|
|
|
errcopy:
|
|
errcopy:
|
|
for (i = 0; i <= newtbl->hash_mask; i++) {
|
|
for (i = 0; i <= newtbl->hash_mask; i++) {
|
|
hlist_for_each_safe(p, q, &newtbl->hash_buckets[i])
|
|
hlist_for_each_safe(p, q, &newtbl->hash_buckets[i])
|
|
- tbl->free_node(p, 0);
|
|
|
|
|
|
+ oldtbl->free_node(p, 0);
|
|
}
|
|
}
|
|
- __mesh_table_free(newtbl);
|
|
|
|
-endgrow:
|
|
|
|
- return NULL;
|
|
|
|
|
|
+ return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -334,10 +329,13 @@ void mesh_mpath_table_grow(void)
|
|
{
|
|
{
|
|
struct mesh_table *oldtbl, *newtbl;
|
|
struct mesh_table *oldtbl, *newtbl;
|
|
|
|
|
|
|
|
+ newtbl = mesh_table_alloc(mesh_paths->size_order + 1);
|
|
|
|
+ if (!newtbl)
|
|
|
|
+ return;
|
|
write_lock(&pathtbl_resize_lock);
|
|
write_lock(&pathtbl_resize_lock);
|
|
oldtbl = mesh_paths;
|
|
oldtbl = mesh_paths;
|
|
- newtbl = mesh_table_grow(mesh_paths);
|
|
|
|
- if (!newtbl) {
|
|
|
|
|
|
+ if (mesh_table_grow(mesh_paths, newtbl) < 0) {
|
|
|
|
+ __mesh_table_free(newtbl);
|
|
write_unlock(&pathtbl_resize_lock);
|
|
write_unlock(&pathtbl_resize_lock);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -352,10 +350,13 @@ void mesh_mpp_table_grow(void)
|
|
{
|
|
{
|
|
struct mesh_table *oldtbl, *newtbl;
|
|
struct mesh_table *oldtbl, *newtbl;
|
|
|
|
|
|
|
|
+ newtbl = mesh_table_alloc(mpp_paths->size_order + 1);
|
|
|
|
+ if (!newtbl)
|
|
|
|
+ return;
|
|
write_lock(&pathtbl_resize_lock);
|
|
write_lock(&pathtbl_resize_lock);
|
|
oldtbl = mpp_paths;
|
|
oldtbl = mpp_paths;
|
|
- newtbl = mesh_table_grow(mpp_paths);
|
|
|
|
- if (!newtbl) {
|
|
|
|
|
|
+ if (mesh_table_grow(mpp_paths, newtbl) < 0) {
|
|
|
|
+ __mesh_table_free(newtbl);
|
|
write_unlock(&pathtbl_resize_lock);
|
|
write_unlock(&pathtbl_resize_lock);
|
|
return;
|
|
return;
|
|
}
|
|
}
|