summaryrefslogtreecommitdiff
path: root/fs/bcachefs/extent_update.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bcachefs/extent_update.c')
-rw-r--r--fs/bcachefs/extent_update.c67
1 files changed, 39 insertions, 28 deletions
diff --git a/fs/bcachefs/extent_update.c b/fs/bcachefs/extent_update.c
index e76e58a568bf..7ddb156c765c 100644
--- a/fs/bcachefs/extent_update.c
+++ b/fs/bcachefs/extent_update.c
@@ -68,7 +68,6 @@ static int count_iters_for_insert(struct btree_trans *trans,
u64 idx = REFLINK_P_IDX(p.v);
unsigned sectors = bpos_min(*end, p.k->p).offset -
bkey_start_offset(p.k);
- struct btree_iter iter;
struct bkey_s_c r_k;
for_each_btree_key_norestart(trans, iter,
@@ -88,11 +87,9 @@ static int count_iters_for_insert(struct btree_trans *trans,
r_k.k->p.offset - idx);
*end = bpos_min(*end, pos);
- ret = 1;
- break;
+ return 1;
}
}
- bch2_trans_iter_exit(trans, &iter);
break;
}
@@ -101,55 +98,69 @@ static int count_iters_for_insert(struct btree_trans *trans,
return ret2 ?: ret;
}
-int bch2_extent_atomic_end(struct btree_trans *trans,
- struct btree_iter *iter,
- struct bpos *end)
+int bch2_extent_trim_atomic(struct btree_trans *trans,
+ struct btree_iter *iter,
+ struct bkey_i *insert)
{
- unsigned nr_iters = 0;
+ enum bch_bkey_type whiteout_type =
+ extent_whiteout_type(trans->c, iter->btree_id, &insert->k);
+ struct bpos end = insert->k.p;
struct btree_iter copy;
- bch2_trans_copy_iter(trans, &copy, iter);
+ bch2_trans_copy_iter(&copy, iter);
- int ret = bch2_btree_iter_traverse(trans, &copy);
+ int ret = bch2_btree_iter_traverse(&copy);
if (ret)
goto err;
+ copy.flags |= BTREE_ITER_nofilter_whiteouts;
+
struct bkey_s_c k;
- for_each_btree_key_max_continue_norestart(trans, copy, *end, 0, k, ret) {
+ unsigned nr_iters = 0;
+ for_each_btree_key_continue_norestart(copy, 0, k, ret) {
unsigned offset = 0;
if (bkey_gt(iter->pos, bkey_start_pos(k.k)))
offset = iter->pos.offset - bkey_start_offset(k.k);
- ret = count_iters_for_insert(trans, k, offset, end, &nr_iters);
- if (ret)
- break;
+ if (bkey_extent_whiteout(k.k)) {
+ if (bpos_gt(k.k->p, insert->k.p)) {
+ if (k.k->type == KEY_TYPE_extent_whiteout)
+ break;
+ else
+ continue;
+ } else if (k.k->type != whiteout_type) {
+ nr_iters += 1;
+ if (nr_iters >= EXTENT_ITERS_MAX) {
+ end = bpos_min(end, k.k->p);
+ break;
+ }
+ }
+ } else {
+ if (bpos_ge(bkey_start_pos(k.k), end))
+ break;
+
+ ret = count_iters_for_insert(trans, k, offset, &end, &nr_iters);
+ if (ret)
+ break;
+ }
}
err:
- bch2_trans_iter_exit(trans, &copy);
- return ret < 0 ? ret : 0;
-}
-
-int bch2_extent_trim_atomic(struct btree_trans *trans,
- struct btree_iter *iter,
- struct bkey_i *k)
-{
- struct bpos end = k->k.p;
- int ret = bch2_extent_atomic_end(trans, iter, &end);
- if (ret)
+ bch2_trans_iter_exit(&copy);
+ if (ret < 0)
return ret;
/* tracepoint */
- if (bpos_lt(end, k->k.p)) {
+ if (bpos_lt(end, insert->k.p)) {
if (trace_extent_trim_atomic_enabled()) {
CLASS(printbuf, buf)();
bch2_bpos_to_text(&buf, end);
prt_newline(&buf);
- bch2_bkey_val_to_text(&buf, trans->c, bkey_i_to_s_c(k));
+ bch2_bkey_val_to_text(&buf, trans->c, bkey_i_to_s_c(insert));
trace_extent_trim_atomic(trans->c, buf.buf);
}
- bch2_cut_back(end, k);
+ bch2_cut_back(end, insert);
}
return 0;
}