Merge branch 'pm-sysoff'
[linux-2.6-microblaze.git] / lib / assoc_array.c
index 079c72e..ca0b4f3 100644 (file)
@@ -1461,6 +1461,7 @@ int assoc_array_gc(struct assoc_array *array,
        struct assoc_array_ptr *cursor, *ptr;
        struct assoc_array_ptr *new_root, *new_parent, **new_ptr_pp;
        unsigned long nr_leaves_on_tree;
+       bool retained;
        int keylen, slot, nr_free, next_slot, i;
 
        pr_devel("-->%s()\n", __func__);
@@ -1536,6 +1537,7 @@ continue_node:
                goto descend;
        }
 
+retry_compress:
        pr_devel("-- compress node %p --\n", new_n);
 
        /* Count up the number of empty slots in this node and work out the
@@ -1553,6 +1555,7 @@ continue_node:
        pr_devel("free=%d, leaves=%lu\n", nr_free, new_n->nr_leaves_on_branch);
 
        /* See what we can fold in */
+       retained = false;
        next_slot = 0;
        for (slot = 0; slot < ASSOC_ARRAY_FAN_OUT; slot++) {
                struct assoc_array_shortcut *s;
@@ -1602,9 +1605,14 @@ continue_node:
                        pr_devel("[%d] retain node %lu/%d [nx %d]\n",
                                 slot, child->nr_leaves_on_branch, nr_free + 1,
                                 next_slot);
+                       retained = true;
                }
        }
 
+       if (retained && new_n->nr_leaves_on_branch <= ASSOC_ARRAY_FAN_OUT) {
+               pr_devel("internal nodes remain despite enough space, retrying\n");
+               goto retry_compress;
+       }
        pr_devel("after: %lu\n", new_n->nr_leaves_on_branch);
 
        nr_leaves_on_tree = new_n->nr_leaves_on_branch;