]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: Fix split & insert to use last slot.
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 1 Feb 2019 19:21:33 +0000 (14:21 -0500)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Wed, 31 Jul 2019 14:52:39 +0000 (10:52 -0400)
The last slot was revealed to be NULL always.  Fix this by changing the
the end calculations and to ensure it is okay to use the final slot.

Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
lib/maple_tree.c

index a3ddd43965b0504b67da07b5b4ec9eb88d227c41..83d98d53d534f414a957282edbe26e791b007439 100644 (file)
@@ -415,13 +415,13 @@ unsigned char ma_data_end_r64(const struct maple_range_64 *mr64,
        for (data_end = 0; data_end < MAPLE_RANGE64_SLOTS - 1; data_end++) {
                last = mr64->pivot[data_end];
                if (last == 0 && data_end > 0)
-                       return data_end;
+                       return data_end - 1;
                if (last == ULONG_MAX)
-                       return data_end;
+                       return data_end - 1;
        }
 
-       if (mr64->slot[data_end] != NULL)
-               data_end++;
+       if (mr64->slot[data_end] == NULL)
+               data_end--;
 
        return data_end;
 }
@@ -458,7 +458,7 @@ void ma_copy(struct ma_state *mas, struct ma_cp *cp)
 
        dst64 = &cp->dst->mr64;
        while (sloc <= cp->src_end &&
-                       dloc <= cp->dst_end) {
+               dloc <= cp->dst_end) {
 
                if (sloc != 0 && sloc < MAPLE_RANGE64_SLOTS - 1 &&
                    src64->pivot[sloc] == 0)
@@ -641,7 +641,7 @@ static int ma_split(struct ma_state *mas, unsigned char slot)
                ma_copy(mas, &cp);
                cp.dst_start += 1;
                cp.src_start = p_slot + 1;
-               cp.src_end = p_end;
+               cp.src_end = p_end + 1;
                ma_copy(mas, &cp);
                // Update encoded slots in children
                ma_adopt_children(new_parent);
@@ -711,7 +711,7 @@ static int _ma_insert(struct ma_state *mas, void *entry, unsigned char slot)
                max = mr64->pivot[slot];
 
        if (slot == MAPLE_NODE_SLOTS)
-               slot = o_end;
+               slot = o_end + 1; // Append.
 
        if (slot > 0)
                min = mr64->pivot[slot - 1];
@@ -723,7 +723,8 @@ static int _ma_insert(struct ma_state *mas, void *entry, unsigned char slot)
        if (mas->index && min != mas->index - 1)
                n_end++;
 
-       if (n_end > MAPLE_RANGE64_SLOTS - 1) {
+       if (n_end > MAPLE_RANGE64_SLOTS - 1 ||
+           (n_end == MAPLE_RANGE64_SLOTS - 1 && mas->max == ULONG_MAX)) {
                unsigned char split = ma_split(mas, slot);
                if (mas_is_err(mas))
                        return 0;
@@ -734,8 +735,6 @@ static int _ma_insert(struct ma_state *mas, void *entry, unsigned char slot)
                n_end -= split;
                mr64 = &mt_to_node(mas->node)->mr64;
                o_end = ma_data_end_r64(mr64, mas->max); // Old end is not so old now.
-               if (o_end == 1)
-                       o_end = 0; // This node is empty, append at the start.
        }
        /* Save the node in case we are not appending. */
        p_mr64 = mr64;
@@ -743,7 +742,7 @@ static int _ma_insert(struct ma_state *mas, void *entry, unsigned char slot)
 
        /* Figure out if this is an append or not.
         * Appending does not need to create a new node. */
-       if (slot == o_end) {
+       if (slot - 1 == o_end) {
                o_end = n_end; /* Appending */
        } else {
                /* Not appending */
@@ -766,7 +765,7 @@ static int _ma_insert(struct ma_state *mas, void *entry, unsigned char slot)
                mr64->pivot[slot] = mas->last;
                /* Write NULL entry */
                RCU_INIT_POINTER(mr64->slot[--slot], NULL);
-               if (o_end == n_end) // Append.
+               if (o_end == n_end + 1) // Append.
                        wmb();
 
                mr64->pivot[slot] = mas->index - 1;
@@ -775,10 +774,11 @@ static int _ma_insert(struct ma_state *mas, void *entry, unsigned char slot)
        } else {
                /* Write the entry */
                RCU_INIT_POINTER(mr64->slot[slot], entry);
-               if (o_end == n_end) // Append.
+               if (o_end == n_end + 1) // Append.
                        wmb();
 
-               mr64->pivot[slot++] = mas->last;
+               if (slot < MAPLE_RANGE64_SLOTS - 1)
+                       mr64->pivot[slot++] = mas->last;
        }
 
        /* Skip possible duplicate entry that contains a NULL */
@@ -817,6 +817,8 @@ static void ma_root_expand(struct ma_state *ms, void *entry)
                mn->mr64.pivot[0] = ms->index - 1;
 
        _ma_insert(ms, entry, 1);
+       if (mas_is_err(ms))
+               return;
        /* swap the new root into the tree */
        rcu_assign_pointer(ms->tree->ma_root, mt_mk_root(ms->node));
 }