Commit 7dcbdbd8 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bch2_path_put_nokeep()

The btree iterator code may allocate extra btree paths, temporarily,
that do not refer to keys being returned: we don't need to wait until
transaction restart to drop these, when they're not referenced they
should be deleted right away.

This fixes a transaction path overflow bug.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 5b3243cb
...@@ -1299,6 +1299,18 @@ void bch2_path_put(struct btree_trans *trans, struct btree_path *path, bool inte ...@@ -1299,6 +1299,18 @@ void bch2_path_put(struct btree_trans *trans, struct btree_path *path, bool inte
__bch2_path_free(trans, path); __bch2_path_free(trans, path);
} }
static void bch2_path_put_nokeep(struct btree_trans *trans, struct btree_path *path,
bool intent)
{
EBUG_ON(trans->paths + path->idx != path);
EBUG_ON(!path->ref);
if (!__btree_path_put(path, intent))
return;
__bch2_path_free(trans, path);
}
noinline __cold noinline __cold
void bch2_trans_updates_to_text(struct printbuf *buf, struct btree_trans *trans) void bch2_trans_updates_to_text(struct printbuf *buf, struct btree_trans *trans)
{ {
...@@ -1962,7 +1974,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e ...@@ -1962,7 +1974,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
EBUG_ON(iter->flags & BTREE_ITER_ALL_LEVELS); EBUG_ON(iter->flags & BTREE_ITER_ALL_LEVELS);
if (iter->update_path) { if (iter->update_path) {
bch2_path_put(trans, iter->update_path, bch2_path_put_nokeep(trans, iter->update_path,
iter->flags & BTREE_ITER_INTENT); iter->flags & BTREE_ITER_INTENT);
iter->update_path = NULL; iter->update_path = NULL;
} }
...@@ -1994,7 +2006,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e ...@@ -1994,7 +2006,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
if (iter->update_path && if (iter->update_path &&
bkey_cmp(iter->update_path->pos, k.k->p)) { bkey_cmp(iter->update_path->pos, k.k->p)) {
bch2_path_put(trans, iter->update_path, bch2_path_put_nokeep(trans, iter->update_path,
iter->flags & BTREE_ITER_INTENT); iter->flags & BTREE_ITER_INTENT);
iter->update_path = NULL; iter->update_path = NULL;
} }
...@@ -2237,7 +2249,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter) ...@@ -2237,7 +2249,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
* that candidate * that candidate
*/ */
if (saved_path && bkey_cmp(k.k->p, saved_k.p)) { if (saved_path && bkey_cmp(k.k->p, saved_k.p)) {
bch2_path_put(trans, iter->path, bch2_path_put_nokeep(trans, iter->path,
iter->flags & BTREE_ITER_INTENT); iter->flags & BTREE_ITER_INTENT);
iter->path = saved_path; iter->path = saved_path;
saved_path = NULL; saved_path = NULL;
...@@ -2250,7 +2262,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter) ...@@ -2250,7 +2262,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
iter->snapshot, iter->snapshot,
k.k->p.snapshot)) { k.k->p.snapshot)) {
if (saved_path) if (saved_path)
bch2_path_put(trans, saved_path, bch2_path_put_nokeep(trans, saved_path,
iter->flags & BTREE_ITER_INTENT); iter->flags & BTREE_ITER_INTENT);
saved_path = btree_path_clone(trans, iter->path, saved_path = btree_path_clone(trans, iter->path,
iter->flags & BTREE_ITER_INTENT); iter->flags & BTREE_ITER_INTENT);
...@@ -2294,7 +2306,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter) ...@@ -2294,7 +2306,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
btree_path_set_should_be_locked(iter->path); btree_path_set_should_be_locked(iter->path);
out_no_locked: out_no_locked:
if (saved_path) if (saved_path)
bch2_path_put(trans, saved_path, iter->flags & BTREE_ITER_INTENT); bch2_path_put_nokeep(trans, saved_path, iter->flags & BTREE_ITER_INTENT);
bch2_btree_iter_verify_entry_exit(iter); bch2_btree_iter_verify_entry_exit(iter);
bch2_btree_iter_verify(iter); bch2_btree_iter_verify(iter);
...@@ -2584,7 +2596,7 @@ void bch2_trans_iter_exit(struct btree_trans *trans, struct btree_iter *iter) ...@@ -2584,7 +2596,7 @@ void bch2_trans_iter_exit(struct btree_trans *trans, struct btree_iter *iter)
bch2_path_put(trans, iter->path, bch2_path_put(trans, iter->path,
iter->flags & BTREE_ITER_INTENT); iter->flags & BTREE_ITER_INTENT);
if (iter->update_path) if (iter->update_path)
bch2_path_put(trans, iter->update_path, bch2_path_put_nokeep(trans, iter->update_path,
iter->flags & BTREE_ITER_INTENT); iter->flags & BTREE_ITER_INTENT);
if (iter->key_cache_path) if (iter->key_cache_path)
bch2_path_put(trans, iter->key_cache_path, bch2_path_put(trans, iter->key_cache_path,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment