Skip to content

Commit 968feb8

Browse files
author
Kent Overstreet
committed
bcachefs: Convert for_each_btree_node() to lockrestart_do()
for_each_btree_node() now works similarly to for_each_btree_key(), where the loop body is passed as an argument to be passed to lockrestart_do(). This now calls trans_begin() on every loop iteration - which fixes an SRCU warning in backpointers fsck. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 48d6cc1 commit 968feb8

File tree

4 files changed

+42
-54
lines changed

4 files changed

+42
-54
lines changed

fs/bcachefs/backpointers.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -763,27 +763,22 @@ static int bch2_get_btree_in_memory_pos(struct btree_trans *trans,
763763
btree < BTREE_ID_NR && !ret;
764764
btree++) {
765765
unsigned depth = (BIT_ULL(btree) & btree_leaf_mask) ? 0 : 1;
766-
struct btree_iter iter;
767-
struct btree *b;
768766

769767
if (!(BIT_ULL(btree) & btree_leaf_mask) &&
770768
!(BIT_ULL(btree) & btree_interior_mask))
771769
continue;
772770

773-
bch2_trans_begin(trans);
774-
775-
__for_each_btree_node(trans, iter, btree,
771+
ret = __for_each_btree_node(trans, iter, btree,
776772
btree == start.btree ? start.pos : POS_MIN,
777-
0, depth, BTREE_ITER_prefetch, b, ret) {
773+
0, depth, BTREE_ITER_prefetch, b, ({
778774
mem_may_pin -= btree_buf_bytes(b);
779775
if (mem_may_pin <= 0) {
780776
c->btree_cache.pinned_nodes_end = *end =
781777
BBPOS(btree, b->key.k.p);
782-
bch2_trans_iter_exit(trans, &iter);
783-
return 0;
778+
break;
784779
}
785-
}
786-
bch2_trans_iter_exit(trans, &iter);
780+
0;
781+
}));
787782
}
788783

789784
return ret;

fs/bcachefs/btree_iter.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,6 +1900,7 @@ struct btree *bch2_btree_iter_peek_node(struct btree_iter *iter)
19001900
goto out;
19011901
}
19021902

1903+
/* Only kept for -tools */
19031904
struct btree *bch2_btree_iter_peek_node_and_restart(struct btree_iter *iter)
19041905
{
19051906
struct btree *b;

fs/bcachefs/btree_iter.h

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -600,23 +600,35 @@ void bch2_trans_srcu_unlock(struct btree_trans *);
600600

601601
u32 bch2_trans_begin(struct btree_trans *);
602602

603-
/*
604-
* XXX
605-
* this does not handle transaction restarts from bch2_btree_iter_next_node()
606-
* correctly
607-
*/
608-
#define __for_each_btree_node(_trans, _iter, _btree_id, _start, \
609-
_locks_want, _depth, _flags, _b, _ret) \
610-
for (bch2_trans_node_iter_init((_trans), &(_iter), (_btree_id), \
611-
_start, _locks_want, _depth, _flags); \
612-
(_b) = bch2_btree_iter_peek_node_and_restart(&(_iter)), \
613-
!((_ret) = PTR_ERR_OR_ZERO(_b)) && (_b); \
614-
(_b) = bch2_btree_iter_next_node(&(_iter)))
603+
#define __for_each_btree_node(_trans, _iter, _btree_id, _start, \
604+
_locks_want, _depth, _flags, _b, _do) \
605+
({ \
606+
bch2_trans_begin((_trans)); \
607+
\
608+
struct btree_iter _iter; \
609+
bch2_trans_node_iter_init((_trans), &_iter, (_btree_id), \
610+
_start, _locks_want, _depth, _flags); \
611+
int _ret3 = 0; \
612+
do { \
613+
_ret3 = lockrestart_do((_trans), ({ \
614+
struct btree *_b = bch2_btree_iter_peek_node(&_iter); \
615+
if (!_b) \
616+
break; \
617+
\
618+
PTR_ERR_OR_ZERO(_b) ?: (_do); \
619+
})) ?: \
620+
lockrestart_do((_trans), \
621+
PTR_ERR_OR_ZERO(bch2_btree_iter_next_node(&_iter))); \
622+
} while (!_ret3); \
623+
\
624+
bch2_trans_iter_exit((_trans), &(_iter)); \
625+
_ret3; \
626+
})
615627

616628
#define for_each_btree_node(_trans, _iter, _btree_id, _start, \
617-
_flags, _b, _ret) \
618-
__for_each_btree_node(_trans, _iter, _btree_id, _start, \
619-
0, 0, _flags, _b, _ret)
629+
_flags, _b, _do) \
630+
__for_each_btree_node(_trans, _iter, _btree_id, _start, \
631+
0, 0, _flags, _b, _do)
620632

621633
static inline struct bkey_s_c bch2_btree_iter_peek_prev_type(struct btree_iter *iter,
622634
unsigned flags)

fs/bcachefs/debug.c

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -397,47 +397,27 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf,
397397
size_t size, loff_t *ppos)
398398
{
399399
struct dump_iter *i = file->private_data;
400-
struct btree_trans *trans;
401-
struct btree_iter iter;
402-
struct btree *b;
403-
ssize_t ret;
404400

405401
i->ubuf = buf;
406402
i->size = size;
407403
i->ret = 0;
408404

409-
ret = flush_buf(i);
405+
ssize_t ret = flush_buf(i);
410406
if (ret)
411407
return ret;
412408

413409
if (bpos_eq(SPOS_MAX, i->from))
414410
return i->ret;
415411

416-
trans = bch2_trans_get(i->c);
417-
retry:
418-
bch2_trans_begin(trans);
419-
420-
for_each_btree_node(trans, iter, i->id, i->from, 0, b, ret) {
421-
bch2_btree_node_to_text(&i->buf, i->c, b);
422-
i->from = !bpos_eq(SPOS_MAX, b->key.k.p)
423-
? bpos_successor(b->key.k.p)
424-
: b->key.k.p;
425-
426-
ret = drop_locks_do(trans, flush_buf(i));
427-
if (ret)
428-
break;
429-
}
430-
bch2_trans_iter_exit(trans, &iter);
431-
432-
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
433-
goto retry;
434-
435-
bch2_trans_put(trans);
436-
437-
if (!ret)
438-
ret = flush_buf(i);
412+
return bch2_trans_run(i->c,
413+
for_each_btree_node(trans, iter, i->id, i->from, 0, b, ({
414+
bch2_btree_node_to_text(&i->buf, i->c, b);
415+
i->from = !bpos_eq(SPOS_MAX, b->key.k.p)
416+
? bpos_successor(b->key.k.p)
417+
: b->key.k.p;
439418

440-
return ret ?: i->ret;
419+
drop_locks_do(trans, flush_buf(i));
420+
}))) ?: i->ret;
441421
}
442422

443423
static const struct file_operations btree_format_debug_ops = {

0 commit comments

Comments
 (0)