summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-08-30 14:22:43 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2021-08-30 15:05:51 -0400
commitc0ce64774c72d8a57c6906104e9c3a6b243682d2 (patch)
treec22c6df8f0ce405e1fbd88b05daa23092ed0762b
parentdddd7cf0e949c95c24c0a23141ed47e047a13e53 (diff)
bcachefs: Further reduce iter->trans usage
This is prep work for splitting btree_path out from btree_iter - btree_path will not have a pointer to btree_trans. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/btree_cache.c40
-rw-r--r--fs/bcachefs/btree_cache.h5
-rw-r--r--fs/bcachefs/btree_iter.c158
-rw-r--r--fs/bcachefs/btree_iter.h10
-rw-r--r--fs/bcachefs/btree_key_cache.c13
-rw-r--r--fs/bcachefs/btree_key_cache.h2
-rw-r--r--fs/bcachefs/btree_locking.h30
-rw-r--r--fs/bcachefs/btree_update_interior.c2
-rw-r--r--fs/bcachefs/btree_update_interior.h2
-rw-r--r--fs/bcachefs/btree_update_leaf.c5
-rw-r--r--fs/bcachefs/recovery.c4
11 files changed, 138 insertions, 133 deletions
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c
index cd0c5009e167..64a731cfc01c 100644
--- a/fs/bcachefs/btree_cache.c
+++ b/fs/bcachefs/btree_cache.c
@@ -632,6 +632,7 @@ err:
/* Slowpath, don't want it inlined into btree_iter_traverse() */
static noinline struct btree *bch2_btree_node_fill(struct bch_fs *c,
+ struct btree_trans *trans,
struct btree_iter *iter,
const struct bkey_i *k,
enum btree_id btree_id,
@@ -648,8 +649,8 @@ static noinline struct btree *bch2_btree_node_fill(struct bch_fs *c,
* Parent node must be locked, else we could read in a btree node that's
* been freed:
*/
- if (iter && !bch2_btree_node_relock(iter, level + 1)) {
- btree_trans_restart(iter->trans);
+ if (trans && !bch2_btree_node_relock(trans, iter, level + 1)) {
+ btree_trans_restart(trans);
return ERR_PTR(-EINTR);
}
@@ -680,23 +681,23 @@ static noinline struct btree *bch2_btree_node_fill(struct bch_fs *c,
six_unlock_intent(&b->c.lock);
/* Unlock before doing IO: */
- if (iter && sync)
- bch2_trans_unlock(iter->trans);
+ if (trans && sync)
+ bch2_trans_unlock(trans);
bch2_btree_node_read(c, b, sync);
if (!sync)
return NULL;
- if (iter &&
- (!bch2_trans_relock(iter->trans) ||
- !bch2_btree_iter_relock_intent(iter))) {
- BUG_ON(!iter->trans->restarted);
+ if (trans &&
+ (!bch2_trans_relock(trans) ||
+ !bch2_btree_iter_relock_intent(trans, iter))) {
+ BUG_ON(!trans->restarted);
return ERR_PTR(-EINTR);
}
if (!six_relock_type(&b->c.lock, lock_type, seq)) {
- btree_trans_restart(iter->trans);
+ btree_trans_restart(trans);
return ERR_PTR(-EINTR);
}
@@ -779,7 +780,7 @@ retry:
* else we could read in a btree node from disk that's been
* freed:
*/
- b = bch2_btree_node_fill(c, iter, k, iter->btree_id,
+ b = bch2_btree_node_fill(c, trans, iter, k, iter->btree_id,
level, lock_type, true);
/* We raced and found the btree node in the cache */
@@ -821,7 +822,7 @@ lock_node:
if (btree_node_read_locked(iter, level + 1))
btree_node_unlock(iter, level + 1);
- if (!btree_node_lock(b, k->k.p, level, iter, lock_type,
+ if (!btree_node_lock(trans, iter, b, k->k.p, level, lock_type,
lock_node_check_fn, (void *) k, trace_ip)) {
if (!trans->restarted)
goto retry;
@@ -832,7 +833,7 @@ lock_node:
b->c.level != level ||
race_fault())) {
six_unlock_type(&b->c.lock, lock_type);
- if (bch2_btree_node_relock(iter, level + 1))
+ if (bch2_btree_node_relock(trans, iter, level + 1))
goto retry;
trace_trans_restart_btree_node_reused(trans->ip,
@@ -856,9 +857,9 @@ lock_node:
* should_be_locked is not set on this iterator yet, so we need
* to relock it specifically:
*/
- if (iter &&
+ if (trans &&
(!bch2_trans_relock(trans) ||
- !bch2_btree_iter_relock_intent(iter))) {
+ !bch2_btree_iter_relock_intent(trans, iter))) {
BUG_ON(!trans->restarted);
return ERR_PTR(-EINTR);
}
@@ -917,7 +918,7 @@ retry:
if (nofill)
goto out;
- b = bch2_btree_node_fill(c, NULL, k, btree_id,
+ b = bch2_btree_node_fill(c, NULL, NULL, k, btree_id,
level, SIX_LOCK_read, true);
/* We raced and found the btree node in the cache */
@@ -975,21 +976,24 @@ out:
return b;
}
-int bch2_btree_node_prefetch(struct bch_fs *c, struct btree_iter *iter,
+int bch2_btree_node_prefetch(struct bch_fs *c,
+ struct btree_trans *trans,
+ struct btree_iter *iter,
const struct bkey_i *k,
enum btree_id btree_id, unsigned level)
{
struct btree_cache *bc = &c->btree_cache;
struct btree *b;
- BUG_ON(iter && !btree_node_locked(iter, level + 1));
+ BUG_ON(trans && !btree_node_locked(iter, level + 1));
BUG_ON(level >= BTREE_MAX_DEPTH);
b = btree_cache_find(bc, k);
if (b)
return 0;
- b = bch2_btree_node_fill(c, iter, k, btree_id, level, SIX_LOCK_read, false);
+ b = bch2_btree_node_fill(c, trans, iter, k, btree_id,
+ level, SIX_LOCK_read, false);
return PTR_ERR_OR_ZERO(b);
}
diff --git a/fs/bcachefs/btree_cache.h b/fs/bcachefs/btree_cache.h
index 5032293e8628..6c1c69f3abcf 100644
--- a/fs/bcachefs/btree_cache.h
+++ b/fs/bcachefs/btree_cache.h
@@ -29,8 +29,9 @@ struct btree *bch2_btree_node_get(struct btree_trans *, struct btree_iter *,
struct btree *bch2_btree_node_get_noiter(struct bch_fs *, const struct bkey_i *,
enum btree_id, unsigned, bool);
-int bch2_btree_node_prefetch(struct bch_fs *, struct btree_iter *,
- const struct bkey_i *, enum btree_id, unsigned);
+int bch2_btree_node_prefetch(struct bch_fs *, struct btree_trans *,
+ struct btree_iter *, const struct bkey_i *,
+ enum btree_id, unsigned);
void bch2_btree_node_evict(struct bch_fs *, const struct bkey_i *);
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 5f69a63e1340..a2eca98e4fb5 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -108,17 +108,14 @@ void bch2_btree_node_unlock_write(struct btree_trans *trans,
bch2_btree_node_unlock_write_inlined(trans, iter, b);
}
-void __bch2_btree_node_lock_write(struct btree_trans *trans,
- struct btree_iter *iter, struct btree *b)
+void __bch2_btree_node_lock_write(struct btree_trans *trans, struct btree *b)
{
- struct btree_iter *linked;
+ struct btree_iter *iter;
unsigned readers = 0;
- EBUG_ON(!btree_node_intent_locked(iter, b->c.level));
-
- trans_for_each_iter(trans, linked)
- if (linked->l[b->c.level].b == b &&
- btree_node_read_locked(linked, b->c.level))
+ trans_for_each_iter(trans, iter)
+ if (iter->l[b->c.level].b == b &&
+ btree_node_read_locked(iter, b->c.level))
readers++;
/*
@@ -134,7 +131,8 @@ void __bch2_btree_node_lock_write(struct btree_trans *trans,
&b->c.lock.state.counter);
}
-bool __bch2_btree_node_relock(struct btree_iter *iter, unsigned level)
+bool __bch2_btree_node_relock(struct btree_trans *trans,
+ struct btree_iter *iter, unsigned level)
{
struct btree *b = btree_iter_node(iter, level);
int want = __btree_lock_want(iter, level);
@@ -147,7 +145,7 @@ bool __bch2_btree_node_relock(struct btree_iter *iter, unsigned level)
if (six_relock_type(&b->c.lock, want, iter->l[level].lock_seq) ||
(btree_node_lock_seq_matches(iter, b, level) &&
- btree_node_lock_increment(iter->trans, b, level, want))) {
+ btree_node_lock_increment(trans, b, level, want))) {
mark_btree_node_locked(iter, level, want);
return true;
} else {
@@ -155,7 +153,8 @@ bool __bch2_btree_node_relock(struct btree_iter *iter, unsigned level)
}
}
-static bool bch2_btree_node_upgrade(struct btree_iter *iter, unsigned level)
+static bool bch2_btree_node_upgrade(struct btree_trans *trans,
+ struct btree_iter *iter, unsigned level)
{
struct btree *b = iter->l[level].b;
@@ -176,7 +175,7 @@ static bool bch2_btree_node_upgrade(struct btree_iter *iter, unsigned level)
goto success;
if (btree_node_lock_seq_matches(iter, b, level) &&
- btree_node_lock_increment(iter->trans, b, level, BTREE_NODE_INTENT_LOCKED)) {
+ btree_node_lock_increment(trans, b, level, BTREE_NODE_INTENT_LOCKED)) {
btree_node_unlock(iter, level);
goto success;
}
@@ -199,8 +198,8 @@ static inline bool btree_iter_get_locks(struct btree_trans *trans,
break;
if (!(upgrade
- ? bch2_btree_node_upgrade(iter, l)
- : bch2_btree_node_relock(iter, l))) {
+ ? bch2_btree_node_upgrade(trans, iter, l)
+ : bch2_btree_node_relock(trans, iter, l))) {
(upgrade
? trace_node_upgrade_fail
: trace_node_relock_fail)(trans->ip, trace_ip,
@@ -248,13 +247,13 @@ static struct bpos btree_node_pos(struct btree_bkey_cached_common *_b,
}
/* Slowpath: */
-bool __bch2_btree_node_lock(struct btree *b, struct bpos pos,
- unsigned level, struct btree_iter *iter,
+bool __bch2_btree_node_lock(struct btree_trans *trans,
+ struct btree_iter *iter,
+ struct btree *b, struct bpos pos, unsigned level,
enum six_lock_type type,
six_lock_should_sleep_fn should_sleep_fn, void *p,
unsigned long ip)
{
- struct btree_trans *trans = iter->trans;
struct btree_iter *linked, *deadlock_iter = NULL;
u64 start_time = local_clock();
unsigned reason = 9;
@@ -361,16 +360,10 @@ bool __bch2_btree_node_lock(struct btree *b, struct bpos pos,
/* Btree iterator locking: */
#ifdef CONFIG_BCACHEFS_DEBUG
-static void bch2_btree_iter_verify_locks(struct btree_trans *trans,
- struct btree_iter *iter)
+static void bch2_btree_iter_verify_locks(struct btree_iter *iter)
{
unsigned l;
- if (!(trans->iters_linked & (1ULL << iter->idx))) {
- BUG_ON(iter->nodes_locked);
- return;
- }
-
for (l = 0; btree_iter_node(iter, l); l++) {
if (iter->uptodate >= BTREE_ITER_NEED_RELOCK &&
!btree_node_locked(iter, l))
@@ -386,25 +379,24 @@ void bch2_btree_trans_verify_locks(struct btree_trans *trans)
struct btree_iter *iter;
trans_for_each_iter(trans, iter)
- bch2_btree_iter_verify_locks(trans, iter);
+ bch2_btree_iter_verify_locks(iter);
}
#else
-static inline void bch2_btree_iter_verify_locks(struct btree_trans *trans,
- struct btree_iter *iter) {}
+static inline void bch2_btree_iter_verify_locks(struct btree_iter *iter) {}
#endif
/*
* Only for btree_cache.c - only relocks intent locks
*/
-bool bch2_btree_iter_relock_intent(struct btree_iter *iter)
+bool bch2_btree_iter_relock_intent(struct btree_trans *trans,
+ struct btree_iter *iter)
{
- struct btree_trans *trans = iter->trans;
unsigned l;
for (l = iter->level;
l < iter->locks_want && btree_iter_node(iter, l);
l++) {
- if (!bch2_btree_node_relock(iter, l)) {
+ if (!bch2_btree_node_relock(trans, iter, l)) {
trace_node_relock_fail(trans->ip, _RET_IP_,
btree_iter_type(iter) == BTREE_ITER_CACHED,
iter->btree_id, &iter->real_pos,
@@ -435,10 +427,10 @@ static bool bch2_btree_iter_relock(struct btree_trans *trans,
return ret;
}
-bool __bch2_btree_iter_upgrade(struct btree_iter *iter,
+bool __bch2_btree_iter_upgrade(struct btree_trans *trans,
+ struct btree_iter *iter,
unsigned new_locks_want)
{
- struct btree_trans *trans = iter->trans;
struct btree_iter *linked;
EBUG_ON(iter->locks_want >= new_locks_want);
@@ -503,7 +495,7 @@ void __bch2_btree_iter_downgrade(struct btree_iter *iter,
}
}
- bch2_btree_trans_verify_locks(iter->trans);
+ bch2_btree_iter_verify_locks(iter);
}
void bch2_trans_downgrade(struct btree_trans *trans)
@@ -554,12 +546,13 @@ void bch2_trans_unlock(struct btree_trans *trans)
#ifdef CONFIG_BCACHEFS_DEBUG
-static void bch2_btree_iter_verify_cached(struct btree_iter *iter)
+static void bch2_btree_iter_verify_cached(struct btree_trans *trans,
+ struct btree_iter *iter)
{
struct bkey_cached *ck;
bool locked = btree_node_locked(iter, 0);
- if (!bch2_btree_node_relock(iter, 0))
+ if (!bch2_btree_node_relock(trans, iter, 0))
return;
ck = (void *) iter->l[0].b;
@@ -570,8 +563,8 @@ static void bch2_btree_iter_verify_cached(struct btree_iter *iter)
btree_node_unlock(iter, 0);
}
-static void bch2_btree_iter_verify_level(struct btree_iter *iter,
- unsigned level)
+static void bch2_btree_iter_verify_level(struct btree_trans *trans,
+ struct btree_iter *iter, unsigned level)
{
struct btree_iter_level *l;
struct btree_node_iter tmp;
@@ -589,7 +582,7 @@ static void bch2_btree_iter_verify_level(struct btree_iter *iter,
if (btree_iter_type(iter) == BTREE_ITER_CACHED) {
if (!level)
- bch2_btree_iter_verify_cached(iter);
+ bch2_btree_iter_verify_cached(trans, iter);
return;
}
@@ -598,7 +591,7 @@ static void bch2_btree_iter_verify_level(struct btree_iter *iter,
if (!btree_iter_node(iter, level))
return;
- if (!bch2_btree_node_relock(iter, level))
+ if (!bch2_btree_node_relock(trans, iter, level))
return;
BUG_ON(!btree_iter_pos_in_node(iter, l->b));
@@ -688,10 +681,10 @@ static void bch2_btree_iter_verify(struct btree_iter *iter)
break;
}
- bch2_btree_iter_verify_level(iter, i);
+ bch2_btree_iter_verify_level(trans, iter, i);
}
- bch2_btree_iter_verify_locks(trans, iter);
+ bch2_btree_iter_verify_locks(iter);
}
static void bch2_btree_iter_verify_entry_exit(struct btree_iter *iter)
@@ -715,13 +708,15 @@ void bch2_btree_trans_verify_iters(struct btree_trans *trans, struct btree *b)
return;
trans_for_each_iter_with_node(trans, b, iter)
- bch2_btree_iter_verify_level(iter, b->c.level);
+ bch2_btree_iter_verify_level(trans, iter, b->c.level);
}
#else
-static inline void bch2_btree_iter_verify_level(struct btree_iter *iter, unsigned l) {}
-static inline void bch2_btree_iter_verify(struct btree_iter *iter) {}
+static inline void bch2_btree_iter_verify_level(struct btree_trans *trans,
+ struct btree_iter *iter, unsigned l) {}
+static inline void bch2_btree_iter_verify(struct btree_trans *trans,
+ struct btree_iter *iter) {}
static inline void bch2_btree_iter_verify_entry_exit(struct btree_iter *iter) {}
#endif
@@ -767,7 +762,7 @@ void bch2_btree_iter_fix_key_modified(struct btree_trans *trans,
trans_for_each_iter_with_node(trans, b, linked) {
__bch2_btree_iter_fix_key_modified(linked, b, where);
- bch2_btree_iter_verify_level(linked, b->c.level);
+ bch2_btree_iter_verify_level(trans, linked, b->c.level);
}
}
@@ -892,7 +887,7 @@ void bch2_btree_node_iter_fix(struct btree_trans *trans,
__bch2_btree_node_iter_fix(linked, b,
&linked->l[b->c.level].iter, t,
where, clobber_u64s, new_u64s);
- bch2_btree_iter_verify_level(linked, b->c.level);
+ bch2_btree_iter_verify_level(trans, linked, b->c.level);
}
}
@@ -977,7 +972,8 @@ static inline bool btree_iter_advance_to_pos(struct btree_iter *iter,
/*
* Verify that iterator for parent node points to child node:
*/
-static void btree_iter_verify_new_node(struct btree_iter *iter, struct btree *b)
+static void btree_iter_verify_new_node(struct btree_trans *trans,
+ struct btree_iter *iter, struct btree *b)
{
struct btree_iter_level *l;
unsigned plevel;
@@ -993,7 +989,7 @@ static void btree_iter_verify_new_node(struct btree_iter *iter, struct btree *b)
parent_locked = btree_node_locked(iter, plevel);
- if (!bch2_btree_node_relock(iter, plevel))
+ if (!bch2_btree_node_relock(trans, iter, plevel))
return;
l = &iter->l[plevel];
@@ -1007,7 +1003,7 @@ static void btree_iter_verify_new_node(struct btree_iter *iter, struct btree *b)
char buf4[100];
struct bkey uk = bkey_unpack_key(b, k);
- bch2_dump_btree_node(iter->trans->c, l->b);
+ bch2_dump_btree_node(trans->c, l->b);
bch2_bpos_to_text(&PBUF(buf1), iter->real_pos);
bch2_bkey_to_text(&PBUF(buf2), &uk);
bch2_bpos_to_text(&PBUF(buf3), b->data->min_key);
@@ -1024,8 +1020,8 @@ static void btree_iter_verify_new_node(struct btree_iter *iter, struct btree *b)
btree_node_unlock(iter, b->c.level + 1);
}
-static inline void __btree_iter_init(struct btree_iter *iter,
- unsigned level)
+static inline void __btree_iter_level_init(struct btree_iter *iter,
+ unsigned level)
{
struct btree_iter_level *l = &iter->l[level];
@@ -1041,19 +1037,20 @@ static inline void __btree_iter_init(struct btree_iter *iter,
btree_iter_set_dirty(iter, BTREE_ITER_NEED_PEEK);
}
-static inline void btree_iter_node_set(struct btree_iter *iter,
- struct btree *b)
+static inline void btree_iter_level_init(struct btree_trans *trans,
+ struct btree_iter *iter,
+ struct btree *b)
{
BUG_ON(btree_iter_type(iter) == BTREE_ITER_CACHED);
- btree_iter_verify_new_node(iter, b);
+ btree_iter_verify_new_node(trans, iter, b);
EBUG_ON(!btree_iter_pos_in_node(iter, b));
EBUG_ON(b->c.lock.state.seq & 1);
iter->l[b->c.level].lock_seq = b->c.lock.state.seq;
iter->l[b->c.level].b = b;
- __btree_iter_init(iter, b->c.level);
+ __btree_iter_level_init(iter, b->c.level);
}
/*
@@ -1082,7 +1079,7 @@ void bch2_btree_iter_node_replace(struct btree_trans *trans,
mark_btree_node_locked(linked, b->c.level, t);
}
- btree_iter_node_set(linked, b);
+ btree_iter_level_init(trans, linked, b);
}
}
@@ -1109,7 +1106,7 @@ void bch2_btree_iter_reinit_node(struct btree_trans *trans,
struct btree_iter *linked;
trans_for_each_iter_with_node(trans, b, linked)
- __btree_iter_init(linked, b->c.level);
+ __btree_iter_level_init(linked, b->c.level);
}
static int lock_root_check_fn(struct six_lock *lock, void *p)
@@ -1150,8 +1147,8 @@ static inline int btree_iter_lock_root(struct btree_trans *trans,
}
lock_type = __btree_lock_want(iter, iter->level);
- if (unlikely(!btree_node_lock(b, SPOS_MAX, iter->level,
- iter, lock_type,
+ if (unlikely(!btree_node_lock(trans, iter, b, SPOS_MAX,
+ iter->level, lock_type,
lock_root_check_fn, rootp,
trace_ip))) {
if (trans->restarted)
@@ -1169,7 +1166,7 @@ static inline int btree_iter_lock_root(struct btree_trans *trans,
iter->l[i].b = NULL;
mark_btree_node_locked(iter, iter->level, lock_type);
- btree_iter_node_set(iter, b);
+ btree_iter_level_init(trans, iter, b);
return 0;
}
@@ -1194,7 +1191,7 @@ static int btree_iter_prefetch(struct btree_trans *trans, struct btree_iter *ite
bch2_bkey_buf_init(&tmp);
while (nr && !ret) {
- if (!bch2_btree_node_relock(iter, iter->level))
+ if (!bch2_btree_node_relock(trans, iter, iter->level))
break;
bch2_btree_node_iter_advance(&node_iter, l->b);
@@ -1203,8 +1200,8 @@ static int btree_iter_prefetch(struct btree_trans *trans, struct btree_iter *ite
break;
bch2_bkey_buf_unpack(&tmp, c, l->b, k);
- ret = bch2_btree_node_prefetch(c, iter, tmp.k, iter->btree_id,
- iter->level - 1);
+ ret = bch2_btree_node_prefetch(c, trans, iter, tmp.k,
+ iter->btree_id, iter->level - 1);
}
if (!was_locked)
@@ -1214,7 +1211,8 @@ static int btree_iter_prefetch(struct btree_trans *trans, struct btree_iter *ite
return ret;
}
-static noinline void btree_node_mem_ptr_set(struct btree_iter *iter,
+static noinline void btree_node_mem_ptr_set(struct btree_trans *trans,
+ struct btree_iter *iter,
unsigned plevel, struct btree *b)
{
struct btree_iter_level *l = &iter->l[plevel];
@@ -1222,7 +1220,7 @@ static noinline void btree_node_mem_ptr_set(struct btree_iter *iter,
struct bkey_packed *k;
struct bch_btree_ptr_v2 *bp;
- if (!bch2_btree_node_relock(iter, plevel))
+ if (!bch2_btree_node_relock(trans, iter, plevel))
return;
k = bch2_btree_node_iter_peek_all(&l->iter, l->b);
@@ -1259,11 +1257,11 @@ static __always_inline int btree_iter_down(struct btree_trans *trans,
goto err;
mark_btree_node_locked(iter, level, lock_type);
- btree_iter_node_set(iter, b);
+ btree_iter_level_init(trans, iter, b);
if (tmp.k->k.type == KEY_TYPE_btree_ptr_v2 &&
unlikely(b != btree_node_mem_ptr(tmp.k)))
- btree_node_mem_ptr_set(iter, level + 1, b);
+ btree_node_mem_ptr_set(trans, iter, level + 1, b);
if (iter->flags & BTREE_ITER_PREFETCH)
ret = btree_iter_prefetch(trans, iter);
@@ -1272,7 +1270,7 @@ static __always_inline int btree_iter_down(struct btree_trans *trans,
btree_node_unlock(iter, level + 1);
iter->level = level;
- bch2_btree_iter_verify_locks(trans, iter);
+ bch2_btree_iter_verify_locks(iter);
err:
bch2_bkey_buf_exit(&tmp, c);
return ret;
@@ -1306,9 +1304,9 @@ retry_all:
if (iter1->btree_id == iter2->btree_id &&
iter1->locks_want < iter2->locks_want)
- __bch2_btree_iter_upgrade(iter1, iter2->locks_want);
+ __bch2_btree_iter_upgrade(trans, iter1, iter2->locks_want);
else if (!iter1->locks_want && iter2->locks_want)
- __bch2_btree_iter_upgrade(iter1, 1);
+ __bch2_btree_iter_upgrade(trans, iter1, 1);
}
bch2_trans_unlock(trans);
@@ -1364,11 +1362,12 @@ static int bch2_btree_iter_traverse_all(struct btree_trans *trans)
return __btree_iter_traverse_all(trans, 0, _RET_IP_);
}
-static inline bool btree_iter_good_node(struct btree_iter *iter,
+static inline bool btree_iter_good_node(struct btree_trans *trans,
+ struct btree_iter *iter,
unsigned l, int check_pos)
{
if (!is_btree_node(iter, l) ||
- !bch2_btree_node_relock(iter, l))
+ !bch2_btree_node_relock(trans, iter, l))
return false;
if (check_pos < 0 && btree_iter_pos_before_node(iter, iter->l[l].b))
@@ -1378,13 +1377,14 @@ static inline bool btree_iter_good_node(struct btree_iter *iter,
return true;
}
-static inline unsigned btree_iter_up_until_good_node(struct btree_iter *iter,
+static inline unsigned btree_iter_up_until_good_node(struct btree_trans *trans,
+ struct btree_iter *iter,
int check_pos)
{
unsigned l = iter->level;
while (btree_iter_node(iter, l) &&
- !btree_iter_good_node(iter, l, check_pos)) {
+ !btree_iter_good_node(trans, iter, l, check_pos)) {
btree_node_unlock(iter, l);
iter->l[l].b = BTREE_ITER_NO_NODE_UP;
l++;
@@ -1419,20 +1419,20 @@ static int btree_iter_traverse_one(struct btree_trans *trans,
}
if (btree_iter_type(iter) == BTREE_ITER_CACHED) {
- ret = bch2_btree_iter_traverse_cached(iter);
+ ret = bch2_btree_iter_traverse_cached(trans, iter);
goto out;
}
if (unlikely(iter->level >= BTREE_MAX_DEPTH))
goto out;
- iter->level = btree_iter_up_until_good_node(iter, 0);
+ iter->level = btree_iter_up_until_good_node(trans, iter, 0);
/* If we need intent locks, take them too: */
for (l = iter->level + 1;
l < iter->locks_want && btree_iter_node(iter, l);
l++)
- if (!bch2_btree_node_relock(iter, l))
+ if (!bch2_btree_node_relock(trans, iter, l))
while (iter->level <= l) {
btree_node_unlock(iter, iter->level);
iter->l[iter->level].b = BTREE_ITER_NO_NODE_UP;
@@ -1643,7 +1643,7 @@ static void btree_iter_set_search_pos(struct btree_iter *iter, struct bpos new_p
return;
}
- l = btree_iter_up_until_good_node(iter, cmp);
+ l = btree_iter_up_until_good_node(trans, iter, cmp);
if (btree_iter_node(iter, l)) {
/*
@@ -1654,7 +1654,7 @@ static void btree_iter_set_search_pos(struct btree_iter *iter, struct bpos new_p
*/
if (cmp < 0 ||
!btree_iter_advance_to_pos(iter, &iter->l[l], 8))
- __btree_iter_init(iter, l);
+ __btree_iter_level_init(iter, l);
/* Don't leave it locked if we're not supposed to: */
if (btree_lock_want(iter, l) == BTREE_NODE_UNLOCKED)
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
index 6dad6f1a2d9b..b6354782a2d0 100644
--- a/fs/bcachefs/btree_iter.h
+++ b/fs/bcachefs/btree_iter.h
@@ -135,7 +135,7 @@ void bch2_btree_node_iter_fix(struct btree_trans *trans, struct btree_iter *,
struct btree *, struct btree_node_iter *,
struct bkey_packed *, unsigned, unsigned);
-bool bch2_btree_iter_relock_intent(struct btree_iter *);
+bool bch2_btree_iter_relock_intent(struct btree_trans *, struct btree_iter *);
bool bch2_trans_relock(struct btree_trans *);
void bch2_trans_unlock(struct btree_trans *);
@@ -148,15 +148,17 @@ static inline int btree_trans_restart(struct btree_trans *trans)
return -EINTR;
}
-bool __bch2_btree_iter_upgrade(struct btree_iter *, unsigned);
+bool __bch2_btree_iter_upgrade(struct btree_trans *,
+ struct btree_iter *, unsigned);
-static inline bool bch2_btree_iter_upgrade(struct btree_iter *iter,
+static inline bool bch2_btree_iter_upgrade(struct btree_trans *trans,
+ struct btree_iter *iter,
unsigned new_locks_want)
{
new_locks_want = min(new_locks_want, BTREE_MAX_DEPTH);
return iter->locks_want < new_locks_want
- ? __bch2_btree_iter_upgrade(iter, new_locks_want)
+ ? __bch2_btree_iter_upgrade(trans, iter, new_locks_want)
: iter->uptodate <= BTREE_ITER_NEED_PEEK;
}
diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c
index 6bc20813d00d..568c1f2704c2 100644
--- a/fs/bcachefs/btree_key_cache.c
+++ b/fs/bcachefs/btree_key_cache.c
@@ -212,7 +212,7 @@ static int btree_key_cache_fill(struct btree_trans *trans,
if (ret)
goto err;
- if (!bch2_btree_node_relock(ck_iter, 0)) {
+ if (!bch2_btree_node_relock(trans, ck_iter, 0)) {
trace_transaction_restart_ip(trans->ip, _THIS_IP_);
ret = btree_trans_restart(trans);
goto err;
@@ -265,9 +265,8 @@ static int bkey_cached_check_fn(struct six_lock *lock, void *p)
}
__flatten
-int bch2_btree_iter_traverse_cached(struct btree_iter *iter)
+int bch2_btree_iter_traverse_cached(struct btree_trans *trans, struct btree_iter *iter)
{
- struct btree_trans *trans = iter->trans;
struct bch_fs *c = trans->c;
struct bkey_cached *ck;
int ret = 0;
@@ -276,7 +275,7 @@ int bch2_btree_iter_traverse_cached(struct btree_iter *iter)
iter->l[1].b = NULL;
- if (bch2_btree_node_relock(iter, 0)) {
+ if (bch2_btree_node_relock(trans, iter, 0)) {
ck = (void *) iter->l[0].b;
goto fill;
}
@@ -301,7 +300,7 @@ retry:
} else {
enum six_lock_type lock_want = __btree_lock_want(iter, 0);
- if (!btree_node_lock((void *) ck, iter->pos, 0, iter, lock_want,
+ if (!btree_node_lock(trans, iter, (void *) ck, iter->pos, 0, lock_want,
bkey_cached_check_fn, iter, _THIS_IP_)) {
if (!trans->restarted)
goto retry;
@@ -325,7 +324,7 @@ retry:
fill:
if (!ck->valid && !(iter->flags & BTREE_ITER_CACHED_NOFILL)) {
if (!iter->locks_want &&
- !!__bch2_btree_iter_upgrade(iter, 1)) {
+ !!__bch2_btree_iter_upgrade(trans, iter, 1)) {
trace_transaction_restart_ip(trans->ip, _THIS_IP_);
BUG_ON(!trans->restarted);
ret = -EINTR;
@@ -343,7 +342,7 @@ fill:
iter->uptodate = BTREE_ITER_NEED_PEEK;
if ((iter->flags & BTREE_ITER_INTENT) &&
- !bch2_btree_iter_upgrade(iter, 1)) {
+ !bch2_btree_iter_upgrade(trans, iter, 1)) {
BUG_ON(!trans->restarted);
ret = -EINTR;
}
diff --git a/fs/bcachefs/btree_key_cache.h b/fs/bcachefs/btree_key_cache.h
index 7e2b0a08f745..d890632e4425 100644
--- a/fs/bcachefs/btree_key_cache.h
+++ b/fs/bcachefs/btree_key_cache.h
@@ -26,7 +26,7 @@ int bch2_btree_key_cache_journal_flush(struct journal *,
struct bkey_cached *
bch2_btree_key_cache_find(struct bch_fs *, enum btree_id, struct bpos);
-int bch2_btree_iter_traverse_cached(struct btree_iter *);
+int bch2_btree_iter_traverse_cached(struct btree_trans *, struct btree_iter *);
bool bch2_btree_insert_key_cached(struct btree_trans *,
struct btree_iter *, struct bkey_i *);
diff --git a/fs/bcachefs/btree_locking.h b/fs/bcachefs/btree_locking.h
index 869c498e3f78..f8b358f8f2c1 100644
--- a/fs/bcachefs/btree_locking.h
+++ b/fs/bcachefs/btree_locking.h
@@ -167,40 +167,38 @@ static inline bool btree_node_lock_increment(struct btree_trans *trans,
return false;
}
-bool __bch2_btree_node_lock(struct btree *, struct bpos, unsigned,
- struct btree_iter *, enum six_lock_type,
- six_lock_should_sleep_fn, void *,
- unsigned long);
+bool __bch2_btree_node_lock(struct btree_trans *, struct btree_iter *,
+ struct btree *, struct bpos, unsigned,
+ enum six_lock_type, six_lock_should_sleep_fn,
+ void *, unsigned long);
-static inline bool btree_node_lock(struct btree *b,
- struct bpos pos, unsigned level,
+static inline bool btree_node_lock(struct btree_trans *trans,
struct btree_iter *iter,
+ struct btree *b, struct bpos pos, unsigned level,
enum six_lock_type type,
six_lock_should_sleep_fn should_sleep_fn, void *p,
unsigned long ip)
{
- struct btree_trans *trans = iter->trans;
-
EBUG_ON(level >= BTREE_MAX_DEPTH);
EBUG_ON(!(trans->iters_linked & (1ULL << iter->idx)));
return likely(six_trylock_type(&b->c.lock, type)) ||
btree_node_lock_increment(trans, b, level, type) ||
- __bch2_btree_node_lock(b, pos, level, iter, type,
+ __bch2_btree_node_lock(trans, iter, b, pos, level, type,
should_sleep_fn, p, ip);
}
-bool __bch2_btree_node_relock(struct btree_iter *, unsigned);
+bool __bch2_btree_node_relock(struct btree_trans *, struct btree_iter *, unsigned);
-static inline bool bch2_btree_node_relock(struct btree_iter *iter,
- unsigned level)
+static inline bool bch2_btree_node_relock(struct btree_trans *trans,
+ struct btree_iter *iter, unsigned level)
{
EBUG_ON(btree_node_locked(iter, level) &&
btree_node_locked_type(iter, level) !=
__btree_lock_want(iter, level));
return likely(btree_node_locked(iter, level)) ||
- __bch2_btree_node_relock(iter, level);
+ __bch2_btree_node_relock(trans, iter, level);
}
/*
@@ -225,8 +223,7 @@ bch2_btree_node_unlock_write_inlined(struct btree_trans *trans, struct btree_ite
void bch2_btree_node_unlock_write(struct btree_trans *,
struct btree_iter *, struct btree *);
-void __bch2_btree_node_lock_write(struct btree_trans *,
- struct btree_iter *, struct btree *);
+void __bch2_btree_node_lock_write(struct btree_trans *, struct btree *);
static inline void bch2_btree_node_lock_write(struct btree_trans *trans,
struct btree_iter *iter,
@@ -234,9 +231,10 @@ static inline void bch2_btree_node_lock_write(struct btree_trans *trans,
{
EBUG_ON(iter->l[b->c.level].b != b);
EBUG_ON(iter->l[b->c.level].lock_seq != b->c.lock.state.seq);
+ EBUG_ON(!btree_node_intent_locked(iter, b->c.level));
if (unlikely(!six_trylock_write(&b->c.lock)))
- __bch2_btree_node_lock_write(trans, iter, b);
+ __bch2_btree_node_lock_write(trans, b);
}
#endif /* _BCACHEFS_BTREE_LOCKING_H */
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c
index 3d7c47712b74..d18d539bcc8e 100644
--- a/fs/bcachefs/btree_update_interior.c
+++ b/fs/bcachefs/btree_update_interior.c
@@ -937,7 +937,7 @@ retry:
* XXX: figure out how far we might need to split,
* instead of locking/reserving all the way to the root:
*/
- if (!bch2_btree_iter_upgrade(iter, U8_MAX)) {
+ if (!bch2_btree_iter_upgrade(trans, iter, U8_MAX)) {
trace_trans_restart_iter_upgrade(trans->ip, _RET_IP_,
iter->btree_id,
&iter->real_pos);
diff --git a/fs/bcachefs/btree_update_interior.h b/fs/bcachefs/btree_update_interior.h
index 07046dab614b..13b3a1bf0f4f 100644
--- a/fs/bcachefs/btree_update_interior.h
+++ b/fs/bcachefs/btree_update_interior.h
@@ -132,7 +132,7 @@ static inline int bch2_foreground_maybe_merge_sibling(struct btree_trans *trans,
if (iter->uptodate >= BTREE_ITER_NEED_TRAVERSE)
return 0;
- if (!bch2_btree_node_relock(iter, level))
+ if (!bch2_btree_node_relock(trans, iter, level))
return 0;
b = iter->l[level].b;
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index 21fd6b2a7532..aabf408a5114 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -561,7 +561,7 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans,
*/
trans_for_each_iter(trans, iter)
if (iter->nodes_locked != iter->nodes_intent_locked &&
- !bch2_btree_iter_upgrade(iter, 1)) {
+ !bch2_btree_iter_upgrade(trans, iter, 1)) {
trace_trans_restart_upgrade(trans->ip, trace_ip,
iter->btree_id,
&iter->real_pos);
@@ -783,7 +783,8 @@ int __bch2_trans_commit(struct btree_trans *trans)
trans_for_each_update(trans, i) {
BUG_ON(!i->iter->should_be_locked);
- if (unlikely(!bch2_btree_iter_upgrade(i->iter, i->level + 1))) {
+ if (unlikely(!bch2_btree_iter_upgrade(trans, i->iter,
+ i->level + 1))) {
trace_trans_restart_upgrade(trans->ip, _RET_IP_,
i->iter->btree_id,
&i->iter->pos);
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index b02af94f4037..71b0f14f41f3 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -326,8 +326,8 @@ static void btree_and_journal_iter_prefetch(struct bch_fs *c, struct btree *b,
(k = bch2_btree_and_journal_iter_peek(&iter)).k) {
bch2_bkey_buf_reassemble(&tmp, c, k);
- bch2_btree_node_prefetch(c, NULL, tmp.k,
- b->c.btree_id, b->c.level - 1);
+ bch2_btree_node_prefetch(c, NULL, NULL, tmp.k,
+ b->c.btree_id, b->c.level - 1);
bch2_btree_and_journal_iter_advance(&iter);
i++;