| From: Liam Howlett <liam.howlett@oracle.com> |
| Subject: maple_tree: fix mt_destroy_walk() on full non-leaf non-alloc nodes |
| Date: Wed, 15 Jun 2022 14:19:38 +0000 |
| |
| It is possible to iterate over the metadata of full non-leaf nodes when |
| operating in non-alloc mode. |
| |
| Link: https://lkml.kernel.org/r/20220615141921.417598-2-Liam.Howlett@oracle.com |
| Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com> |
| Cc: Qian Cai <quic_qiancai@quicinc.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| lib/maple_tree.c | 12 ++++++++---- |
| 1 file changed, 8 insertions(+), 4 deletions(-) |
| |
| --- a/lib/maple_tree.c~maple-tree-add-new-data-structure-fix-7 |
| +++ a/lib/maple_tree.c |
| @@ -5429,11 +5429,15 @@ static void mt_destroy_walk(struct maple |
| goto start_slots_free; |
| type = mte_node_type(mas.node); |
| slots = ma_slots(mte_to_node(mas.node), type); |
| - if ((offset < mt_slots[type]) && (slots[offset])) { |
| - struct maple_enode *parent = mas.node; |
| + if ((offset < mt_slots[type])) { |
| + struct maple_enode *next = slots[offset]; |
| |
| - mas.node = mas_slot_locked(&mas, slots, offset); |
| - slots = mas_destroy_descend(&mas, parent, offset); |
| + if (mte_node_type(next) && mte_to_node(next)) { |
| + struct maple_enode *parent = mas.node; |
| + |
| + mas.node = mas_slot_locked(&mas, slots, offset); |
| + slots = mas_destroy_descend(&mas, parent, offset); |
| + } |
| } |
| node = mas_mn(&mas); |
| } while (start != mas.node); |
| _ |