]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: Fix spanning store detection on ULONG_MAX
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Thu, 10 Mar 2022 15:26:23 +0000 (10:26 -0500)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Thu, 10 Mar 2022 15:26:46 +0000 (10:26 -0500)
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
lib/maple_tree.c

index 556cdbd0db81198858b06725cbc69c693afb08d8..a7a0d57e57f6226c26daa90b302c938e3e0871a6 100644 (file)
@@ -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);
 }