Add CRC checks to the superblock.
PATCH 6/9 Add CRC checks to the superblock.
From: Dave Chinner <[email protected]>
[hch: minor adaptions]
Signed-off-by Dave Chinner <[email protected]>
Signed-off-by Christoph Hellwig <[email protected]>
fs/xfs/xfs_mount.c +49 -6
@@ -44,6 +44,7 @@#include "xfs_quota.h" #include "xfs_fsops.h" #include "xfs_utils.h" +#include "xfs_cksum.h" STATIC int xfs_mount_log_sb(xfs_mount_t *, __int64_t); STATIC int xfs_uuid_mount(xfs_mount_t *);
@@ -119,6 +120,8 @@ static const struct { { offsetof(xfs_sb_t, sb_logsunit), 0 }, { offsetof(xfs_sb_t, sb_features2), 0 }, { offsetof(xfs_sb_t, sb_bad_features2), 0 }, + { offsetof(xfs_sb_t, sb_crc), 0 }, + { offsetof(xfs_sb_t, sb_pad), 0 }, { sizeof(xfs_sb_t), 0 } };
@@ -409,6 +412,7 @@ xfs_sb_from_disk( to->sb_logsunit =be32_to_cpu (from->sb_logsunit); to->sb_features2 =be32_to_cpu (from->sb_features2); to->sb_bad_features2 =be32_to_cpu (from->sb_bad_features2); + to->sb_crc =be32_to_cpu (from->sb_crc); }/*
@@ -465,6 +469,24 @@ xfs_sb_to_disk( }/* +* Calculate the superblock CRC and stuff it in the buffer. +* +* We get called here just before the superblock is written +* to disk. We should also do some validity checking here. +* +* We CRC the entire superblock sector, not just the bits we use +* so that changes in structure size as features are included do +* not invalidate CRCs. +*/ +void +xfs_sb_calc_crc ( +struct xfs_buf *bp) +{ +xfs_update_cksum (XFS_BUF_PTR (bp),XFS_BUF_SIZE (bp), + offsetof(struct xfs_sb , sb_crc)); +} + +/* * xfs_readsb * * Does the initial read of the superblock.
@@ -475,6 +497,7 @@ xfs_readsb(xfs_mount_t *mp, int flags)unsigned int sector_size;unsigned int extra_flags;xfs_buf_t *bp; +xfs_sb_t *sbp = &mp->m_sb;int error;ASSERT (mp->m_sb_bp ==NULL );
@@ -504,7 +527,25 @@ xfs_readsb(xfs_mount_t *mp, int flags)*/ xfs_sb_from_disk (&mp->m_sb,XFS_BUF_TO_SBP (bp)); - error =xfs_mount_validate_sb (mp, &(mp->m_sb), flags); +/* +* If the superblock has the CRC feature bit set or +* the CRC field is non-null, check that the CRC is valid. +* We check the CRC field is non-null because a single bit +* error could clear the feature bit and unused parts of +* the superblock are supposed to be zero. Hence a non-null +* crc field indicates that we've potentially lost a feature +* bit and we should check it anyway. +*/ +if (xfs_sb_version_hascrc (sbp) || sbp->sb_crc !=0 ) { +if (!xfs_verify_cksum (XFS_BUF_PTR (bp), sbp->sb_sectsize, + offsetof(struct xfs_sb , sb_crc))) { +xfs_fs_mount_cmn_err (flags,"SB CRC check failed" ); + error =EFSCORRUPTED ; + goto fail; + } + } + + error =xfs_mount_validate_sb (mp, sbp, flags);if (error) {xfs_fs_mount_cmn_err (flags,"SB validate failed" ); goto fail;
@@ -513,10 +554,10 @@ xfs_readsb(xfs_mount_t *mp, int flags)/* * We must be able to do sector-sized and sector-aligned IO. */ -if (sector_size > mp->m_sb.sb_sectsize) { +if (sector_size > sbp->sb_sectsize) {xfs_fs_mount_cmn_err (flags,"device supports only %u byte sectors (not %u)" , - sector_size, mp->m_sb.sb_sectsize); + sector_size, sbp->sb_sectsize); error =ENOSYS ; goto fail; }
@@ -525,10 +566,10 @@ xfs_readsb(xfs_mount_t *mp, int flags)* If device sector size is smaller than the superblock size, * re-read the superblock so the buffer is correctly sized. */ -if (sector_size < mp->m_sb.sb_sectsize) { +if (sector_size < sbp->sb_sectsize) {XFS_BUF_UNMANAGE (bp);xfs_buf_relse (bp); - sector_size = mp->m_sb.sb_sectsize; + sector_size = sbp->sb_sectsize; bp =xfs_buf_read_flags (mp->m_ddev_targp,XFS_SB_DADDR ,BTOBB (sector_size), extra_flags);if (!bp ||XFS_BUF_ISERROR (bp)) {
@@ -544,11 +585,13 @@ xfs_readsb(xfs_mount_t *mp, int flags)xfs_icsb_reinit_counters (mp); mp->m_sb_bp = bp; +if (xfs_sb_version_hascrc (sbp)) +xfs_buf_set_io_callback (bp, xfs_sb_calc_crc);xfs_buf_relse (bp);ASSERT (XFS_BUF_VALUSEMA (bp) >0 );return 0 ; - fail: +fail:if (bp) {XFS_BUF_UNMANAGE (bp);xfs_buf_relse (bp);
fs/xfs/xfs_sb.h +10 -2
@@ -159,7 +159,10 @@ typedef struct xfs_sb {*/ __uint32_t sb_bad_features2; +__uint32_t sb_crc;/* superblock crc */ +/* must be padded to 64 bit alignment */ +__uint32_t sb_pad; } xfs_sb_t;/*
@@ -227,9 +230,12 @@ typedef struct xfs_dsb {* for features2 bits. Easiest just to mark it bad and not use * it for anything else. */ -__be32 sb_bad_features2; +__be32 sb_bad_features2; + +__be32 sb_crc;/* superblock crc */ /* must be padded to 64 bit alignment */ +__be32 sb_pad; } xfs_dsb_t;/*
@@ -248,7 +254,7 @@ typedef enum {XFS_SBS_GQUOTINO ,XFS_SBS_QFLAGS ,XFS_SBS_FLAGS ,XFS_SBS_SHARED_VN ,XFS_SBS_INOALIGNMT ,XFS_SBS_UNIT ,XFS_SBS_WIDTH ,XFS_SBS_DIRBLKLOG ,XFS_SBS_LOGSECTLOG ,XFS_SBS_LOGSECTSIZE ,XFS_SBS_LOGSUNIT , -XFS_SBS_FEATURES2 ,XFS_SBS_BAD_FEATURES2 , +XFS_SBS_FEATURES2 ,XFS_SBS_BAD_FEATURES2 ,XFS_SBS_CRC ,XFS_SBS_PAD , XFS_SBS_FIELDCOUNT } xfs_sb_field_t;
@@ -274,6 +280,8 @@ typedef enum {#define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS)#define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2)#define XFS_SB_BAD_FEATURES2 XFS_SB_MVAL(BAD_FEATURES2) +#define XFS_SB_CRC XFS_SB_MVAL(CRC) +#define XFS_SB_PAD XFS_SB_MVAL(PAD)#define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT)#define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1)#define XFS_SB_MOD_BITS \
fs/xfs/xfs_trans.c +1 -0
@@ -44,6 +44,7 @@#include "xfs_trans_priv.h" #include "xfs_trans_space.h" #include "xfs_inode_item.h" +#include "xfs_cksum.h" STATIC void xfs_trans_apply_sb_deltas(xfs_trans_t *);
fs/xfs/xfs_mount.h +1 -0
@@ -506,6 +506,7 @@ typedef struct xfs_mod_sb {#define XFS_MOUNT_ILOCK (mp) mutex_lock(&((mp)->m_ilock))#define XFS_MOUNT_IUNLOCK (mp) mutex_unlock(&((mp)->m_ilock)) +extern void xfs_sb_calc_crc (struct xfs_buf *);extern void xfs_mod_sb (xfs_trans_t *,__int64_t );extern int xfs_log_sbcount (xfs_mount_t *,uint );extern int xfs_mountfs (xfs_mount_t *mp);
fs/xfs/xfs_log_recover.c +3 -0
@@ -1941,6 +1941,9 @@ xlog_recover_do_reg_buffer(case XFS_BMAP_CRC_MAGIC :xfs_btree_lblock_calc_crc (bp);break ; +case XFS_SB_MAGIC : +xfs_sb_calc_crc (bp); +break ;default :break ; }
On Fri, Sep 26, 2008 at 12:56:39AM +0200, Christoph Hellwig wrote:
| From: Dave Chinner <[email protected]> | | [hch: minor adaptions]
I suggest a more comprehensive header here. Otherwise code looks good.
| | | Signed-off-by: Dave Chinner <[email protected]> | Signed-off-by: Christoph Hellwig <[email protected]> |
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs