From: Darrick J. Wong Date: Tue, 27 Feb 2018 04:43:19 +0000 (-0600) Subject: xfs: refactor inode verifier corruption error printing X-Git-Tag: v4.16.0-rc1~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1d3bac1f3b6b4aa8b4de1ed6a95b0440b1bcd953;p=thirdparty%2Fxfsprogs-dev.git xfs: refactor inode verifier corruption error printing Source kernel commit: 22431bf3dfbf44d7356933776eb486a6a01dea6f 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 Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Eric Sandeen --- diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 82627668f..d35676e9c 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -527,7 +527,11 @@ int libxfs_mod_incore_sb(struct xfs_mount *, int, int64_t, int); #define xfs_reinit_percpu_counters(mp) void xfs_trans_mod_sb(struct xfs_trans *, uint, long); -void xfs_verifier_error(struct xfs_buf *bp, int error, xfs_failaddr_t failaddr); +void xfs_verifier_error(struct xfs_buf *bp, int error, + xfs_failaddr_t failaddr); +void xfs_inode_verifier_error(struct xfs_inode *ip, int error, + const char *name, void *buf, size_t bufsz, + xfs_failaddr_t failaddr); /* XXX: this is clearly a bug - a shared header needs to export this */ /* xfs_rtalloc.c */ diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 7b75648c2..3c5def295 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -1344,21 +1344,23 @@ bool libxfs_inode_verify_forks( struct xfs_inode *ip) { + struct xfs_ifork *ifp; xfs_failaddr_t fa; fa = xfs_ifork_verify_data(ip, &xfs_default_ifork_ops); if (fa) { - xfs_alert(ip->i_mount, - "%s: bad inode %Lu inline data fork at %pF", - __func__, ip->i_ino, fa); + ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); + xfs_inode_verifier_error(ip, -EFSCORRUPTED, "data fork", + ifp->if_u1.if_data, ifp->if_bytes, fa); return false; } fa = xfs_ifork_verify_attr(ip, &xfs_default_ifork_ops); if (fa) { - xfs_alert(ip->i_mount, - "%s: bad inode %Lu inline attr fork at %pF", - __func__, ip->i_ino, fa); + ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK); + xfs_inode_verifier_error(ip, -EFSCORRUPTED, "attr fork", + ifp ? ifp->if_u1.if_data : NULL, + ifp ? ifp->if_bytes : 0, fa); return false; } return true; diff --git a/libxfs/util.c b/libxfs/util.c index 2d3b72177..aac558cf0 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -743,6 +743,25 @@ xfs_verifier_error( bp->b_ops->name, bp->b_bn, BBTOB(bp->b_length)); } +/* + * Warnings for inode corruption problems. Don't bother with the stack + * trace unless the error level is turned up high. + */ +void +xfs_inode_verifier_error( + struct xfs_inode *ip, + int error, + const char *name, + void *buf, + size_t bufsz, + xfs_failaddr_t failaddr) +{ + xfs_alert(NULL, "Metadata %s detected at %p, inode 0x%llx %s", + error == -EFSBADCRC ? "CRC error" : "corruption", + failaddr ? failaddr : __return_address, + ip->i_ino, name); +} + /* * This is called from I/O verifiers on v5 superblock filesystems. In the * kernel, it validates the metadata LSN parameter against the current LSN of diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c index ecbd51785..2c805b342 100644 --- a/libxfs/xfs_inode_buf.c +++ b/libxfs/xfs_inode_buf.c @@ -577,10 +577,8 @@ xfs_iread( /* even unallocated inodes are verified */ fa = xfs_dinode_verify(mp, ip->i_ino, dip); if (fa) { - xfs_alert(mp, "%s: validation failed for inode %lld at %pS", - __func__, ip->i_ino, fa); - - XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, dip); + xfs_inode_verifier_error(ip, -EFSCORRUPTED, "dinode", dip, + sizeof(*dip), fa); error = -EFSCORRUPTED; goto out_brelse; }