Skip to content

Commit e1f0e1a

Browse files
author
Kent Overstreet
committed
bcachefs: Fix restart handling in btree_node_scrub_work()
btree node scrub was sometimes failing to rewrite nodes with errors; bch2_btree_node_rewrite() can return a transaction restart and we weren't checking - the lockrestart_do() needs to wrap the entire operation. And there's a better helper it should've been using, bch2_btree_node_rewrite_key(), which makes all this more convenient. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 6c4897c commit e1f0e1a

3 files changed

Lines changed: 14 additions & 28 deletions

File tree

fs/bcachefs/btree_io.c

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,28 +1986,12 @@ static void btree_node_scrub_work(struct work_struct *work)
19861986
prt_newline(&err);
19871987

19881988
if (!btree_node_scrub_check(c, scrub->buf, scrub->written, &err)) {
1989-
struct btree_trans *trans = bch2_trans_get(c);
1990-
1991-
struct btree_iter iter;
1992-
bch2_trans_node_iter_init(trans, &iter, scrub->btree,
1993-
scrub->key.k->k.p, 0, scrub->level - 1, 0);
1994-
1995-
struct btree *b;
1996-
int ret = lockrestart_do(trans,
1997-
PTR_ERR_OR_ZERO(b = bch2_btree_iter_peek_node(trans, &iter)));
1998-
if (ret)
1999-
goto err;
2000-
2001-
if (bkey_i_to_btree_ptr_v2(&b->key)->v.seq == scrub->seq) {
2002-
bch_err(c, "error validating btree node during scrub on %s at btree %s",
2003-
scrub->ca->name, err.buf);
2004-
2005-
ret = bch2_btree_node_rewrite(trans, &iter, b, 0, 0);
2006-
}
2007-
err:
2008-
bch2_trans_iter_exit(trans, &iter);
2009-
bch2_trans_begin(trans);
2010-
bch2_trans_put(trans);
1989+
int ret = bch2_trans_do(c,
1990+
bch2_btree_node_rewrite_key(trans, scrub->btree, scrub->level - 1,
1991+
scrub->key.k, 0));
1992+
if (!bch2_err_matches(ret, ENOENT) &&
1993+
!bch2_err_matches(ret, EROFS))
1994+
bch_err_fn_ratelimited(c, ret);
20111995
}
20121996

20131997
printbuf_exit(&err);

fs/bcachefs/btree_update_interior.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,9 +2293,9 @@ int bch2_btree_node_rewrite(struct btree_trans *trans,
22932293
goto out;
22942294
}
22952295

2296-
static int bch2_btree_node_rewrite_key(struct btree_trans *trans,
2297-
enum btree_id btree, unsigned level,
2298-
struct bkey_i *k, unsigned flags)
2296+
int bch2_btree_node_rewrite_key(struct btree_trans *trans,
2297+
enum btree_id btree, unsigned level,
2298+
struct bkey_i *k, unsigned flags)
22992299
{
23002300
struct btree_iter iter;
23012301
bch2_trans_node_iter_init(trans, &iter,
@@ -2367,9 +2367,8 @@ static void async_btree_node_rewrite_work(struct work_struct *work)
23672367

23682368
int ret = bch2_trans_do(c, bch2_btree_node_rewrite_key(trans,
23692369
a->btree_id, a->level, a->key.k, 0));
2370-
if (ret != -ENOENT &&
2371-
!bch2_err_matches(ret, EROFS) &&
2372-
ret != -BCH_ERR_journal_shutdown)
2370+
if (!bch2_err_matches(ret, ENOENT) &&
2371+
!bch2_err_matches(ret, EROFS))
23732372
bch_err_fn_ratelimited(c, ret);
23742373

23752374
spin_lock(&c->btree_node_rewrites_lock);

fs/bcachefs/btree_update_interior.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ static inline int bch2_foreground_maybe_merge(struct btree_trans *trans,
176176

177177
int bch2_btree_node_rewrite(struct btree_trans *, struct btree_iter *,
178178
struct btree *, unsigned, unsigned);
179+
int bch2_btree_node_rewrite_key(struct btree_trans *,
180+
enum btree_id, unsigned,
181+
struct bkey_i *, unsigned);
179182
int bch2_btree_node_rewrite_pos(struct btree_trans *,
180183
enum btree_id, unsigned,
181184
struct bpos, unsigned, unsigned);

0 commit comments

Comments
 (0)