2017-03-16 22:18:50 -08:00
// SPDX-License-Identifier: GPL-2.0
# include "bcachefs.h"
# include "error.h"
2024-03-30 15:59:57 -04:00
# include "journal.h"
2024-03-23 20:07:46 -04:00
# include "recovery_passes.h"
2017-03-16 22:18:50 -08:00
# include "super.h"
2023-12-31 10:04:54 -05:00
# include "thread_with_file.h"
2017-03-16 22:18:50 -08:00
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 )
{
2023-11-26 17:05:02 -05:00
set_bit ( BCH_FS_error , & c - > flags ) ;
2017-03-16 22:18:50 -08:00
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 ) )
2024-03-30 15:59:57 -04:00
bch_err ( c , " inconsistency detected - emergency read only at journal seq %llu " ,
journal_cur_seq ( & c - > journal ) ) ;
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 ( ) ;
}
}
2024-02-06 17:24:18 -05:00
int bch2_topology_error ( struct bch_fs * c )
2021-04-24 16:32:35 -04:00
{
2023-11-26 17:05:02 -05:00
set_bit ( BCH_FS_topology_error , & c - > flags ) ;
2024-02-06 17:24:18 -05:00
if ( ! test_bit ( BCH_FS_fsck_running , & c - > flags ) ) {
2021-04-24 16:32:35 -04:00
bch2_inconsistent_error ( c ) ;
2024-02-06 17:24:18 -05:00
return - BCH_ERR_btree_need_topology_repair ;
} else {
return bch2_run_explicit_recovery_pass ( c , BCH_RECOVERY_PASS_check_topology ) ? :
- BCH_ERR_btree_node_read_validate_error ;
}
2021-04-24 16:32:35 -04:00
}
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 ,
} ;
2023-12-31 10:04:54 -05:00
static enum ask_yn parse_yn_response ( char * buf )
{
buf = strim ( buf ) ;
if ( strlen ( buf ) = = 1 )
switch ( buf [ 0 ] ) {
case ' n ' :
return YN_NO ;
case ' y ' :
return YN_YES ;
case ' N ' :
return YN_ALLNO ;
case ' Y ' :
return YN_ALLYES ;
}
return - 1 ;
}
2017-03-16 22:18:50 -08:00
# ifdef __KERNEL__
2023-12-31 10:04:54 -05:00
static enum ask_yn bch2_fsck_ask_yn ( struct bch_fs * c )
{
struct stdio_redirect * stdio = c - > stdio ;
if ( c - > stdio_filter & & c - > stdio_filter ! = current )
stdio = NULL ;
if ( ! stdio )
return YN_NO ;
char buf [ 100 ] ;
int ret ;
do {
bch2_print ( c , " (y,n, or Y,N for all errors of this type) " ) ;
int r = bch2_stdio_redirect_readline ( stdio , buf , sizeof ( buf ) - 1 ) ;
if ( r < 0 )
return YN_NO ;
buf [ r ] = ' \0 ' ;
} while ( ( ret = parse_yn_response ( buf ) ) < 0 ) ;
return ret ;
}
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
2023-12-31 10:04:54 -05:00
static enum ask_yn bch2_fsck_ask_yn ( struct bch_fs * c )
2023-04-15 14:26:14 -04:00
{
char * buf = NULL ;
size_t buflen = 0 ;
2023-12-31 10:04:54 -05:00
int ret ;
2023-04-15 14:26:14 -04:00
2023-12-31 10:04:54 -05:00
do {
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-12-31 10:04:54 -05:00
} while ( ( ret = parse_yn_response ( buf ) ) < 0 ) ;
2023-04-15 14:26:14 -04:00
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
2023-12-31 19:41:45 -05:00
if ( ! test_bit ( BCH_FS_fsck_running , & c - > flags ) )
2022-09-25 18:18:48 -04:00
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 ;
}
2023-10-24 20:44:36 -04:00
int bch2_fsck_err ( struct bch_fs * c ,
enum bch_fsck_flags flags ,
enum bch_sb_error_id err ,
const char * fmt , . . . )
2022-09-25 18:18:48 -04:00
{
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 ;
2024-01-03 20:34:46 -05:00
if ( ( flags & FSCK_CAN_FIX ) & &
test_bit ( err , c - > sb . errors_silent ) )
2023-12-29 15:15:14 -05:00
return - BCH_ERR_fsck_fix ;
2023-10-24 20:44:36 -04:00
bch2_sb_error_count ( c , err ) ;
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
2023-12-31 19:41:45 -05:00
if ( ! test_bit ( BCH_FS_fsck_running , & c - > flags ) ) {
2022-09-25 18:18:48 -04:00
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? " ) ;
2023-12-31 10:04:54 -05:00
if ( bch2_fs_stdio_redirect ( c ) )
bch2_print ( c , " %s " , out - > buf ) ;
else
bch2_print_string_as_lines ( KERN_ERR , out - > buf ) ;
2022-09-25 18:18:48 -04:00
print = false ;
2023-04-15 14:26:14 -04:00
2023-12-31 10:04:54 -05:00
ask = bch2_fsck_ask_yn ( c ) ;
2023-04-15 14:26:14 -04:00
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 ;
2023-12-31 10:04:54 -05:00
if ( print ) {
if ( bch2_fs_stdio_redirect ( c ) )
bch2_print ( c , " %s \n " , out - > buf ) ;
else
bch2_print_string_as_lines ( KERN_ERR , out - > buf ) ;
}
2022-09-25 18:18:48 -04:00
2023-12-31 19:41:45 -05:00
if ( test_bit ( BCH_FS_fsck_running , & c - > flags ) & &
2022-09-25 18:18:48 -04:00
( 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 ) {
2023-11-26 17:05:02 -05:00
set_bit ( BCH_FS_errors_fixed , & c - > flags ) ;
2019-03-28 09:34:55 -04:00
} else {
2023-11-26 17:05:02 -05:00
set_bit ( BCH_FS_errors_not_fixed , & c - > flags ) ;
set_bit ( BCH_FS_error , & c - > flags ) ;
2019-03-28 09:34:55 -04:00
}
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
}