diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2018-02-26 22:43:19 -0600 |
---|---|---|
committer | Eric Sandeen <sandeen@redhat.com> | 2018-02-26 22:43:19 -0600 |
commit | 1d3bac1f3b6b4aa8b4de1ed6a95b0440b1bcd953 (patch) | |
tree | 160670996cba555bbf1c47f66dc1b66f1060f318 | |
parent | 885ba5ce1dd446a82f2ecf1f03ad834d253b05d7 (diff) | |
download | xfsprogs-dev-1d3bac1f3b6b4aa8b4de1ed6a95b0440b1bcd953.tar.gz |
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 <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r-- | libxfs/libxfs_priv.h | 6 | ||||
-rw-r--r-- | libxfs/rdwr.c | 14 | ||||
-rw-r--r-- | libxfs/util.c | 19 | ||||
-rw-r--r-- | libxfs/xfs_inode_buf.c | 6 |
4 files changed, 34 insertions, 11 deletions
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 82627668fb..d35676e9c7 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 7b75648c22..3c5def2950 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 2d3b721777..aac558cf0c 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -744,6 +744,25 @@ xfs_verifier_error( } /* + * 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 * the active log. We don't have an active log in userspace so this kind of diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c index ecbd517854..2c805b342e 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; } |