diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index d65edc460b07..0439c5b07f61 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -473,7 +473,7 @@ static void __bch2_btree_iter_verify(struct btree_iter *iter, } BUG_ON(iter->uptodate == BTREE_ITER_UPTODATE && - (iter->flags & BTREE_ITER_TYPE) == BTREE_ITER_KEYS && + btree_iter_type(iter) == BTREE_ITER_KEYS && !bkey_whiteout(&iter->k) && bch2_btree_node_iter_end(&l->iter)); } @@ -1152,6 +1152,7 @@ static inline void bch2_btree_iter_checks(struct btree_iter *iter, EBUG_ON(!!(iter->flags & BTREE_ITER_IS_EXTENTS) != (btree_node_type_is_extents(iter->btree_id) && type != BTREE_ITER_NODES)); + EBUG_ON(btree_iter_type(iter) != type); bch2_btree_trans_verify_locks(iter->trans); } @@ -1661,7 +1662,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) { int ret; - bch2_btree_iter_checks(iter, BTREE_ITER_SLOTS); + bch2_btree_iter_checks(iter, BTREE_ITER_KEYS); if (iter->uptodate == BTREE_ITER_UPTODATE) return btree_iter_peek_uptodate(iter); @@ -1675,7 +1676,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) struct bkey_s_c bch2_btree_iter_next_slot(struct btree_iter *iter) { - bch2_btree_iter_checks(iter, BTREE_ITER_SLOTS); + bch2_btree_iter_checks(iter, BTREE_ITER_KEYS); iter->pos = btree_type_successor(iter->btree_id, iter->k.p); @@ -1830,7 +1831,7 @@ static int bch2_trans_realloc_iters(struct btree_trans *trans, return 0; } -static int btree_trans_iter_alloc(struct btree_trans *trans) +static struct btree_iter *btree_trans_iter_alloc(struct btree_trans *trans) { unsigned idx = __ffs64(~trans->iters_linked); @@ -1840,7 +1841,7 @@ static int btree_trans_iter_alloc(struct btree_trans *trans) if (trans->nr_iters == trans->size) { int ret = bch2_trans_realloc_iters(trans, trans->size * 2); if (ret) - return ret; + return ERR_PTR(ret); } idx = trans->nr_iters++; @@ -1850,7 +1851,7 @@ static int btree_trans_iter_alloc(struct btree_trans *trans) got_slot: BUG_ON(trans->iters_linked & (1ULL << idx)); trans->iters_linked |= 1ULL << idx; - return idx; + return &trans->iters[idx]; } static struct btree_iter *__btree_trans_get_iter(struct btree_trans *trans, @@ -1858,37 +1859,29 @@ static struct btree_iter *__btree_trans_get_iter(struct btree_trans *trans, unsigned flags, u64 iter_id) { struct btree_iter *iter; - int idx; BUG_ON(trans->nr_iters > BTREE_ITER_MAX); - for (idx = 0; idx < trans->nr_iters; idx++) { - if (!(trans->iters_linked & (1ULL << idx))) - continue; - - iter = &trans->iters[idx]; + trans_for_each_iter(trans, iter) if (iter_id ? iter->id == iter_id : (iter->btree_id == btree_id && !bkey_cmp(iter->pos, pos))) goto found; - } - idx = -1; -found: - if (idx < 0) { - idx = btree_trans_iter_alloc(trans); - if (idx < 0) - return ERR_PTR(idx); - iter = &trans->iters[idx]; + iter = NULL; +found: + if (!iter) { + iter = btree_trans_iter_alloc(trans); + if (IS_ERR(iter)) + return iter; + iter->id = iter_id; bch2_btree_iter_init(trans, iter, btree_id, pos, flags); } else { - iter = &trans->iters[idx]; - - iter->flags &= ~(BTREE_ITER_INTENT|BTREE_ITER_PREFETCH); - iter->flags |= flags & (BTREE_ITER_INTENT|BTREE_ITER_PREFETCH); + iter->flags &= ~(BTREE_ITER_SLOTS|BTREE_ITER_INTENT|BTREE_ITER_PREFETCH); + iter->flags |= flags & (BTREE_ITER_SLOTS|BTREE_ITER_INTENT|BTREE_ITER_PREFETCH); if ((iter->flags & BTREE_ITER_INTENT) && !bch2_btree_iter_upgrade(iter, 1)) { @@ -1898,9 +1891,9 @@ static struct btree_iter *__btree_trans_get_iter(struct btree_trans *trans, } BUG_ON(iter->btree_id != btree_id); - BUG_ON(trans->iters_live & (1ULL << idx)); - trans->iters_live |= 1ULL << idx; - trans->iters_touched |= 1ULL << idx; + BUG_ON(trans->iters_live & (1ULL << iter->idx)); + trans->iters_live |= 1ULL << iter->idx; + trans->iters_touched |= 1ULL << iter->idx; BUG_ON(iter->btree_id != btree_id); BUG_ON((iter->flags ^ flags) & BTREE_ITER_TYPE); @@ -1950,29 +1943,26 @@ struct btree_iter *bch2_trans_copy_iter(struct btree_trans *trans, struct btree_iter *src) { struct btree_iter *iter; - unsigned offset = offsetof(struct btree_iter, trans); - int i, idx; + int idx, i; - idx = btree_trans_iter_alloc(trans); - if (idx < 0) - return ERR_PTR(idx); + iter = btree_trans_iter_alloc(trans); + if (IS_ERR(iter)) + return iter; + + idx = iter->idx; + *iter = *src; + iter->idx = idx; trans->iters_live |= 1ULL << idx; trans->iters_touched |= 1ULL << idx; trans->iters_unlink_on_restart |= 1ULL << idx; - iter = &trans->iters[idx]; - - memcpy((void *) iter + offset, - (void *) src + offset, - sizeof(*iter) - offset); - for (i = 0; i < BTREE_MAX_DEPTH; i++) if (btree_node_locked(iter, i)) six_lock_increment(&iter->l[i].b->c.lock, __btree_lock_want(iter, i)); - return &trans->iters[idx]; + return iter; } static int bch2_trans_preload_mem(struct btree_trans *trans, size_t size) diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index 88e048fa0fba..299d1173df62 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -183,20 +183,20 @@ struct btree_node_iter { enum btree_iter_type { BTREE_ITER_KEYS, - BTREE_ITER_SLOTS, BTREE_ITER_NODES, }; #define BTREE_ITER_TYPE ((1 << 2) - 1) -#define BTREE_ITER_INTENT (1 << 2) -#define BTREE_ITER_PREFETCH (1 << 3) +#define BTREE_ITER_SLOTS (1 << 2) +#define BTREE_ITER_INTENT (1 << 3) +#define BTREE_ITER_PREFETCH (1 << 4) /* * Used in bch2_btree_iter_traverse(), to indicate whether we're searching for * @pos or the first key strictly greater than @pos */ -#define BTREE_ITER_IS_EXTENTS (1 << 4) -#define BTREE_ITER_ERROR (1 << 5) +#define BTREE_ITER_IS_EXTENTS (1 << 5) +#define BTREE_ITER_ERROR (1 << 6) enum btree_iter_uptodate { BTREE_ITER_UPTODATE = 0, @@ -241,6 +241,11 @@ struct btree_iter { u64 id; }; +static inline enum btree_iter_type btree_iter_type(struct btree_iter *iter) +{ + return iter->flags & BTREE_ITER_TYPE; +} + struct deferred_update { struct journal_preres res; struct journal_entry_pin journal; diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index 42c5719155e6..791e72ce1c29 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -447,10 +447,9 @@ static int bchfs_write_index_update(struct bch_write_op *wop) bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024); - iter = bch2_trans_get_iter(&trans, - BTREE_ID_EXTENTS, - bkey_start_pos(&k->k), - BTREE_ITER_INTENT); + iter = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS, + bkey_start_pos(&k->k), + BTREE_ITER_SLOTS|BTREE_ITER_INTENT); do { BKEY_PADDED(k) tmp; diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index b0bff54a18e2..07fe6b5cd517 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -1417,8 +1417,8 @@ static void bch2_rbio_narrow_crcs(struct bch_read_bio *rbio) bch2_trans_begin(&trans); iter = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS, rbio->pos, - BTREE_ITER_INTENT); - k = bch2_btree_iter_peek(iter); + BTREE_ITER_SLOTS|BTREE_ITER_INTENT); + k = bch2_btree_iter_peek_slot(iter); if (IS_ERR_OR_NULL(k.k)) goto out;