summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-01-16 10:12:39 -0800
committerDarrick J. Wong <darrick.wong@oracle.com>2019-02-04 09:31:22 -0800
commitedf60a8373c02bfc90a1bc8729ecc92828ec2b00 (patch)
tree6a3d5ddeaaa6f765b1c5402f33c17851ecc80bee
parentbabcf3e7ff0e5ac0cc5f583cc75278bc0ab633be (diff)
xfs: whine to dmesg when we encounter errorsdjwong-wtf_2019-02-04
Forward everything scrub whines about to dmesg. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r--fs/xfs/scrub/btree.c66
-rw-r--r--fs/xfs/scrub/common.c88
-rw-r--r--fs/xfs/scrub/common.h1
-rw-r--r--fs/xfs/scrub/dabtree.c15
-rw-r--r--fs/xfs/scrub/scrub.c5
-rw-r--r--fs/xfs/xfs_error.c4
6 files changed, 175 insertions, 4 deletions
diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c
index 6f94d1f7322d..6271a277eabe 100644
--- a/fs/xfs/scrub/btree.c
+++ b/fs/xfs/scrub/btree.c
@@ -24,6 +24,22 @@
/* btree scrubbing */
+/* Figure out which block the btree cursor was pointing to. */
+static inline xfs_fsblock_t
+xfs_scrub_btree_cur_fsbno(
+ struct xfs_btree_cur *cur,
+ int level)
+{
+ if (level < cur->bc_nlevels && cur->bc_bufs[level])
+ return XFS_DADDR_TO_FSB(cur->bc_mp, cur->bc_bufs[level]->b_bn);
+ else if (level == cur->bc_nlevels - 1 &&
+ cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
+ return XFS_INO_TO_FSB(cur->bc_mp, cur->bc_private.b.ip->i_ino);
+ else if (!(cur->bc_flags & XFS_BTREE_LONG_PTRS))
+ return XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno, 0);
+ return NULLFSBLOCK;
+}
+
/*
* Check for btree operation errors. See the section about handling
* operational errors in common.c.
@@ -53,11 +69,37 @@ __xchk_btree_process_error(
/* fall through */
default:
if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
+ {
+ xfs_fsblock_t fsbno = xfs_scrub_btree_cur_fsbno(cur, level);
+ xfs_scrub_whine(sc->mp, "ino %llu fork %d type %d btnum %d level %d ptr %d agno %u agbno %u error %d ret_ip %pS",
+ cur->bc_private.b.ip->i_ino,
+ cur->bc_private.b.whichfork,
+ sc->sm->sm_type,
+ cur->bc_btnum,
+ level,
+ cur->bc_ptrs[level],
+ XFS_FSB_TO_AGNO(cur->bc_mp, fsbno),
+ XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno),
+ *error,
+ ret_ip);
trace_xchk_ifork_btree_op_error(sc, cur, level,
*error, ret_ip);
+ }
else
+ {
+ xfs_fsblock_t fsbno = xfs_scrub_btree_cur_fsbno(cur, level);
+ xfs_scrub_whine(sc->mp, "type %d btnum %d level %d ptr %d agno %u agbno %u error %d ret_ip %pS",
+ sc->sm->sm_type,
+ cur->bc_btnum,
+ level,
+ cur->bc_ptrs[level],
+ XFS_FSB_TO_AGNO(cur->bc_mp, fsbno),
+ XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno),
+ *error,
+ ret_ip);
trace_xchk_btree_op_error(sc, cur, level,
*error, ret_ip);
+ }
break;
}
return false;
@@ -97,11 +139,35 @@ __xchk_btree_set_corrupt(
sc->sm->sm_flags |= errflag;
if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
+ {
+ xfs_fsblock_t fsbno = xfs_scrub_btree_cur_fsbno(cur, level);
+ xfs_scrub_whine(sc->mp, "ino %llu fork %d type %d btnum %d level %d ptr %d agno %u agbno %u ret_ip %pS",
+ cur->bc_private.b.ip->i_ino,
+ cur->bc_private.b.whichfork,
+ sc->sm->sm_type,
+ cur->bc_btnum,
+ level,
+ cur->bc_ptrs[level],
+ XFS_FSB_TO_AGNO(cur->bc_mp, fsbno),
+ XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno),
+ ret_ip);
trace_xchk_ifork_btree_error(sc, cur, level,
ret_ip);
+ }
else
+ {
+ xfs_fsblock_t fsbno = xfs_scrub_btree_cur_fsbno(cur, level);
+ xfs_scrub_whine(sc->mp, "type %d btnum %d level %d ptr %d agno %u agbno %u ret_ip %pS",
+ sc->sm->sm_type,
+ cur->bc_btnum,
+ level,
+ cur->bc_ptrs[level],
+ XFS_FSB_TO_AGNO(cur->bc_mp, fsbno),
+ XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno),
+ ret_ip);
trace_xchk_btree_error(sc, cur, level,
ret_ip);
+ }
}
void
diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c
index 3277c21bc914..121c05d234e1 100644
--- a/fs/xfs/scrub/common.c
+++ b/fs/xfs/scrub/common.c
@@ -33,6 +33,7 @@
#include "xfs_attr.h"
#include "xfs_reflink.h"
#include "xfs_rtrmap_btree.h"
+#include "xfs_error.h"
#include "scrub/xfs_scrub.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
@@ -91,6 +92,12 @@ __xchk_process_error(
*error = 0;
/* fall through */
default:
+ xfs_scrub_whine(sc->mp, "type %d agno %u agbno %u error %d ret_ip %pS",
+ sc->sm->sm_type,
+ agno,
+ bno,
+ *error,
+ ret_ip);
trace_xchk_op_error(sc, agno, bno, *error,
ret_ip);
break;
@@ -144,6 +151,13 @@ __xchk_fblock_process_error(
*error = 0;
/* fall through */
default:
+ xfs_scrub_whine(sc->mp, "ino %llu fork %d type %d offset %llu error %d ret_ip %pS",
+ sc->ip->i_ino,
+ whichfork,
+ sc->sm->sm_type,
+ offset,
+ *error,
+ ret_ip);
trace_xchk_file_op_error(sc, whichfork, offset, *error,
ret_ip);
break;
@@ -216,6 +230,11 @@ xchk_block_set_corrupt(
struct xfs_buf *bp)
{
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
+ xfs_scrub_whine(sc->mp, "type %d agno %u agbno %u ret_ip %pS",
+ sc->sm->sm_type,
+ XFS_FSB_TO_AGNO(sc->mp, XFS_DADDR_TO_FSB(sc->mp, bp->b_bn)),
+ XFS_FSB_TO_AGBNO(sc->mp, XFS_DADDR_TO_FSB(sc->mp, bp->b_bn)),
+ __return_address);
trace_xchk_block_error(sc, bp->b_bn, __return_address);
}
@@ -226,6 +245,11 @@ xchk_block_xref_set_corrupt(
struct xfs_buf *bp)
{
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT;
+ xfs_scrub_whine(sc->mp, "type %d agno %u agbno %u ret_ip %pS",
+ sc->sm->sm_type,
+ XFS_FSB_TO_AGNO(sc->mp, XFS_DADDR_TO_FSB(sc->mp, bp->b_bn)),
+ XFS_FSB_TO_AGBNO(sc->mp, XFS_DADDR_TO_FSB(sc->mp, bp->b_bn)),
+ __return_address);
trace_xchk_block_error(sc, bp->b_bn, __return_address);
}
@@ -240,6 +264,8 @@ xchk_ino_set_corrupt(
xfs_ino_t ino)
{
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
+ xfs_scrub_whine(sc->mp, "ino %llu type %d ret_ip %pS",
+ ino, sc->sm->sm_type, __return_address);
trace_xchk_ino_error(sc, ino, __return_address);
}
@@ -250,6 +276,8 @@ xchk_ino_xref_set_corrupt(
xfs_ino_t ino)
{
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT;
+ xfs_scrub_whine(sc->mp, "ino %llu type %d ret_ip %pS",
+ ino, sc->sm->sm_type, __return_address);
trace_xchk_ino_error(sc, ino, __return_address);
}
@@ -261,6 +289,12 @@ xchk_fblock_set_corrupt(
xfs_fileoff_t offset)
{
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
+ xfs_scrub_whine(sc->mp, "ino %llu fork %d type %d offset %llu ret_ip %pS",
+ sc->ip->i_ino,
+ whichfork,
+ sc->sm->sm_type,
+ offset,
+ __return_address);
trace_xchk_fblock_error(sc, whichfork, offset, __return_address);
}
@@ -272,6 +306,12 @@ xchk_fblock_xref_set_corrupt(
xfs_fileoff_t offset)
{
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XCORRUPT;
+ xfs_scrub_whine(sc->mp, "ino %llu fork %d type %d offset %llu ret_ip %pS",
+ sc->ip->i_ino,
+ whichfork,
+ sc->sm->sm_type,
+ offset,
+ __return_address);
trace_xchk_fblock_error(sc, whichfork, offset, __return_address);
}
@@ -285,6 +325,8 @@ xchk_ino_set_warning(
xfs_ino_t ino)
{
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING;
+ xfs_scrub_whine(sc->mp, "ino %llu type %d agno %u agbno %u ret_ip %pS",
+ ino, sc->sm->sm_type, __return_address);
trace_xchk_ino_warning(sc, ino, __return_address);
}
@@ -296,6 +338,12 @@ xchk_fblock_set_warning(
xfs_fileoff_t offset)
{
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_WARNING;
+ xfs_scrub_whine(sc->mp, "ino %llu fork %d type %d offset %llu ret_ip %pS",
+ sc->ip->i_ino,
+ whichfork,
+ sc->sm->sm_type,
+ offset,
+ __return_address);
trace_xchk_fblock_warning(sc, whichfork, offset, __return_address);
}
@@ -738,6 +786,12 @@ xchk_get_inode(
error = -EFSCORRUPTED;
/* fall through */
default:
+ xfs_scrub_whine(mp, "type %d agno %u agbno %u error %d ret_ip %pS",
+ sc->sm->sm_type,
+ XFS_INO_TO_AGNO(mp, sc->sm->sm_ino),
+ XFS_INO_TO_AGBNO(mp, sc->sm->sm_ino),
+ error,
+ __return_address);
trace_xchk_op_error(sc,
XFS_INO_TO_AGNO(mp, sc->sm->sm_ino),
XFS_INO_TO_AGBNO(mp, sc->sm->sm_ino),
@@ -810,6 +864,10 @@ xchk_should_check_xref(
}
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_XFAIL;
+ xfs_scrub_whine(sc->mp, "type %d xref error %d ret_ip %pS",
+ sc->sm->sm_type,
+ *error,
+ __return_address);
trace_xchk_xref_error(sc, *error, __return_address);
/*
@@ -840,6 +898,11 @@ xchk_buffer_recheck(
if (!fa)
return;
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
+ xfs_scrub_whine(sc->mp, "type %d agno %u agbno %u ret_ip %pS",
+ sc->sm->sm_type,
+ XFS_FSB_TO_AGNO(sc->mp, XFS_DADDR_TO_FSB(sc->mp, bp->b_bn)),
+ XFS_FSB_TO_AGBNO(sc->mp, XFS_DADDR_TO_FSB(sc->mp, bp->b_bn)),
+ fa);
trace_xchk_block_error(sc, bp->b_bn, fa);
}
@@ -1147,3 +1210,28 @@ xfs_scrub_foreach_live_inode(
return error;
}
+
+void
+xfs_scrub_whine(
+ const struct xfs_mount *mp,
+ const char *fmt,
+ ...)
+{
+ struct va_format vaf;
+ va_list args;
+ int level;
+
+ va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ printk(KERN_INFO "XFS (%s) %pf: %pV\n", mp->m_fsname, __return_address,
+ &vaf);
+ va_end(args);
+
+ if (!kstrtoint(KERN_INFO, 0, &level) &&
+ level <= LOGLEVEL_ERR &&
+ xfs_error_level >= XFS_ERRLEVEL_HIGH)
+ xfs_stack_trace();
+}
diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h
index 3d8a55b13dcc..e1276db2fe4c 100644
--- a/fs/xfs/scrub/common.h
+++ b/fs/xfs/scrub/common.h
@@ -132,6 +132,7 @@ int xchk_get_inode(struct xfs_scrub *sc, struct xfs_inode *ip_in);
int xchk_setup_inode_contents(struct xfs_scrub *sc, struct xfs_inode *ip,
unsigned int resblks);
void xchk_buffer_recheck(struct xfs_scrub *sc, struct xfs_buf *bp);
+void xfs_scrub_whine(const struct xfs_mount *mp, const char *fmt, ...);
/*
* Don't bother cross-referencing if we already found corruption or cross
diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c
index e2ecf9c77010..c6ab123b6051 100644
--- a/fs/xfs/scrub/dabtree.c
+++ b/fs/xfs/scrub/dabtree.c
@@ -57,6 +57,14 @@ xchk_da_process_error(
*error = 0;
/* fall through */
default:
+ xfs_scrub_whine(sc->mp, "ino %llu fork %d type %d offset %llu error %d ret_ip %pS",
+ sc->ip->i_ino,
+ ds->dargs.whichfork,
+ sc->sm->sm_type,
+ xfs_dir2_da_to_db(ds->dargs.geo,
+ ds->state->path.blk[level].blkno),
+ *error,
+ __return_address);
trace_xchk_file_op_error(sc, ds->dargs.whichfork,
xfs_dir2_da_to_db(ds->dargs.geo,
ds->state->path.blk[level].blkno),
@@ -79,6 +87,13 @@ xchk_da_set_corrupt(
sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
+ xfs_scrub_whine(sc->mp, "ino %llu fork %d type %d offset %llu ret_ip %pS",
+ sc->ip->i_ino,
+ ds->dargs.whichfork,
+ sc->sm->sm_type,
+ xfs_dir2_da_to_db(ds->dargs.geo,
+ ds->state->path.blk[level].blkno),
+ __return_address);
trace_xchk_fblock_error(sc, ds->dargs.whichfork,
xfs_dir2_da_to_db(ds->dargs.geo,
ds->state->path.blk[level].blkno),
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index 6d7f85b27078..f8d38a400e88 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -564,6 +564,11 @@ retry_op:
* already tried to fix it, then attempt a repair.
*/
error = xrep_attempt(ip, &sc, &already_fixed);
+ if (error != -EOPNOTSUPP && error != -ENOENT)
+ xfs_scrub_whine(mp, "REPAIRED? ino 0x%llx type %u agno %u inum %llu gen %u flags 0x%x error %d",
+ ip->i_ino, sm->sm_type, sm->sm_agno,
+ sm->sm_ino, sm->sm_gen, sm->sm_flags,
+ already_fixed ? 0 : error);
if (error == -EAGAIN) {
if (sc.try_harder)
try_harder = true;
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index 9866f542e77b..2a63461af068 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -250,10 +250,6 @@ xfs_errortag_test(
randfactor = mp->m_errortag[error_tag];
if (!randfactor || prandom_u32() % randfactor)
return false;
-
- xfs_warn_ratelimited(mp,
-"Injecting error (%s) at file %s, line %d, on filesystem \"%s\"",
- expression, file, line, mp->m_fsname);
return true;
}