xfs: catch buffers written without verifiers attached
authorDave Chinner <dchinner@redhat.com>
Mon, 4 Aug 2014 02:42:40 +0000 (12:42 +1000)
committerDave Chinner <david@fromorbit.com>
Mon, 4 Aug 2014 02:42:40 +0000 (12:42 +1000)
We recently had a bug where buffers were slipping through log
recovery without any verifier attached to them. This was resulting
in on-disk CRC mismatches for valid data. Add some warning code to
catch this occurrence so that we catch such bugs during development
rather than not being aware they exist.

Note that we cannot do this verification unconditionally as non-CRC
filesystems don't always attach verifiers to the buffers being
written. e.g. during log recovery we cannot identify all the
different types of buffers correctly on non-CRC filesystems, so we
can't attach the correct verifiers in all cases and so we don't
attach any. Hence we don't want on non-CRC filesystems to avoid
spamming the logs with false indications.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/xfs_buf.c
fs/xfs/xfs_log.c

index a6dc83e70ece5e3ad7eede2072869ed5599f8e26..cd7b8ca9b06410c5d34e92161906532a6221ef66 100644 (file)
@@ -1330,6 +1330,20 @@ _xfs_buf_ioapply(
                                                   SHUTDOWN_CORRUPT_INCORE);
                                return;
                        }
+               } else if (bp->b_bn != XFS_BUF_DADDR_NULL) {
+                       struct xfs_mount *mp = bp->b_target->bt_mount;
+
+                       /*
+                        * non-crc filesystems don't attach verifiers during
+                        * log recovery, so don't warn for such filesystems.
+                        */
+                       if (xfs_sb_version_hascrc(&mp->m_sb)) {
+                               xfs_warn(mp,
+                                       "%s: no ops on block 0x%llx/0x%x",
+                                       __func__, bp->b_bn, bp->b_length);
+                               xfs_hex_dump(bp->b_addr, 64);
+                               dump_stack();
+                       }
                }
        } else if (bp->b_flags & XBF_READ_AHEAD) {
                rw = READA;
index 7647818b8c8ae4aa4d85557ebf78637125e4de4d..d015ed7d4a26a0e1cd42878b7fc1c395ebd419dd 100644 (file)
@@ -1369,8 +1369,14 @@ xlog_alloc_log(
 
        xlog_get_iclog_buffer_size(mp, log);
 
+       /*
+        * Use a NULL block for the extra log buffer used during splits so that
+        * it will trigger errors if we ever try to do IO on it without first
+        * having set it up properly.
+        */
        error = -ENOMEM;
-       bp = xfs_buf_alloc(mp->m_logdev_targp, 0, BTOBB(log->l_iclog_size), 0);
+       bp = xfs_buf_alloc(mp->m_logdev_targp, XFS_BUF_DADDR_NULL,
+                          BTOBB(log->l_iclog_size), 0);
        if (!bp)
                goto out_free_log;
 
This page took 0.027493 seconds and 5 git commands to generate.