summaryrefslogtreecommitdiff
path: root/fs/bcachefs/str_hash.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-09-26 22:21:39 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:28 -0400
commit64bc00115335450c4178fea04c5b664cf73a9729 (patch)
tree3e491d56806bfa5037273a1dd4fb631a2c8177c7 /fs/bcachefs/str_hash.h
parenta7199432c3cbcd42141cfd5c047bf8828c2390d8 (diff)
bcachefs: Rework btree iterator lifetimes
The btree_trans struct needs to memoize/cache btree iterators, so that on transaction restart we don't have to completely redo btree lookups, and so that we can do them all at once in the correct order when the transaction had to restart to avoid a deadlock. This switches the btree iterator lookups to work based on iterator position, instead of trying to match them up based on the stack trace. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/str_hash.h')
-rw-r--r--fs/bcachefs/str_hash.h25
1 files changed, 13 insertions, 12 deletions
diff --git a/fs/bcachefs/str_hash.h b/fs/bcachefs/str_hash.h
index 886f1bc8aa14..31e55acbbead 100644
--- a/fs/bcachefs/str_hash.h
+++ b/fs/bcachefs/str_hash.h
@@ -202,12 +202,13 @@ int bch2_hash_needs_whiteout(struct btree_trans *trans,
if (k.k->type == desc.key_type &&
desc.hash_bkey(info, k) <= start->pos.offset) {
- bch2_trans_iter_free_on_commit(trans, iter);
- return 1;
+ iter->flags |= BTREE_ITER_KEEP_UNTIL_COMMIT;
+ ret = 1;
+ break;
}
}
- bch2_trans_iter_free(trans, iter);
+ bch2_trans_iter_put(trans, iter);
return ret;
}
@@ -247,11 +248,14 @@ int bch2_hash_set(struct btree_trans *trans,
goto not_found;
}
+ if (!ret)
+ ret = -ENOSPC;
+out:
if (slot)
- bch2_trans_iter_free(trans, slot);
- bch2_trans_iter_free(trans, iter);
+ bch2_trans_iter_put(trans, slot);
+ bch2_trans_iter_put(trans, iter);
- return ret ?: -ENOSPC;
+ return ret;
found:
found = true;
not_found:
@@ -261,17 +265,14 @@ not_found:
} else if (found && (flags & BCH_HASH_SET_MUST_CREATE)) {
ret = -EEXIST;
} else {
- if (!found && slot) {
- bch2_trans_iter_free(trans, iter);
- iter = slot;
- }
+ if (!found && slot)
+ swap(iter, slot);
insert->k.p = iter->pos;
bch2_trans_update(trans, iter, insert);
- bch2_trans_iter_free_on_commit(trans, iter);
}
- return ret;
+ goto out;
}
static __always_inline