diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-04-28 23:52:19 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:06 -0400 |
commit | 81d22e5d832452ee479c64d5678c7422bc1bef5b (patch) | |
tree | 98fdb6a0523a382e07cd945c54d2ea837b228670 /fs/bcachefs/btree_update_leaf.c | |
parent | 59ba21d99fc7a19d32fc4c2cb21509b8876d8e01 (diff) | |
download | lwn-81d22e5d832452ee479c64d5678c7422bc1bef5b.tar.gz lwn-81d22e5d832452ee479c64d5678c7422bc1bef5b.zip |
bcachefs: Refactor extent_handle_overwrites()
Prep work for extent merging
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 | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index e16feeebcf2c..1c12a11e45f7 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -775,74 +775,94 @@ bch2_trans_commit_get_rw_cold(struct btree_trans *trans) return 0; } +static int __btree_delete_at(struct btree_trans *trans, enum btree_id btree_id, + struct bpos pos, unsigned trigger_flags) +{ + struct btree_iter *iter; + struct bkey_i *update; + int ret; + + update = bch2_trans_kmalloc(trans, sizeof(struct bkey)); + if ((ret = PTR_ERR_OR_ZERO(update))) + return ret; + + bkey_init(&update->k); + update->k.p = pos; + + iter = bch2_trans_get_iter(trans, btree_id, pos, + BTREE_ITER_NOT_EXTENTS| + BTREE_ITER_INTENT); + bch2_trans_update(trans, iter, update, trigger_flags); + bch2_trans_iter_put(trans, iter); + return 0; +} + static int extent_handle_overwrites(struct btree_trans *trans, - enum btree_id btree_id, - struct bkey_i *insert, - unsigned trigger_flags) + struct btree_insert_entry *i) { struct btree_iter *iter, *update_iter; - struct bpos start = bkey_start_pos(&insert->k); + struct bpos start = bkey_start_pos(&i->k->k); struct bkey_i *update; struct bkey_s_c k; - int ret; + int ret = 0; - for_each_btree_key(trans, iter, btree_id, start, - BTREE_ITER_INTENT| - BTREE_ITER_WITH_UPDATES, k, ret) { - if (bkey_cmp(insert->k.p, bkey_start_pos(k.k)) <= 0) - break; + iter = bch2_trans_get_iter(trans, i->btree_id, start, + BTREE_ITER_INTENT| + BTREE_ITER_WITH_UPDATES| + BTREE_ITER_NOT_EXTENTS); + k = bch2_btree_iter_peek(iter); + if (!k.k || (ret = bkey_err(k))) + goto out; + if (!bkey_cmp(k.k->p, bkey_start_pos(&i->k->k))) + goto next; + + while (bkey_cmp(i->k->k.p, bkey_start_pos(k.k)) > 0) { 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))) - break; + goto out; bkey_reassemble(update, k); bch2_cut_back(start, update); - update_iter = bch2_trans_get_iter(trans, btree_id, update->k.p, + update_iter = bch2_trans_get_iter(trans, i->btree_id, update->k.p, BTREE_ITER_NOT_EXTENTS| BTREE_ITER_INTENT); - bch2_trans_update(trans, update_iter, update, - trigger_flags); + bch2_trans_update(trans, update_iter, update, i->trigger_flags); bch2_trans_iter_put(trans, update_iter); } - 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))) - break; - - bkey_init(&update->k); - update->k.p = k.k->p; - - update_iter = bch2_trans_get_iter(trans, btree_id, update->k.p, - BTREE_ITER_NOT_EXTENTS| - BTREE_ITER_INTENT); - bch2_trans_update(trans, update_iter, update, - trigger_flags); - bch2_trans_iter_put(trans, update_iter); + if (bkey_cmp(k.k->p, i->k->k.p) <= 0) { + ret = __btree_delete_at(trans, i->btree_id, k.k->p, + i->trigger_flags); + if (ret) + goto out; } - if (bkey_cmp(k.k->p, insert->k.p) > 0) { + if (bkey_cmp(k.k->p, i->k->k.p) > 0) { update = bch2_trans_kmalloc(trans, bkey_bytes(k.k)); if ((ret = PTR_ERR_OR_ZERO(update))) - break; + goto out; bkey_reassemble(update, k); - bch2_cut_front(insert->k.p, update); + bch2_cut_front(i->k->k.p, update); - update_iter = bch2_trans_get_iter(trans, btree_id, update->k.p, + update_iter = bch2_trans_get_iter(trans, i->btree_id, update->k.p, BTREE_ITER_NOT_EXTENTS| BTREE_ITER_INTENT); bch2_trans_update(trans, update_iter, update, - trigger_flags); + i->trigger_flags); bch2_trans_iter_put(trans, update_iter); - break; + goto out; } +next: + k = bch2_btree_iter_next(iter); + if (!k.k || (ret = bkey_err(k))) + goto out; } +out: bch2_trans_iter_put(trans, iter); return ret; @@ -1002,7 +1022,7 @@ int bch2_trans_update(struct btree_trans *trans, struct btree_iter *iter, if (ret) return ret; - ret = extent_handle_overwrites(trans, n.btree_id, n.k, flags); + ret = extent_handle_overwrites(trans, &n); if (ret) return ret; @@ -1012,7 +1032,7 @@ int bch2_trans_update(struct btree_trans *trans, struct btree_iter *iter, if (bkey_deleted(&n.k->k)) return 0; - n.iter = bch2_trans_get_iter(trans, n.iter->btree_id, n.k->k.p, + n.iter = bch2_trans_get_iter(trans, n.btree_id, n.k->k.p, BTREE_ITER_INTENT| BTREE_ITER_NOT_EXTENTS); bch2_trans_iter_put(trans, n.iter); |