From: Liam R. Howlett Date: Thu, 1 Sep 2022 01:03:02 +0000 (-0400) Subject: maple_tree: Avoid BUG_ON() when setting a leaf node as a parent X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=2398c88a53309860594cdb44754d4720d2b13a42;p=users%2Fjedix%2Flinux-maple.git maple_tree: Avoid BUG_ON() when setting a leaf node as a parent Don't crash the kernel in the very unlikely case that the node passed as the parent is actually a leaf. Instead, use MT_WARN_ON() to increase the probability of the debug information being recorded. Signed-off-by: Liam R. Howlett --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index dfcc2edfb3a9..ee083601dabe 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -443,7 +443,7 @@ enum maple_type mas_parent_enum(struct ma_state *mas, struct maple_enode *enode) } /* - * mte_set_parent() - Set the parent node and encode the slot + * mas_set_parent() - Set the parent node and encode the slot * @enode: The encoded maple node. * @parent: The encoded maple node that is the parent of @enode. * @slot: The slot that @enode resides in @parent. @@ -452,16 +452,19 @@ enum maple_type mas_parent_enum(struct ma_state *mas, struct maple_enode *enode) * parent type. */ static inline -void mte_set_parent(struct maple_enode *enode, const struct maple_enode *parent, - unsigned char slot) +void mas_set_parent(struct ma_state *mas, struct maple_enode *enode, + const struct maple_enode *parent, unsigned char slot) { unsigned long val = (unsigned long) parent; unsigned long shift; unsigned long type; enum maple_type p_type = mte_node_type(parent); - BUG_ON(p_type == maple_dense); - BUG_ON(p_type == maple_leaf_64); + if (MT_WARN_ON(mas->tree, p_type == maple_dense)) + pr_err("Dense node %p cannot be parent\n", parent); + + if (MT_WARN_ON(mas->tree, p_type == maple_leaf_64)) + pr_err("Leaf node %p cannot be parent\n", parent); switch (p_type) { case maple_range_64: @@ -1729,7 +1732,7 @@ static inline void mas_adopt_children(struct ma_state *mas, offset = ma_data_end(node, type, pivots, mas->max); do { child = mas_slot_locked(mas, slots, offset); - mte_set_parent(child, parent, offset); + mas_set_parent(mas, child, parent, offset); } while (offset--); } @@ -2716,9 +2719,9 @@ static inline void mas_set_split_parent(struct ma_state *mas, return; if ((*slot) <= split) - mte_set_parent(mas->node, left, *slot); + mas_set_parent(mas, mas->node, left, *slot); else if (right) - mte_set_parent(mas->node, right, (*slot) - split - 1); + mas_set_parent(mas, mas->node, right, (*slot) - split - 1); (*slot)++; } @@ -3113,12 +3116,12 @@ static int mas_spanning_rebalance(struct ma_state *mas, mte_node_type(mast->orig_l->node)); mast->orig_l->depth++; mab_mas_cp(mast->bn, 0, mt_slots[mast->bn->type] - 1, &l_mas, true); - mte_set_parent(left, l_mas.node, slot); + mas_set_parent(mas, left, l_mas.node, slot); if (middle) - mte_set_parent(middle, l_mas.node, ++slot); + mas_set_parent(mas, middle, l_mas.node, ++slot); if (right) - mte_set_parent(right, l_mas.node, ++slot); + mas_set_parent(mas, right, l_mas.node, ++slot); if (mas_is_root_limits(mast->l)) { new_root: @@ -3345,8 +3348,8 @@ static inline bool mas_split_final_node(struct maple_subtree_state *mast, * The Big_node data should just fit in a single node. */ ancestor = mas_new_ma_node(mas, mast->bn); - mte_set_parent(mast->l->node, ancestor, mast->l->offset); - mte_set_parent(mast->r->node, ancestor, mast->r->offset); + mas_set_parent(mas, mast->l->node, ancestor, mast->l->offset); + mas_set_parent(mas, mast->r->node, ancestor, mast->r->offset); mte_to_node(ancestor)->parent = mas_mn(mas)->parent; mast->l->node = ancestor;