From f85fc6220f1c7fdb467a4d5b43e9bfbd2fb36c1d Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Wed, 13 Nov 2013 06:40:33 +0000 Subject: [PATCH] libxfs: bring across inode buffer readahead verifier changes These were made for log recovery readahead in the kernel, so are not directly used in userspace. Hence bringing the change across is simply to keep files in sync. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Rich Johnston --- libxfs/xfs_inode_buf.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c index b096f7724..dbe1b87d0 100644 --- a/libxfs/xfs_inode_buf.c +++ b/libxfs/xfs_inode_buf.c @@ -46,9 +46,22 @@ xfs_inobp_check( } #endif +/* + * If we are doing readahead on an inode buffer, we might be in log recovery + * reading an inode allocation buffer that hasn't yet been replayed, and hence + * has not had the inode cores stamped into it. Hence for readahead, the buffer + * may be potentially invalid. + * + * If the readahead buffer is invalid, we don't want to mark it with an error, + * but we do want to clear the DONE status of the buffer so that a followup read + * will re-read it from disk. This will ensure that we don't get an unnecessary + * warnings during log recovery and we don't get unnecessary panics on debug + * kernels. + */ static void xfs_inode_buf_verify( - struct xfs_buf *bp) + struct xfs_buf *bp, + bool readahead) { struct xfs_mount *mp = bp->b_target->bt_mount; int i; @@ -69,6 +82,11 @@ xfs_inode_buf_verify( if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, XFS_RANDOM_ITOBP_INOTOBP))) { + if (readahead) { + bp->b_flags &= ~XBF_DONE; + return; + } + xfs_buf_ioerror(bp, EFSCORRUPTED); XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH, mp, dip); @@ -87,14 +105,21 @@ static void xfs_inode_buf_read_verify( struct xfs_buf *bp) { - xfs_inode_buf_verify(bp); + xfs_inode_buf_verify(bp, false); +} + +static void +xfs_inode_buf_readahead_verify( + struct xfs_buf *bp) +{ + xfs_inode_buf_verify(bp, true); } static void xfs_inode_buf_write_verify( struct xfs_buf *bp) { - xfs_inode_buf_verify(bp); + xfs_inode_buf_verify(bp, false); } const struct xfs_buf_ops xfs_inode_buf_ops = { @@ -102,6 +127,12 @@ const struct xfs_buf_ops xfs_inode_buf_ops = { .verify_write = xfs_inode_buf_write_verify, }; +const struct xfs_buf_ops xfs_inode_buf_ra_ops = { + .verify_read = xfs_inode_buf_readahead_verify, + .verify_write = xfs_inode_buf_write_verify, +}; + + /* * This routine is called to map an inode to the buffer containing the on-disk * version of the inode. It returns a pointer to the buffer containing the @@ -191,7 +222,7 @@ xfs_dinode_from_disk( to->di_ino = be64_to_cpu(from->di_ino); to->di_lsn = be64_to_cpu(from->di_lsn); memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); - platform_uuid_copy(&to->di_uuid, &from->di_uuid); + uuid_copy(&to->di_uuid, &from->di_uuid); } } @@ -237,7 +268,7 @@ xfs_dinode_to_disk( to->di_ino = cpu_to_be64(from->di_ino); to->di_lsn = cpu_to_be64(from->di_lsn); memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); - platform_uuid_copy(&to->di_uuid, &from->di_uuid); + uuid_copy(&to->di_uuid, &from->di_uuid); to->di_flushiter = 0; } else { to->di_flushiter = cpu_to_be16(from->di_flushiter); -- 2.47.2