aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-01-22 21:09:48 -0500
committerDarrick J. Wong <darrick.wong@oracle.com>2018-01-29 10:27:22 -0500
commit22431bf3dfbf44d7356933776eb486a6a01dea6f (patch)
tree5d4aecebcd8cdb86a29e317d2ddeadaff9ed4e85
parent67a3f6d01495bbf520186aa3ecd013ba02b81462 (diff)
xfs: refactor inode verifier corruption error printing
Refactor inode verifier error reporting into a non-libxfs function so that we aren't encoding the message format in libxfs. This also changes the kernel dmesg output to resemble buffer verifier errors more closely. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--fs/xfs/libxfs/xfs_inode_buf.c6
-rw-r--r--fs/xfs/xfs_error.c37
-rw-r--r--fs/xfs/xfs_error.h3
-rw-r--r--fs/xfs/xfs_inode.c14
4 files changed, 50 insertions, 10 deletions
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 4035b5d5f6fd..d7e7e58f0ee2 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -578,10 +578,8 @@ xfs_iread(
578 /* even unallocated inodes are verified */ 578 /* even unallocated inodes are verified */
579 fa = xfs_dinode_verify(mp, ip->i_ino, dip); 579 fa = xfs_dinode_verify(mp, ip->i_ino, dip);
580 if (fa) { 580 if (fa) {
581 xfs_alert(mp, "%s: validation failed for inode %lld at %pS", 581 xfs_inode_verifier_error(ip, -EFSCORRUPTED, "dinode", dip,
582 __func__, ip->i_ino, fa); 582 sizeof(*dip), fa);
583
584 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, dip);
585 error = -EFSCORRUPTED; 583 error = -EFSCORRUPTED;
586 goto out_brelse; 584 goto out_brelse;
587 } 585 }
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index 980d5f0660b5..ccf520f0b00d 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -24,6 +24,7 @@
24#include "xfs_errortag.h" 24#include "xfs_errortag.h"
25#include "xfs_error.h" 25#include "xfs_error.h"
26#include "xfs_sysfs.h" 26#include "xfs_sysfs.h"
27#include "xfs_inode.h"
27 28
28#ifdef DEBUG 29#ifdef DEBUG
29 30
@@ -372,3 +373,39 @@ xfs_verifier_error(
372 if (xfs_error_level >= XFS_ERRLEVEL_HIGH) 373 if (xfs_error_level >= XFS_ERRLEVEL_HIGH)
373 xfs_stack_trace(); 374 xfs_stack_trace();
374} 375}
376
377/*
378 * Warnings for inode corruption problems. Don't bother with the stack
379 * trace unless the error level is turned up high.
380 */
381void
382xfs_inode_verifier_error(
383 struct xfs_inode *ip,
384 int error,
385 const char *name,
386 void *buf,
387 size_t bufsz,
388 xfs_failaddr_t failaddr)
389{
390 struct xfs_mount *mp = ip->i_mount;
391 xfs_failaddr_t fa;
392 int sz;
393
394 fa = failaddr ? failaddr : __return_address;
395
396 xfs_alert(mp, "Metadata %s detected at %pS, inode 0x%llx %s",
397 error == -EFSBADCRC ? "CRC error" : "corruption",
398 fa, ip->i_ino, name);
399
400 xfs_alert(mp, "Unmount and run xfs_repair");
401
402 if (buf && xfs_error_level >= XFS_ERRLEVEL_LOW) {
403 sz = min_t(size_t, XFS_CORRUPTION_DUMP_LEN, bufsz);
404 xfs_alert(mp, "First %d bytes of corrupted metadata buffer:",
405 sz);
406 xfs_hex_dump(buf, sz);
407 }
408
409 if (xfs_error_level >= XFS_ERRLEVEL_HIGH)
410 xfs_stack_trace();
411}
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index a3ba05bd983d..7e728c5a46b8 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -28,6 +28,9 @@ extern void xfs_corruption_error(const char *tag, int level,
28 int linenum, xfs_failaddr_t failaddr); 28 int linenum, xfs_failaddr_t failaddr);
29extern void xfs_verifier_error(struct xfs_buf *bp, int error, 29extern void xfs_verifier_error(struct xfs_buf *bp, int error,
30 xfs_failaddr_t failaddr); 30 xfs_failaddr_t failaddr);
31extern void xfs_inode_verifier_error(struct xfs_inode *ip, int error,
32 const char *name, void *buf, size_t bufsz,
33 xfs_failaddr_t failaddr);
31 34
32#define XFS_ERROR_REPORT(e, lvl, mp) \ 35#define XFS_ERROR_REPORT(e, lvl, mp) \
33 xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address) 36 xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 4ea6476bcbd7..5366fb619db6 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -3486,21 +3486,23 @@ bool
3486xfs_inode_verify_forks( 3486xfs_inode_verify_forks(
3487 struct xfs_inode *ip) 3487 struct xfs_inode *ip)
3488{ 3488{
3489 struct xfs_ifork *ifp;
3489 xfs_failaddr_t fa; 3490 xfs_failaddr_t fa;
3490 3491
3491 fa = xfs_ifork_verify_data(ip, &xfs_default_ifork_ops); 3492 fa = xfs_ifork_verify_data(ip, &xfs_default_ifork_ops);
3492 if (fa) { 3493 if (fa) {
3493 xfs_alert(ip->i_mount, 3494 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
3494 "%s: bad inode %llu inline data fork at %pS", 3495 xfs_inode_verifier_error(ip, -EFSCORRUPTED, "data fork",
3495 __func__, ip->i_ino, fa); 3496 ifp->if_u1.if_data, ifp->if_bytes, fa);
3496 return false; 3497 return false;
3497 } 3498 }
3498 3499
3499 fa = xfs_ifork_verify_attr(ip, &xfs_default_ifork_ops); 3500 fa = xfs_ifork_verify_attr(ip, &xfs_default_ifork_ops);
3500 if (fa) { 3501 if (fa) {
3501 xfs_alert(ip->i_mount, 3502 ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK);
3502 "%s: bad inode %llu inline attr fork at %pS", 3503 xfs_inode_verifier_error(ip, -EFSCORRUPTED, "attr fork",
3503 __func__, ip->i_ino, fa); 3504 ifp ? ifp->if_u1.if_data : NULL,
3505 ifp ? ifp->if_bytes : 0, fa);
3504 return false; 3506 return false;
3505 } 3507 }
3506 return true; 3508 return true;