Linux Audio

Check our new training course

Loading...
v4.6
  1/*
  2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  3 * All Rights Reserved.
  4 *
  5 * This program is free software; you can redistribute it and/or
  6 * modify it under the terms of the GNU General Public License as
  7 * published by the Free Software Foundation.
  8 *
  9 * This program is distributed in the hope that it would be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 * GNU General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU General Public License
 15 * along with this program; if not, write the Free Software Foundation,
 16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 17 */
 18#include "xfs.h"
 19#include "xfs_format.h"
 20#include "xfs_fs.h"
 21#include "xfs_log_format.h"
 22#include "xfs_trans_resv.h"
 
 
 23#include "xfs_mount.h"
 24#include "xfs_error.h"
 25
 26#ifdef DEBUG
 27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 28int	xfs_etest[XFS_NUM_INJECT_ERROR];
 29int64_t	xfs_etest_fsid[XFS_NUM_INJECT_ERROR];
 30char *	xfs_etest_fsname[XFS_NUM_INJECT_ERROR];
 31int	xfs_error_test_active;
 32
 33int
 34xfs_error_test(int error_tag, int *fsidp, char *expression,
 35	       int line, char *file, unsigned long randfactor)
 36{
 37	int i;
 38	int64_t fsid;
 39
 40	if (prandom_u32() % randfactor)
 41		return 0;
 42
 43	memcpy(&fsid, fsidp, sizeof(xfs_fsid_t));
 44
 45	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++)  {
 46		if (xfs_etest[i] == error_tag && xfs_etest_fsid[i] == fsid) {
 47			xfs_warn(NULL,
 48	"Injecting error (%s) at file %s, line %d, on filesystem \"%s\"",
 49				expression, file, line, xfs_etest_fsname[i]);
 50			return 1;
 51		}
 52	}
 53
 54	return 0;
 55}
 56
 57int
 58xfs_errortag_add(int error_tag, xfs_mount_t *mp)
 59{
 60	int i;
 61	int len;
 62	int64_t fsid;
 63
 64	memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
 65
 66	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++)  {
 67		if (xfs_etest_fsid[i] == fsid && xfs_etest[i] == error_tag) {
 68			xfs_warn(mp, "error tag #%d on", error_tag);
 69			return 0;
 70		}
 71	}
 72
 73	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++)  {
 74		if (xfs_etest[i] == 0) {
 75			xfs_warn(mp, "Turned on XFS error tag #%d",
 76				error_tag);
 77			xfs_etest[i] = error_tag;
 78			xfs_etest_fsid[i] = fsid;
 79			len = strlen(mp->m_fsname);
 80			xfs_etest_fsname[i] = kmem_alloc(len + 1, KM_SLEEP);
 81			strcpy(xfs_etest_fsname[i], mp->m_fsname);
 82			xfs_error_test_active++;
 83			return 0;
 84		}
 85	}
 86
 87	xfs_warn(mp, "error tag overflow, too many turned on");
 88
 89	return 1;
 90}
 91
 92int
 93xfs_errortag_clearall(xfs_mount_t *mp, int loud)
 94{
 95	int64_t fsid;
 96	int cleared = 0;
 97	int i;
 98
 99	memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
100
101
102	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
103		if ((fsid == 0LL || xfs_etest_fsid[i] == fsid) &&
104		     xfs_etest[i] != 0) {
105			cleared = 1;
106			xfs_warn(mp, "Clearing XFS error tag #%d",
107				xfs_etest[i]);
108			xfs_etest[i] = 0;
109			xfs_etest_fsid[i] = 0LL;
110			kmem_free(xfs_etest_fsname[i]);
111			xfs_etest_fsname[i] = NULL;
112			xfs_error_test_active--;
113		}
114	}
115
116	if (loud || cleared)
117		xfs_warn(mp, "Cleared all XFS error tags for filesystem");
118
119	return 0;
120}
121#endif /* DEBUG */
122
123void
124xfs_error_report(
125	const char		*tag,
126	int			level,
127	struct xfs_mount	*mp,
128	const char		*filename,
129	int			linenum,
130	void			*ra)
131{
132	if (level <= xfs_error_level) {
133		xfs_alert_tag(mp, XFS_PTAG_ERROR_REPORT,
134		"Internal error %s at line %d of file %s.  Caller %pS",
135			    tag, linenum, filename, ra);
136
137		xfs_stack_trace();
138	}
139}
140
141void
142xfs_corruption_error(
143	const char		*tag,
144	int			level,
145	struct xfs_mount	*mp,
146	void			*p,
147	const char		*filename,
148	int			linenum,
149	void			*ra)
150{
151	if (level <= xfs_error_level)
152		xfs_hex_dump(p, 64);
153	xfs_error_report(tag, level, mp, filename, linenum, ra);
154	xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair");
155}
156
157/*
158 * Warnings specifically for verifier errors.  Differentiate CRC vs. invalid
159 * values, and omit the stack trace unless the error level is tuned high.
160 */
161void
162xfs_verifier_error(
163	struct xfs_buf		*bp)
164{
165	struct xfs_mount *mp = bp->b_target->bt_mount;
166
167	xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx",
168		  bp->b_error == -EFSBADCRC ? "CRC error" : "corruption",
169		  __return_address, bp->b_ops->name, bp->b_bn);
170
171	xfs_alert(mp, "Unmount and run xfs_repair");
172
173	if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
174		xfs_alert(mp, "First 64 bytes of corrupted metadata buffer:");
175		xfs_hex_dump(xfs_buf_offset(bp, 0), 64);
176	}
177
178	if (xfs_error_level >= XFS_ERRLEVEL_HIGH)
179		xfs_stack_trace();
180}
v3.15
  1/*
  2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  3 * All Rights Reserved.
  4 *
  5 * This program is free software; you can redistribute it and/or
  6 * modify it under the terms of the GNU General Public License as
  7 * published by the Free Software Foundation.
  8 *
  9 * This program is distributed in the hope that it would be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 * GNU General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU General Public License
 15 * along with this program; if not, write the Free Software Foundation,
 16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 17 */
 18#include "xfs.h"
 19#include "xfs_format.h"
 20#include "xfs_fs.h"
 21#include "xfs_log_format.h"
 22#include "xfs_trans_resv.h"
 23#include "xfs_sb.h"
 24#include "xfs_ag.h"
 25#include "xfs_mount.h"
 26#include "xfs_error.h"
 27
 28#ifdef DEBUG
 29
 30int	xfs_etrap[XFS_ERROR_NTRAP] = {
 31	0,
 32};
 33
 34int
 35xfs_error_trap(int e)
 36{
 37	int i;
 38
 39	if (!e)
 40		return 0;
 41	for (i = 0; i < XFS_ERROR_NTRAP; i++) {
 42		if (xfs_etrap[i] == 0)
 43			break;
 44		if (e != xfs_etrap[i])
 45			continue;
 46		xfs_notice(NULL, "%s: error %d", __func__, e);
 47		BUG();
 48		break;
 49	}
 50	return e;
 51}
 52
 53int	xfs_etest[XFS_NUM_INJECT_ERROR];
 54int64_t	xfs_etest_fsid[XFS_NUM_INJECT_ERROR];
 55char *	xfs_etest_fsname[XFS_NUM_INJECT_ERROR];
 56int	xfs_error_test_active;
 57
 58int
 59xfs_error_test(int error_tag, int *fsidp, char *expression,
 60	       int line, char *file, unsigned long randfactor)
 61{
 62	int i;
 63	int64_t fsid;
 64
 65	if (prandom_u32() % randfactor)
 66		return 0;
 67
 68	memcpy(&fsid, fsidp, sizeof(xfs_fsid_t));
 69
 70	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++)  {
 71		if (xfs_etest[i] == error_tag && xfs_etest_fsid[i] == fsid) {
 72			xfs_warn(NULL,
 73	"Injecting error (%s) at file %s, line %d, on filesystem \"%s\"",
 74				expression, file, line, xfs_etest_fsname[i]);
 75			return 1;
 76		}
 77	}
 78
 79	return 0;
 80}
 81
 82int
 83xfs_errortag_add(int error_tag, xfs_mount_t *mp)
 84{
 85	int i;
 86	int len;
 87	int64_t fsid;
 88
 89	memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
 90
 91	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++)  {
 92		if (xfs_etest_fsid[i] == fsid && xfs_etest[i] == error_tag) {
 93			xfs_warn(mp, "error tag #%d on", error_tag);
 94			return 0;
 95		}
 96	}
 97
 98	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++)  {
 99		if (xfs_etest[i] == 0) {
100			xfs_warn(mp, "Turned on XFS error tag #%d",
101				error_tag);
102			xfs_etest[i] = error_tag;
103			xfs_etest_fsid[i] = fsid;
104			len = strlen(mp->m_fsname);
105			xfs_etest_fsname[i] = kmem_alloc(len + 1, KM_SLEEP);
106			strcpy(xfs_etest_fsname[i], mp->m_fsname);
107			xfs_error_test_active++;
108			return 0;
109		}
110	}
111
112	xfs_warn(mp, "error tag overflow, too many turned on");
113
114	return 1;
115}
116
117int
118xfs_errortag_clearall(xfs_mount_t *mp, int loud)
119{
120	int64_t fsid;
121	int cleared = 0;
122	int i;
123
124	memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
125
126
127	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
128		if ((fsid == 0LL || xfs_etest_fsid[i] == fsid) &&
129		     xfs_etest[i] != 0) {
130			cleared = 1;
131			xfs_warn(mp, "Clearing XFS error tag #%d",
132				xfs_etest[i]);
133			xfs_etest[i] = 0;
134			xfs_etest_fsid[i] = 0LL;
135			kmem_free(xfs_etest_fsname[i]);
136			xfs_etest_fsname[i] = NULL;
137			xfs_error_test_active--;
138		}
139	}
140
141	if (loud || cleared)
142		xfs_warn(mp, "Cleared all XFS error tags for filesystem");
143
144	return 0;
145}
146#endif /* DEBUG */
147
148void
149xfs_error_report(
150	const char		*tag,
151	int			level,
152	struct xfs_mount	*mp,
153	const char		*filename,
154	int			linenum,
155	inst_t			*ra)
156{
157	if (level <= xfs_error_level) {
158		xfs_alert_tag(mp, XFS_PTAG_ERROR_REPORT,
159		"Internal error %s at line %d of file %s.  Caller %pF",
160			    tag, linenum, filename, ra);
161
162		xfs_stack_trace();
163	}
164}
165
166void
167xfs_corruption_error(
168	const char		*tag,
169	int			level,
170	struct xfs_mount	*mp,
171	void			*p,
172	const char		*filename,
173	int			linenum,
174	inst_t			*ra)
175{
176	if (level <= xfs_error_level)
177		xfs_hex_dump(p, 64);
178	xfs_error_report(tag, level, mp, filename, linenum, ra);
179	xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair");
180}
181
182/*
183 * Warnings specifically for verifier errors.  Differentiate CRC vs. invalid
184 * values, and omit the stack trace unless the error level is tuned high.
185 */
186void
187xfs_verifier_error(
188	struct xfs_buf		*bp)
189{
190	struct xfs_mount *mp = bp->b_target->bt_mount;
191
192	xfs_alert(mp, "Metadata %s detected at %pF, block 0x%llx",
193		  bp->b_error == EFSBADCRC ? "CRC error" : "corruption",
194		  __return_address, bp->b_bn);
195
196	xfs_alert(mp, "Unmount and run xfs_repair");
197
198	if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
199		xfs_alert(mp, "First 64 bytes of corrupted metadata buffer:");
200		xfs_hex_dump(xfs_buf_offset(bp, 0), 64);
201	}
202
203	if (xfs_error_level >= XFS_ERRLEVEL_HIGH)
204		xfs_stack_trace();
205}