diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-03-28 05:03:30 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-23 00:08:18 +0300 |
commit | 0f2383677172176691bbc760c5af4d87f67f78fc (patch) | |
tree | 880ad6e20a36b1d6408a80e9995b5f3fed269138 | |
parent | 7c26ecae326aee84bb53cfb163108a20fb3094d1 (diff) | |
download | linux-0f2383677172176691bbc760c5af4d87f67f78fc.tar.xz |
bcachefs: trans_for_each_iter()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/alloc_background.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/btree_cache.c | 6 | ||||
-rw-r--r-- | fs/bcachefs/btree_iter.c | 98 | ||||
-rw-r--r-- | fs/bcachefs/btree_iter.h | 103 | ||||
-rw-r--r-- | fs/bcachefs/btree_locking.h | 5 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 30 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 64 | ||||
-rw-r--r-- | fs/bcachefs/debug.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/ec.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/fs-io.c | 38 | ||||
-rw-r--r-- | fs/bcachefs/fsck.c | 123 | ||||
-rw-r--r-- | fs/bcachefs/inode.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/io.c | 10 | ||||
-rw-r--r-- | fs/bcachefs/migrate.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/move.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/quota.c | 2 |
16 files changed, 255 insertions, 248 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index 436eb1e1ab07..3549f0f54624 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -945,7 +945,7 @@ static int bch2_invalidate_one_bucket2(struct btree_trans *trans, bch2_btree_iter_set_pos(iter, POS(ca->dev_idx, b)); retry: k = bch2_btree_iter_peek_slot(iter); - ret = btree_iter_err(k); + ret = bkey_err(k); if (ret) return ret; diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c index 65fc82fba071..55aaa3e4aa84 100644 --- a/fs/bcachefs/btree_cache.c +++ b/fs/bcachefs/btree_cache.c @@ -814,7 +814,7 @@ struct btree *bch2_btree_node_get_sibling(struct bch_fs *c, * We might have got -EINTR because trylock failed, and we're * holding other locks that would cause us to deadlock: */ - for_each_linked_btree_iter(iter, linked) + trans_for_each_iter(iter->trans, linked) if (btree_iter_cmp(iter, linked) < 0) __bch2_btree_iter_unlock(linked); @@ -839,13 +839,13 @@ struct btree *bch2_btree_node_get_sibling(struct bch_fs *c, } } - bch2_btree_iter_relock(iter); + bch2_btree_trans_relock(iter->trans); } out: if (btree_lock_want(iter, level + 1) == BTREE_NODE_UNLOCKED) btree_node_unlock(iter, level + 1); - bch2_btree_iter_verify_locks(iter); + bch2_btree_trans_verify_locks(iter->trans); BUG_ON((!may_drop_locks || !IS_ERR(ret)) && (iter->uptodate >= BTREE_ITER_NEED_RELOCK || diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index 5280e77f548f..f018ca7999f7 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -70,7 +70,7 @@ void bch2_btree_node_unlock_write(struct btree *b, struct btree_iter *iter) EBUG_ON(iter->l[b->level].b != b); EBUG_ON(iter->l[b->level].lock_seq + 1 != b->lock.state.seq); - for_each_btree_iter_with_node(iter, b, linked) + trans_for_each_iter_with_node(iter->trans, b, linked) linked->l[b->level].lock_seq += 2; six_unlock_write(&b->lock); @@ -83,7 +83,7 @@ void __bch2_btree_node_lock_write(struct btree *b, struct btree_iter *iter) EBUG_ON(btree_node_read_locked(iter, b->level)); - for_each_linked_btree_iter(iter, linked) + trans_for_each_iter(iter->trans, linked) if (linked->l[b->level].b == b && btree_node_read_locked(linked, b->level)) readers++; @@ -187,7 +187,8 @@ static inline bool btree_iter_get_locks(struct btree_iter *iter, if (iter->uptodate == BTREE_ITER_NEED_RELOCK) iter->uptodate = BTREE_ITER_NEED_PEEK; - bch2_btree_iter_verify_locks(iter); + bch2_btree_trans_verify_locks(iter->trans); + return iter->uptodate < BTREE_ITER_NEED_RELOCK; } @@ -202,7 +203,7 @@ bool __bch2_btree_node_lock(struct btree *b, struct bpos pos, bool ret = true; /* Check if it's safe to block: */ - for_each_btree_iter(iter, linked) { + trans_for_each_iter(iter->trans, linked) { if (!linked->nodes_locked) continue; @@ -262,7 +263,7 @@ bool __bch2_btree_node_lock(struct btree *b, struct bpos pos, /* Btree iterator locking: */ #ifdef CONFIG_BCACHEFS_DEBUG -void __bch2_btree_iter_verify_locks(struct btree_iter *iter) +void bch2_btree_iter_verify_locks(struct btree_iter *iter) { unsigned l; @@ -279,35 +280,23 @@ void __bch2_btree_iter_verify_locks(struct btree_iter *iter) } } -void bch2_btree_iter_verify_locks(struct btree_iter *iter) +void bch2_btree_trans_verify_locks(struct btree_trans *trans) { - struct btree_iter *linked; - - for_each_btree_iter(iter, linked) - __bch2_btree_iter_verify_locks(linked); + struct btree_iter *iter; + trans_for_each_iter(trans, iter) + bch2_btree_iter_verify_locks(iter); } #endif __flatten -static bool __bch2_btree_iter_relock(struct btree_iter *iter) +static bool bch2_btree_iter_relock(struct btree_iter *iter) { return iter->uptodate >= BTREE_ITER_NEED_RELOCK ? btree_iter_get_locks(iter, false) : true; } -bool bch2_btree_iter_relock(struct btree_iter *iter) -{ - struct btree_iter *linked; - bool ret = true; - - for_each_btree_iter(iter, linked) - ret &= __bch2_btree_iter_relock(linked); - - return ret; -} - bool __bch2_btree_iter_upgrade(struct btree_iter *iter, unsigned new_locks_want) { @@ -325,8 +314,9 @@ bool __bch2_btree_iter_upgrade(struct btree_iter *iter, * on iterators that might lock ancestors before us to avoid getting * -EINTR later: */ - for_each_linked_btree_iter(iter, linked) - if (linked->btree_id == iter->btree_id && + trans_for_each_iter(iter->trans, linked) + if (linked != iter && + linked->btree_id == iter->btree_id && btree_iter_cmp(linked, iter) <= 0 && linked->locks_want < new_locks_want) { linked->locks_want = new_locks_want; @@ -371,7 +361,7 @@ void __bch2_btree_iter_downgrade(struct btree_iter *iter, * might have had to modify locks_want on linked iterators due to lock * ordering: */ - for_each_btree_iter(iter, linked) { + trans_for_each_iter(iter->trans, linked) { unsigned new_locks_want = downgrade_to ?: (linked->flags & BTREE_ITER_INTENT ? 1 : 0); @@ -394,19 +384,40 @@ void __bch2_btree_iter_downgrade(struct btree_iter *iter, } } - bch2_btree_iter_verify_locks(iter); + bch2_btree_trans_verify_locks(iter->trans); } int bch2_btree_iter_unlock(struct btree_iter *iter) { struct btree_iter *linked; - for_each_btree_iter(iter, linked) + trans_for_each_iter(iter->trans, linked) __bch2_btree_iter_unlock(linked); - return iter->flags & BTREE_ITER_ERROR ? -EIO : 0; + return btree_iter_err(iter); } +bool bch2_btree_trans_relock(struct btree_trans *trans) +{ + struct btree_iter *iter; + bool ret = true; + + trans_for_each_iter(trans, iter) + ret &= bch2_btree_iter_relock(iter); + + return ret; +} + +void bch2_btree_trans_unlock(struct btree_trans *trans) +{ + struct btree_iter *iter; + + trans_for_each_iter(trans, iter) + __bch2_btree_iter_unlock(iter); +} + +/* Btree transaction locking: */ + /* Btree iterator: */ #ifdef CONFIG_BCACHEFS_DEBUG @@ -464,7 +475,7 @@ void bch2_btree_iter_verify(struct btree_iter *iter, struct btree *b) { struct btree_iter *linked; - for_each_btree_iter_with_node(iter, b, linked) + trans_for_each_iter_with_node(iter->trans, b, linked) __bch2_btree_iter_verify(linked, b); } @@ -618,7 +629,7 @@ void bch2_btree_node_iter_fix(struct btree_iter *iter, __bch2_btree_node_iter_fix(iter, b, node_iter, t, where, clobber_u64s, new_u64s); - for_each_btree_iter_with_node(iter, b, linked) + trans_for_each_iter_with_node(iter->trans, b, linked) __bch2_btree_node_iter_fix(linked, b, &linked->l[b->level].iter, t, where, clobber_u64s, new_u64s); @@ -776,7 +787,7 @@ void bch2_btree_iter_node_replace(struct btree_iter *iter, struct btree *b) enum btree_node_locked_type t; struct btree_iter *linked; - for_each_btree_iter(iter, linked) + trans_for_each_iter(iter->trans, linked) if (btree_iter_pos_in_node(linked, b)) { /* * bch2_btree_iter_node_drop() has already been called - @@ -810,7 +821,7 @@ void bch2_btree_iter_node_drop(struct btree_iter *iter, struct btree *b) iter->l[level].b = BTREE_ITER_NOT_END; mark_btree_node_unlocked(iter, level); - for_each_btree_iter(iter, linked) + trans_for_each_iter(iter->trans, linked) if (linked->l[level].b == b) { __btree_node_unlock(linked, level); linked->l[level].b = BTREE_ITER_NOT_END; @@ -825,7 +836,7 @@ void bch2_btree_iter_reinit_node(struct btree_iter *iter, struct btree *b) { struct btree_iter *linked; - for_each_btree_iter_with_node(iter, b, linked) + trans_for_each_iter_with_node(iter->trans, b, linked) __btree_iter_init(linked, b->level); } @@ -1005,7 +1016,7 @@ retry: iter = iter->next; } while (iter != sorted_iters); - ret = btree_iter_linked(iter) ? -EINTR : 0; + ret = btree_trans_has_multiple_iters(iter->trans) ? -EINTR : 0; out: bch2_btree_cache_cannibalize_unlock(c); return ret; @@ -1051,7 +1062,7 @@ int __must_check __bch2_btree_iter_traverse(struct btree_iter *iter) if (unlikely(iter->level >= BTREE_MAX_DEPTH)) return 0; - if (__bch2_btree_iter_relock(iter)) + if (bch2_btree_iter_relock(iter)) return 0; /* @@ -1091,7 +1102,7 @@ int __must_check __bch2_btree_iter_traverse(struct btree_iter *iter) iter->uptodate = BTREE_ITER_NEED_PEEK; - bch2_btree_iter_verify_locks(iter); + bch2_btree_trans_verify_locks(iter->trans); __bch2_btree_iter_verify(iter, iter->l[iter->level].b); return 0; } @@ -1104,7 +1115,7 @@ int __must_check bch2_btree_iter_traverse(struct btree_iter *iter) if (unlikely(ret)) ret = btree_iter_traverse_error(iter, ret); - BUG_ON(ret == -EINTR && !btree_iter_linked(iter)); + BUG_ON(ret == -EINTR && !btree_trans_has_multiple_iters(iter->trans)); return ret; } @@ -1117,7 +1128,7 @@ static inline void bch2_btree_iter_checks(struct btree_iter *iter, (iter->btree_id == BTREE_ID_EXTENTS && type != BTREE_ITER_NODES)); - bch2_btree_iter_verify_locks(iter); + bch2_btree_trans_verify_locks(iter->trans); } /* Iterate across nodes (leaf and interior nodes) */ @@ -1619,7 +1630,7 @@ static void bch2_btree_iter_unlink(struct btree_iter *iter) if (!btree_iter_linked(iter)) return; - for_each_linked_btree_iter(iter, linked) + trans_for_each_iter(iter->trans, linked) if (linked->next == iter) { linked->next = iter->next; iter->next = iter; @@ -1686,7 +1697,7 @@ int bch2_trans_iter_put(struct btree_trans *trans, struct btree_iter *iter) { ssize_t idx = btree_trans_iter_idx(trans, iter); - int ret = (iter->flags & BTREE_ITER_ERROR) ? -EIO : 0; + int ret = btree_iter_err(iter); trans->iters_live &= ~(1ULL << idx); return ret; @@ -1706,7 +1717,7 @@ static inline void __bch2_trans_iter_free(struct btree_trans *trans, int bch2_trans_iter_free(struct btree_trans *trans, struct btree_iter *iter) { - int ret = (iter->flags & BTREE_ITER_ERROR) ? -EIO : 0; + int ret = btree_iter_err(iter); __bch2_trans_iter_free(trans, btree_trans_iter_idx(trans, iter)); return ret; @@ -1715,7 +1726,7 @@ int bch2_trans_iter_free(struct btree_trans *trans, int bch2_trans_iter_free_on_commit(struct btree_trans *trans, struct btree_iter *iter) { - int ret = (iter->flags & BTREE_ITER_ERROR) ? -EIO : 0; + int ret = btree_iter_err(iter); trans->iters_unlink_on_commit |= 1ULL << btree_trans_iter_idx(trans, iter); @@ -1966,8 +1977,7 @@ int bch2_trans_unlock(struct btree_trans *trans) unsigned idx = __ffs(iters); struct btree_iter *iter = &trans->iters[idx]; - if (iter->flags & BTREE_ITER_ERROR) - ret = -EIO; + ret = ret ?: btree_iter_err(iter); __bch2_btree_iter_unlock(iter); iters ^= 1 << idx; 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); } diff --git a/fs/bcachefs/btree_locking.h b/fs/bcachefs/btree_locking.h index c036cd0458a4..37e09474fde4 100644 --- a/fs/bcachefs/btree_locking.h +++ b/fs/bcachefs/btree_locking.h @@ -163,8 +163,9 @@ static inline bool btree_node_lock_increment(struct btree_iter *iter, { struct btree_iter *linked; - for_each_linked_btree_iter(iter, linked) - if (linked->l[level].b == b && + trans_for_each_iter(iter->trans, linked) + if (linked != iter && + linked->l[level].b == b && btree_node_locked_type(linked, level) >= want) { six_lock_increment(&b->lock, want); return true; diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index 8b96faf107f8..6e9a87c6b1be 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -246,7 +246,7 @@ void bch2_btree_node_free_inmem(struct bch_fs *c, struct btree *b, { struct btree_iter *linked; - for_each_btree_iter(iter, linked) + trans_for_each_iter(iter->trans, linked) BUG_ON(linked->l[b->level].b == b); /* @@ -1438,7 +1438,7 @@ static void btree_split(struct btree_update *as, struct btree *b, bch2_btree_node_free_inmem(c, b, iter); - bch2_btree_iter_verify_locks(iter); + bch2_btree_trans_verify_locks(iter->trans); bch2_time_stats_update(&c->times[BCH_TIME_btree_node_split], start_time); @@ -1474,7 +1474,7 @@ bch2_btree_insert_keys_interior(struct btree_update *as, struct btree *b, btree_update_updated_node(as, b); - for_each_btree_iter_with_node(iter, b, linked) + trans_for_each_iter_with_node(iter->trans, b, linked) bch2_btree_node_iter_peek(&linked->l[b->level].iter, b); bch2_btree_iter_verify(iter, b); @@ -1559,7 +1559,7 @@ int bch2_btree_split_leaf(struct bch_fs *c, struct btree_iter *iter, * We already have a disk reservation and open buckets pinned; this * allocation must not block: */ - for_each_btree_iter(iter, linked) + trans_for_each_iter(iter->trans, linked) if (linked->btree_id == BTREE_ID_EXTENTS) flags |= BTREE_INSERT_USE_RESERVE; @@ -1571,10 +1571,10 @@ int bch2_btree_split_leaf(struct bch_fs *c, struct btree_iter *iter, if (flags & BTREE_INSERT_NOUNLOCK) return -EINTR; - bch2_btree_iter_unlock(iter); + bch2_btree_trans_unlock(iter->trans); down_read(&c->gc_lock); - if (btree_iter_linked(iter)) + if (!bch2_btree_trans_relock(iter->trans)) ret = -EINTR; } @@ -1753,7 +1753,7 @@ retry: if (!(flags & BTREE_INSERT_GC_LOCK_HELD)) up_read(&c->gc_lock); out: - bch2_btree_iter_verify_locks(iter); + bch2_btree_trans_verify_locks(iter->trans); /* * Don't downgrade locks here: we're called after successful insert, @@ -2036,10 +2036,10 @@ int bch2_btree_node_update_key(struct bch_fs *c, struct btree_iter *iter, return -EINTR; if (!down_read_trylock(&c->gc_lock)) { - bch2_btree_iter_unlock(iter); + bch2_btree_trans_unlock(iter->trans); down_read(&c->gc_lock); - if (!bch2_btree_iter_relock(iter)) { + if (!bch2_btree_trans_relock(iter->trans)) { ret = -EINTR; goto err; } @@ -2050,15 +2050,15 @@ int bch2_btree_node_update_key(struct bch_fs *c, struct btree_iter *iter, /* bch2_btree_reserve_get will unlock */ ret = bch2_btree_cache_cannibalize_lock(c, &cl); if (ret) { - ret = -EINTR; - - bch2_btree_iter_unlock(iter); + bch2_btree_trans_unlock(iter->trans); up_read(&c->gc_lock); closure_sync(&cl); down_read(&c->gc_lock); - if (!bch2_btree_iter_relock(iter)) + if (!bch2_btree_trans_relock(iter->trans)) { + ret = -EINTR; goto err; + } } new_hash = bch2_btree_node_mem_alloc(c); @@ -2079,12 +2079,12 @@ int bch2_btree_node_update_key(struct bch_fs *c, struct btree_iter *iter, if (ret != -EINTR) goto err; - bch2_btree_iter_unlock(iter); + bch2_btree_trans_unlock(iter->trans); up_read(&c->gc_lock); closure_sync(&cl); down_read(&c->gc_lock); - if (!bch2_btree_iter_relock(iter)) + if (!bch2_btree_trans_relock(iter->trans)) goto err; } diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index 45838db7b991..8b043d3c19ad 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -51,25 +51,6 @@ static void btree_trans_unlock_write(struct btree_trans *trans) bch2_btree_node_unlock_write(i->iter->l[0].b, i->iter); } -static bool btree_trans_relock(struct btree_trans *trans) -{ - struct btree_insert_entry *i; - - trans_for_each_update_iter(trans, i) - return bch2_btree_iter_relock(i->iter); - return true; -} - -static void btree_trans_unlock(struct btree_trans *trans) -{ - struct btree_insert_entry *i; - - trans_for_each_update_iter(trans, i) { - bch2_btree_iter_unlock(i->iter); - break; - } -} - static inline int btree_trans_cmp(struct btree_insert_entry l, struct btree_insert_entry r) { @@ -422,8 +403,6 @@ static inline void btree_insert_entry_checks(struct btree_trans *trans, EBUG_ON((i->iter->flags & BTREE_ITER_IS_EXTENTS) && !(trans->flags & BTREE_INSERT_ATOMIC)); - - bch2_btree_iter_verify_locks(i->iter); } BUG_ON(debug_check_bkeys(c) && @@ -451,14 +430,14 @@ static int bch2_trans_journal_preres_get(struct btree_trans *trans) if (ret != -EAGAIN) return ret; - btree_trans_unlock(trans); + bch2_btree_trans_unlock(trans); ret = bch2_journal_preres_get(&c->journal, &trans->journal_preres, u64s, 0); if (ret) return ret; - if (!btree_trans_relock(trans)) { + if (!bch2_btree_trans_relock(trans)) { trans_restart(" (iter relock after journal preres get blocked)"); return -EINTR; } @@ -617,12 +596,9 @@ static inline int do_btree_insert_at(struct btree_trans *trans, * have been traversed/locked, depending on what the caller was * doing: */ - trans_for_each_update_iter(trans, i) { - for_each_btree_iter(i->iter, linked) - if (linked->uptodate < BTREE_ITER_NEED_RELOCK) - linked->flags |= BTREE_ITER_NOUNLOCK; - break; - } + trans_for_each_iter(trans, linked) + if (linked->uptodate < BTREE_ITER_NEED_RELOCK) + linked->flags |= BTREE_ITER_NOUNLOCK; } trans_for_each_update_iter(trans, i) @@ -707,20 +683,20 @@ int bch2_trans_commit_error(struct btree_trans *trans, return ret; } - if (btree_trans_relock(trans)) + if (bch2_btree_trans_relock(trans)) return 0; trans_restart(" (iter relock after marking replicas)"); ret = -EINTR; break; case BTREE_INSERT_NEED_JOURNAL_RES: - btree_trans_unlock(trans); + bch2_btree_trans_unlock(trans); ret = bch2_trans_journal_res_get(trans, JOURNAL_RES_GET_CHECK); if (ret) return ret; - if (btree_trans_relock(trans)) + if (bch2_btree_trans_relock(trans)) return 0; trans_restart(" (iter relock after journal res get blocked)"); @@ -785,10 +761,9 @@ static int __bch2_trans_commit(struct btree_trans *trans, goto err; } - if (i->iter->flags & BTREE_ITER_ERROR) { - ret = -EIO; + ret = btree_iter_err(i->iter); + if (ret) goto err; - } } ret = do_btree_insert_at(trans, stopped_at); @@ -802,16 +777,10 @@ static int __bch2_trans_commit(struct btree_trans *trans, bch2_btree_iter_downgrade(i->iter); err: /* make sure we didn't drop or screw up locks: */ - trans_for_each_update_iter(trans, i) { - bch2_btree_iter_verify_locks(i->iter); - break; - } + bch2_btree_trans_verify_locks(trans); - trans_for_each_update_iter(trans, i) { - for_each_btree_iter(i->iter, linked) - linked->flags &= ~BTREE_ITER_NOUNLOCK; - break; - } + trans_for_each_iter(trans, linked) + linked->flags &= ~BTREE_ITER_NOUNLOCK; return ret; } @@ -847,13 +816,14 @@ int bch2_trans_commit(struct btree_trans *trans, trans_for_each_update(trans, i) btree_insert_entry_checks(trans, i); + bch2_btree_trans_verify_locks(trans); if (unlikely(!(trans->flags & BTREE_INSERT_NOCHECK_RW) && !percpu_ref_tryget(&c->writes))) { if (likely(!(trans->flags & BTREE_INSERT_LAZY_RW))) return -EROFS; - btree_trans_unlock(trans); + bch2_btree_trans_unlock(trans); ret = bch2_fs_read_write_early(c); if (ret) @@ -861,7 +831,7 @@ int bch2_trans_commit(struct btree_trans *trans, percpu_ref_get(&c->writes); - if (!btree_trans_relock(trans)) { + if (!bch2_btree_trans_relock(trans)) { ret = -EINTR; goto err; } @@ -962,7 +932,7 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id, iter = bch2_trans_get_iter(&trans, id, start, BTREE_ITER_INTENT); while ((k = bch2_btree_iter_peek(iter)).k && - !(ret = btree_iter_err(k)) && + !(ret = bkey_err(k)) && bkey_cmp(iter->pos, end) < 0) { unsigned max_sectors = KEY_SIZE_MAX & (~0 << c->block_bits); /* really shouldn't be using a bare, unpadded bkey_i */ diff --git a/fs/bcachefs/debug.c b/fs/bcachefs/debug.c index 64e079280a9a..bb69a2acd8dd 100644 --- a/fs/bcachefs/debug.c +++ b/fs/bcachefs/debug.c @@ -226,7 +226,7 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf, iter = bch2_trans_get_iter(&trans, i->id, i->from, BTREE_ITER_PREFETCH); k = bch2_btree_iter_peek(iter); - while (k.k && !(err = btree_iter_err(k))) { + while (k.k && !(err = bkey_err(k))) { bch2_bkey_val_to_text(&PBUF(i->buf), i->c, k); i->bytes = strlen(i->buf); BUG_ON(i->bytes >= PAGE_SIZE); @@ -333,7 +333,7 @@ static ssize_t bch2_read_bfloat_failed(struct file *file, char __user *buf, iter = bch2_trans_get_iter(&trans, i->id, i->from, BTREE_ITER_PREFETCH); while ((k = bch2_btree_iter_peek(iter)).k && - !(err = btree_iter_err(k))) { + !(err = bkey_err(k))) { struct btree_iter_level *l = &iter->l[0]; struct bkey_packed *_k = bch2_btree_node_iter_peek(&l->iter, l->b); diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c index c33bcffa7871..5fc0025e66bf 100644 --- a/fs/bcachefs/ec.c +++ b/fs/bcachefs/ec.c @@ -426,7 +426,7 @@ int bch2_ec_read_extent(struct bch_fs *c, struct bch_read_bio *rbio) POS(0, stripe_idx), BTREE_ITER_SLOTS); k = bch2_btree_iter_peek_slot(iter); - if (btree_iter_err(k) || k.k->type != KEY_TYPE_stripe) { + if (bkey_err(k) || k.k->type != KEY_TYPE_stripe) { __bcache_io_error(c, "error doing reconstruct read: stripe not found"); kfree(buf); @@ -541,7 +541,7 @@ static int ec_stripe_mem_alloc(struct bch_fs *c, if (!__ec_stripe_mem_alloc(c, idx, GFP_NOWAIT|__GFP_NOWARN)) return 0; - bch2_btree_iter_unlock(iter); + bch2_btree_trans_unlock(iter->trans); if (!__ec_stripe_mem_alloc(c, idx, GFP_KERNEL)) return -EINTR; @@ -750,7 +750,7 @@ static int ec_stripe_update_ptrs(struct bch_fs *c, BTREE_ITER_INTENT); while ((k = bch2_btree_iter_peek(iter)).k && - !(ret = btree_iter_err(k)) && + !(ret = bkey_err(k)) && bkey_cmp(bkey_start_pos(k.k), pos->p) < 0) { idx = extent_matches_stripe(c, &s->key.v, k); if (idx < 0) { @@ -1170,7 +1170,7 @@ static int __bch2_stripe_write_key(struct btree_trans *trans, bch2_btree_iter_set_pos(iter, POS(0, idx)); k = bch2_btree_iter_peek_slot(iter); - ret = btree_iter_err(k); + ret = bkey_err(k); if (ret) return ret; diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index efc189c02db7..d865081d4a21 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -251,7 +251,7 @@ static int sum_sector_overwrites(struct btree_trans *trans, * carefully not advancing past @new and thus whatever leaf node * @_iter currently points to: */ - BUG_ON(btree_iter_err(old)); + BUG_ON(bkey_err(old)); if (allocating && !*allocating && @@ -322,10 +322,10 @@ static int bch2_extent_update(struct btree_trans *trans, if (i_sectors_delta || new_i_size > inode->ei_inode.bi_size) { if (c->opts.new_inode_updates) { - bch2_btree_iter_unlock(extent_iter); + bch2_btree_trans_unlock(trans); mutex_lock(&inode->ei_update_lock); - if (!bch2_btree_iter_relock(extent_iter)) { + if (!bch2_btree_trans_relock(trans)) { mutex_unlock(&inode->ei_update_lock); return -EINTR; } @@ -921,10 +921,11 @@ static void readpage_bio_extend(struct readpages_iter *iter, } } -static void bchfs_read(struct bch_fs *c, struct btree_iter *iter, +static void bchfs_read(struct btree_trans *trans, struct btree_iter *iter, struct bch_read_bio *rbio, u64 inum, struct readpages_iter *readpages_iter) { + struct bch_fs *c = trans->c; struct bio *bio = &rbio->bio; int flags = BCH_READ_RETRY_IF_STALE| BCH_READ_MAY_PROMOTE; @@ -943,7 +944,7 @@ static void bchfs_read(struct bch_fs *c, struct btree_iter *iter, BUG_ON(!k.k); if (IS_ERR(k.k)) { - int ret = bch2_btree_iter_unlock(iter); + int ret = btree_iter_err(iter); BUG_ON(!ret); bcache_io_error(c, bio, "btree IO error %i", ret); bio_endio(bio); @@ -951,7 +952,7 @@ static void bchfs_read(struct bch_fs *c, struct btree_iter *iter, } bkey_reassemble(&tmp.k, k); - bch2_btree_iter_unlock(iter); + bch2_btree_trans_unlock(trans); k = bkey_i_to_s_c(&tmp.k); if (readpages_iter) { @@ -1030,7 +1031,8 @@ void bch2_readahead(struct readahead_control *ractl) rbio->bio.bi_end_io = bch2_readpages_end_io; __bio_add_page(&rbio->bio, page, PAGE_SIZE, 0); - bchfs_read(c, iter, rbio, inode->v.i_ino, &readpages_iter); + bchfs_read(&trans, iter, rbio, inode->v.i_ino, + &readpages_iter); } bch2_pagecache_add_put(&inode->ei_pagecache_lock); @@ -1054,7 +1056,7 @@ static void __bchfs_readpage(struct bch_fs *c, struct bch_read_bio *rbio, iter = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS, POS_MIN, BTREE_ITER_SLOTS); - bchfs_read(c, iter, rbio, inum, NULL); + bchfs_read(&trans, iter, rbio, inum, NULL); bch2_trans_exit(&trans); } @@ -2098,7 +2100,7 @@ static int __bch2_fpunch(struct bch_fs *c, struct bch_inode_info *inode, BTREE_ITER_INTENT); while ((k = bch2_btree_iter_peek(iter)).k && - !(ret = btree_iter_err(k)) && + !(ret = bkey_err(k)) && bkey_cmp(iter->pos, end) < 0) { struct disk_reservation disk_res = bch2_disk_reservation_init(c, 0); @@ -2437,14 +2439,14 @@ static long bch2_fcollapse(struct bch_inode_info *inode, ret = bch2_btree_iter_traverse(dst); if (ret) - goto btree_iter_err; + goto bkey_err; bch2_btree_iter_set_pos(src, POS(dst->pos.inode, dst->pos.offset + (len >> 9))); k = bch2_btree_iter_peek_slot(src); - if ((ret = btree_iter_err(k))) - goto btree_iter_err; + if ((ret = bkey_err(k))) + goto bkey_err; bkey_reassemble(©.k, k); @@ -2465,7 +2467,7 @@ static long bch2_fcollapse(struct bch_inode_info *inode, dst, ©.k, 0, true, true, NULL); bch2_disk_reservation_put(c, &disk_res); -btree_iter_err: +bkey_err: if (ret == -EINTR) ret = 0; if (ret) @@ -2559,8 +2561,8 @@ static long bch2_fallocate(struct bch_inode_info *inode, int mode, struct bkey_s_c k; k = bch2_btree_iter_peek_slot(iter); - if ((ret = btree_iter_err(k))) - goto btree_iter_err; + if ((ret = bkey_err(k))) + goto bkey_err; /* already reserved */ if (k.k->type == KEY_TYPE_reservation && @@ -2591,7 +2593,7 @@ static long bch2_fallocate(struct bch_inode_info *inode, int mode, "a_res, sectors, true); if (unlikely(ret)) - goto btree_iter_err; + goto bkey_err; } if (reservation.v.nr_replicas < replicas || @@ -2599,7 +2601,7 @@ static long bch2_fallocate(struct bch_inode_info *inode, int mode, ret = bch2_disk_reservation_get(c, &disk_res, sectors, replicas, 0); if (unlikely(ret)) - goto btree_iter_err; + goto bkey_err; reservation.v.nr_replicas = disk_res.nr_replicas; } @@ -2608,7 +2610,7 @@ static long bch2_fallocate(struct bch_inode_info *inode, int mode, &disk_res, "a_res, iter, &reservation.k_i, 0, true, true, NULL); -btree_iter_err: +bkey_err: bch2_quota_reservation_put(c, inode, "a_res); bch2_disk_reservation_put(c, &disk_res); if (ret == -EINTR) diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 41284d38db2f..c4d9d2761cdc 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -33,9 +33,10 @@ static s64 bch2_count_inode_sectors(struct btree_trans *trans, u64 inum) return bch2_trans_iter_free(trans, iter) ?: sectors; } -static int remove_dirent(struct bch_fs *c, struct btree_iter *iter, +static int remove_dirent(struct btree_trans *trans, struct bkey_s_c_dirent dirent) { + struct bch_fs *c = trans->c; struct qstr name; struct bch_inode_unpacked dir_inode; struct bch_hash_info dir_hash_info; @@ -52,8 +53,8 @@ static int remove_dirent(struct bch_fs *c, struct btree_iter *iter, buf[name.len] = '\0'; name.name = buf; - /* Unlock iter so we don't deadlock, after copying name: */ - bch2_btree_iter_unlock(iter); + /* Unlock so we don't deadlock, after copying name: */ + bch2_btree_trans_unlock(trans); ret = bch2_inode_find_by_inum(c, dir_inum, &dir_inode); if (ret) { @@ -143,29 +144,33 @@ static int walk_inode(struct bch_fs *c, struct inode_walker *w, u64 inum) struct hash_check { struct bch_hash_info info; - struct btree_trans *trans; /* start of current chain of hash collisions: */ struct btree_iter *chain; /* next offset in current chain of hash collisions: */ - u64 next; + u64 chain_end; }; -static void hash_check_init(const struct bch_hash_desc desc, - struct btree_trans *trans, +static void hash_check_init(struct hash_check *h) +{ + h->chain = NULL; +} + +static void hash_stop_chain(struct btree_trans *trans, struct hash_check *h) { - h->trans = trans; - h->chain = bch2_trans_get_iter(trans, desc.btree_id, POS_MIN, 0); - h->next = -1; + if (h->chain) + bch2_trans_iter_free(trans, h->chain); + h->chain = NULL; } -static void hash_check_set_inode(struct hash_check *h, struct bch_fs *c, +static void hash_check_set_inode(struct btree_trans *trans, + struct hash_check *h, const struct bch_inode_unpacked *bi) { - h->info = bch2_hash_info_init(c, bi); - h->next = -1; + h->info = bch2_hash_info_init(trans->c, bi); + hash_stop_chain(trans, h); } static int hash_redo_key(const struct bch_hash_desc desc, @@ -186,8 +191,6 @@ static int hash_redo_key(const struct bch_hash_desc desc, if (ret) goto err; - bch2_btree_iter_unlock(k_iter); - bch2_hash_set(trans, desc, &h->info, k_iter->pos.inode, tmp, BCH_HASH_SET_MUST_CREATE); ret = bch2_trans_commit(trans, NULL, NULL, @@ -232,7 +235,7 @@ static int hash_check_duplicates(struct btree_trans *trans, if (!bkey_cmp(h->chain->pos, k_iter->pos)) return 0; - iter = bch2_trans_copy_iter(h->trans, h->chain); + iter = bch2_trans_copy_iter(trans, h->chain); BUG_ON(IS_ERR(iter)); for_each_btree_key_continue(iter, 0, k2) { @@ -252,23 +255,39 @@ static int hash_check_duplicates(struct btree_trans *trans, } } fsck_err: - bch2_trans_iter_free(h->trans, iter); + bch2_trans_iter_free(trans, iter); return ret; } -static bool key_has_correct_hash(const struct bch_hash_desc desc, - struct hash_check *h, struct bch_fs *c, - struct btree_iter *k_iter, struct bkey_s_c k) +static void hash_set_chain_start(struct btree_trans *trans, + const struct bch_hash_desc desc, + struct hash_check *h, + struct btree_iter *k_iter, struct bkey_s_c k) { - u64 hash; + bool hole = (k.k->type != KEY_TYPE_whiteout && + k.k->type != desc.key_type); - if (k.k->type != KEY_TYPE_whiteout && - k.k->type != desc.key_type) - return true; + if (hole || k.k->p.offset > h->chain_end + 1) + hash_stop_chain(trans, h); + + if (!hole) { + if (!h->chain) { + h->chain = bch2_trans_copy_iter(trans, k_iter); + BUG_ON(IS_ERR(h->chain)); + } + + h->chain_end = k.k->p.offset; + } +} + +static bool key_has_correct_hash(struct btree_trans *trans, + const struct bch_hash_desc desc, + struct hash_check *h, + struct btree_iter *k_iter, struct bkey_s_c k) +{ + u64 hash; - if (k.k->p.offset != h->next) - bch2_btree_iter_copy(h->chain, k_iter); - h->next = k.k->p.offset + 1; + hash_set_chain_start(trans, desc, h, k_iter, k); if (k.k->type != desc.key_type) return true; @@ -288,13 +307,7 @@ static int hash_check_key(struct btree_trans *trans, u64 hashed; int ret = 0; - if (k.k->type != KEY_TYPE_whiteout && - k.k->type != desc.key_type) - return 0; - - if (k.k->p.offset != h->next) - bch2_btree_iter_copy(h->chain, k_iter); - h->next = k.k->p.offset + 1; + hash_set_chain_start(trans, desc, h, k_iter, k); if (k.k->type != desc.key_type) return 0; @@ -332,7 +345,7 @@ static int check_dirent_hash(struct btree_trans *trans, struct hash_check *h, unsigned len; u64 hash; - if (key_has_correct_hash(bch2_dirent_hash_desc, h, c, iter, *k)) + if (key_has_correct_hash(trans, bch2_dirent_hash_desc, h, iter, *k)) return 0; len = bch2_dirent_name_bytes(bkey_s_c_to_dirent(*k)); @@ -526,7 +539,7 @@ static int check_dirents(struct bch_fs *c) iter = bch2_trans_get_iter(&trans, BTREE_ID_DIRENTS, POS(BCACHEFS_ROOT_INO, 0), 0); - hash_check_init(bch2_dirent_hash_desc, &trans, &h); + hash_check_init(&h); for_each_btree_key_continue(iter, 0, k) { struct bkey_s_c_dirent d; @@ -554,7 +567,7 @@ static int check_dirents(struct bch_fs *c) } if (w.first_this_inode && w.have_inode) - hash_check_set_inode(&h, c, &w.inode); + hash_check_set_inode(&trans, &h, &w.inode); ret = check_dirent_hash(&trans, &h, iter, &k); if (ret > 0) { @@ -587,7 +600,7 @@ static int check_dirents(struct bch_fs *c) ".. dirent") || fsck_err_on(memchr(d.v->d_name, '/', name_len), c, "dirent name has invalid chars")) { - ret = remove_dirent(c, iter, d); + ret = remove_dirent(&trans, d); if (ret) goto err; continue; @@ -597,7 +610,7 @@ static int check_dirents(struct bch_fs *c) "dirent points to own directory:\n%s", (bch2_bkey_val_to_text(&PBUF(buf), c, k), buf))) { - ret = remove_dirent(c, iter, d); + ret = remove_dirent(&trans, d); if (ret) goto err; continue; @@ -614,7 +627,7 @@ static int check_dirents(struct bch_fs *c) "dirent points to missing inode:\n%s", (bch2_bkey_val_to_text(&PBUF(buf), c, k), buf))) { - ret = remove_dirent(c, iter, d); + ret = remove_dirent(&trans, d); if (ret) goto err; continue; @@ -650,6 +663,8 @@ static int check_dirents(struct bch_fs *c) } } + + hash_stop_chain(&trans, &h); err: fsck_err: return bch2_trans_exit(&trans) ?: ret; @@ -677,7 +692,7 @@ static int check_xattrs(struct bch_fs *c) iter = bch2_trans_get_iter(&trans, BTREE_ID_XATTRS, POS(BCACHEFS_ROOT_INO, 0), 0); - hash_check_init(bch2_xattr_hash_desc, &trans, &h); + hash_check_init(&h); for_each_btree_key_continue(iter, 0, k) { ret = walk_inode(c, &w, k.k->p.inode); @@ -694,7 +709,7 @@ static int check_xattrs(struct bch_fs *c) } if (w.first_this_inode && w.have_inode) - hash_check_set_inode(&h, c, &w.inode); + hash_check_set_inode(&trans, &h, &w.inode); ret = hash_check_key(&trans, bch2_xattr_hash_desc, &h, iter, k); @@ -926,7 +941,7 @@ next: if (fsck_err_on(inode_bitmap_test(&dirs_done, d_inum), c, "directory %llu has multiple hardlinks", d_inum)) { - ret = remove_dirent(c, iter, dirent); + ret = remove_dirent(&trans, dirent); if (ret) goto err; continue; @@ -972,7 +987,7 @@ up: if (fsck_err_on(!inode_bitmap_test(&dirs_done, k.k->p.inode), c, "unreachable directory found (inum %llu)", k.k->p.inode)) { - bch2_btree_iter_unlock(iter); + bch2_btree_trans_unlock(&trans); ret = reattach_inode(c, lostfound_inode, k.k->p.inode); if (ret) { @@ -1187,6 +1202,9 @@ static int check_inode(struct btree_trans *trans, int ret = 0; ret = bch2_inode_unpack(inode, &u); + + bch2_btree_trans_unlock(trans); + if (bch2_fs_inconsistent_on(ret, c, "error unpacking inode %llu in fsck", inode.k->p.inode)) @@ -1306,7 +1324,7 @@ static int bch2_gc_walk_inodes(struct bch_fs *c, nlinks_iter = genradix_iter_init(links, 0); while ((k = bch2_btree_iter_peek(iter)).k && - !(ret2 = btree_iter_err(k))) { + !(ret2 = bkey_err(k))) { peek_nlinks: link = genradix_iter_peek(&nlinks_iter, links); if (!link && (!k.k || iter->pos.inode >= range_end)) @@ -1326,12 +1344,6 @@ peek_nlinks: link = genradix_iter_peek(&nlinks_iter, links); link = &zero_links; if (k.k && k.k->type == KEY_TYPE_inode) { - /* - * Avoid potential deadlocks with iter for - * truncate/rm/etc.: - */ - bch2_btree_iter_unlock(iter); - ret = check_inode(&trans, lostfound_inode, iter, bkey_s_c_to_inode(k), link); BUG_ON(ret == -EINTR); @@ -1402,7 +1414,7 @@ static int check_inodes_fast(struct bch_fs *c) struct btree_iter *iter; struct bkey_s_c k; struct bkey_s_c_inode inode; - int ret = 0; + int ret = 0, ret2; bch2_trans_init(&trans, c); @@ -1426,12 +1438,9 @@ static int check_inodes_fast(struct bch_fs *c) } } - if (!ret) - ret = bch2_btree_iter_unlock(iter); + ret2 = bch2_trans_exit(&trans); - bch2_trans_exit(&trans); - - return ret; + return ret ?: ret2; } /* diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c index c6336e7a2a23..7be24865cc3f 100644 --- a/fs/bcachefs/inode.c +++ b/fs/bcachefs/inode.c @@ -323,7 +323,7 @@ again: while (1) { struct bkey_s_c k = bch2_btree_iter_peek_slot(iter); - ret = btree_iter_err(k); + ret = bkey_err(k); if (ret) return ret; @@ -399,7 +399,7 @@ int bch2_inode_rm(struct bch_fs *c, u64 inode_nr) struct bkey_s_c k = bch2_btree_iter_peek_slot(iter); u32 bi_generation = 0; - ret = btree_iter_err(k); + ret = bkey_err(k); if (ret) break; diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index 62ee09121036..71481b9728f5 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -1279,7 +1279,7 @@ retry: rbio->bio.bi_status = 0; k = bch2_btree_iter_peek_slot(iter); - if (btree_iter_err(k)) + if (bkey_err(k)) goto err; bkey_reassemble(&tmp.k, k); @@ -1332,7 +1332,7 @@ retry: bkey_reassemble(&tmp.k, k); k = bkey_i_to_s_c(&tmp.k); - bch2_btree_iter_unlock(iter); + bch2_btree_trans_unlock(&trans); bytes = min_t(unsigned, bvec_iter.bi_size, (k.k->p.offset - bvec_iter.bi_sector) << 9); @@ -1357,7 +1357,7 @@ retry: * If we get here, it better have been because there was an error * reading a btree node */ - BUG_ON(!(iter->flags & BTREE_ITER_ERROR)); + BUG_ON(!btree_iter_err(iter)); __bcache_io_error(c, "btree IO error"); err: rbio->bio.bi_status = BLK_STS_IOERR; @@ -1893,7 +1893,7 @@ void bch2_read(struct bch_fs *c, struct bch_read_bio *rbio, u64 inode) */ bkey_reassemble(&tmp.k, k); k = bkey_i_to_s_c(&tmp.k); - bch2_btree_iter_unlock(iter); + bch2_btree_trans_unlock(&trans); bytes = min_t(unsigned, rbio->bio.bi_iter.bi_size, (k.k->p.offset - rbio->bio.bi_iter.bi_sector) << 9); @@ -1915,7 +1915,7 @@ void bch2_read(struct bch_fs *c, struct bch_read_bio *rbio, u64 inode) * If we get here, it better have been because there was an error * reading a btree node */ - BUG_ON(!(iter->flags & BTREE_ITER_ERROR)); + BUG_ON(!btree_iter_err(iter)); bcache_io_error(c, &rbio->bio, "btree IO error"); bch2_trans_exit(&trans); diff --git a/fs/bcachefs/migrate.c b/fs/bcachefs/migrate.c index 2b63b07db2bc..98202fbabfaf 100644 --- a/fs/bcachefs/migrate.c +++ b/fs/bcachefs/migrate.c @@ -52,7 +52,7 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags) while ((k = bch2_btree_iter_peek(iter)).k && - !(ret = btree_iter_err(k))) { + !(ret = bkey_err(k))) { if (!bkey_extent_is_data(k.k) || !bch2_extent_has_device(bkey_s_c_to_extent(k), dev_idx)) { ret = bch2_mark_bkey_replicas(c, k); diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c index 3f3e34e07f35..9793896bee77 100644 --- a/fs/bcachefs/move.c +++ b/fs/bcachefs/move.c @@ -77,7 +77,7 @@ static int bch2_migrate_index_update(struct bch_write_op *op) bool did_work = false; int nr; - ret = btree_iter_err(k); + ret = bkey_err(k); if (ret) break; @@ -539,7 +539,7 @@ peek: if (!k.k) break; - ret = btree_iter_err(k); + ret = bkey_err(k); if (ret) break; if (bkey_cmp(bkey_start_pos(k.k), end) >= 0) diff --git a/fs/bcachefs/quota.c b/fs/bcachefs/quota.c index f5dd13e92200..a4f75d53b42c 100644 --- a/fs/bcachefs/quota.c +++ b/fs/bcachefs/quota.c @@ -732,7 +732,7 @@ static int bch2_set_quota(struct super_block *sb, struct kqid qid, BTREE_ITER_SLOTS|BTREE_ITER_INTENT); k = bch2_btree_iter_peek_slot(iter); - ret = btree_iter_err(k); + ret = bkey_err(k); if (unlikely(ret)) return ret; |