summaryrefslogtreecommitdiff
path: root/fs/bcachefs/btree_iter.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-03-27 22:03:30 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:18 -0400
commit0f2383677172176691bbc760c5af4d87f67f78fc (patch)
tree880ad6e20a36b1d6408a80e9995b5f3fed269138 /fs/bcachefs/btree_iter.h
parent7c26ecae326aee84bb53cfb163108a20fb3094d1 (diff)
downloadlwn-0f2383677172176691bbc760c5af4d87f67f78fc.tar.gz
lwn-0f2383677172176691bbc760c5af4d87f67f78fc.zip
bcachefs: trans_for_each_iter()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_iter.h')
-rw-r--r--fs/bcachefs/btree_iter.h103
1 files changed, 59 insertions, 44 deletions
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
index 4be472e45310..70b5cc6ee5ab 100644
--- a/fs/bcachefs/btree_iter.h
+++ b/fs/bcachefs/btree_iter.h
@@ -23,11 +23,44 @@ static inline struct btree *btree_node_parent(struct btree_iter *iter,
return btree_iter_node(iter, b->level + 1);
}
+static inline bool btree_trans_has_multiple_iters(const struct btree_trans *trans)
+{
+ return hweight64(trans->iters_linked) > 1;
+}
+
static inline bool btree_iter_linked(const struct btree_iter *iter)
{
return iter->next != iter;
}
+static inline int btree_iter_err(const struct btree_iter *iter)
+{
+ return iter->flags & BTREE_ITER_ERROR ? -EIO : 0;
+}
+
+/* Iterate over iters within a transaction: */
+
+static inline struct btree_iter *
+__trans_next_iter(struct btree_trans *trans, struct btree_iter *iter)
+{
+ unsigned idx;
+
+ /* XXX expensive pointer subtraction: */
+
+ for (idx = iter - trans->iters;
+ idx < trans->nr_iters;
+ idx++)
+ if (trans->iters_linked & (1ULL << idx))
+ return &trans->iters[idx];
+
+ return NULL;
+}
+
+#define trans_for_each_iter(_trans, _iter) \
+ for (_iter = (_trans)->iters; \
+ (_iter = __trans_next_iter((_trans), _iter)); \
+ _iter++)
+
static inline bool __iter_has_node(const struct btree_iter *iter,
const struct btree *b)
{
@@ -44,59 +77,39 @@ static inline bool __iter_has_node(const struct btree_iter *iter,
}
static inline struct btree_iter *
-__next_linked_iter(struct btree_iter *iter, struct btree_iter *linked)
+__trans_next_iter_with_node(struct btree_trans *trans, struct btree *b,
+ struct btree_iter *iter)
{
- return linked->next != iter ? linked->next : NULL;
-}
+ unsigned idx;
-static inline struct btree_iter *
-__next_iter_with_node(struct btree_iter *iter, struct btree *b,
- struct btree_iter *linked)
-{
- while (linked && !__iter_has_node(linked, b))
- linked = __next_linked_iter(iter, linked);
+ /* XXX expensive pointer subtraction: */
+
+ for (idx = iter - trans->iters;
+ idx < trans->nr_iters;
+ idx++) {
+ if (!(trans->iters_linked & (1ULL << idx)))
+ continue;
- return linked;
+ iter = &trans->iters[idx];
+ if (__iter_has_node(iter, b))
+ return iter;
+ }
+
+ return NULL;
}
-/**
- * for_each_btree_iter - iterate over all iterators linked with @_iter,
- * including @_iter
- */
-#define for_each_btree_iter(_iter, _linked) \
- for ((_linked) = (_iter); (_linked); \
- (_linked) = __next_linked_iter(_iter, _linked))
-
-/**
- * for_each_btree_iter_with_node - iterate over all iterators linked with @_iter
- * that also point to @_b
- *
- * @_b is assumed to be locked by @_iter
- *
- * Filters out iterators that don't have a valid btree_node iterator for @_b -
- * i.e. iterators for which bch2_btree_node_relock() would not succeed.
- */
-#define for_each_btree_iter_with_node(_iter, _b, _linked) \
- for ((_linked) = (_iter); \
- ((_linked) = __next_iter_with_node(_iter, _b, _linked)); \
- (_linked) = __next_linked_iter(_iter, _linked))
-
-/**
- * for_each_linked_btree_iter - iterate over all iterators linked with @_iter,
- * _not_ including @_iter
- */
-#define for_each_linked_btree_iter(_iter, _linked) \
- for ((_linked) = (_iter)->next; \
- (_linked) != (_iter); \
- (_linked) = (_linked)->next)
+#define trans_for_each_iter_with_node(_trans, _b, _iter) \
+ for (_iter = (_trans)->iters; \
+ (_iter = __trans_next_iter_with_node((_trans), (_b), _iter));\
+ _iter++)
#ifdef CONFIG_BCACHEFS_DEBUG
void bch2_btree_iter_verify(struct btree_iter *, struct btree *);
-void bch2_btree_iter_verify_locks(struct btree_iter *);
+void bch2_btree_trans_verify_locks(struct btree_trans *);
#else
static inline void bch2_btree_iter_verify(struct btree_iter *iter,
struct btree *b) {}
-static inline void bch2_btree_iter_verify_locks(struct btree_iter *iter) {}
+static inline void bch2_btree_trans_verify_locks(struct btree_trans *iter) {}
#endif
void bch2_btree_node_iter_fix(struct btree_iter *, struct btree *,
@@ -104,7 +117,9 @@ void bch2_btree_node_iter_fix(struct btree_iter *, struct btree *,
unsigned, unsigned);
int bch2_btree_iter_unlock(struct btree_iter *);
-bool bch2_btree_iter_relock(struct btree_iter *);
+
+bool bch2_btree_trans_relock(struct btree_trans *);
+void bch2_btree_trans_unlock(struct btree_trans *);
bool __bch2_btree_iter_upgrade(struct btree_iter *, unsigned);
bool __bch2_btree_iter_upgrade_nounlock(struct btree_iter *, unsigned);
@@ -252,7 +267,7 @@ static inline struct bkey_s_c __bch2_btree_iter_next(struct btree_iter *iter,
!IS_ERR_OR_NULL((_k).k); \
(_k) = __bch2_btree_iter_next(_iter, _flags))
-static inline int btree_iter_err(struct bkey_s_c k)
+static inline int bkey_err(struct bkey_s_c k)
{
return PTR_ERR_OR_ZERO(k.k);
}