]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Fix clearing of implied pivot at end of node in node reuse
authorLiam R. Howlett <Liam.Howlett@oracle.com>
Thu, 3 Mar 2022 15:47:07 +0000 (10:47 -0500)
committerLiam R. Howlett <Liam.Howlett@oracle.com>
Tue, 8 Mar 2022 18:19:16 +0000 (13:19 -0500)
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
lib/maple_tree.c

index f1fdb441ead776adcf46c71e6ce2ad175589312a..bb7fa9727378b169678d7de6fa2996721c7c6417 100644 (file)
@@ -2116,8 +2116,7 @@ static inline unsigned char mas_store_b_node(struct ma_wr_state *wr_mas,
 
        /* Copy end data to the end of the node. */
        mas_mab_cp(mas, slot, wr_mas->node_end + 1, b_node, ++b_end);
-       b_end = b_node->b_end - 1;
-       return b_end;
+       return b_node->b_end - 1;
 }
 
 /*
@@ -3429,27 +3428,25 @@ static int mas_split(struct ma_state *mas, struct maple_big_node *b_node)
  *
  * Return: True if node was reused, false otherwise.
  */
-static inline bool mas_reuse_node(struct ma_state *mas,
+static inline bool mas_reuse_node(struct ma_wr_state *wr_mas,
                          struct maple_big_node *bn, unsigned char end)
 {
        /* Need to be rcu safe. */
-       if (mt_in_rcu(mas->tree))
+       if (mt_in_rcu(wr_mas->mas->tree))
                return false;
 
-       mab_mas_cp(bn, 0, bn->b_end, mas, false);
-
+       mab_mas_cp(bn, 0, bn->b_end, wr_mas->mas, false);
        if (end > bn->b_end) {
-               /* Zero end of node. */
-               enum maple_type mt = mte_node_type(mas->node);
-               struct maple_node *mn = mas_mn(mas);
-               unsigned long *pivots = ma_pivots(mn, mt);
-               void __rcu **slots = ma_slots(mn, mt);
-               char clear = mt_slots[mt] - bn->b_end - 2;
+               char clear = mt_slots[wr_mas->type] - bn->b_end - 2;
 
+               if (bn->pivot[bn->b_end] != wr_mas->mas->max)
+                       clear++;
+
+               /* Zero end of node. */
                if (clear > 0) {
-                       memset(slots + bn->b_end + 1, 0,
+                       memset(wr_mas->slots + bn->b_end+1, 0,
                               sizeof(void *) * clear);
-                       memset(pivots + bn->b_end + 1, 0,
+                       memset(wr_mas->pivots + bn->b_end+1, 0,
                               sizeof(unsigned long *) * clear);
                }
        }
@@ -3463,7 +3460,7 @@ static inline bool mas_reuse_node(struct ma_state *mas,
  * @b_node: The maple big node
  * @end: The end of the data.
  */
-static inline int mas_commit_b_node(struct ma_state *mas,
+static inline int mas_commit_b_node(struct ma_wr_state *wr_mas,
                            struct maple_big_node *b_node, unsigned char end)
 {
        struct maple_node *node;
@@ -3471,27 +3468,28 @@ static inline int mas_commit_b_node(struct ma_state *mas,
        enum maple_type b_type = b_node->type;
 
        if ((b_end < mt_min_slots[b_type]) &&
-           (!mte_is_root(mas->node)) && (mas_mt_height(mas) > 1))
-               return mas_rebalance(mas, b_node);
+           (!mte_is_root(wr_mas->mas->node)) &&
+           (mas_mt_height(wr_mas->mas) > 1))
+               return mas_rebalance(wr_mas->mas, b_node);
 
        if (b_end >= mt_slots[b_type])
-               return mas_split(mas, b_node);
+               return mas_split(wr_mas->mas, b_node);
 
-       if (mas_reuse_node(mas, b_node, end))
+       if (mas_reuse_node(wr_mas, b_node, end))
                goto reuse_node;
 
-       mas_node_count(mas, 1);
-       if (mas_is_err(mas))
+       mas_node_count(wr_mas->mas, 1);
+       if (mas_is_err(wr_mas->mas))
                return 0;
 
-       node = mas_pop_node(mas);
-       node->parent = mas_mn(mas)->parent;
-       mas->node = mt_mk_node(node, b_type);
-       mab_mas_cp(b_node, 0, b_end, mas, true);
+       node = mas_pop_node(wr_mas->mas);
+       node->parent = mas_mn(wr_mas->mas)->parent;
+       wr_mas->mas->node = mt_mk_node(node, b_type);
+       mab_mas_cp(b_node, 0, b_end, wr_mas->mas, true);
 
-       mas_replace(mas, false);
+       mas_replace(wr_mas->mas, false);
 reuse_node:
-       mas_update_gap(mas);
+       mas_update_gap(wr_mas->mas);
        return 1;
 }
 
@@ -4227,7 +4225,7 @@ slow_path:
               sizeof(unsigned long) * zero);
 
        trace_ma_write(__func__, mas, 0, wr_mas->entry);
-       mas_commit_b_node(mas, &b_node, wr_mas->node_end);
+       mas_commit_b_node(wr_mas, &b_node, wr_mas->node_end);
 }
 
 /*