Linux Audio

Check our new training course

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