Skip to content

Commit b00750c

Browse files
author
Kent Overstreet
committed
bcachefs: Better helpers for inconsistency errors
An inconsistency error often happens as part of an event with multiple error messages, and we want to build up one single error message with proper indenting to produce more readable log messages that don't get garbled. Add new helpers that emit messages to a printbuf instead of printing them directly, next patch will convert to use them. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 1ece532 commit b00750c

File tree

2 files changed

+110
-38
lines changed

2 files changed

+110
-38
lines changed

fs/bcachefs/error.c

Lines changed: 96 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,16 @@
1111

1212
#define FSCK_ERR_RATELIMIT_NR 10
1313

14-
bool bch2_inconsistent_error(struct bch_fs *c)
14+
void bch2_log_msg_start(struct bch_fs *c, struct printbuf *out)
15+
{
16+
printbuf_indent_add_nextline(out, 2);
17+
18+
#ifdef BCACHEFS_LOG_PREFIX
19+
prt_printf(out, bch2_log_msg(c, ""));
20+
#endif
21+
}
22+
23+
bool __bch2_inconsistent_error(struct bch_fs *c, struct printbuf *out)
1524
{
1625
set_bit(BCH_FS_error, &c->flags);
1726

@@ -21,8 +30,8 @@ bool bch2_inconsistent_error(struct bch_fs *c)
2130
case BCH_ON_ERROR_fix_safe:
2231
case BCH_ON_ERROR_ro:
2332
if (bch2_fs_emergency_read_only(c))
24-
bch_err(c, "inconsistency detected - emergency read only at journal seq %llu",
25-
journal_cur_seq(&c->journal));
33+
prt_printf(out, "inconsistency detected - emergency read only at journal seq %llu\n",
34+
journal_cur_seq(&c->journal));
2635
return true;
2736
case BCH_ON_ERROR_panic:
2837
panic(bch2_fmt(c, "panic after error"));
@@ -32,6 +41,56 @@ bool bch2_inconsistent_error(struct bch_fs *c)
3241
}
3342
}
3443

44+
bool bch2_inconsistent_error(struct bch_fs *c)
45+
{
46+
struct printbuf buf = PRINTBUF;
47+
printbuf_indent_add_nextline(&buf, 2);
48+
49+
bool ret = __bch2_inconsistent_error(c, &buf);
50+
if (ret)
51+
bch_err(c, "%s", buf.buf);
52+
printbuf_exit(&buf);
53+
return ret;
54+
}
55+
56+
__printf(3, 0)
57+
static bool bch2_fs_trans_inconsistent(struct bch_fs *c, struct btree_trans *trans,
58+
const char *fmt, va_list args)
59+
{
60+
struct printbuf buf = PRINTBUF;
61+
62+
bch2_log_msg_start(c, &buf);
63+
64+
prt_vprintf(&buf, fmt, args);
65+
prt_newline(&buf);
66+
67+
if (trans)
68+
bch2_trans_updates_to_text(&buf, trans);
69+
bool ret = __bch2_inconsistent_error(c, &buf);
70+
bch2_print_string_as_lines(KERN_ERR, buf.buf);
71+
72+
printbuf_exit(&buf);
73+
return ret;
74+
}
75+
76+
bool bch2_fs_inconsistent(struct bch_fs *c, const char *fmt, ...)
77+
{
78+
va_list args;
79+
va_start(args, fmt);
80+
bool ret = bch2_fs_trans_inconsistent(c, NULL, fmt, args);
81+
va_end(args);
82+
return ret;
83+
}
84+
85+
bool bch2_trans_inconsistent(struct btree_trans *trans, const char *fmt, ...)
86+
{
87+
va_list args;
88+
va_start(args, fmt);
89+
bool ret = bch2_fs_trans_inconsistent(trans->c, trans, fmt, args);
90+
va_end(args);
91+
return ret;
92+
}
93+
3594
int bch2_topology_error(struct bch_fs *c)
3695
{
3796
set_bit(BCH_FS_topology_error, &c->flags);
@@ -44,6 +103,31 @@ int bch2_topology_error(struct bch_fs *c)
44103
}
45104
}
46105

106+
int __bch2_topology_error(struct bch_fs *c, struct printbuf *out)
107+
{
108+
prt_printf(out, "btree topology error: ");
109+
110+
return bch2_topology_error(c);
111+
}
112+
113+
int bch2_fs_topology_error(struct bch_fs *c, const char *fmt, ...)
114+
{
115+
struct printbuf buf = PRINTBUF;
116+
117+
bch2_log_msg_start(c, &buf);
118+
119+
va_list args;
120+
va_start(args, fmt);
121+
prt_vprintf(&buf, fmt, args);
122+
va_end(args);
123+
124+
int ret = __bch2_topology_error(c, &buf);
125+
bch2_print_string_as_lines(KERN_ERR, buf.buf);
126+
127+
printbuf_exit(&buf);
128+
return ret;
129+
}
130+
47131
void bch2_fatal_error(struct bch_fs *c)
48132
{
49133
if (bch2_fs_emergency_read_only(c))
@@ -379,6 +463,7 @@ int __bch2_fsck_err(struct bch_fs *c,
379463
!(flags & (FSCK_CAN_FIX|FSCK_CAN_IGNORE))) {
380464
prt_str(out, ", shutting down");
381465
inconsistent = true;
466+
print = true;
382467
ret = -BCH_ERR_fsck_errors_not_fixed;
383468
} else if (flags & FSCK_CAN_FIX) {
384469
prt_str(out, ", ");
@@ -440,25 +525,27 @@ int __bch2_fsck_err(struct bch_fs *c,
440525
prt_newline(out);
441526

442527
if (inconsistent)
443-
bch2_inconsistent_error(c);
528+
__bch2_inconsistent_error(c, out);
444529
else if (exiting)
445530
prt_printf(out, "Unable to continue, halting\n");
446531
else if (suppressing)
447532
prt_printf(out, "Ratelimiting new instances of previous error\n");
448533

449534
if (print) {
535+
/* possibly strip an empty line, from printbuf_indent_add */
536+
while (out->pos && out->buf[out->pos - 1] == ' ')
537+
--out->pos;
538+
printbuf_nul_terminate(out);
539+
450540
if (bch2_fs_stdio_redirect(c))
451-
bch2_print(c, "%s\n", out->buf);
541+
bch2_print(c, "%s", out->buf);
452542
else
453543
bch2_print_string_as_lines(KERN_ERR, out->buf);
454544
}
455545

456546
if (s)
457547
s->ret = ret;
458548

459-
if (inconsistent)
460-
bch2_inconsistent_error(c);
461-
462549
/*
463550
* We don't yet track whether the filesystem currently has errors, for
464551
* log_fsck_err()s: that would require us to track for every error type
@@ -527,9 +614,7 @@ int __bch2_bkey_fsck_err(struct bch_fs *c,
527614
prt_vprintf(&buf, fmt, args);
528615
va_end(args);
529616

530-
prt_str(&buf, ": delete?");
531-
532-
int ret = __bch2_fsck_err(c, NULL, fsck_flags, err, "%s", buf.buf);
617+
int ret = __bch2_fsck_err(c, NULL, fsck_flags, err, "%s, delete?", buf.buf);
533618
printbuf_exit(&buf);
534619
return ret;
535620
}

fs/bcachefs/error.h

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ struct work_struct;
1818

1919
/* Error messages: */
2020

21+
void bch2_log_msg_start(struct bch_fs *, struct printbuf *);
22+
2123
/*
2224
* Inconsistency errors: The on disk data is inconsistent. If these occur during
2325
* initial recovery, they don't indicate a bug in the running code - we walk all
@@ -29,21 +31,10 @@ struct work_struct;
2931
* BCH_ON_ERROR_CONTINUE mode
3032
*/
3133

34+
bool __bch2_inconsistent_error(struct bch_fs *, struct printbuf *);
3235
bool bch2_inconsistent_error(struct bch_fs *);
33-
34-
int bch2_topology_error(struct bch_fs *);
35-
36-
#define bch2_fs_topology_error(c, ...) \
37-
({ \
38-
bch_err(c, "btree topology error: " __VA_ARGS__); \
39-
bch2_topology_error(c); \
40-
})
41-
42-
#define bch2_fs_inconsistent(c, ...) \
43-
({ \
44-
bch_err(c, __VA_ARGS__); \
45-
bch2_inconsistent_error(c); \
46-
})
36+
__printf(2, 3)
37+
bool bch2_fs_inconsistent(struct bch_fs *, const char *, ...);
4738

4839
#define bch2_fs_inconsistent_on(cond, ...) \
4940
({ \
@@ -53,26 +44,22 @@ int bch2_topology_error(struct bch_fs *);
5344
_ret; \
5445
})
5546

56-
/*
57-
* When a transaction update discovers or is causing a fs inconsistency, it's
58-
* helpful to also dump the pending updates:
59-
*/
60-
#define bch2_trans_inconsistent(trans, ...) \
61-
({ \
62-
bch_err(trans->c, __VA_ARGS__); \
63-
bch2_dump_trans_updates(trans); \
64-
bch2_inconsistent_error(trans->c); \
65-
})
47+
__printf(2, 3)
48+
bool bch2_trans_inconsistent(struct btree_trans *, const char *, ...);
6649

67-
#define bch2_trans_inconsistent_on(cond, trans, ...) \
50+
#define bch2_trans_inconsistent_on(cond, ...) \
6851
({ \
6952
bool _ret = unlikely(!!(cond)); \
70-
\
7153
if (_ret) \
72-
bch2_trans_inconsistent(trans, __VA_ARGS__); \
54+
bch2_trans_inconsistent(__VA_ARGS__); \
7355
_ret; \
7456
})
7557

58+
int bch2_topology_error(struct bch_fs *);
59+
int __bch2_topology_error(struct bch_fs *, struct printbuf *);
60+
__printf(2, 3)
61+
int bch2_fs_topology_error(struct bch_fs *, const char *, ...);
62+
7663
/*
7764
* Fsck errors: inconsistency errors we detect at mount time, and should ideally
7865
* be able to repair:

0 commit comments

Comments
 (0)