Skip to content

Commit 6d77ce4

Browse files
author
Kent Overstreet
committed
bcachefs: Better printing of inconsistency errors
Build up and emit the error message for an inconsistency error all at once, instead of spread over multiple printk calls, so they're not jumbled in the dmesg log. Also, add better indenting. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 7337f9f commit 6d77ce4

File tree

10 files changed

+153
-151
lines changed

10 files changed

+153
-151
lines changed

fs/bcachefs/backpointers.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ static noinline int backpointer_mod_err(struct btree_trans *trans,
9696
{
9797
struct bch_fs *c = trans->c;
9898
struct printbuf buf = PRINTBUF;
99+
int ret = 0;
99100

100101
if (insert) {
101102
prt_printf(&buf, "existing backpointer found when inserting ");
@@ -125,17 +126,15 @@ static noinline int backpointer_mod_err(struct btree_trans *trans,
125126

126127
prt_printf(&buf, "for ");
127128
bch2_bkey_val_to_text(&buf, c, orig_k);
128-
129-
bch_err(c, "%s", buf.buf);
130129
}
131130

132-
printbuf_exit(&buf);
131+
if (c->curr_recovery_pass > BCH_RECOVERY_PASS_check_extents_to_backpointers &&
132+
__bch2_inconsistent_error(c, &buf))
133+
ret = -BCH_ERR_erofs_unfixed_errors;
133134

134-
if (c->curr_recovery_pass > BCH_RECOVERY_PASS_check_extents_to_backpointers) {
135-
return bch2_inconsistent_error(c) ? BCH_ERR_erofs_unfixed_errors : 0;
136-
} else {
137-
return 0;
138-
}
135+
bch_err(c, "%s", buf.buf);
136+
printbuf_exit(&buf);
137+
return ret;
139138
}
140139

141140
int bch2_bucket_backpointer_mod_nowritebuffer(struct btree_trans *trans,

fs/bcachefs/btree_io.c

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -548,32 +548,39 @@ static int __btree_err(int ret,
548548
enum bch_sb_error_id err_type,
549549
const char *fmt, ...)
550550
{
551-
struct printbuf out = PRINTBUF;
552551
bool silent = c->curr_recovery_pass == BCH_RECOVERY_PASS_scan_for_btree_nodes;
553-
va_list args;
552+
553+
if (!have_retry && ret == -BCH_ERR_btree_node_read_err_want_retry)
554+
ret = -BCH_ERR_btree_node_read_err_fixable;
555+
if (!have_retry && ret == -BCH_ERR_btree_node_read_err_must_retry)
556+
ret = -BCH_ERR_btree_node_read_err_bad_node;
557+
558+
if (!silent && ret != -BCH_ERR_btree_node_read_err_fixable)
559+
bch2_sb_error_count(c, err_type);
560+
561+
struct printbuf out = PRINTBUF;
562+
if (write != WRITE && ret != -BCH_ERR_btree_node_read_err_fixable) {
563+
printbuf_indent_add_nextline(&out, 2);
564+
#ifdef BCACHEFS_LOG_PREFIX
565+
prt_printf(&out, bch2_log_msg(c, ""));
566+
#endif
567+
}
554568

555569
btree_err_msg(&out, c, ca, b, i, k, b->written, write);
556570

571+
va_list args;
557572
va_start(args, fmt);
558573
prt_vprintf(&out, fmt, args);
559574
va_end(args);
560575

561576
if (write == WRITE) {
562-
bch2_print_string_as_lines(KERN_ERR, out.buf);
563-
ret = c->opts.errors == BCH_ON_ERROR_continue
564-
? 0
565-
: -BCH_ERR_fsck_errors_not_fixed;
566-
goto out;
577+
prt_str(&out, ", ");
578+
ret = __bch2_inconsistent_error(c, &out)
579+
? -BCH_ERR_fsck_errors_not_fixed
580+
: 0;
581+
silent = false;
567582
}
568583

569-
if (!have_retry && ret == -BCH_ERR_btree_node_read_err_want_retry)
570-
ret = -BCH_ERR_btree_node_read_err_fixable;
571-
if (!have_retry && ret == -BCH_ERR_btree_node_read_err_must_retry)
572-
ret = -BCH_ERR_btree_node_read_err_bad_node;
573-
574-
if (!silent && ret != -BCH_ERR_btree_node_read_err_fixable)
575-
bch2_sb_error_count(c, err_type);
576-
577584
switch (ret) {
578585
case -BCH_ERR_btree_node_read_err_fixable:
579586
ret = !silent
@@ -583,25 +590,21 @@ static int __btree_err(int ret,
583590
ret != -BCH_ERR_fsck_ignore)
584591
goto fsck_err;
585592
ret = -BCH_ERR_fsck_fix;
586-
break;
587-
case -BCH_ERR_btree_node_read_err_want_retry:
588-
case -BCH_ERR_btree_node_read_err_must_retry:
589-
if (!silent)
590-
bch2_print_string_as_lines(KERN_ERR, out.buf);
591-
break;
593+
goto out;
592594
case -BCH_ERR_btree_node_read_err_bad_node:
593-
if (!silent)
594-
bch2_print_string_as_lines(KERN_ERR, out.buf);
595-
ret = bch2_topology_error(c);
595+
prt_str(&out, ", ");
596+
ret = __bch2_topology_error(c, &out);
597+
if (ret)
598+
silent = false;
596599
break;
597600
case -BCH_ERR_btree_node_read_err_incompatible:
598-
if (!silent)
599-
bch2_print_string_as_lines(KERN_ERR, out.buf);
600601
ret = -BCH_ERR_fsck_errors_not_fixed;
602+
silent = false;
601603
break;
602-
default:
603-
BUG();
604604
}
605+
606+
if (!silent)
607+
bch2_print_string_as_lines(KERN_ERR, out.buf);
605608
out:
606609
fsck_err:
607610
printbuf_exit(&out);

fs/bcachefs/btree_iter.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,16 +1495,6 @@ void bch2_trans_updates_to_text(struct printbuf *buf, struct btree_trans *trans)
14951495
printbuf_indent_sub(buf, 2);
14961496
}
14971497

1498-
noinline __cold
1499-
void bch2_dump_trans_updates(struct btree_trans *trans)
1500-
{
1501-
struct printbuf buf = PRINTBUF;
1502-
1503-
bch2_trans_updates_to_text(&buf, trans);
1504-
bch2_print_str(trans->c, buf.buf);
1505-
printbuf_exit(&buf);
1506-
}
1507-
15081498
static void bch2_btree_path_to_text_short(struct printbuf *out, struct btree_trans *trans, btree_path_idx_t path_idx)
15091499
{
15101500
struct btree_path *path = trans->paths + path_idx;

fs/bcachefs/btree_iter.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
void bch2_trans_updates_to_text(struct printbuf *, struct btree_trans *);
1010
void bch2_btree_path_to_text(struct printbuf *, struct btree_trans *, btree_path_idx_t);
1111
void bch2_trans_paths_to_text(struct printbuf *, struct btree_trans *);
12-
void bch2_dump_trans_updates(struct btree_trans *);
1312
void bch2_dump_trans_paths_updates(struct btree_trans *);
1413

1514
static inline int __bkey_err(const struct bkey *k)

fs/bcachefs/btree_node_scan.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -579,10 +579,12 @@ int bch2_get_scanned_nodes(struct bch_fs *c, enum btree_id btree,
579579

580580
found_btree_node_to_key(&tmp.k, &n);
581581

582-
struct printbuf buf = PRINTBUF;
583-
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&tmp.k));
584-
bch_verbose(c, "%s(): recovering %s", __func__, buf.buf);
585-
printbuf_exit(&buf);
582+
if (c->opts.verbose) {
583+
struct printbuf buf = PRINTBUF;
584+
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&tmp.k));
585+
bch_verbose(c, "%s(): recovering %s", __func__, buf.buf);
586+
printbuf_exit(&buf);
587+
}
586588

587589
BUG_ON(bch2_bkey_validate(c, bkey_i_to_s_c(&tmp.k),
588590
(struct bkey_validate_context) {

fs/bcachefs/btree_update_interior.c

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
5454
struct bkey_buf prev;
5555
int ret = 0;
5656

57+
printbuf_indent_add_nextline(&buf, 2);
58+
5759
BUG_ON(b->key.k.type == KEY_TYPE_btree_ptr_v2 &&
5860
!bpos_eq(bkey_i_to_btree_ptr_v2(&b->key)->v.min_key,
5961
b->data->min_key));
@@ -64,19 +66,20 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
6466

6567
if (b == btree_node_root(c, b)) {
6668
if (!bpos_eq(b->data->min_key, POS_MIN)) {
67-
printbuf_reset(&buf);
69+
ret = __bch2_topology_error(c, &buf);
70+
6871
bch2_bpos_to_text(&buf, b->data->min_key);
6972
log_fsck_err(trans, btree_root_bad_min_key,
7073
"btree root with incorrect min_key: %s", buf.buf);
71-
goto topology_repair;
74+
goto out;
7275
}
7376

7477
if (!bpos_eq(b->data->max_key, SPOS_MAX)) {
75-
printbuf_reset(&buf);
78+
ret = __bch2_topology_error(c, &buf);
7679
bch2_bpos_to_text(&buf, b->data->max_key);
7780
log_fsck_err(trans, btree_root_bad_max_key,
7881
"btree root with incorrect max_key: %s", buf.buf);
79-
goto topology_repair;
82+
goto out;
8083
}
8184
}
8285

@@ -94,9 +97,8 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
9497
: bpos_successor(prev.k->k.p);
9598

9699
if (!bpos_eq(expected_min, bp.v->min_key)) {
97-
bch2_topology_error(c);
100+
ret = __bch2_topology_error(c, &buf);
98101

99-
printbuf_reset(&buf);
100102
prt_str(&buf, "end of prev node doesn't match start of next node\nin ");
101103
bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
102104
prt_str(&buf, " node ");
@@ -107,28 +109,25 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
107109
bch2_bkey_val_to_text(&buf, c, k);
108110

109111
log_fsck_err(trans, btree_node_topology_bad_min_key, "%s", buf.buf);
110-
goto topology_repair;
112+
goto out;
111113
}
112114

113115
bch2_bkey_buf_reassemble(&prev, c, k);
114116
bch2_btree_and_journal_iter_advance(&iter);
115117
}
116118

117119
if (bkey_deleted(&prev.k->k)) {
118-
bch2_topology_error(c);
120+
ret = __bch2_topology_error(c, &buf);
119121

120-
printbuf_reset(&buf);
121122
prt_str(&buf, "empty interior node\nin ");
122123
bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
123124
prt_str(&buf, " node ");
124125
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
125126

126127
log_fsck_err(trans, btree_node_topology_empty_interior_node, "%s", buf.buf);
127-
goto topology_repair;
128128
} else if (!bpos_eq(prev.k->k.p, b->key.k.p)) {
129-
bch2_topology_error(c);
129+
ret = __bch2_topology_error(c, &buf);
130130

131-
printbuf_reset(&buf);
132131
prt_str(&buf, "last child node doesn't end at end of parent node\nin ");
133132
bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level);
134133
prt_str(&buf, " node ");
@@ -137,17 +136,13 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b)
137136
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(prev.k));
138137

139138
log_fsck_err(trans, btree_node_topology_bad_max_key, "%s", buf.buf);
140-
goto topology_repair;
141139
}
142140
out:
143141
fsck_err:
144142
bch2_btree_and_journal_iter_exit(&iter);
145143
bch2_bkey_buf_exit(&prev, c);
146144
printbuf_exit(&buf);
147145
return ret;
148-
topology_repair:
149-
ret = bch2_topology_error(c);
150-
goto out;
151146
}
152147

153148
/* Calculate ideal packed bkey format for new btree nodes: */
@@ -2007,18 +2002,22 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
20072002
}
20082003

20092004
if (!bpos_eq(bpos_successor(prev->data->max_key), next->data->min_key)) {
2010-
struct printbuf buf1 = PRINTBUF, buf2 = PRINTBUF;
2011-
2012-
bch2_bpos_to_text(&buf1, prev->data->max_key);
2013-
bch2_bpos_to_text(&buf2, next->data->min_key);
2014-
bch_err(c,
2015-
"%s(): btree topology error:\n"
2016-
" prev ends at %s\n"
2017-
" next starts at %s",
2018-
__func__, buf1.buf, buf2.buf);
2019-
printbuf_exit(&buf1);
2020-
printbuf_exit(&buf2);
2021-
ret = bch2_topology_error(c);
2005+
struct printbuf buf = PRINTBUF;
2006+
2007+
printbuf_indent_add_nextline(&buf, 2);
2008+
prt_printf(&buf, "%s(): ", __func__);
2009+
ret = __bch2_topology_error(c, &buf);
2010+
prt_newline(&buf);
2011+
2012+
prt_printf(&buf, "prev ends at ");
2013+
bch2_bpos_to_text(&buf, prev->data->max_key);
2014+
prt_newline(&buf);
2015+
2016+
prt_printf(&buf, "next starts at ");
2017+
bch2_bpos_to_text(&buf, next->data->min_key);
2018+
2019+
bch_err(c, "%s", buf.buf);
2020+
printbuf_exit(&buf);
20222021
goto err;
20232022
}
20242023

0 commit comments

Comments
 (0)