} else if (dst_slot)
wr_pivot = mas_get_safe_pivot(mas, dst_slot - 1);
- if (dst_slot && mas->index < wr_pivot) {
+ if (dst_slot && mas->index <= wr_pivot) {
mas_set_safe_pivot(mas, dst_slot - 1, mas->index - 1);
} else if (entry && mas->index && (mas->index - 1 != wr_pivot)) {
if (dst_slot && !mte_get_rcu_slot(mas->node, dst_slot - 1))
static inline int _mas_add_slot_cnt(struct ma_state *mas,
const unsigned char slot, const unsigned long min,
- const unsigned long max)
+ const unsigned long max, void *entry)
{
int slot_cnt;
unsigned char slot_max = mt_slot_count(mas->node);
- bool prev_null = !!mte_get_rcu_slot(mas->node, slot);
+ bool prev_null = false;
unsigned long prev_piv = (mas->min ? mas->min - 1 : mas->min);
slot_cnt = __mas_add_slot_cnt(mas, prev_piv, 0, slot, false, true);
slot_cnt++; // (2?)
if (max > mas->last) { // ends before this_slot.
+ void *prev_val = mte_get_rcu_slot(mas->node, slot);
slot_cnt++; // (2 or 3?)
prev_piv = max;
+ if (!prev_val || mt_will_coalesce(prev_val))
+ prev_null = true;
} else {
- prev_null = false;
+ if (!entry)
+ prev_null = true;
prev_piv = mas->last;
}
ret = 1;
goto complete;
}
- new_end = _mas_add_slot_cnt(mas, slot, min, max) - coalesce;
+ new_end = _mas_add_slot_cnt(mas, slot, min, max, entry);
if (!spans_node && new_end > slot_cnt + 1) {
mas_split(mas, slot, active, old_end, entry);
if (mas_is_err(mas))
break;
}
mt_validate(mt);
-#if check_erase2_debug
+#if check_erase2_debug > 1
mt_dump(mt);
+#endif
+#if check_erase2_debug
pr_err("Done\n");
#endif
MT_BUG_ON(mt, check != entry_cnt);
check = 0;
+ addr = 0;
mas_reset(&mas);
mas.index = 0;
rcu_read_lock();
mas_for_each(&mas, foo, ULONG_MAX) {
- if (mas_retry(&mas, foo))
+ if (mas_retry(&mas, foo)) {
+ if (addr == mas.index) {
+ mt_dump(mas.tree);
+ printk("retry failed %lu - %lu\n",
+ mas.index, mas.last);
+ MT_BUG_ON(mt, 1);
+ }
+ addr = mas.index;
continue;
+ }
#if check_erase2_debug > 1
- pr_err("mas: %lu -> %p\n", addr+1, foo);
+ pr_err("mas: %lu -> %p\n", mas.index, foo);
#endif
check++;
if (check > entry_cnt)