xfs: refactor inode buffer verifier error logging
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 23 Mar 2018 17:06:53 +0000 (10:06 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Sat, 24 Mar 2018 01:05:07 +0000 (18:05 -0700)
When the inode buffer verifier encounters an error, it's much more
helpful to print a buffer from the offending inode instead of just the
start of the inode chunk buffer.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
fs/xfs/libxfs/xfs_inode_buf.c
fs/xfs/xfs_error.c
fs/xfs/xfs_error.h

index 4fe17b3..51019e5 100644 (file)
@@ -115,13 +115,15 @@ xfs_inode_buf_verify(
                                return;
                        }
 
-                       xfs_verifier_error(bp, -EFSCORRUPTED, __this_address);
 #ifdef DEBUG
                        xfs_alert(mp,
                                "bad inode magic/vsn daddr %lld #%d (magic=%x)",
                                (unsigned long long)bp->b_bn, i,
                                be16_to_cpu(dip->di_magic));
 #endif
+                       xfs_buf_verifier_error(bp, -EFSCORRUPTED,
+                                       __func__, dip, sizeof(*dip),
+                                       NULL);
                }
        }
        xfs_inobp_check(mp, bp);
index ccf520f..a63f508 100644 (file)
@@ -347,27 +347,32 @@ xfs_corruption_error(
  * values, and omit the stack trace unless the error level is tuned high.
  */
 void
-xfs_verifier_error(
+xfs_buf_verifier_error(
        struct xfs_buf          *bp,
        int                     error,
+       const char              *name,
+       void                    *buf,
+       size_t                  bufsz,
        xfs_failaddr_t          failaddr)
 {
        struct xfs_mount        *mp = bp->b_target->bt_mount;
        xfs_failaddr_t          fa;
+       int                     sz;
 
        fa = failaddr ? failaddr : __return_address;
        __xfs_buf_ioerror(bp, error, fa);
 
-       xfs_alert(mp, "Metadata %s detected at %pS, %s block 0x%llx",
+       xfs_alert(mp, "Metadata %s detected at %pS, %s block 0x%llx %s",
                  bp->b_error == -EFSBADCRC ? "CRC error" : "corruption",
-                 fa, bp->b_ops->name, bp->b_bn);
+                 fa, bp->b_ops->name, bp->b_bn, name);
 
        xfs_alert(mp, "Unmount and run xfs_repair");
 
        if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
+               sz = min_t(size_t, XFS_CORRUPTION_DUMP_LEN, bufsz);
                xfs_alert(mp, "First %d bytes of corrupted metadata buffer:",
-                               XFS_CORRUPTION_DUMP_LEN);
-               xfs_hex_dump(xfs_buf_offset(bp, 0), XFS_CORRUPTION_DUMP_LEN);
+                               sz);
+               xfs_hex_dump(buf, sz);
        }
 
        if (xfs_error_level >= XFS_ERRLEVEL_HIGH)
@@ -375,6 +380,20 @@ xfs_verifier_error(
 }
 
 /*
+ * Warnings specifically for verifier errors.  Differentiate CRC vs. invalid
+ * values, and omit the stack trace unless the error level is tuned high.
+ */
+void
+xfs_verifier_error(
+       struct xfs_buf          *bp,
+       int                     error,
+       xfs_failaddr_t          failaddr)
+{
+       return xfs_buf_verifier_error(bp, error, "", xfs_buf_offset(bp, 0),
+                       XFS_CORRUPTION_DUMP_LEN, failaddr);
+}
+
+/*
  * Warnings for inode corruption problems.  Don't bother with the stack
  * trace unless the error level is turned up high.
  */
index 7e728c5..ce39134 100644 (file)
@@ -26,6 +26,9 @@ extern void xfs_error_report(const char *tag, int level, struct xfs_mount *mp,
 extern void xfs_corruption_error(const char *tag, int level,
                        struct xfs_mount *mp, void *p, const char *filename,
                        int linenum, xfs_failaddr_t failaddr);
+extern void xfs_buf_verifier_error(struct xfs_buf *bp, int error,
+                       const char *name, void *buf, size_t bufsz,
+                       xfs_failaddr_t failaddr);
 extern void xfs_verifier_error(struct xfs_buf *bp, int error,
                        xfs_failaddr_t failaddr);
 extern void xfs_inode_verifier_error(struct xfs_inode *ip, int error,