Re: [PATCH] lib/assoc_array: fix stale nr_leaves_on_tree after gc

From: Josh Law

Date: Wed Mar 18 2026 - 13:43:17 EST




On 18 March 2026 17:23:19 GMT, Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> wrote:
>On Wed, 18 Mar 2026 16:49:59 +0000 Josh Law <objecting@xxxxxxxxxxxxx> wrote:
>
>> In assoc_array_gc(), assoc_array_apply_edit() publishes the new tree
>> root before nr_leaves_on_tree is updated, creating a window where the
>> tree is visible with a stale leaf count. Move the nr_leaves_on_tree
>> assignment before assoc_array_apply_edit() so the count is consistent
>> when the new root becomes visible.
>>
>> ...
>>
>> --- a/lib/assoc_array.c
>> +++ b/lib/assoc_array.c
>> @@ -1711,8 +1711,8 @@ int assoc_array_gc(struct assoc_array *array,
>>
>> gc_complete:
>> edit->set[0].to = new_root;
>> - assoc_array_apply_edit(edit);
>> array->nr_leaves_on_tree = nr_leaves_on_tree;
>> + assoc_array_apply_edit(edit);
>> return 0;
>
>But assoc_array_apply_edit() alters array->nr_leaves_on_tree and now we
>immediately overwrite that alteration?


2/2

No, unless if the resulting tree is completely empty (edit->array->root == NULL). In that scenario, assoc_array_apply_edit() explicitly sets edit->array->nr_leaves_on_tree = 0, but since it's zero, it overwrites 0 with 0,

and In the assoc_array_gc() path, the edit struct is allocated with kzalloc(),
and edit->adjust_count_on is never set (it stays NULL). Because it's NULL,
assoc_array_apply_edit() actually skips the block that alters array->nr_leaves_on_tree

V/R

Josh Law