@@ -34,6 +34,7 @@ bool __bch2_inconsistent_error(struct bch_fs *c, struct printbuf *out)
34
34
journal_cur_seq (& c -> journal ));
35
35
return true;
36
36
case BCH_ON_ERROR_panic :
37
+ bch2_print_string_as_lines (KERN_ERR , out -> buf );
37
38
panic (bch2_fmt (c , "panic after error" ));
38
39
return true;
39
40
default :
@@ -268,15 +269,16 @@ static enum ask_yn bch2_fsck_ask_yn(struct bch_fs *c, struct btree_trans *trans)
268
269
269
270
#endif
270
271
271
- static struct fsck_err_state * fsck_err_get (struct bch_fs * c , const char * fmt )
272
+ static struct fsck_err_state * fsck_err_get (struct bch_fs * c ,
273
+ enum bch_sb_error_id id )
272
274
{
273
275
struct fsck_err_state * s ;
274
276
275
277
if (!test_bit (BCH_FS_fsck_running , & c -> flags ))
276
278
return NULL ;
277
279
278
280
list_for_each_entry (s , & c -> fsck_error_msgs , list )
279
- if (s -> fmt == fmt ) {
281
+ if (s -> id == id ) {
280
282
/*
281
283
* move it to the head of the list: repeated fsck errors
282
284
* are common
@@ -294,7 +296,7 @@ static struct fsck_err_state *fsck_err_get(struct bch_fs *c, const char *fmt)
294
296
}
295
297
296
298
INIT_LIST_HEAD (& s -> list );
297
- s -> fmt = fmt ;
299
+ s -> id = id ;
298
300
list_add (& s -> list , & c -> fsck_error_msgs );
299
301
return s ;
300
302
}
@@ -344,15 +346,59 @@ static int do_fsck_ask_yn(struct bch_fs *c,
344
346
return ask ;
345
347
}
346
348
349
+ static struct fsck_err_state * count_fsck_err_locked (struct bch_fs * c ,
350
+ enum bch_sb_error_id id , const char * msg ,
351
+ bool * repeat , bool * print , bool * suppress )
352
+ {
353
+ bch2_sb_error_count (c , id );
354
+
355
+ struct fsck_err_state * s = fsck_err_get (c , id );
356
+ if (s ) {
357
+ /*
358
+ * We may be called multiple times for the same error on
359
+ * transaction restart - this memoizes instead of asking the user
360
+ * multiple times for the same error:
361
+ */
362
+ if (s -> last_msg && !strcmp (msg , s -> last_msg )) {
363
+ * repeat = true;
364
+ * print = false;
365
+ return s ;
366
+ }
367
+
368
+ kfree (s -> last_msg );
369
+ s -> last_msg = kstrdup (msg , GFP_KERNEL );
370
+
371
+ if (c -> opts .ratelimit_errors &&
372
+ s -> nr >= FSCK_ERR_RATELIMIT_NR ) {
373
+ if (s -> nr == FSCK_ERR_RATELIMIT_NR )
374
+ * suppress = true;
375
+ else
376
+ * print = false;
377
+ }
378
+
379
+ s -> nr ++ ;
380
+ }
381
+ return s ;
382
+ }
383
+
384
+ void __bch2_count_fsck_err (struct bch_fs * c ,
385
+ enum bch_sb_error_id id , const char * msg ,
386
+ bool * repeat , bool * print , bool * suppress )
387
+ {
388
+ bch2_sb_error_count (c , id );
389
+
390
+ mutex_lock (& c -> fsck_error_msgs_lock );
391
+ count_fsck_err_locked (c , id , msg , repeat , print , suppress );
392
+ mutex_unlock (& c -> fsck_error_msgs_lock );
393
+ }
394
+
347
395
int __bch2_fsck_err (struct bch_fs * c ,
348
396
struct btree_trans * trans ,
349
397
enum bch_fsck_flags flags ,
350
398
enum bch_sb_error_id err ,
351
399
const char * fmt , ...)
352
400
{
353
- struct fsck_err_state * s = NULL ;
354
401
va_list args ;
355
- bool print = true, suppressing = false, inconsistent = false, exiting = false;
356
402
struct printbuf buf = PRINTBUF , * out = & buf ;
357
403
int ret = - BCH_ERR_fsck_ignore ;
358
404
const char * action_orig = "fix?" , * action = action_orig ;
@@ -387,8 +433,6 @@ int __bch2_fsck_err(struct bch_fs *c,
387
433
? - BCH_ERR_fsck_fix
388
434
: - BCH_ERR_fsck_ignore ;
389
435
390
- bch2_sb_error_count (c , err );
391
-
392
436
printbuf_indent_add_nextline (out , 2 );
393
437
394
438
#ifdef BCACHEFS_LOG_PREFIX
@@ -414,35 +458,13 @@ int __bch2_fsck_err(struct bch_fs *c,
414
458
}
415
459
416
460
mutex_lock (& c -> fsck_error_msgs_lock );
417
- s = fsck_err_get (c , fmt );
418
- if (s ) {
419
- /*
420
- * We may be called multiple times for the same error on
421
- * transaction restart - this memoizes instead of asking the user
422
- * multiple times for the same error:
423
- */
424
- if (s -> last_msg && !strcmp (buf .buf , s -> last_msg )) {
425
- ret = s -> ret ;
426
- goto err_unlock ;
427
- }
428
-
429
- kfree (s -> last_msg );
430
- s -> last_msg = kstrdup (buf .buf , GFP_KERNEL );
431
- if (!s -> last_msg ) {
432
- ret = - ENOMEM ;
433
- goto err_unlock ;
434
- }
435
-
436
- if (c -> opts .ratelimit_errors &&
437
- !(flags & FSCK_NO_RATELIMIT ) &&
438
- s -> nr >= FSCK_ERR_RATELIMIT_NR ) {
439
- if (s -> nr == FSCK_ERR_RATELIMIT_NR )
440
- suppressing = true;
441
- else
442
- print = false;
443
- }
444
-
445
- s -> nr ++ ;
461
+ bool repeat = false, print = true, suppress = false;
462
+ bool inconsistent = false, exiting = false;
463
+ struct fsck_err_state * s =
464
+ count_fsck_err_locked (c , err , buf .buf , & repeat , & print , & suppress );
465
+ if (repeat ) {
466
+ ret = s -> ret ;
467
+ goto err_unlock ;
446
468
}
447
469
448
470
if ((flags & FSCK_AUTOFIX ) &&
@@ -528,7 +550,7 @@ int __bch2_fsck_err(struct bch_fs *c,
528
550
__bch2_inconsistent_error (c , out );
529
551
else if (exiting )
530
552
prt_printf (out , "Unable to continue, halting\n" );
531
- else if (suppressing )
553
+ else if (suppress )
532
554
prt_printf (out , "Ratelimiting new instances of previous error\n" );
533
555
534
556
if (print ) {
0 commit comments