]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/error.c
Update bcachefs sources to 1336a995cbc3 bcachefs: Silence transaction restart error...
[bcachefs-tools-debian] / libbcachefs / error.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include "bcachefs.h"
3 #include "error.h"
4 #include "super.h"
5
6 #define FSCK_ERR_RATELIMIT_NR   10
7
8 bool bch2_inconsistent_error(struct bch_fs *c)
9 {
10         set_bit(BCH_FS_ERROR, &c->flags);
11
12         switch (c->opts.errors) {
13         case BCH_ON_ERROR_continue:
14                 return false;
15         case BCH_ON_ERROR_ro:
16                 if (bch2_fs_emergency_read_only(c))
17                         bch_err(c, "inconsistency detected - emergency read only");
18                 return true;
19         case BCH_ON_ERROR_panic:
20                 panic(bch2_fmt(c, "panic after error"));
21                 return true;
22         default:
23                 BUG();
24         }
25 }
26
27 void bch2_topology_error(struct bch_fs *c)
28 {
29         set_bit(BCH_FS_TOPOLOGY_ERROR, &c->flags);
30         if (test_bit(BCH_FS_FSCK_DONE, &c->flags))
31                 bch2_inconsistent_error(c);
32 }
33
34 void bch2_fatal_error(struct bch_fs *c)
35 {
36         if (bch2_fs_emergency_read_only(c))
37                 bch_err(c, "fatal error - emergency read only");
38 }
39
40 void bch2_io_error_work(struct work_struct *work)
41 {
42         struct bch_dev *ca = container_of(work, struct bch_dev, io_error_work);
43         struct bch_fs *c = ca->fs;
44         bool dev;
45
46         down_write(&c->state_lock);
47         dev = bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_ro,
48                                     BCH_FORCE_IF_DEGRADED);
49         if (dev
50             ? __bch2_dev_set_state(c, ca, BCH_MEMBER_STATE_ro,
51                                   BCH_FORCE_IF_DEGRADED)
52             : bch2_fs_emergency_read_only(c))
53                 bch_err(ca,
54                         "too many IO errors, setting %s RO",
55                         dev ? "device" : "filesystem");
56         up_write(&c->state_lock);
57 }
58
59 void bch2_io_error(struct bch_dev *ca)
60 {
61         //queue_work(system_long_wq, &ca->io_error_work);
62 }
63
64 enum ask_yn {
65         YN_NO,
66         YN_YES,
67         YN_ALLNO,
68         YN_ALLYES,
69 };
70
71 #ifdef __KERNEL__
72 #define bch2_fsck_ask_yn()      YN_NO
73 #else
74
75 #include "tools-util.h"
76
77 enum ask_yn bch2_fsck_ask_yn(void)
78 {
79         char *buf = NULL;
80         size_t buflen = 0;
81         bool ret;
82
83         while (true) {
84                 fputs(" (y,n, or Y,N for all errors of this type) ", stdout);
85                 fflush(stdout);
86
87                 if (getline(&buf, &buflen, stdin) < 0)
88                         die("error reading from standard input");
89
90                 strim(buf);
91                 if (strlen(buf) != 1)
92                         continue;
93
94                 switch (buf[0]) {
95                 case 'n':
96                         return YN_NO;
97                 case 'y':
98                         return YN_YES;
99                 case 'N':
100                         return YN_ALLNO;
101                 case 'Y':
102                         return YN_ALLYES;
103                 }
104         }
105
106         free(buf);
107         return ret;
108 }
109
110 #endif
111
112 static struct fsck_err_state *fsck_err_get(struct bch_fs *c, const char *fmt)
113 {
114         struct fsck_err_state *s;
115
116         if (test_bit(BCH_FS_FSCK_DONE, &c->flags))
117                 return NULL;
118
119         list_for_each_entry(s, &c->fsck_errors, list)
120                 if (s->fmt == fmt) {
121                         /*
122                          * move it to the head of the list: repeated fsck errors
123                          * are common
124                          */
125                         list_move(&s->list, &c->fsck_errors);
126                         return s;
127                 }
128
129         s = kzalloc(sizeof(*s), GFP_NOFS);
130         if (!s) {
131                 if (!c->fsck_alloc_err)
132                         bch_err(c, "kmalloc err, cannot ratelimit fsck errs");
133                 c->fsck_alloc_err = true;
134                 return NULL;
135         }
136
137         INIT_LIST_HEAD(&s->list);
138         s->fmt = fmt;
139         list_add(&s->list, &c->fsck_errors);
140         return s;
141 }
142
143 int bch2_fsck_err(struct bch_fs *c, unsigned flags, const char *fmt, ...)
144 {
145         struct fsck_err_state *s = NULL;
146         va_list args;
147         bool print = true, suppressing = false, inconsistent = false;
148         struct printbuf buf = PRINTBUF, *out = &buf;
149         int ret = -BCH_ERR_fsck_ignore;
150
151         va_start(args, fmt);
152         prt_vprintf(out, fmt, args);
153         va_end(args);
154
155         mutex_lock(&c->fsck_error_lock);
156         s = fsck_err_get(c, fmt);
157         if (s) {
158                 /*
159                  * We may be called multiple times for the same error on
160                  * transaction restart - this memoizes instead of asking the user
161                  * multiple times for the same error:
162                  */
163                 if (s->last_msg && !strcmp(buf.buf, s->last_msg)) {
164                         ret = s->ret;
165                         mutex_unlock(&c->fsck_error_lock);
166                         printbuf_exit(&buf);
167                         return ret;
168                 }
169
170                 kfree(s->last_msg);
171                 s->last_msg = kstrdup(buf.buf, GFP_KERNEL);
172
173                 if (c->opts.ratelimit_errors &&
174                     !(flags & FSCK_NO_RATELIMIT) &&
175                     s->nr >= FSCK_ERR_RATELIMIT_NR) {
176                         if (s->nr == FSCK_ERR_RATELIMIT_NR)
177                                 suppressing = true;
178                         else
179                                 print = false;
180                 }
181
182                 s->nr++;
183         }
184
185 #ifdef BCACHEFS_LOG_PREFIX
186         if (!strncmp(fmt, "bcachefs:", 9))
187                 prt_printf(out, bch2_log_msg(c, ""));
188 #endif
189
190         if (test_bit(BCH_FS_FSCK_DONE, &c->flags)) {
191                 if (c->opts.errors != BCH_ON_ERROR_continue ||
192                     !(flags & (FSCK_CAN_FIX|FSCK_CAN_IGNORE))) {
193                         prt_str(out, ", shutting down");
194                         inconsistent = true;
195                         ret = -BCH_ERR_fsck_errors_not_fixed;
196                 } else if (flags & FSCK_CAN_FIX) {
197                         prt_str(out, ", fixing");
198                         ret = -BCH_ERR_fsck_fix;
199                 } else {
200                         prt_str(out, ", continuing");
201                         ret = -BCH_ERR_fsck_ignore;
202                 }
203         } else if (c->opts.fix_errors == FSCK_FIX_exit) {
204                 prt_str(out, ", exiting");
205                 ret = -BCH_ERR_fsck_errors_not_fixed;
206         } else if (flags & FSCK_CAN_FIX) {
207                 int fix = s && s->fix
208                         ? s->fix
209                         : c->opts.fix_errors;
210
211                 if (fix == FSCK_FIX_ask) {
212                         int ask;
213
214                         prt_str(out, ": fix?");
215                         bch2_print_string_as_lines(KERN_ERR, out->buf);
216                         print = false;
217
218                         ask = bch2_fsck_ask_yn();
219
220                         if (ask >= YN_ALLNO && s)
221                                 s->fix = ask == YN_ALLNO
222                                         ? FSCK_FIX_no
223                                         : FSCK_FIX_yes;
224
225                         ret = ask & 1
226                                 ? -BCH_ERR_fsck_fix
227                                 : -BCH_ERR_fsck_ignore;
228                 } else if (fix == FSCK_FIX_yes ||
229                            (c->opts.nochanges &&
230                             !(flags & FSCK_CAN_IGNORE))) {
231                         prt_str(out, ", fixing");
232                         ret = -BCH_ERR_fsck_fix;
233                 } else {
234                         prt_str(out, ", not fixing");
235                 }
236         } else if (flags & FSCK_NEED_FSCK) {
237                 prt_str(out, " (run fsck to correct)");
238         } else {
239                 prt_str(out, " (repair unimplemented)");
240         }
241
242         if (ret == -BCH_ERR_fsck_ignore &&
243             (c->opts.fix_errors == FSCK_FIX_exit ||
244              !(flags & FSCK_CAN_IGNORE)))
245                 ret = -BCH_ERR_fsck_errors_not_fixed;
246
247         if (print)
248                 bch2_print_string_as_lines(KERN_ERR, out->buf);
249
250         if (!test_bit(BCH_FS_FSCK_DONE, &c->flags) &&
251             (ret != -BCH_ERR_fsck_fix &&
252              ret != -BCH_ERR_fsck_ignore))
253                 bch_err(c, "Unable to continue, halting");
254         else if (suppressing)
255                 bch_err(c, "Ratelimiting new instances of previous error");
256
257         if (s)
258                 s->ret = ret;
259
260         mutex_unlock(&c->fsck_error_lock);
261
262         printbuf_exit(&buf);
263
264         if (inconsistent)
265                 bch2_inconsistent_error(c);
266
267         if (ret == -BCH_ERR_fsck_fix) {
268                 set_bit(BCH_FS_ERRORS_FIXED, &c->flags);
269         } else {
270                 set_bit(BCH_FS_ERRORS_NOT_FIXED, &c->flags);
271                 set_bit(BCH_FS_ERROR, &c->flags);
272         }
273
274         return ret;
275 }
276
277 void bch2_flush_fsck_errs(struct bch_fs *c)
278 {
279         struct fsck_err_state *s, *n;
280
281         mutex_lock(&c->fsck_error_lock);
282
283         list_for_each_entry_safe(s, n, &c->fsck_errors, list) {
284                 if (s->ratelimited && s->last_msg)
285                         bch_err(c, "Saw %llu errors like:\n    %s", s->nr, s->last_msg);
286
287                 list_del(&s->list);
288                 kfree(s->last_msg);
289                 kfree(s);
290         }
291
292         mutex_unlock(&c->fsck_error_lock);
293 }