2017-03-16 22:18:50 -08:00
// SPDX-License-Identifier: GPL-2.0
# include "bcachefs.h"
# include "error.h"
# include "super.h"
2019-09-07 12:42:27 -04:00
# define FSCK_ERR_RATELIMIT_NR 10
2017-03-16 22:18:50 -08:00
bool bch2_inconsistent_error ( struct bch_fs * c )
{
set_bit ( BCH_FS_ERROR , & c - > flags ) ;
switch ( c - > opts . errors ) {
2021-02-20 19:47:58 -05:00
case BCH_ON_ERROR_continue :
2017-03-16 22:18:50 -08:00
return false ;
2021-02-20 19:47:58 -05:00
case BCH_ON_ERROR_ro :
2017-03-16 22:18:50 -08:00
if ( bch2_fs_emergency_read_only ( c ) )
2022-01-11 22:08:44 -05:00
bch_err ( c , " inconsistency detected - emergency read only " ) ;
2017-03-16 22:18:50 -08:00
return true ;
2021-02-20 19:47:58 -05:00
case BCH_ON_ERROR_panic :
2017-03-16 22:18:50 -08:00
panic ( bch2_fmt ( c , " panic after error " ) ) ;
return true ;
default :
BUG ( ) ;
}
}
2021-04-24 16:32:35 -04:00
void bch2_topology_error ( struct bch_fs * c )
{
set_bit ( BCH_FS_TOPOLOGY_ERROR , & c - > flags ) ;
2023-02-01 15:45:45 -05:00
if ( test_bit ( BCH_FS_FSCK_DONE , & c - > flags ) )
2021-04-24 16:32:35 -04:00
bch2_inconsistent_error ( c ) ;
}
2017-03-16 22:18:50 -08:00
void bch2_fatal_error ( struct bch_fs * c )
{
if ( bch2_fs_emergency_read_only ( c ) )
2022-01-11 22:08:44 -05:00
bch_err ( c , " fatal error - emergency read only " ) ;
2017-03-16 22:18:50 -08:00
}
void bch2_io_error_work ( struct work_struct * work )
{
struct bch_dev * ca = container_of ( work , struct bch_dev , io_error_work ) ;
struct bch_fs * c = ca - > fs ;
bool dev ;
2020-06-15 14:58:47 -04:00
down_write ( & c - > state_lock ) ;
2021-02-20 19:47:58 -05:00
dev = bch2_dev_state_allowed ( c , ca , BCH_MEMBER_STATE_ro ,
2017-03-16 22:18:50 -08:00
BCH_FORCE_IF_DEGRADED ) ;
if ( dev
2021-02-20 19:47:58 -05:00
? __bch2_dev_set_state ( c , ca , BCH_MEMBER_STATE_ro ,
2017-03-16 22:18:50 -08:00
BCH_FORCE_IF_DEGRADED )
: bch2_fs_emergency_read_only ( c ) )
bch_err ( ca ,
" too many IO errors, setting %s RO " ,
dev ? " device " : " filesystem " ) ;
2020-06-15 14:58:47 -04:00
up_write ( & c - > state_lock ) ;
2017-03-16 22:18:50 -08:00
}
2023-10-25 16:29:37 -04:00
void bch2_io_error ( struct bch_dev * ca , enum bch_member_error_type type )
2017-03-16 22:18:50 -08:00
{
2023-10-25 16:29:37 -04:00
atomic64_inc ( & ca - > errors [ type ] ) ;
2017-03-16 22:18:50 -08:00
//queue_work(system_long_wq, &ca->io_error_work);
}
2023-04-15 14:26:14 -04:00
enum ask_yn {
YN_NO ,
YN_YES ,
YN_ALLNO ,
YN_ALLYES ,
} ;
2017-03-16 22:18:50 -08:00
# ifdef __KERNEL__
2023-04-15 14:26:14 -04:00
# define bch2_fsck_ask_yn() YN_NO
2017-03-16 22:18:50 -08:00
# else
2023-04-15 14:26:14 -04:00
2017-03-16 22:18:50 -08:00
# include "tools-util.h"
2023-04-15 14:26:14 -04:00
enum ask_yn bch2_fsck_ask_yn ( void )
{
char * buf = NULL ;
size_t buflen = 0 ;
bool ret ;
while ( true ) {
2023-06-04 18:08:56 -04:00
fputs ( " (y,n, or Y,N for all errors of this type) " , stdout ) ;
2023-04-15 14:26:14 -04:00
fflush ( stdout ) ;
if ( getline ( & buf , & buflen , stdin ) < 0 )
die ( " error reading from standard input " ) ;
2023-06-04 18:08:56 -04:00
strim ( buf ) ;
2023-04-15 14:26:14 -04:00
if ( strlen ( buf ) ! = 1 )
continue ;
switch ( buf [ 0 ] ) {
case ' n ' :
return YN_NO ;
case ' y ' :
return YN_YES ;
case ' N ' :
return YN_ALLNO ;
case ' Y ' :
return YN_ALLYES ;
}
}
free ( buf ) ;
return ret ;
}
2017-03-16 22:18:50 -08:00
# endif
2022-09-25 18:18:48 -04:00
static struct fsck_err_state * fsck_err_get ( struct bch_fs * c , const char * fmt )
2017-03-16 22:18:50 -08:00
{
2022-09-25 18:18:48 -04:00
struct fsck_err_state * s ;
2017-03-16 22:18:50 -08:00
2022-09-25 18:18:48 -04:00
if ( test_bit ( BCH_FS_FSCK_DONE , & c - > flags ) )
return NULL ;
2017-03-16 22:18:50 -08:00
2023-10-25 15:51:16 -04:00
list_for_each_entry ( s , & c - > fsck_error_msgs , list )
2022-09-25 18:18:48 -04:00
if ( s - > fmt = = fmt ) {
/*
* move it to the head of the list : repeated fsck errors
* are common
*/
2023-10-25 15:51:16 -04:00
list_move ( & s - > list , & c - > fsck_error_msgs ) ;
2022-09-25 18:18:48 -04:00
return s ;
}
2017-03-16 22:18:50 -08:00
2020-05-28 17:15:41 -04:00
s = kzalloc ( sizeof ( * s ) , GFP_NOFS ) ;
2017-03-16 22:18:50 -08:00
if ( ! s ) {
2023-10-25 15:51:16 -04:00
if ( ! c - > fsck_alloc_msgs_err )
2017-03-16 22:18:50 -08:00
bch_err ( c , " kmalloc err, cannot ratelimit fsck errs " ) ;
2023-10-25 15:51:16 -04:00
c - > fsck_alloc_msgs_err = true ;
2022-09-25 18:18:48 -04:00
return NULL ;
2017-03-16 22:18:50 -08:00
}
INIT_LIST_HEAD ( & s - > list ) ;
s - > fmt = fmt ;
2023-10-25 15:51:16 -04:00
list_add ( & s - > list , & c - > fsck_error_msgs ) ;
2022-09-25 18:18:48 -04:00
return s ;
}
int bch2_fsck_err ( struct bch_fs * c , unsigned flags , const char * fmt , . . . )
{
struct fsck_err_state * s = NULL ;
va_list args ;
2022-10-09 00:54:36 -04:00
bool print = true , suppressing = false , inconsistent = false ;
2022-09-25 18:18:48 -04:00
struct printbuf buf = PRINTBUF , * out = & buf ;
int ret = - BCH_ERR_fsck_ignore ;
2023-02-16 21:02:14 -05:00
va_start ( args , fmt ) ;
prt_vprintf ( out , fmt , args ) ;
va_end ( args ) ;
2023-10-25 15:51:16 -04:00
mutex_lock ( & c - > fsck_error_msgs_lock ) ;
2022-09-25 18:18:48 -04:00
s = fsck_err_get ( c , fmt ) ;
if ( s ) {
2023-04-25 14:32:39 -04:00
/*
* We may be called multiple times for the same error on
* transaction restart - this memoizes instead of asking the user
* multiple times for the same error :
*/
2023-02-16 21:02:14 -05:00
if ( s - > last_msg & & ! strcmp ( buf . buf , s - > last_msg ) ) {
ret = s - > ret ;
2023-10-25 15:51:16 -04:00
mutex_unlock ( & c - > fsck_error_msgs_lock ) ;
2023-02-16 21:02:14 -05:00
printbuf_exit ( & buf ) ;
return ret ;
}
kfree ( s - > last_msg ) ;
s - > last_msg = kstrdup ( buf . buf , GFP_KERNEL ) ;
2022-09-25 18:18:48 -04:00
if ( c - > opts . ratelimit_errors & &
! ( flags & FSCK_NO_RATELIMIT ) & &
s - > nr > = FSCK_ERR_RATELIMIT_NR ) {
if ( s - > nr = = FSCK_ERR_RATELIMIT_NR )
suppressing = true ;
else
print = false ;
}
s - > nr + + ;
2019-11-06 15:32:11 -05:00
}
2022-09-25 18:18:48 -04:00
2022-11-13 20:01:42 -05:00
# ifdef BCACHEFS_LOG_PREFIX
2022-09-25 18:18:48 -04:00
if ( ! strncmp ( fmt , " bcachefs: " , 9 ) )
prt_printf ( out , bch2_log_msg ( c , " " ) ) ;
2022-11-13 20:01:42 -05:00
# endif
2022-09-25 18:18:48 -04:00
if ( test_bit ( BCH_FS_FSCK_DONE , & c - > flags ) ) {
if ( c - > opts . errors ! = BCH_ON_ERROR_continue | |
! ( flags & ( FSCK_CAN_FIX | FSCK_CAN_IGNORE ) ) ) {
prt_str ( out , " , shutting down " ) ;
2022-10-09 00:54:36 -04:00
inconsistent = true ;
2022-09-25 18:18:48 -04:00
ret = - BCH_ERR_fsck_errors_not_fixed ;
} else if ( flags & FSCK_CAN_FIX ) {
prt_str ( out , " , fixing " ) ;
ret = - BCH_ERR_fsck_fix ;
} else {
prt_str ( out , " , continuing " ) ;
ret = - BCH_ERR_fsck_ignore ;
}
2023-07-11 23:47:29 -04:00
} else if ( c - > opts . fix_errors = = FSCK_FIX_exit ) {
2022-09-25 18:18:48 -04:00
prt_str ( out , " , exiting " ) ;
ret = - BCH_ERR_fsck_errors_not_fixed ;
2019-03-28 09:34:55 -04:00
} else if ( flags & FSCK_CAN_FIX ) {
2023-04-15 14:26:14 -04:00
int fix = s & & s - > fix
? s - > fix
: c - > opts . fix_errors ;
2023-07-11 23:47:29 -04:00
if ( fix = = FSCK_FIX_ask ) {
2023-04-15 14:26:14 -04:00
int ask ;
2022-09-25 18:18:48 -04:00
prt_str ( out , " : fix? " ) ;
bch2_print_string_as_lines ( KERN_ERR , out - > buf ) ;
print = false ;
2023-04-15 14:26:14 -04:00
ask = bch2_fsck_ask_yn ( ) ;
if ( ask > = YN_ALLNO & & s )
s - > fix = ask = = YN_ALLNO
2023-07-11 23:47:29 -04:00
? FSCK_FIX_no
: FSCK_FIX_yes ;
2023-04-15 14:26:14 -04:00
ret = ask & 1
2022-09-25 18:18:48 -04:00
? - BCH_ERR_fsck_fix
: - BCH_ERR_fsck_ignore ;
2023-07-11 23:47:29 -04:00
} else if ( fix = = FSCK_FIX_yes | |
2017-03-16 22:18:50 -08:00
( c - > opts . nochanges & &
! ( flags & FSCK_CAN_IGNORE ) ) ) {
2022-09-25 18:18:48 -04:00
prt_str ( out , " , fixing " ) ;
ret = - BCH_ERR_fsck_fix ;
2017-03-16 22:18:50 -08:00
} else {
2022-09-25 18:18:48 -04:00
prt_str ( out , " , not fixing " ) ;
2017-03-16 22:18:50 -08:00
}
} else if ( flags & FSCK_NEED_FSCK ) {
2022-09-25 18:18:48 -04:00
prt_str ( out , " (run fsck to correct) " ) ;
2017-03-16 22:18:50 -08:00
} else {
2022-09-25 18:18:48 -04:00
prt_str ( out , " (repair unimplemented) " ) ;
2017-03-16 22:18:50 -08:00
}
2022-09-25 18:18:48 -04:00
if ( ret = = - BCH_ERR_fsck_ignore & &
2023-07-11 23:47:29 -04:00
( c - > opts . fix_errors = = FSCK_FIX_exit | |
2022-09-25 18:18:48 -04:00
! ( flags & FSCK_CAN_IGNORE ) ) )
ret = - BCH_ERR_fsck_errors_not_fixed ;
if ( print )
bch2_print_string_as_lines ( KERN_ERR , out - > buf ) ;
if ( ! test_bit ( BCH_FS_FSCK_DONE , & c - > flags ) & &
( ret ! = - BCH_ERR_fsck_fix & &
ret ! = - BCH_ERR_fsck_ignore ) )
bch_err ( c , " Unable to continue, halting " ) ;
else if ( suppressing )
2017-03-16 22:18:50 -08:00
bch_err ( c , " Ratelimiting new instances of previous error " ) ;
2023-02-16 21:02:14 -05:00
if ( s )
s - > ret = ret ;
2023-10-25 15:51:16 -04:00
mutex_unlock ( & c - > fsck_error_msgs_lock ) ;
2017-03-16 22:18:50 -08:00
2022-09-25 18:18:48 -04:00
printbuf_exit ( & buf ) ;
2022-10-09 00:54:36 -04:00
if ( inconsistent )
bch2_inconsistent_error ( c ) ;
2022-09-25 18:18:48 -04:00
if ( ret = = - BCH_ERR_fsck_fix ) {
2019-03-28 09:34:55 -04:00
set_bit ( BCH_FS_ERRORS_FIXED , & c - > flags ) ;
} else {
2021-04-24 16:32:35 -04:00
set_bit ( BCH_FS_ERRORS_NOT_FIXED , & c - > flags ) ;
2019-03-28 09:34:55 -04:00
set_bit ( BCH_FS_ERROR , & c - > flags ) ;
}
2022-09-25 18:18:48 -04:00
return ret ;
2017-03-16 22:18:50 -08:00
}
void bch2_flush_fsck_errs ( struct bch_fs * c )
{
struct fsck_err_state * s , * n ;
2023-10-25 15:51:16 -04:00
mutex_lock ( & c - > fsck_error_msgs_lock ) ;
2017-03-16 22:18:50 -08:00
2023-10-25 15:51:16 -04:00
list_for_each_entry_safe ( s , n , & c - > fsck_error_msgs , list ) {
2023-02-16 21:02:14 -05:00
if ( s - > ratelimited & & s - > last_msg )
bch_err ( c , " Saw %llu errors like: \n %s " , s - > nr , s - > last_msg ) ;
2017-03-16 22:18:50 -08:00
list_del ( & s - > list ) ;
2023-02-16 21:02:14 -05:00
kfree ( s - > last_msg ) ;
2017-03-16 22:18:50 -08:00
kfree ( s ) ;
}
2023-10-25 15:51:16 -04:00
mutex_unlock ( & c - > fsck_error_msgs_lock ) ;
2017-03-16 22:18:50 -08:00
}