diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-03-20 21:04:57 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:56 -0400 |
commit | 4cfb722ca16d89ada724c142201fc86872283a90 (patch) | |
tree | f97235cd433078e18abe252c0feb7ad13a688934 /fs/bcachefs/btree_update_leaf.c | |
parent | 4ce41957a7370e398dd1ae960e5184af8315de35 (diff) | |
download | lwn-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.c | 103 |
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; } |