summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_iter.h
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/btree_iter.h')
-rw-r--r--libbcachefs/btree_iter.h107
1 files changed, 104 insertions, 3 deletions
diff --git a/libbcachefs/btree_iter.h b/libbcachefs/btree_iter.h
index ff29478..c630ab5 100644
--- a/libbcachefs/btree_iter.h
+++ b/libbcachefs/btree_iter.h
@@ -397,19 +397,76 @@ void *__bch2_trans_kmalloc(struct btree_trans *, size_t);
static inline void *bch2_trans_kmalloc(struct btree_trans *trans, size_t size)
{
- unsigned new_top = trans->mem_top + size;
- void *p = trans->mem + trans->mem_top;
+ size = roundup(size, 8);
+
+ if (likely(trans->mem_top + size <= trans->mem_bytes)) {
+ void *p = trans->mem + trans->mem_top;
- if (likely(new_top <= trans->mem_bytes)) {
trans->mem_top += size;
memset(p, 0, size);
return p;
} else {
return __bch2_trans_kmalloc(trans, size);
+ }
+}
+
+static inline void *bch2_trans_kmalloc_nomemzero(struct btree_trans *trans, size_t size)
+{
+ size = roundup(size, 8);
+
+ if (likely(trans->mem_top + size <= trans->mem_bytes)) {
+ void *p = trans->mem + trans->mem_top;
+ trans->mem_top += size;
+ return p;
+ } else {
+ return __bch2_trans_kmalloc(trans, size);
}
}
+static inline struct bkey_i *bch2_bkey_make_mut(struct btree_trans *trans, struct bkey_s_c k)
+{
+ struct bkey_i *mut = bch2_trans_kmalloc_nomemzero(trans, bkey_bytes(k.k));
+
+ if (!IS_ERR(mut))
+ bkey_reassemble(mut, k);
+ return mut;
+}
+
+static inline struct bkey_i *bch2_bkey_get_mut(struct btree_trans *trans,
+ struct btree_iter *iter)
+{
+ struct bkey_s_c k = bch2_btree_iter_peek_slot(iter);
+
+ return unlikely(IS_ERR(k.k))
+ ? ERR_CAST(k.k)
+ : bch2_bkey_make_mut(trans, k);
+}
+
+#define bch2_bkey_get_mut_typed(_trans, _iter, _type) \
+({ \
+ struct bkey_i *_k = bch2_bkey_get_mut(_trans, _iter); \
+ struct bkey_i_##_type *_ret; \
+ \
+ if (IS_ERR(_k)) \
+ _ret = ERR_CAST(_k); \
+ else if (unlikely(_k->k.type != KEY_TYPE_##_type)) \
+ _ret = ERR_PTR(-ENOENT); \
+ else \
+ _ret = bkey_i_to_##_type(_k); \
+ _ret; \
+})
+
+#define bch2_bkey_alloc(_trans, _iter, _type) \
+({ \
+ struct bkey_i_##_type *_k = bch2_trans_kmalloc(_trans, sizeof(*_k));\
+ if (!IS_ERR(_k)) { \
+ bkey_##_type##_init(&_k->k_i); \
+ _k->k.p = (_iter)->pos; \
+ } \
+ _k; \
+})
+
u32 bch2_trans_begin(struct btree_trans *);
static inline struct btree *
@@ -575,6 +632,36 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans,
_ret; \
})
+#define for_each_btree_key2_upto(_trans, _iter, _btree_id, \
+ _start, _end, _flags, _k, _do) \
+({ \
+ int _ret = 0; \
+ \
+ bch2_trans_iter_init((_trans), &(_iter), (_btree_id), \
+ (_start), (_flags)); \
+ \
+ while (1) { \
+ u32 _restart_count = bch2_trans_begin(_trans); \
+ \
+ _ret = 0; \
+ (_k) = bch2_btree_iter_peek_upto_type(&(_iter), _end, (_flags));\
+ if (!(_k).k) \
+ break; \
+ \
+ _ret = bkey_err(_k) ?: (_do); \
+ if (bch2_err_matches(_ret, BCH_ERR_transaction_restart))\
+ continue; \
+ if (_ret) \
+ break; \
+ bch2_trans_verify_not_restarted(_trans, _restart_count);\
+ if (!bch2_btree_iter_advance(&(_iter))) \
+ break; \
+ } \
+ \
+ bch2_trans_iter_exit((_trans), &(_iter)); \
+ _ret; \
+})
+
#define for_each_btree_key_reverse(_trans, _iter, _btree_id, \
_start, _flags, _k, _do) \
({ \
@@ -613,6 +700,14 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans,
(_do) ?: bch2_trans_commit(_trans, (_disk_res),\
(_journal_seq), (_commit_flags)))
+#define for_each_btree_key_upto_commit(_trans, _iter, _btree_id, \
+ _start, _end, _iter_flags, _k, \
+ _disk_res, _journal_seq, _commit_flags,\
+ _do) \
+ for_each_btree_key2_upto(_trans, _iter, _btree_id, _start, _end, _iter_flags, _k,\
+ (_do) ?: bch2_trans_commit(_trans, (_disk_res),\
+ (_journal_seq), (_commit_flags)))
+
#define for_each_btree_key(_trans, _iter, _btree_id, \
_start, _flags, _k, _ret) \
for (bch2_trans_iter_init((_trans), &(_iter), (_btree_id), \
@@ -649,6 +744,12 @@ __bch2_btree_iter_peek_and_restart(struct btree_trans *trans,
!((_ret) = bkey_err(_k)) && (_k).k; \
bch2_btree_iter_advance(&(_iter)))
+#define for_each_btree_key_upto_continue_norestart(_iter, _end, _flags, _k, _ret)\
+ for (; \
+ (_k) = bch2_btree_iter_peek_upto_type(&(_iter), _end, _flags), \
+ !((_ret) = bkey_err(_k)) && (_k).k; \
+ bch2_btree_iter_advance(&(_iter)))
+
/* new multiple iterator interface: */
void bch2_trans_updates_to_text(struct printbuf *, struct btree_trans *);