brintos

brintos / linux-shallow public Read only

0
0
Text · 6.7 KiB · 6551ada Raw
256 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef _BCACHEFS_ERROR_H3#define _BCACHEFS_ERROR_H4 5#include <linux/list.h>6#include <linux/printk.h>7#include "bkey_types.h"8#include "sb-errors.h"9 10struct bch_dev;11struct bch_fs;12struct work_struct;13 14/*15 * XXX: separate out errors that indicate on disk data is inconsistent, and flag16 * superblock as such17 */18 19/* Error messages: */20 21/*22 * Inconsistency errors: The on disk data is inconsistent. If these occur during23 * initial recovery, they don't indicate a bug in the running code - we walk all24 * the metadata before modifying anything. If they occur at runtime, they25 * indicate either a bug in the running code or (less likely) data is being26 * silently corrupted under us.27 *28 * XXX: audit all inconsistent errors and make sure they're all recoverable, in29 * BCH_ON_ERROR_CONTINUE mode30 */31 32bool bch2_inconsistent_error(struct bch_fs *);33 34int 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 the59 * entire filesystem:60 */61 62#define bch2_dev_inconsistent(ca, ...)					\63do {									\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's79 * 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 ideally99 * be able to repair:100 */101 102struct 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) __cold115int __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 124void 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 170enum bch_validate_flags;171__printf(5, 6)172int __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 point181 */182#define bkey_fsck_err(c, _err_type, _err_msg, ...)			\183do {									\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, ...)					\195do {									\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 RW202 * mode - pretty much just due to metadata IO errors:203 */204 205void bch2_fatal_error(struct bch_fs *);206 207#define bch2_fs_fatal_error(c, _msg, ...)				\208do {									\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 data224 * 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 228void bch2_io_error_work(struct work_struct *);229 230/* Does the error handling without logging a message */231void 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 */256