[Top] [All Lists]

[PATCH 04/13] libxfs: skip verification on initial "guess" superblock re

To: xfs@xxxxxxxxxxx
Subject: [PATCH 04/13] libxfs: skip verification on initial "guess" superblock read
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Tue, 4 Mar 2014 19:51:48 +1100
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1393923117-9559-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1393923117-9559-1-git-send-email-david@xxxxxxxxxxxxx>
From: Dave Chinner <dchinner@xxxxxxxxxx>

[userspace port]

When xfs_readsb() does the very first read of the superblock,
it makes a guess at the length of the buffer, based on the
sector size of the underlying storage.  This may or may
not match the filesystem sector size in sb_sectsize, so
we can't i.e. do a CRC check on it; it might be too short.

In fact, mounting a filesystem with sb_sectsize larger
than the device sector size will cause a mount failure
if CRCs are enabled, because we are checksumming a length
which exceeds the buffer passed to it.

So always read twice; the first time we read with NULL
buffer ops to skip verification; then set the proper
read length, hook up the proper verifier, and give it
another go.

Once we are sure that we've got the right buffer length,
we can also use bp->b_length in the xfs_sb_read_verify,
rather than the less-trusted on-disk sectorsize for
secondary superblocks.  Before this we ran the risk of
passing junk to the crc32c routines, which didn't always
handle extreme values.

Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
 libxfs/xfs_sb.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index 5c10c97..6ad99a5 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -566,7 +566,7 @@ xfs_sb_read_verify(
                                                XFS_SB_VERSION_5) ||
             dsb->sb_crc != 0)) {
-               if (!xfs_verify_cksum(bp->b_addr, be16_to_cpu(dsb->sb_sectsize),
+               if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
                                      offsetof(struct xfs_sb, sb_crc))) {
                        /* Only fail bad secondaries on a known V5 filesystem */
                        if (bp->b_bn == XFS_SB_DADDR ||
@@ -599,7 +599,6 @@ xfs_sb_quiet_read_verify(
        struct xfs_dsb  *dsb = XFS_BUF_TO_SBP(bp);
        if (dsb->sb_magicnum == cpu_to_be32(XFS_SB_MAGIC)) {
                /* XFS filesystem, verify noisily! */

<Prev in Thread] Current Thread [Next in Thread>