From ab0122dfc08882730f5141e7e5ff25b800153123 Mon Sep 17 00:00:00 2001 From: "Liam R. Howlett" Date: Thu, 10 Mar 2022 10:26:23 -0500 Subject: [PATCH] maple_tree: Fix spanning store detection on ULONG_MAX Signed-off-by: Liam R. Howlett --- lib/maple_tree.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 556cdbd0db81..a7a0d57e57f6 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -842,7 +842,7 @@ static inline void *mas_root(struct ma_state *mas) return rcu_dereference_check(mas->tree->ma_root, mt_locked(mas->tree)); } -static inline void *mt_root_locked(const struct maple_tree *mt) +static inline void *mt_root_locked(struct maple_tree *mt) { return rcu_dereference_protected(mt->ma_root, mt_locked(mt)); } @@ -2073,15 +2073,14 @@ static inline void mas_bulk_rebalance(struct ma_state *mas, unsigned char end, /* * mas_store_b_node() - Store an @entry into the b_node while also copying the * data from a maple encoded node. - * @mas: the maple state + * @wr_mas: the maple write state * @b_node: the maple_big_node to fill with data - * @entry: the data to store. + * @offset_end: the offset to end copying * * Return: The actual end of the data stored in @b_node */ -static inline unsigned char mas_store_b_node(struct ma_wr_state *wr_mas, - struct maple_big_node *b_node, - unsigned char offset_end) +static inline void mas_store_b_node(struct ma_wr_state *wr_mas, + struct maple_big_node *b_node, unsigned char offset_end) { unsigned char slot; unsigned char b_end; @@ -2115,7 +2114,7 @@ static inline unsigned char mas_store_b_node(struct ma_wr_state *wr_mas, /* Appended. */ if (mas->last >= mas->max) - return b_end; + goto b_end; /* Handle new range ending before old range ends */ piv = mas_logical_pivot(mas, wr_mas->pivots, offset_end, wr_mas->type); @@ -2135,11 +2134,15 @@ static inline unsigned char mas_store_b_node(struct ma_wr_state *wr_mas, slot = offset_end + 1; if (slot > wr_mas->node_end) - return b_end; + goto b_end; /* Copy end data to the end of the node. */ mas_mab_cp(mas, slot, wr_mas->node_end + 1, b_node, ++b_end); - return b_node->b_end - 1; + b_node->b_end--; + return; + +b_end: + b_node->b_end = b_end; } /* @@ -3618,7 +3621,7 @@ static bool mas_is_span_wr(struct ma_wr_state *wr_mas) return false; /* Detect spanning store wr walk */ - if ((last == ULONG_MAX) && (wr_mas->mas->index == ULONG_MAX)) + if (last == ULONG_MAX) return false; } @@ -3916,11 +3919,13 @@ static inline int mas_wr_spanning_store(struct ma_wr_state *wr_mas) mas->last = l_mas.last = r_mas.last; } + memset(&b_node, 0, sizeof(struct maple_big_node)); /* Copy l_mas and store the value in b_node. */ - b_node.b_end = mas_store_b_node(&l_wr_mas, &b_node, l_wr_mas.node_end); + mas_store_b_node(&l_wr_mas, &b_node, l_wr_mas.node_end); /* Copy r_mas into b_node. */ - mas_mab_cp(&r_mas, r_mas.offset, r_wr_mas.node_end, - &b_node, b_node.b_end + 1); + if (r_mas.offset <= r_wr_mas.node_end) + mas_mab_cp(&r_mas, r_mas.offset, r_wr_mas.node_end, + &b_node, b_node.b_end + 1); /* Stop spanning searches by searching for just index. */ l_mas.index = l_mas.last = mas->index; @@ -4191,7 +4196,6 @@ static inline bool mas_wr_append(struct ma_wr_state *wr_mas) static inline void mas_wr_modify(struct ma_wr_state *wr_mas) { - unsigned char zero; unsigned char node_slots; unsigned char node_size; struct ma_state *mas = wr_mas->mas; @@ -4231,12 +4235,8 @@ static inline void mas_wr_modify(struct ma_wr_state *wr_mas) return; slow_path: - b_node.b_end = mas_store_b_node(wr_mas, &b_node, wr_mas->offset_end); - zero = MAPLE_BIG_NODE_SLOTS - b_node.b_end - 1; - memset(b_node.slot + b_node.b_end + 1, 0, sizeof(void *) * zero--); - memset(b_node.pivot + b_node.b_end + 1, 0, - sizeof(unsigned long) * zero); - + memset(&b_node, 0, sizeof(struct maple_big_node)); + mas_store_b_node(wr_mas, &b_node, wr_mas->offset_end); trace_ma_write(__func__, mas, 0, wr_mas->entry); mas_commit_b_node(wr_mas, &b_node, wr_mas->node_end); } -- 2.50.1