diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2019-01-16 10:12:39 -0800 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2019-02-04 09:31:22 -0800 |
commit | edf60a8373c02bfc90a1bc8729ecc92828ec2b00 (patch) | |
tree | 6a3d5ddeaaa6f765b1c5402f33c17851ecc80bee | |
parent | babcf3e7ff0e5ac0cc5f583cc75278bc0ab633be (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.c | 66 | ||||
-rw-r--r-- | fs/xfs/scrub/common.c | 88 | ||||
-rw-r--r-- | fs/xfs/scrub/common.h | 1 | ||||
-rw-r--r-- | fs/xfs/scrub/dabtree.c | 15 | ||||
-rw-r--r-- | fs/xfs/scrub/scrub.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_error.c | 4 |
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; } |