hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/lib/assoc_array.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Generic associative array implementation.
23 *
34 * See Documentation/core-api/assoc_array.rst for information.
45 *
56 * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
67 * Written by David Howells (dhowells@redhat.com)
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public Licence
10
- * as published by the Free Software Foundation; either version
11
- * 2 of the Licence, or (at your option) any later version.
128 */
139 //#define DEBUG
1410 #include <linux/rcupdate.h>
....@@ -1117,6 +1113,7 @@
11171113 index_key))
11181114 goto found_leaf;
11191115 }
1116
+ /* fall through */
11201117 case assoc_array_walk_tree_empty:
11211118 case assoc_array_walk_found_wrong_shortcut:
11221119 default:
....@@ -1465,6 +1462,7 @@
14651462 struct assoc_array_ptr *cursor, *ptr;
14661463 struct assoc_array_ptr *new_root, *new_parent, **new_ptr_pp;
14671464 unsigned long nr_leaves_on_tree;
1465
+ bool retained;
14681466 int keylen, slot, nr_free, next_slot, i;
14691467
14701468 pr_devel("-->%s()\n", __func__);
....@@ -1541,6 +1539,7 @@
15411539 goto descend;
15421540 }
15431541
1542
+retry_compress:
15441543 pr_devel("-- compress node %p --\n", new_n);
15451544
15461545 /* Count up the number of empty slots in this node and work out the
....@@ -1558,6 +1557,7 @@
15581557 pr_devel("free=%d, leaves=%lu\n", nr_free, new_n->nr_leaves_on_branch);
15591558
15601559 /* See what we can fold in */
1560
+ retained = false;
15611561 next_slot = 0;
15621562 for (slot = 0; slot < ASSOC_ARRAY_FAN_OUT; slot++) {
15631563 struct assoc_array_shortcut *s;
....@@ -1607,9 +1607,14 @@
16071607 pr_devel("[%d] retain node %lu/%d [nx %d]\n",
16081608 slot, child->nr_leaves_on_branch, nr_free + 1,
16091609 next_slot);
1610
+ retained = true;
16101611 }
16111612 }
16121613
1614
+ if (retained && new_n->nr_leaves_on_branch <= ASSOC_ARRAY_FAN_OUT) {
1615
+ pr_devel("internal nodes remain despite enough space, retrying\n");
1616
+ goto retry_compress;
1617
+ }
16131618 pr_devel("after: %lu\n", new_n->nr_leaves_on_branch);
16141619
16151620 nr_leaves_on_tree = new_n->nr_leaves_on_branch;