Linux Audio

Check our new training course

Loading...
v3.1
  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_fs.h"
 20#include "xfs_types.h"
 21#include "xfs_log.h"
 22#include "xfs_inum.h"
 23#include "xfs_trans.h"
 24#include "xfs_sb.h"
 25#include "xfs_ag.h"
 26#include "xfs_mount.h"
 27#include "xfs_bmap_btree.h"
 28#include "xfs_dinode.h"
 29#include "xfs_inode.h"
 30#include "xfs_utils.h"
 31#include "xfs_error.h"
 32
 33#ifdef DEBUG
 34
 35int	xfs_etrap[XFS_ERROR_NTRAP] = {
 36	0,
 37};
 38
 39int
 40xfs_error_trap(int e)
 41{
 42	int i;
 43
 44	if (!e)
 45		return 0;
 46	for (i = 0; i < XFS_ERROR_NTRAP; i++) {
 47		if (xfs_etrap[i] == 0)
 48			break;
 49		if (e != xfs_etrap[i])
 50			continue;
 51		xfs_notice(NULL, "%s: error %d", __func__, e);
 52		BUG();
 53		break;
 54	}
 55	return e;
 56}
 57
 58int	xfs_etest[XFS_NUM_INJECT_ERROR];
 59int64_t	xfs_etest_fsid[XFS_NUM_INJECT_ERROR];
 60char *	xfs_etest_fsname[XFS_NUM_INJECT_ERROR];
 61int	xfs_error_test_active;
 62
 63int
 64xfs_error_test(int error_tag, int *fsidp, char *expression,
 65	       int line, char *file, unsigned long randfactor)
 66{
 67	int i;
 68	int64_t fsid;
 69
 70	if (random32() % randfactor)
 71		return 0;
 72
 73	memcpy(&fsid, fsidp, sizeof(xfs_fsid_t));
 74
 75	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++)  {
 76		if (xfs_etest[i] == error_tag && xfs_etest_fsid[i] == fsid) {
 77			xfs_warn(NULL,
 78	"Injecting error (%s) at file %s, line %d, on filesystem \"%s\"",
 79				expression, file, line, xfs_etest_fsname[i]);
 80			return 1;
 81		}
 82	}
 83
 84	return 0;
 85}
 86
 87int
 88xfs_errortag_add(int error_tag, xfs_mount_t *mp)
 89{
 90	int i;
 91	int len;
 92	int64_t fsid;
 93
 94	memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
 95
 96	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++)  {
 97		if (xfs_etest_fsid[i] == fsid && xfs_etest[i] == error_tag) {
 98			xfs_warn(mp, "error tag #%d on", error_tag);
 99			return 0;
100		}
101	}
102
103	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++)  {
104		if (xfs_etest[i] == 0) {
105			xfs_warn(mp, "Turned on XFS error tag #%d",
106				error_tag);
107			xfs_etest[i] = error_tag;
108			xfs_etest_fsid[i] = fsid;
109			len = strlen(mp->m_fsname);
110			xfs_etest_fsname[i] = kmem_alloc(len + 1, KM_SLEEP);
111			strcpy(xfs_etest_fsname[i], mp->m_fsname);
112			xfs_error_test_active++;
113			return 0;
114		}
115	}
116
117	xfs_warn(mp, "error tag overflow, too many turned on");
118
119	return 1;
120}
121
122int
123xfs_errortag_clearall(xfs_mount_t *mp, int loud)
124{
125	int64_t fsid;
126	int cleared = 0;
127	int i;
128
129	memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
130
131
132	for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
133		if ((fsid == 0LL || xfs_etest_fsid[i] == fsid) &&
134		     xfs_etest[i] != 0) {
135			cleared = 1;
136			xfs_warn(mp, "Clearing XFS error tag #%d",
137				xfs_etest[i]);
138			xfs_etest[i] = 0;
139			xfs_etest_fsid[i] = 0LL;
140			kmem_free(xfs_etest_fsname[i]);
141			xfs_etest_fsname[i] = NULL;
142			xfs_error_test_active--;
143		}
144	}
145
146	if (loud || cleared)
147		xfs_warn(mp, "Cleared all XFS error tags for filesystem");
148
149	return 0;
150}
151#endif /* DEBUG */
152
153void
154xfs_error_report(
155	const char		*tag,
156	int			level,
157	struct xfs_mount	*mp,
158	const char		*filename,
159	int			linenum,
160	inst_t			*ra)
161{
162	if (level <= xfs_error_level) {
163		xfs_alert_tag(mp, XFS_PTAG_ERROR_REPORT,
164		"Internal error %s at line %d of file %s.  Caller 0x%p\n",
165			    tag, linenum, filename, ra);
166
167		xfs_stack_trace();
168	}
169}
170
171void
172xfs_corruption_error(
173	const char		*tag,
174	int			level,
175	struct xfs_mount	*mp,
176	void			*p,
177	const char		*filename,
178	int			linenum,
179	inst_t			*ra)
180{
181	if (level <= xfs_error_level)
182		xfs_hex_dump(p, 16);
183	xfs_error_report(tag, level, mp, filename, linenum, ra);
184	xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185}
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}