summaryrefslogtreecommitdiff
path: root/fs/bcachefs/btree_update_leaf.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-03-20 21:04:57 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:56 -0400
commit4cfb722ca16d89ada724c142201fc86872283a90 (patch)
treef97235cd433078e18abe252c0feb7ad13a688934 /fs/bcachefs/btree_update_leaf.c
parent4ce41957a7370e398dd1ae960e5184af8315de35 (diff)
downloadlwn-4cfb722ca16d89ada724c142201fc86872283a90.tar.gz
lwn-4cfb722ca16d89ada724c142201fc86872283a90.zip
bcachefs: Switch extent_handle_overwrites() to one key at a time
Prep work for snapshots Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_update_leaf.c')
-rw-r--r--fs/bcachefs/btree_update_leaf.c103
1 files changed, 46 insertions, 57 deletions
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index f8b493706c94..e76916cffd5b 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -690,8 +690,8 @@ bch2_trans_commit_get_rw_cold(struct btree_trans *trans)
return 0;
}
-static int __bch2_trans_update2(struct btree_trans *trans,
- struct btree_insert_entry n)
+static void __bch2_trans_update2(struct btree_trans *trans,
+ struct btree_insert_entry n)
{
struct btree_insert_entry *i;
@@ -711,15 +711,13 @@ static int __bch2_trans_update2(struct btree_trans *trans,
else
array_insert_item(trans->updates2, trans->nr_updates2,
i - trans->updates2, n);
-
- return 0;
}
-static int bch2_trans_update2(struct btree_trans *trans,
- struct btree_iter *iter,
- struct bkey_i *insert)
+static void bch2_trans_update2(struct btree_trans *trans,
+ struct btree_iter *iter,
+ struct bkey_i *insert)
{
- return __bch2_trans_update2(trans, (struct btree_insert_entry) {
+ __bch2_trans_update2(trans, (struct btree_insert_entry) {
.bkey_type = __btree_node_type(iter->level, iter->btree_id),
.btree_id = iter->btree_id,
.level = iter->level,
@@ -745,82 +743,81 @@ static int extent_update_to_keys(struct btree_trans *trans,
BTREE_ITER_NOT_EXTENTS);
n.is_extent = false;
- ret = __bch2_trans_update2(trans, n);
+ __bch2_trans_update2(trans, n);
bch2_trans_iter_put(trans, n.iter);
- return ret;
+ return 0;
}
static int extent_handle_overwrites(struct btree_trans *trans,
enum btree_id btree_id,
- struct bpos start, struct bpos end)
+ struct bkey_i *insert)
{
struct btree_iter *iter, *update_iter;
+ struct bpos start = bkey_start_pos(&insert->k);
struct bkey_i *update;
struct bkey_s_c k;
int ret = 0;
- iter = bch2_trans_get_iter(trans, btree_id, start, BTREE_ITER_INTENT);
+ iter = bch2_trans_get_iter(trans, btree_id, start,
+ BTREE_ITER_INTENT);
k = bch2_btree_iter_peek_with_updates(iter);
while (k.k && !(ret = bkey_err(k))) {
- if (bkey_cmp(end, bkey_start_pos(k.k)) <= 0)
+ if (bkey_cmp(insert->k.p, bkey_start_pos(k.k)) <= 0)
break;
if (bkey_cmp(bkey_start_pos(k.k), start) < 0) {
update = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
if ((ret = PTR_ERR_OR_ZERO(update)))
- goto err;
+ break;
bkey_reassemble(update, k);
+
bch2_cut_back(start, update);
- update_iter = bch2_trans_copy_iter(trans, iter);
- update_iter->flags &= ~BTREE_ITER_IS_EXTENTS;
- bch2_btree_iter_set_pos(update_iter, update->k.p);
- ret = bch2_trans_update2(trans, update_iter, update);
+ update_iter = bch2_trans_get_iter(trans, btree_id, update->k.p,
+ BTREE_ITER_NOT_EXTENTS|
+ BTREE_ITER_INTENT);
+ bch2_trans_update2(trans, update_iter, update);
bch2_trans_iter_put(trans, update_iter);
- if (ret)
- goto err;
}
- if (bkey_cmp(k.k->p, end) > 0) {
- update = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
+ if (bkey_cmp(k.k->p, insert->k.p) < 0 ||
+ (!bkey_cmp(k.k->p, insert->k.p) && bkey_deleted(&insert->k))) {
+ update = bch2_trans_kmalloc(trans, sizeof(struct bkey));
if ((ret = PTR_ERR_OR_ZERO(update)))
- goto err;
+ break;
- bkey_reassemble(update, k);
- bch2_cut_front(end, update);
+ bkey_init(&update->k);
+ update->k.p = k.k->p;
- update_iter = bch2_trans_copy_iter(trans, iter);
- update_iter->flags &= ~BTREE_ITER_IS_EXTENTS;
- bch2_btree_iter_set_pos(update_iter, update->k.p);
- ret = bch2_trans_update2(trans, update_iter, update);
+ update_iter = bch2_trans_get_iter(trans, btree_id, update->k.p,
+ BTREE_ITER_NOT_EXTENTS|
+ BTREE_ITER_INTENT);
+ bch2_trans_update2(trans, update_iter, update);
bch2_trans_iter_put(trans, update_iter);
- if (ret)
- goto err;
- } else {
- update = bch2_trans_kmalloc(trans, sizeof(struct bkey));
+ }
+
+ if (bkey_cmp(k.k->p, insert->k.p) > 0) {
+ update = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
if ((ret = PTR_ERR_OR_ZERO(update)))
- goto err;
+ break;
- update->k = *k.k;
- set_bkey_val_u64s(&update->k, 0);
- update->k.type = KEY_TYPE_deleted;
- update->k.size = 0;
+ bkey_reassemble(update, k);
+ bch2_cut_front(insert->k.p, update);
- update_iter = bch2_trans_copy_iter(trans, iter);
- update_iter->flags &= ~BTREE_ITER_IS_EXTENTS;
- bch2_btree_iter_set_pos(update_iter, update->k.p);
- ret = bch2_trans_update2(trans, update_iter, update);
+ update_iter = bch2_trans_get_iter(trans, btree_id, update->k.p,
+ BTREE_ITER_NOT_EXTENTS|
+ BTREE_ITER_INTENT);
+ bch2_trans_update2(trans, update_iter, update);
bch2_trans_iter_put(trans, update_iter);
- if (ret)
- goto err;
+ break;
}
k = bch2_btree_iter_next_with_updates(iter);
}
-err:
bch2_trans_iter_put(trans, iter);
+
return ret;
}
@@ -885,24 +882,16 @@ int __bch2_trans_commit(struct btree_trans *trans)
/* Turn extents updates into keys: */
trans_for_each_update(trans, i)
if (i->is_extent) {
- struct bpos start = bkey_start_pos(&i->k->k);
-
- while (i + 1 < trans->updates + trans->nr_updates &&
- i[0].btree_id == i[1].btree_id &&
- !bkey_cmp(i[0].k->k.p, bkey_start_pos(&i[1].k->k)))
- i++;
-
- ret = extent_handle_overwrites(trans, i->btree_id,
- start, i->k->k.p);
- if (ret)
+ ret = extent_handle_overwrites(trans, i->btree_id, i->k);
+ if (unlikely(ret))
goto out;
}
trans_for_each_update(trans, i) {
ret = i->is_extent
? extent_update_to_keys(trans, *i)
- : __bch2_trans_update2(trans, *i);
- if (ret)
+ : (__bch2_trans_update2(trans, *i), 0);
+ if (unlikely(ret))
goto out;
}