]> Git Repo - J-linux.git/blob - fs/bcachefs/error.h
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / fs / bcachefs / error.h
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 #include "bkey_types.h"
8 #include "sb-errors.h"
9
10 struct bch_dev;
11 struct bch_fs;
12 struct work_struct;
13
14 /*
15  * XXX: separate out errors that indicate on disk data is inconsistent, and flag
16  * superblock as such
17  */
18
19 /* Error messages: */
20
21 /*
22  * Inconsistency errors: The on disk data is inconsistent. If these occur during
23  * initial recovery, they don't indicate a bug in the running code - we walk all
24  * the metadata before modifying anything. If they occur at runtime, they
25  * indicate either a bug in the running code or (less likely) data is being
26  * silently corrupted under us.
27  *
28  * XXX: audit all inconsistent errors and make sure they're all recoverable, in
29  * BCH_ON_ERROR_CONTINUE mode
30  */
31
32 bool bch2_inconsistent_error(struct bch_fs *);
33
34 int bch2_topology_error(struct bch_fs *);
35
36 #define bch2_fs_topology_error(c, ...)                                  \
37 ({                                                                      \
38         bch_err(c, "btree topology error: " __VA_ARGS__);               \
39         bch2_topology_error(c);                                         \
40 })
41
42 #define bch2_fs_inconsistent(c, ...)                                    \
43 ({                                                                      \
44         bch_err(c, __VA_ARGS__);                                        \
45         bch2_inconsistent_error(c);                                     \
46 })
47
48 #define bch2_fs_inconsistent_on(cond, c, ...)                           \
49 ({                                                                      \
50         bool _ret = unlikely(!!(cond));                                 \
51                                                                         \
52         if (_ret)                                                       \
53                 bch2_fs_inconsistent(c, __VA_ARGS__);                   \
54         _ret;                                                           \
55 })
56
57 /*
58  * Later we might want to mark only the particular device inconsistent, not the
59  * entire filesystem:
60  */
61
62 #define bch2_dev_inconsistent(ca, ...)                                  \
63 do {                                                                    \
64         bch_err(ca, __VA_ARGS__);                                       \
65         bch2_inconsistent_error((ca)->fs);                              \
66 } while (0)
67
68 #define bch2_dev_inconsistent_on(cond, ca, ...)                         \
69 ({                                                                      \
70         bool _ret = unlikely(!!(cond));                                 \
71                                                                         \
72         if (_ret)                                                       \
73                 bch2_dev_inconsistent(ca, __VA_ARGS__);                 \
74         _ret;                                                           \
75 })
76
77 /*
78  * When a transaction update discovers or is causing a fs inconsistency, it's
79  * helpful to also dump the pending updates:
80  */
81 #define bch2_trans_inconsistent(trans, ...)                             \
82 ({                                                                      \
83         bch_err(trans->c, __VA_ARGS__);                                 \
84         bch2_dump_trans_updates(trans);                                 \
85         bch2_inconsistent_error(trans->c);                              \
86 })
87
88 #define bch2_trans_inconsistent_on(cond, trans, ...)                    \
89 ({                                                                      \
90         bool _ret = unlikely(!!(cond));                                 \
91                                                                         \
92         if (_ret)                                                       \
93                 bch2_trans_inconsistent(trans, __VA_ARGS__);            \
94         _ret;                                                           \
95 })
96
97 /*
98  * Fsck errors: inconsistency errors we detect at mount time, and should ideally
99  * be able to repair:
100  */
101
102 struct fsck_err_state {
103         struct list_head        list;
104         const char              *fmt;
105         u64                     nr;
106         bool                    ratelimited;
107         int                     ret;
108         int                     fix;
109         char                    *last_msg;
110 };
111
112 #define fsck_err_count(_c, _err)        bch2_sb_err_count(_c, BCH_FSCK_ERR_##_err)
113
114 __printf(5, 6) __cold
115 int __bch2_fsck_err(struct bch_fs *, struct btree_trans *,
116                   enum bch_fsck_flags,
117                   enum bch_sb_error_id,
118                   const char *, ...);
119 #define bch2_fsck_err(c, _flags, _err_type, ...)                                \
120         __bch2_fsck_err(type_is(c, struct bch_fs *) ? (struct bch_fs *) c : NULL,\
121                         type_is(c, struct btree_trans *) ? (struct btree_trans *) c : NULL,\
122                         _flags, BCH_FSCK_ERR_##_err_type, __VA_ARGS__)
123
124 void bch2_flush_fsck_errs(struct bch_fs *);
125
126 #define __fsck_err(c, _flags, _err_type, ...)                           \
127 ({                                                                      \
128         int _ret = bch2_fsck_err(c, _flags, _err_type, __VA_ARGS__);    \
129         if (_ret != -BCH_ERR_fsck_fix &&                                \
130             _ret != -BCH_ERR_fsck_ignore) {                             \
131                 ret = _ret;                                             \
132                 goto fsck_err;                                          \
133         }                                                               \
134                                                                         \
135         _ret == -BCH_ERR_fsck_fix;                                      \
136 })
137
138 /* These macros return true if error should be fixed: */
139
140 /* XXX: mark in superblock that filesystem contains errors, if we ignore: */
141
142 #define __fsck_err_on(cond, c, _flags, _err_type, ...)                  \
143 ({                                                                      \
144         might_sleep();                                                  \
145                                                                         \
146         if (type_is(c, struct bch_fs *))                                \
147                 WARN_ON(bch2_current_has_btree_trans((struct bch_fs *) c));\
148                                                                         \
149         (unlikely(cond) ? __fsck_err(c, _flags, _err_type, __VA_ARGS__) : false);\
150 })
151
152 #define need_fsck_err_on(cond, c, _err_type, ...)                               \
153         __fsck_err_on(cond, c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK, _err_type, __VA_ARGS__)
154
155 #define need_fsck_err(c, _err_type, ...)                                \
156         __fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK, _err_type, __VA_ARGS__)
157
158 #define mustfix_fsck_err(c, _err_type, ...)                             \
159         __fsck_err(c, FSCK_CAN_FIX, _err_type, __VA_ARGS__)
160
161 #define mustfix_fsck_err_on(cond, c, _err_type, ...)                    \
162         __fsck_err_on(cond, c, FSCK_CAN_FIX, _err_type, __VA_ARGS__)
163
164 #define fsck_err(c, _err_type, ...)                                     \
165         __fsck_err(c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, _err_type, __VA_ARGS__)
166
167 #define fsck_err_on(cond, c, _err_type, ...)                            \
168         __fsck_err_on(cond, c, FSCK_CAN_FIX|FSCK_CAN_IGNORE, _err_type, __VA_ARGS__)
169
170 enum bch_validate_flags;
171 __printf(5, 6)
172 int __bch2_bkey_fsck_err(struct bch_fs *,
173                          struct bkey_s_c,
174                          enum bch_validate_flags,
175                          enum bch_sb_error_id,
176                          const char *, ...);
177
178 /*
179  * for now, bkey fsck errors are always handled by deleting the entire key -
180  * this will change at some point
181  */
182 #define bkey_fsck_err(c, _err_type, _err_msg, ...)                      \
183 do {                                                                    \
184         int _ret = __bch2_bkey_fsck_err(c, k, flags,                    \
185                                 BCH_FSCK_ERR_##_err_type,               \
186                                 _err_msg, ##__VA_ARGS__);               \
187         if (_ret != -BCH_ERR_fsck_fix &&                                \
188             _ret != -BCH_ERR_fsck_ignore)                               \
189                 ret = _ret;                                             \
190         ret = -BCH_ERR_fsck_delete_bkey;                                \
191         goto fsck_err;                                                  \
192 } while (0)
193
194 #define bkey_fsck_err_on(cond, ...)                                     \
195 do {                                                                    \
196         if (unlikely(cond))                                             \
197                 bkey_fsck_err(__VA_ARGS__);                             \
198 } while (0)
199
200 /*
201  * Fatal errors: these don't indicate a bug, but we can't continue running in RW
202  * mode - pretty much just due to metadata IO errors:
203  */
204
205 void bch2_fatal_error(struct bch_fs *);
206
207 #define bch2_fs_fatal_error(c, _msg, ...)                               \
208 do {                                                                    \
209         bch_err(c, "%s(): fatal error " _msg, __func__, ##__VA_ARGS__); \
210         bch2_fatal_error(c);                                            \
211 } while (0)
212
213 #define bch2_fs_fatal_err_on(cond, c, ...)                              \
214 ({                                                                      \
215         bool _ret = unlikely(!!(cond));                                 \
216                                                                         \
217         if (_ret)                                                       \
218                 bch2_fs_fatal_error(c, __VA_ARGS__);                    \
219         _ret;                                                           \
220 })
221
222 /*
223  * IO errors: either recoverable metadata IO (because we have replicas), or data
224  * IO - we need to log it and print out a message, but we don't (necessarily)
225  * want to shut down the fs:
226  */
227
228 void bch2_io_error_work(struct work_struct *);
229
230 /* Does the error handling without logging a message */
231 void bch2_io_error(struct bch_dev *, enum bch_member_error_type);
232
233 #define bch2_dev_io_err_on(cond, ca, _type, ...)                        \
234 ({                                                                      \
235         bool _ret = (cond);                                             \
236                                                                         \
237         if (_ret) {                                                     \
238                 bch_err_dev_ratelimited(ca, __VA_ARGS__);               \
239                 bch2_io_error(ca, _type);                               \
240         }                                                               \
241         _ret;                                                           \
242 })
243
244 #define bch2_dev_inum_io_err_on(cond, ca, _type, ...)                   \
245 ({                                                                      \
246         bool _ret = (cond);                                             \
247                                                                         \
248         if (_ret) {                                                     \
249                 bch_err_inum_offset_ratelimited(ca, __VA_ARGS__);       \
250                 bch2_io_error(ca, _type);                               \
251         }                                                               \
252         _ret;                                                           \
253 })
254
255 #endif /* _BCACHEFS_ERROR_H */
This page took 0.041358 seconds and 4 git commands to generate.