2017-03-16 22:18:50 -08:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef _BCACHEFS_ERROR_H
# define _BCACHEFS_ERROR_H
# include <linux/list.h>
# include <linux/printk.h>
2023-10-24 20:44:36 -04:00
# include "sb-errors.h"
2017-03-16 22:18:50 -08:00
struct bch_dev ;
struct bch_fs ;
struct work_struct ;
/*
* XXX : separate out errors that indicate on disk data is inconsistent , and flag
* superblock as such
*/
/* Error messages: */
/*
* Inconsistency errors : The on disk data is inconsistent . If these occur during
* initial recovery , they don ' t indicate a bug in the running code - we walk all
* the metadata before modifying anything . If they occur at runtime , they
* indicate either a bug in the running code or ( less likely ) data is being
* silently corrupted under us .
*
* XXX : audit all inconsistent errors and make sure they ' re all recoverable , in
* BCH_ON_ERROR_CONTINUE mode
*/
bool bch2_inconsistent_error ( struct bch_fs * ) ;
2024-02-06 17:24:18 -05:00
int bch2_topology_error ( struct bch_fs * ) ;
2021-04-24 16:32:35 -04:00
2024-03-23 19:29:19 -04:00
# define bch2_fs_topology_error(c, ...) \
( { \
bch_err ( c , " btree topology error: " __VA_ARGS__ ) ; \
bch2_topology_error ( c ) ; \
} )
2017-03-16 22:18:50 -08:00
# define bch2_fs_inconsistent(c, ...) \
( { \
bch_err ( c , __VA_ARGS__ ) ; \
bch2_inconsistent_error ( c ) ; \
} )
# define bch2_fs_inconsistent_on(cond, c, ...) \
( { \
2022-02-19 03:56:44 -05:00
bool _ret = unlikely ( ! ! ( cond ) ) ; \
2017-03-16 22:18:50 -08:00
\
if ( _ret ) \
bch2_fs_inconsistent ( c , __VA_ARGS__ ) ; \
_ret ; \
} )
/*
* Later we might want to mark only the particular device inconsistent , not the
* entire filesystem :
*/
# define bch2_dev_inconsistent(ca, ...) \
do { \
bch_err ( ca , __VA_ARGS__ ) ; \
bch2_inconsistent_error ( ( ca ) - > fs ) ; \
} while ( 0 )
# define bch2_dev_inconsistent_on(cond, ca, ...) \
( { \
2022-02-19 03:56:44 -05:00
bool _ret = unlikely ( ! ! ( cond ) ) ; \
2017-03-16 22:18:50 -08:00
\
if ( _ret ) \
bch2_dev_inconsistent ( ca , __VA_ARGS__ ) ; \
_ret ; \
} )
2022-03-02 22:18:56 -05:00
/*
* When a transaction update discovers or is causing a fs inconsistency , it ' s
* helpful to also dump the pending updates :
*/
# define bch2_trans_inconsistent(trans, ...) \
( { \
bch_err ( trans - > c , __VA_ARGS__ ) ; \
bch2_dump_trans_updates ( trans ) ; \
2023-01-25 10:08:50 -05:00
bch2_inconsistent_error ( trans - > c ) ; \
2022-03-02 22:18:56 -05:00
} )
# define bch2_trans_inconsistent_on(cond, trans, ...) \
( { \
bool _ret = unlikely ( ! ! ( cond ) ) ; \
\
if ( _ret ) \
bch2_trans_inconsistent ( trans , __VA_ARGS__ ) ; \
_ret ; \
} )
2017-03-16 22:18:50 -08:00
/*
* Fsck errors : inconsistency errors we detect at mount time , and should ideally
* be able to repair :
*/
struct fsck_err_state {
struct list_head list ;
const char * fmt ;
u64 nr ;
2019-11-06 15:32:11 -05:00
bool ratelimited ;
2023-02-16 21:02:14 -05:00
int ret ;
2023-04-15 14:26:14 -04:00
int fix ;
2023-02-16 21:02:14 -05:00
char * last_msg ;
2017-03-16 22:18:50 -08:00
} ;
2023-10-24 20:44:36 -04:00
# define fsck_err_count(_c, _err) bch2_sb_err_count(_c, BCH_FSCK_ERR_##_err)
2017-03-16 22:18:50 -08:00
2024-02-08 21:10:32 -05:00
__printf ( 5 , 6 ) __cold
int __bch2_fsck_err ( struct bch_fs * , struct btree_trans * ,
2023-10-24 20:44:36 -04:00
enum bch_fsck_flags ,
enum bch_sb_error_id ,
const char * , . . . ) ;
2024-02-08 21:10:32 -05:00
# define bch2_fsck_err(c, _flags, _err_type, ...) \
__bch2_fsck_err ( type_is ( c , struct bch_fs * ) ? ( struct bch_fs * ) c : NULL , \
type_is ( c , struct btree_trans * ) ? ( struct btree_trans * ) c : NULL , \
_flags , BCH_FSCK_ERR_ # # _err_type , __VA_ARGS__ )
2017-03-16 22:18:50 -08:00
void bch2_flush_fsck_errs ( struct bch_fs * ) ;
2023-10-24 20:44:36 -04:00
# define __fsck_err(c, _flags, _err_type, ...) \
2017-03-16 22:18:50 -08:00
( { \
2024-02-08 21:10:32 -05:00
int _ret = bch2_fsck_err ( c , _flags , _err_type , __VA_ARGS__ ) ; \
2022-07-19 17:20:18 -04:00
if ( _ret ! = - BCH_ERR_fsck_fix & & \
_ret ! = - BCH_ERR_fsck_ignore ) { \
ret = _ret ; \
2017-03-16 22:18:50 -08:00
goto fsck_err ; \
} \
\
2022-07-19 17:20:18 -04:00
_ret = = - BCH_ERR_fsck_fix ; \
2017-03-16 22:18:50 -08:00
} )
/* These macros return true if error should be fixed: */
/* XXX: mark in superblock that filesystem contains errors, if we ignore: */
2023-10-24 20:44:36 -04:00
# define __fsck_err_on(cond, c, _flags, _err_type, ...) \
2024-06-07 16:35:42 -04:00
( { \
might_sleep ( ) ; \
2024-02-08 21:10:32 -05:00
\
if ( type_is ( c , struct bch_fs * ) ) \
WARN_ON ( bch2_current_has_btree_trans ( ( struct bch_fs * ) c ) ) ; \
\
2024-06-07 16:35:42 -04:00
( unlikely ( cond ) ? __fsck_err ( c , _flags , _err_type , __VA_ARGS__ ) : false ) ; \
2024-02-08 21:10:32 -05:00
} )
2023-10-24 20:44:36 -04:00
# define need_fsck_err_on(cond, c, _err_type, ...) \
__fsck_err_on ( cond , c , FSCK_CAN_IGNORE | FSCK_NEED_FSCK , _err_type , __VA_ARGS__ )
# define need_fsck_err(c, _err_type, ...) \
__fsck_err ( c , FSCK_CAN_IGNORE | FSCK_NEED_FSCK , _err_type , __VA_ARGS__ )
# define mustfix_fsck_err(c, _err_type, ...) \
__fsck_err ( c , FSCK_CAN_FIX , _err_type , __VA_ARGS__ )
# define mustfix_fsck_err_on(cond, c, _err_type, ...) \
__fsck_err_on ( cond , c , FSCK_CAN_FIX , _err_type , __VA_ARGS__ )
2017-03-16 22:18:50 -08:00
2023-10-24 20:44:36 -04:00
# define fsck_err(c, _err_type, ...) \
__fsck_err ( c , FSCK_CAN_FIX | FSCK_CAN_IGNORE , _err_type , __VA_ARGS__ )
2017-03-16 22:18:50 -08:00
2023-10-24 20:44:36 -04:00
# define fsck_err_on(cond, c, _err_type, ...) \
__fsck_err_on ( cond , c , FSCK_CAN_FIX | FSCK_CAN_IGNORE , _err_type , __VA_ARGS__ )
2017-03-16 22:18:50 -08:00
2023-12-13 00:44:34 -05:00
__printf ( 4 , 0 )
2023-10-24 20:44:36 -04:00
static inline void bch2_bkey_fsck_err ( struct bch_fs * c ,
struct printbuf * err_msg ,
enum bch_sb_error_id err_type ,
const char * fmt , . . . )
{
va_list args ;
2017-03-16 22:18:50 -08:00
2023-10-24 20:44:36 -04:00
va_start ( args , fmt ) ;
prt_vprintf ( err_msg , fmt , args ) ;
va_end ( args ) ;
}
2017-03-16 22:18:50 -08:00
2023-10-24 20:44:36 -04:00
# define bkey_fsck_err(c, _err_msg, _err_type, ...) \
do { \
prt_printf ( _err_msg , __VA_ARGS__ ) ; \
bch2_sb_error_count ( c , BCH_FSCK_ERR_ # # _err_type ) ; \
ret = - BCH_ERR_invalid_bkey ; \
goto fsck_err ; \
} while ( 0 )
# define bkey_fsck_err_on(cond, ...) \
do { \
if ( unlikely ( cond ) ) \
bkey_fsck_err ( __VA_ARGS__ ) ; \
} while ( 0 )
2017-03-16 22:18:50 -08:00
/*
* Fatal errors : these don ' t indicate a bug , but we can ' t continue running in RW
* mode - pretty much just due to metadata IO errors :
*/
void bch2_fatal_error ( struct bch_fs * ) ;
2024-03-17 21:51:19 -04:00
# define bch2_fs_fatal_error(c, _msg, ...) \
2017-03-16 22:18:50 -08:00
do { \
2024-03-17 21:51:19 -04:00
bch_err ( c , " %s(): fatal error " _msg , __func__ , # # __VA_ARGS__ ) ; \
2017-03-16 22:18:50 -08:00
bch2_fatal_error ( c ) ; \
} while ( 0 )
# define bch2_fs_fatal_err_on(cond, c, ...) \
( { \
2022-02-19 03:56:44 -05:00
bool _ret = unlikely ( ! ! ( cond ) ) ; \
2017-03-16 22:18:50 -08:00
\
if ( _ret ) \
bch2_fs_fatal_error ( c , __VA_ARGS__ ) ; \
_ret ; \
} )
/*
* IO errors : either recoverable metadata IO ( because we have replicas ) , or data
* IO - we need to log it and print out a message , but we don ' t ( necessarily )
* want to shut down the fs :
*/
void bch2_io_error_work ( struct work_struct * ) ;
/* Does the error handling without logging a message */
2023-10-25 16:29:37 -04:00
void bch2_io_error ( struct bch_dev * , enum bch_member_error_type ) ;
2017-03-16 22:18:50 -08:00
2023-10-25 16:29:37 -04:00
# define bch2_dev_io_err_on(cond, ca, _type, ...) \
2017-03-16 22:18:50 -08:00
( { \
bool _ret = ( cond ) ; \
\
2022-11-15 20:25:08 -05:00
if ( _ret ) { \
bch_err_dev_ratelimited ( ca , __VA_ARGS__ ) ; \
2023-10-25 16:29:37 -04:00
bch2_io_error ( ca , _type ) ; \
2022-11-15 20:25:08 -05:00
} \
2017-03-16 22:18:50 -08:00
_ret ; \
} )
2023-10-25 16:29:37 -04:00
# define bch2_dev_inum_io_err_on(cond, ca, _type, ...) \
2020-12-03 13:57:22 -05:00
( { \
bool _ret = ( cond ) ; \
\
2022-11-15 20:25:08 -05:00
if ( _ret ) { \
bch_err_inum_offset_ratelimited ( ca , __VA_ARGS__ ) ; \
2023-10-25 16:29:37 -04:00
bch2_io_error ( ca , _type ) ; \
2022-11-15 20:25:08 -05:00
} \
2020-12-03 13:57:22 -05:00
_ret ; \
} )
2017-03-16 22:18:50 -08:00
# endif /* _BCACHEFS_ERROR_H */