From: Liam R. Howlett Date: Fri, 1 Feb 2019 19:21:33 +0000 (-0500) Subject: maple_tree: Fix split & insert to use last slot. X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=add03e135570a0983297b7dc9e9a6ef700c74ca0;p=users%2Fjedix%2Flinux-maple.git maple_tree: Fix split & insert to use last slot. 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 --- diff --git a/lib/maple_tree.c b/lib/maple_tree.c index a3ddd43965b0..83d98d53d534 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -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)); }