summaryrefslogtreecommitdiff
path: root/fs/bcachefs/extents.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-03-16 14:27:40 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:17 -0400
commit9a12b1b0978837f19a5ccc2312aeae535d8289a4 (patch)
tree074fbf34180576844ba2f2872b63754fa22c04a8 /fs/bcachefs/extents.c
parentc93cead058779ec6911047d7084c43e3da3e7eaf (diff)
bcachefs: Refactor extent insert path
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/extents.c')
-rw-r--r--fs/bcachefs/extents.c152
1 files changed, 54 insertions, 98 deletions
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
index 1233b3d0b352..420a9a6c59e7 100644
--- a/fs/bcachefs/extents.c
+++ b/fs/bcachefs/extents.c
@@ -782,18 +782,6 @@ static bool extent_i_save(struct btree *b, struct bkey_packed *dst,
return true;
}
-struct extent_insert_state {
- struct btree_insert *trans;
- struct btree_insert_entry *insert;
- struct bpos committed;
-
- /* for deleting: */
- struct bkey_i whiteout;
- bool update_journal;
- bool update_btree;
- bool deleting;
-};
-
static bool bch2_extent_merge_inline(struct bch_fs *,
struct btree_iter *,
struct bkey_packed *,
@@ -880,54 +868,6 @@ static void extent_bset_insert(struct bch_fs *c, struct btree_iter *iter,
bch2_btree_iter_verify(iter, l->b);
}
-static void extent_insert_committed(struct extent_insert_state *s)
-{
- struct bch_fs *c = s->trans->c;
- struct btree_iter *iter = s->insert->iter;
- struct bkey_i *insert = s->insert->k;
- BKEY_PADDED(k) split;
-
- EBUG_ON(bkey_cmp(insert->k.p, s->committed) < 0);
- EBUG_ON(bkey_cmp(s->committed, bkey_start_pos(&insert->k)) < 0);
-
- bkey_copy(&split.k, insert);
- if (s->deleting)
- split.k.k.type = KEY_TYPE_discard;
-
- bch2_cut_back(s->committed, &split.k.k);
-
- if (!bkey_cmp(s->committed, iter->pos))
- return;
-
- bch2_btree_iter_set_pos_same_leaf(iter, s->committed);
-
- if (s->update_btree) {
- if (debug_check_bkeys(c))
- bch2_bkey_debugcheck(c, iter->l[0].b,
- bkey_i_to_s_c(&split.k));
-
- EBUG_ON(bkey_deleted(&split.k.k) || !split.k.k.size);
-
- extent_bset_insert(c, iter, &split.k);
- }
-
- if (s->update_journal) {
- bkey_copy(&split.k, !s->deleting ? insert : &s->whiteout);
- if (s->deleting)
- split.k.k.type = KEY_TYPE_discard;
-
- bch2_cut_back(s->committed, &split.k.k);
-
- EBUG_ON(bkey_deleted(&split.k.k) || !split.k.k.size);
-
- bch2_btree_journal_key(s->trans, iter, &split.k);
- }
-
- bch2_cut_front(s->committed, insert);
-
- insert->k.needs_whiteout = false;
-}
-
static inline struct bpos
bch2_extent_atomic_end(struct bkey_i *k, struct btree_iter *iter)
{
@@ -1005,12 +945,11 @@ bch2_extent_can_insert(struct btree_insert *trans,
}
static void
-extent_squash(struct extent_insert_state *s, struct bkey_i *insert,
+extent_squash(struct bch_fs *c, struct btree_iter *iter,
+ struct bkey_i *insert,
struct bkey_packed *_k, struct bkey_s k,
enum bch_extent_overlap overlap)
{
- struct bch_fs *c = s->trans->c;
- struct btree_iter *iter = s->insert->iter;
struct btree_iter_level *l = &iter->l[0];
switch (overlap) {
@@ -1096,34 +1035,39 @@ extent_squash(struct extent_insert_state *s, struct bkey_i *insert,
}
}
-static void __bch2_insert_fixup_extent(struct extent_insert_state *s)
+struct extent_insert_state {
+ struct bkey_i whiteout;
+ bool update_journal;
+ bool update_btree;
+ bool deleting;
+};
+
+static void __bch2_insert_fixup_extent(struct bch_fs *c,
+ struct btree_iter *iter,
+ struct bkey_i *insert,
+ struct extent_insert_state *s)
{
- struct btree_iter *iter = s->insert->iter;
struct btree_iter_level *l = &iter->l[0];
struct bkey_packed *_k;
struct bkey unpacked;
- struct bkey_i *insert = s->insert->k;
- while (bkey_cmp(s->committed, insert->k.p) < 0 &&
- (_k = bch2_btree_node_iter_peek_filter(&l->iter, l->b,
+ while ((_k = bch2_btree_node_iter_peek_filter(&l->iter, l->b,
KEY_TYPE_discard))) {
struct bkey_s k = __bkey_disassemble(l->b, _k, &unpacked);
- enum bch_extent_overlap overlap = bch2_extent_overlap(&insert->k, k.k);
-
- EBUG_ON(bkey_cmp(iter->pos, k.k->p) >= 0);
+ struct bpos cur_end = bpos_min(insert->k.p, k.k->p);
+ enum bch_extent_overlap overlap =
+ bch2_extent_overlap(&insert->k, k.k);
if (bkey_cmp(bkey_start_pos(k.k), insert->k.p) >= 0)
break;
- s->committed = bpos_min(s->insert->k->k.p, k.k->p);
-
if (!bkey_whiteout(k.k))
s->update_journal = true;
if (!s->update_journal) {
- bch2_cut_front(s->committed, insert);
- bch2_cut_front(s->committed, &s->whiteout);
- bch2_btree_iter_set_pos_same_leaf(iter, s->committed);
+ bch2_cut_front(cur_end, insert);
+ bch2_cut_front(cur_end, &s->whiteout);
+ bch2_btree_iter_set_pos_same_leaf(iter, cur_end);
goto next;
}
@@ -1157,19 +1101,16 @@ static void __bch2_insert_fixup_extent(struct extent_insert_state *s)
_k->needs_whiteout = false;
}
- extent_squash(s, insert, _k, k, overlap);
+ extent_squash(c, iter, insert, _k, k, overlap);
if (!s->update_btree)
- bch2_cut_front(s->committed, insert);
+ bch2_cut_front(cur_end, insert);
next:
if (overlap == BCH_EXTENT_OVERLAP_FRONT ||
overlap == BCH_EXTENT_OVERLAP_MIDDLE)
break;
}
- if (bkey_cmp(s->committed, insert->k.p) < 0)
- s->committed = bpos_min(s->insert->k->k.p, l->b->key.k.p);
-
/*
* may have skipped past some deleted extents greater than the insert
* key, before we got to a non deleted extent and knew we could bail out
@@ -1179,7 +1120,7 @@ next:
struct btree_node_iter node_iter = l->iter;
while ((_k = bch2_btree_node_iter_prev_all(&node_iter, l->b)) &&
- bkey_cmp_left_packed(l->b, _k, &s->committed) > 0)
+ bkey_cmp_left_packed(l->b, _k, &insert->k.p) > 0)
l->iter = node_iter;
}
}
@@ -1226,36 +1167,51 @@ next:
void bch2_insert_fixup_extent(struct btree_insert *trans,
struct btree_insert_entry *insert)
{
+ struct bch_fs *c = trans->c;
struct btree_iter *iter = insert->iter;
struct extent_insert_state s = {
- .trans = trans,
- .insert = insert,
- .committed = iter->pos,
-
.whiteout = *insert->k,
.update_journal = !bkey_whiteout(&insert->k->k),
.update_btree = !bkey_whiteout(&insert->k->k),
.deleting = bkey_whiteout(&insert->k->k),
};
+ BKEY_PADDED(k) tmp;
EBUG_ON(iter->level);
EBUG_ON(!insert->k->k.size);
-
- /*
- * As we process overlapping extents, we advance @iter->pos both to
- * signal to our caller (btree_insert_key()) how much of @insert->k has
- * been inserted, and also to keep @iter->pos consistent with
- * @insert->k and the node iterator that we're advancing:
- */
EBUG_ON(bkey_cmp(iter->pos, bkey_start_pos(&insert->k->k)));
- __bch2_insert_fixup_extent(&s);
+ __bch2_insert_fixup_extent(c, iter, insert->k, &s);
- extent_insert_committed(&s);
+ bch2_btree_iter_set_pos_same_leaf(iter, insert->k->k.p);
- BUG_ON(insert->k->k.size);
- EBUG_ON(bkey_cmp(iter->pos, bkey_start_pos(&insert->k->k)));
- EBUG_ON(bkey_cmp(iter->pos, s.committed));
+ if (s.update_btree) {
+ bkey_copy(&tmp.k, insert->k);
+
+ if (s.deleting)
+ tmp.k.k.type = KEY_TYPE_discard;
+
+ if (debug_check_bkeys(c))
+ bch2_bkey_debugcheck(c, iter->l[0].b,
+ bkey_i_to_s_c(&tmp.k));
+
+ EBUG_ON(bkey_deleted(&tmp.k.k) || !tmp.k.k.size);
+
+ extent_bset_insert(c, iter, &tmp.k);
+ }
+
+ if (s.update_journal) {
+ bkey_copy(&tmp.k, !s.deleting ? insert->k : &s.whiteout);
+
+ if (s.deleting)
+ tmp.k.k.type = KEY_TYPE_discard;
+
+ EBUG_ON(bkey_deleted(&tmp.k.k) || !tmp.k.k.size);
+
+ bch2_btree_journal_key(trans, iter, &tmp.k);
+ }
+
+ bch2_cut_front(insert->k->k.p, insert->k);
}
const char *bch2_extent_invalid(const struct bch_fs *c, struct bkey_s_c k)