diff options
Diffstat (limited to 'libbcachefs/btree_iter.h')
-rw-r--r-- | libbcachefs/btree_iter.h | 107 |
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 *); |