1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _BCACHEFS_ERROR_H 3 #define _BCACHEFS_ERROR_H 4 5 #include <linux/list.h> 6 #include <linux/printk.h> 7 8 struct bch_dev; 9 struct bch_fs; 10 struct work_struct; 11 12 /* 13 * XXX: separate out errors that indicate on disk data is inconsistent, and flag 14 * superblock as such 15 */ 16 17 /* Error messages: */ 18 19 /* 20 * Inconsistency errors: The on disk data is inconsistent. If these occur during 21 * initial recovery, they don't indicate a bug in the running code - we walk all 22 * the metadata before modifying anything. If they occur at runtime, they 23 * indicate either a bug in the running code or (less likely) data is being 24 * silently corrupted under us. 25 * 26 * XXX: audit all inconsistent errors and make sure they're all recoverable, in 27 * BCH_ON_ERROR_CONTINUE mode 28 */ 29 30 bool bch2_inconsistent_error(struct bch_fs *); 31 32 void bch2_topology_error(struct bch_fs *); 33 34 #define bch2_fs_inconsistent(c, ...) \ 35 ({ \ 36 bch_err(c, __VA_ARGS__); \ 37 bch2_inconsistent_error(c); \ 38 }) 39 40 #define bch2_fs_inconsistent_on(cond, c, ...) \ 41 ({ \ 42 bool _ret = unlikely(!!(cond)); \ 43 \ 44 if (_ret) \ 45 bch2_fs_inconsistent(c, __VA_ARGS__); \ 46 _ret; \ 47 }) 48 49 /* 50 * Later we might want to mark only the particular device inconsistent, not the 51 * entire filesystem: 52 */ 53 54 #define bch2_dev_inconsistent(ca, ...) \ 55 do { \ 56 bch_err(ca, __VA_ARGS__); \ 57 bch2_inconsistent_error((ca)->fs); \ 58 } while (0) 59 60 #define bch2_dev_inconsistent_on(cond, ca, ...) \ 61 ({ \ 62 bool _ret = unlikely(!!(cond)); \ 63 \ 64 if (_ret) \ 65 bch2_dev_inconsistent(ca, __VA_ARGS__); \ 66 _ret; \ 67 }) 68 69 /* 70 * When a transaction update discovers or is causing a fs inconsistency, it's 71 * helpful to also dump the pending updates: 72 */ 73 #define bch2_trans_inconsistent(trans, ...) \ 74 ({ \ 75 bch_err(trans->c, __VA_ARGS__); \ 76 bch2_dump_trans_updates(trans); \ 77 bch2_inconsistent_error(trans->c); \ 78 }) 79 80 #define bch2_trans_inconsistent_on(cond, trans, ...) \ 81 ({ \ 82 bool _ret = unlikely(!!(cond)); \ 83 \ 84 if (_ret) \ 85 bch2_trans_inconsistent(trans, __VA_ARGS__); \ 86 _ret; \ 87 }) 88 89 /* 90 * Fsck errors: inconsistency errors we detect at mount time, and should ideally 91 * be able to repair: 92 */ 93 94 struct fsck_err_state { 95 struct list_head list; 96 const char *fmt; 97 u64 nr; 98 bool ratelimited; 99 int ret; 100 int fix; 101 char *last_msg; 102 }; 103 104 #define FSCK_CAN_FIX (1 << 0) 105 #define FSCK_CAN_IGNORE (1 << 1) 106 #define FSCK_NEED_FSCK (1 << 2) 107 #define FSCK_NO_RATELIMIT (1 << 3) 108 109 __printf(3, 4) __cold 110 int bch2_fsck_err(struct bch_fs *, unsigned, const char *, ...); 111 void bch2_flush_fsck_errs(struct bch_fs *); 112 113 #define __fsck_err(c, _flags, msg, ...) \ 114 ({ \ 115 int _ret = bch2_fsck_err(c, _flags, msg, ##__VA_ARGS__); \ 116 \ 117 if (_ret != -BCH_ERR_fsck_fix && \ 118 _ret != -BCH_ERR_fsck_ignore) { \ 119 ret = _ret; \ 120 goto fsck_err; \ 121 } \ 122 \ 123 _ret == -BCH_ERR_fsck_fix; \ 124 }) 125 126 /* These macros return true if error should be fixed: */ 127 128 /* XXX: mark in superblock that filesystem contains errors, if we ignore: */ 129 130 #define __fsck_err_on(cond, c, _flags, ...) \ 131 (unlikely(cond) ? __fsck_err(c, _flags, ##__VA_ARGS__) : false) 132 133 #define need_fsck_err_on(cond, c, ...) \ 134 __fsck_err_on(cond, c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK, ##__VA_ARGS__) 135 136 #define need_fsck_err(c, ...) \ 137 __fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK, ##__VA_ARGS__) 138 139 #define mustfix_fsck_err(c, ...) \ 140 __fsck_err(c, FSCK_CAN_FIX, ##__VA_ARGS__) 141 142 #define mustfix_fsck_err_on(cond, c, ...) \ 143 __fsck_err_on(cond, c, FSCK_CAN_FIX, ##__VA_ARGS__) 144 145 #define fsck_err(c, ...) \ 146 __fsck_err(c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, ##__VA_ARGS__) 147 148 #define fsck_err_on(cond, c, ...) \ 149 __fsck_err_on(cond, c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, ##__VA_ARGS__) 150 151 /* 152 * Fatal errors: these don't indicate a bug, but we can't continue running in RW 153 * mode - pretty much just due to metadata IO errors: 154 */ 155 156 void bch2_fatal_error(struct bch_fs *); 157 158 #define bch2_fs_fatal_error(c, ...) \ 159 do { \ 160 bch_err(c, __VA_ARGS__); \ 161 bch2_fatal_error(c); \ 162 } while (0) 163 164 #define bch2_fs_fatal_err_on(cond, c, ...) \ 165 ({ \ 166 bool _ret = unlikely(!!(cond)); \ 167 \ 168 if (_ret) \ 169 bch2_fs_fatal_error(c, __VA_ARGS__); \ 170 _ret; \ 171 }) 172 173 /* 174 * IO errors: either recoverable metadata IO (because we have replicas), or data 175 * IO - we need to log it and print out a message, but we don't (necessarily) 176 * want to shut down the fs: 177 */ 178 179 void bch2_io_error_work(struct work_struct *); 180 181 /* Does the error handling without logging a message */ 182 void bch2_io_error(struct bch_dev *); 183 184 #define bch2_dev_io_err_on(cond, ca, ...) \ 185 ({ \ 186 bool _ret = (cond); \ 187 \ 188 if (_ret) { \ 189 bch_err_dev_ratelimited(ca, __VA_ARGS__); \ 190 bch2_io_error(ca); \ 191 } \ 192 _ret; \ 193 }) 194 195 #define bch2_dev_inum_io_err_on(cond, ca, ...) \ 196 ({ \ 197 bool _ret = (cond); \ 198 \ 199 if (_ret) { \ 200 bch_err_inum_offset_ratelimited(ca, __VA_ARGS__); \ 201 bch2_io_error(ca); \ 202 } \ 203 _ret; \ 204 }) 205 206 #endif /* _BCACHEFS_ERROR_H */ 207