add support for large btree blocks with CRCs and additional RAS information
PATCH 5/9 add support for large btree blocks with CRCs and additional RAS information
Add support for larger btree blocks that contains a CRC32C checksum, a filesystem uuid and block number for detecting filesystem consistency and out of place writes. The use of these blocks is triggered by the crc superblock patches just added.
Note that we currently do not log the crc of the block, but re-created it during log recovery. With the pending patch to also checksum the log this should be safe against filesystem corruption but doesn't really follow the end to end argument. Also poking into the buffer to find out whether this is a btree buffer during log recovery is not a very clean way to implement this. I'll look into how well adding crcs to the buffer log items for every btree is going to work and hope I can switch to that variant for the next version.
fs/xfs/xfs_btree.h +30 -5
@@ -47,6 +47,10 @@ extern kmem_zone_t *xfs_btree_cur_zone;* * To get the size of the actual short or long form headers please use * the size macros below. Never use sizeof(xfs_btree_block). +* +* The blkno, crc and uuid fields are only available in filesystems with +* the crc feature bit, and all accesses to them must be conditional on +* that flag. */ struct xfs_btree_block {__be32 bb_magic;/* magic number for block type */
@@ -56,16 +60,32 @@ struct xfs_btree_block {struct {__be32 bb_leftsib;__be32 bb_rightsib; + +__be64 bb_blkno; +uuid_t bb_uuid; +__be32 bb_crc; +__be32 bb_pad;/* padding for alignment */ } s;/* short form pointers */ struct {__be64 bb_leftsib;__be64 bb_rightsib; + +__be64 bb_blkno; +uuid_t bb_uuid; +__be32 bb_crc; +__be32 bb_pad;/* padding for alignment */ } l;/* long form pointers */ } bb_u;/* rest */ };#define XFS_BTREE_SBLOCK_LEN 16/* size of a short form block */ #define XFS_BTREE_LBLOCK_LEN 24/* size of a long form block */ +#define XFS_BTREE_CRCBLOCK_ADD 32/* size of blkno + crc + uuid */ + +#define XFS_BTREE_SBLOCK_CRC_OFF \ + offsetof(struct xfs_btree_block, bb_u.s.bb_crc) +#define XFS_BTREE_LBLOCK_CRC_OFF \ + offsetof(struct xfs_btree_block, bb_u.l.bb_crc)/*
@@ -101,13 +121,11 @@ union xfs_btree_rec {#define XFS_BB_NUMRECS 0x04#define XFS_BB_LEFTSIB 0x08#define XFS_BB_RIGHTSIB 0x10 +#define XFS_BB_BLKNO 0x20#define XFS_BB_NUM_BITS 5#define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1) - -/* -* Magic numbers for btree blocks. -*/ -extern const __uint32_t xfs_magics[]; +#define XFS_BB_NUM_BITS_CRC 8 +#define XFS_BB_ALL_BITS_CRC ((1 << XFS_BB_NUM_BITS_CRC) - 1)/* * Generic stats interface
@@ -275,6 +293,7 @@ typedef struct xfs_btree_cur#define XFS_BTREE_LONG_PTRS (1<<0)/* pointers are 64bits long */ #define XFS_BTREE_ROOT_IN_INODE (1<<1)/* root may be variable size */ #define XFS_BTREE_LASTREC_UPDATE (1<<2)/* track last rec externally */ +#define XFS_BTREE_CRC_BLOCKS (1<<3)/* uses extended btree blocks */ #define XFS_BTREE_NOERROR 0
@@ -438,6 +457,12 @@ int xfs_btree_delete(struct xfs_btree_cuint xfs_btree_get_rec (struct xfs_btree_cur *,union xfs_btree_rec **,int *);/* +* CRC calculation is also needed for growfs. +*/ +void xfs_btree_lblock_calc_crc (struct xfs_buf *); +void xfs_btree_sblock_calc_crc (struct xfs_buf *); + +/* * Internal btree helpers also used by xfs_bmap.c. */ void xfs_btree_log_block (struct xfs_btree_cur *,struct xfs_buf *,int );
fs/xfs/xfs_bmap_btree.c +20 -2
@@ -77,12 +77,20 @@ xfs_bmdr_to_bmbt(xfs_bmbt_key_t *tkp;__be64 *tpp; - rblock->bb_magic =cpu_to_be32 (XFS_BMAP_MAGIC ); +if (xfs_sb_version_hascrc (&mp->m_sb)) + rblock->bb_magic =cpu_to_be32 (XFS_BMAP_MAGIC ); +else + rblock->bb_magic =cpu_to_be32 (XFS_BMAP_CRC_MAGIC ); rblock->bb_level = dblock->bb_level;ASSERT (be16_to_cpu (rblock->bb_level) >0 ); rblock->bb_numrecs = dblock->bb_numrecs; rblock->bb_u.l.bb_leftsib =cpu_to_be64 (NULLDFSBNO ); rblock->bb_u.l.bb_rightsib =cpu_to_be64 (NULLDFSBNO ); +if (xfs_sb_version_hascrc (&mp->m_sb)) { + rblock->bb_u.l.bb_blkno =cpu_to_be64 (XFS_BUF_DADDR_NULL ); +uuid_copy (&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid); + rblock->bb_u.l.bb_pad =0 ; + } dmxr =xfs_bmdr_maxrecs (mp, dblocklen,0 ); fkp =XFS_BMDR_KEY_ADDR (dblock,1 ); tkp =XFS_BMBT_KEY_ADDR (mp, rblock,1 );
@@ -440,10 +448,18 @@ xfs_bmbt_to_bmdr(xfs_bmbt_key_t *tkp;__be64 *tpp; -ASSERT (be32_to_cpu (rblock->bb_magic) ==XFS_BMAP_MAGIC ); +if (xfs_sb_version_hascrc (&mp->m_sb)) +ASSERT (be32_to_cpu (rblock->bb_magic) ==XFS_BMAP_CRC_MAGIC ); +else +ASSERT (be32_to_cpu (rblock->bb_magic) ==XFS_BMAP_MAGIC );ASSERT (be64_to_cpu (rblock->bb_u.l.bb_leftsib) ==NULLDFSBNO );ASSERT (be64_to_cpu (rblock->bb_u.l.bb_rightsib) ==NULLDFSBNO );ASSERT (be16_to_cpu (rblock->bb_level) >0 ); +if (xfs_sb_version_hascrc (&mp->m_sb)) { +ASSERT (uuid_equal (&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); +ASSERT (rblock->bb_u.l.bb_blkno == +cpu_to_be64 (XFS_BUF_DADDR_NULL )); + } dblock->bb_level = rblock->bb_level; dblock->bb_numrecs = rblock->bb_numrecs; dmxr =xfs_bmdr_maxrecs (mp, dblocklen,0 );
@@ -885,6 +901,8 @@ xfs_bmbt_init_cursor( cur->bc_ops = &xfs_bmbt_ops; cur->bc_flags =XFS_BTREE_LONG_PTRS |XFS_BTREE_ROOT_IN_INODE ; +if (xfs_sb_version_hascrc (&mp->m_sb)) + cur->bc_flags |=XFS_BTREE_CRC_BLOCKS ; cur->bc_private.b.forksize =XFS_IFORK_SIZE (ip, whichfork); cur->bc_private.b.ip = ip;
fs/xfs/xfs_bmap_btree.h +10 -8
@@ -18,7 +18,8 @@#ifndef __XFS_BMAP_BTREE_H__#define __XFS_BMAP_BTREE_H__ -#define XFS_BMAP_MAGIC 0x424d4150/* 'BMAP' */ +#define XFS_BMAP_MAGIC 0x424d4150/* 'BMAP' */ +#define XFS_BMAP_CRC_MAGIC 0x424d4158struct xfs_btree_cur ;struct xfs_btree_block ;
@@ -148,10 +149,11 @@ typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_/* * Btree block header size depends on a superblock flag. -* -* (not quite yet, but soon) */ -#define XFS_BMBT_BLOCK_LEN (mp) XFS_BTREE_LBLOCK_LEN +#define XFS_BMBT_BLOCK_LEN (mp) \ + (xfs_sb_version_hascrc(&((mp)->m_sb)) ? \ + XFS_BTREE_LBLOCK_LEN + XFS_BTREE_CRCBLOCK_ADD : \ + XFS_BTREE_LBLOCK_LEN)#define XFS_BMBT_REC_ADDR (mp, block, index) \ ((xfs_bmbt_rec_t *) \
@@ -198,12 +200,12 @@ typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_#define XFS_BMAP_BROOT_PTR_ADDR (mp, bb, i, sz) \ XFS_BMBT_PTR_ADDR(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, 0)) -#define XFS_BMAP_BROOT_SPACE_CALC (nrecs) \ - (int)(XFS_BTREE_LBLOCK_LEN + \ +#define XFS_BMAP_BROOT_SPACE_CALC (mp, nrecs) \ + (int)(XFS_BMBT_BLOCK_LEN(mp) + \ ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) -#define XFS_BMAP_BROOT_SPACE (bb) \ - (XFS_BMAP_BROOT_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs))) +#define XFS_BMAP_BROOT_SPACE (mp, bb) \ + (XFS_BMAP_BROOT_SPACE_CALC(mp, be16_to_cpu((bb)->bb_numrecs)))#define XFS_BMDR_SPACE_CALC (nrecs) \ (int)(sizeof(xfs_bmdr_block_t) + \ ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
fs/xfs/xfs_btree.c +217 -46
442 lines not on this page · raw message
fs/xfs/xfs_dinode.h +2 -2
@@ -164,8 +164,8 @@ typedef enum xfs_dinode_fmt* Inode size for given fs. */ #define XFS_LITINO (mp) ((mp)->m_litino) -#define XFS_BROOT_SIZE_ADJ \ - (XFS_BTREE_LBLOCK_LEN - sizeof(xfs_bmdr_block_t)) +#define XFS_BROOT_SIZE_ADJ (ip) \ + (XFS_BMBT_BLOCK_LEN((ip)->i_mount) - sizeof(xfs_bmdr_block_t))/* * Inode data & attribute fork sizes, per inode.
fs/xfs/xfs_inode.c +14 -13
@@ -613,6 +613,7 @@ xfs_iformat_btree( xfs_dinode_t *dip, int whichfork) { +struct xfs_mount *mp = ip->i_mount;xfs_bmdr_block_t *dfp;xfs_ifork_t *ifp;/* REFERENCED */
@@ -621,7 +622,7 @@ xfs_iformat_btree( ifp =XFS_IFORK_PTR (ip, whichfork); dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR (dip, whichfork); - size =XFS_BMAP_BROOT_SPACE (dfp); + size =XFS_BMAP_BROOT_SPACE (mp, dfp); nrecs =be16_to_cpu (dfp->bb_numrecs);/*
@@ -633,13 +634,12 @@ xfs_iformat_btree(*/ if (unlikely (XFS_IFORK_NEXTENTS (ip, whichfork) <= ifp->if_ext_max ||XFS_BMDR_SPACE_CALC (nrecs) > -XFS_DFORK_SIZE (dip, ip->i_mount, whichfork) +XFS_DFORK_SIZE (dip, mp, whichfork) ||XFS_IFORK_NEXTENTS (ip, whichfork) > ip->i_d.di_nblocks)) { -xfs_fs_repair_cmn_err (CE_WARN , ip->i_mount, +xfs_fs_repair_cmn_err (CE_WARN , mp,"corrupt inode %Lu (btree)." , (unsigned long long ) ip->i_ino); -XFS_ERROR_REPORT ("xfs_iformat_btree" ,XFS_ERRLEVEL_LOW , - ip->i_mount); +XFS_ERROR_REPORT ("xfs_iformat_btree" ,XFS_ERRLEVEL_LOW , mp);return XFS_ERROR (EFSCORRUPTED ); }
@@ -2330,7 +2330,7 @@ xfs_iroot_realloc(* allocate it now and get out. */ if (ifp->if_broot_bytes ==0 ) { - new_size = (size_t )XFS_BMAP_BROOT_SPACE_CALC (rec_diff); + new_size =XFS_BMAP_BROOT_SPACE_CALC (mp, rec_diff); ifp->if_broot =kmem_alloc (new_size,KM_SLEEP ); ifp->if_broot_bytes = (int )new_size;return ;
@@ -2344,9 +2344,9 @@ xfs_iroot_realloc(*/ cur_max =xfs_bmbt_maxrecs (mp, ifp->if_broot_bytes,0 ); new_max = cur_max + rec_diff; - new_size = (size_t )XFS_BMAP_BROOT_SPACE_CALC (new_max); + new_size = (size_t )XFS_BMAP_BROOT_SPACE_CALC (mp, new_max); ifp->if_broot =kmem_realloc (ifp->if_broot, new_size, - (size_t )XFS_BMAP_BROOT_SPACE_CALC (cur_max),/* old size */ + (size_t )XFS_BMAP_BROOT_SPACE_CALC (mp, cur_max),/* old size */ KM_SLEEP ); op = (char *)XFS_BMAP_BROOT_PTR_ADDR (mp, ifp->if_broot,1 , ifp->if_broot_bytes);
@@ -2354,7 +2354,7 @@ xfs_iroot_realloc( (int)new_size); ifp->if_broot_bytes = (int )new_size;ASSERT (ifp->if_broot_bytes <= -XFS_IFORK_SIZE (ip, whichfork) +XFS_BROOT_SIZE_ADJ ); +XFS_IFORK_SIZE (ip, whichfork) +XFS_BROOT_SIZE_ADJ (ip));memmove (np, op, cur_max * (uint )sizeof (xfs_dfsbno_t));return ; }
@@ -2369,7 +2369,7 @@ xfs_iroot_realloc( new_max = cur_max + rec_diff;ASSERT (new_max >=0 );if (new_max >0 ) - new_size = (size_t )XFS_BMAP_BROOT_SPACE_CALC (new_max); + new_size = (size_t )XFS_BMAP_BROOT_SPACE_CALC (mp, new_max);else new_size =0 ;if (new_size >0 ) {
@@ -2377,7 +2377,8 @@ xfs_iroot_realloc(/* * First copy over the btree block header. */ -memcpy (new_broot, ifp->if_broot,XFS_BTREE_LBLOCK_LEN ); +memcpy (new_broot, ifp->if_broot, +XFS_BMBT_BLOCK_LEN (ip->i_mount)); }else { new_broot =NULL ; ifp->if_flags &= ~XFS_IFBROOT ;
@@ -2407,7 +2408,7 @@ xfs_iroot_realloc( ifp->if_broot = new_broot; ifp->if_broot_bytes = (int )new_size;ASSERT (ifp->if_broot_bytes <= -XFS_IFORK_SIZE (ip, whichfork) +XFS_BROOT_SIZE_ADJ ); +XFS_IFORK_SIZE (ip, whichfork) +XFS_BROOT_SIZE_ADJ (ip));return ; }
@@ -2874,7 +2875,7 @@ xfs_iflush_fork(ASSERT (ifp->if_broot !=NULL );ASSERT (ifp->if_broot_bytes <= (XFS_IFORK_SIZE (ip, whichfork) + -XFS_BROOT_SIZE_ADJ )); +XFS_BROOT_SIZE_ADJ (ip)));xfs_bmbt_to_bmdr (mp, ifp->if_broot, ifp->if_broot_bytes, (xfs_bmdr_block_t *)cp,XFS_DFORK_SIZE (dip, mp, whichfork));
fs/xfs/xfs_attr_leaf.c +1 -1
@@ -172,7 +172,7 @@ xfs_attr_shortform_bytesfit(xfs_inode_telse return dp->i_d.di_forkoff; }else - dsize =XFS_BMAP_BROOT_SPACE (dp->i_df.if_broot); + dsize =XFS_BMAP_BROOT_SPACE (mp, dp->i_df.if_broot);break ; }
fs/xfs/xfs_bmap.c +39 -7
97 lines not on this page · raw message
fs/xfs/xfs_alloc_btree.c +2 -0
@@ -474,6 +474,8 @@ xfs_allocbt_init_cursor( cur->bc_ops = &xfs_allocbt_ops;if (btnum ==XFS_BTNUM_CNT ) cur->bc_flags =XFS_BTREE_LASTREC_UPDATE ; +if (xfs_sb_version_hascrc (&mp->m_sb)) + cur->bc_flags |=XFS_BTREE_CRC_BLOCKS ; cur->bc_private.a.agbp = agbp; cur->bc_private.a.agno = agno;
fs/xfs/xfs_ialloc_btree.c +2 -0
@@ -359,6 +359,8 @@ xfs_inobt_init_cursor( cur->bc_blocklog = mp->m_sb.sb_blocklog; cur->bc_ops = &xfs_inobt_ops; +if (xfs_sb_version_hascrc (&mp->m_sb)) + cur->bc_flags |=XFS_BTREE_CRC_BLOCKS ; cur->bc_private.a.agbp = agbp; cur->bc_private.a.agno = agno;
fs/xfs/xfs_mount.c +6 -0
@@ -567,6 +567,12 @@ xfs_readsb(xfs_mount_t *mp, int flags) STATIC voidxfs_mount_common (xfs_mount_t *mp,xfs_sb_t *sbp) { + +if (xfs_sb_version_hascrc (sbp)) +printk ("XFS: using CRCs\n" ); +else +printk ("XFS: not using CRCs\n" ); + mp->m_agfrotor = mp->m_agirotor =0 ;spin_lock_init (&mp->m_agirotor_lock); mp->m_maxagi = mp->m_sb.sb_agcount;
fs/xfs/xfs_fsops.c +27 -3
@@ -253,11 +253,19 @@ xfs_growfs_data_private( BTOBB(mp->m_sb.sb_blocksize), 0); block =XFS_BUF_TO_BLOCK (bp);memset (block,0 , mp->m_sb.sb_blocksize); - block->bb_magic =cpu_to_be32 (XFS_ABTB_MAGIC ); block->bb_level =0 ; block->bb_numrecs =cpu_to_be16 (1 ); block->bb_u.s.bb_leftsib =cpu_to_be32 (NULLAGBLOCK ); block->bb_u.s.bb_rightsib =cpu_to_be32 (NULLAGBLOCK ); +if (xfs_sb_version_hascrc (&mp->m_sb)) { + block->bb_magic =cpu_to_be32 (XFS_ABTB_CRC_MAGIC ); + block->bb_u.s.bb_blkno =cpu_to_be64 (XFS_BUF_ADDR (bp)); +uuid_copy (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); + block->bb_u.s.bb_pad =0 ; +xfs_buf_set_io_callback (bp, xfs_btree_sblock_calc_crc); + }else { + block->bb_magic =cpu_to_be32 (XFS_ABTB_MAGIC ); + } arec =XFS_ALLOC_REC_ADDR (mp, block,1 ); arec->ar_startblock =cpu_to_be32 (XFS_PREALLOC_BLOCKS (mp)); arec->ar_blockcount = cpu_to_be32(
@@ -274,11 +282,19 @@ xfs_growfs_data_private( BTOBB(mp->m_sb.sb_blocksize), 0); block =XFS_BUF_TO_BLOCK (bp);memset (block,0 , mp->m_sb.sb_blocksize); - block->bb_magic =cpu_to_be32 (XFS_ABTC_MAGIC ); block->bb_level =0 ; block->bb_numrecs =cpu_to_be16 (1 ); block->bb_u.s.bb_leftsib =cpu_to_be32 (NULLAGBLOCK ); block->bb_u.s.bb_rightsib =cpu_to_be32 (NULLAGBLOCK ); +if (xfs_sb_version_hascrc (&mp->m_sb)) { + block->bb_magic =cpu_to_be32 (XFS_ABTC_CRC_MAGIC ); + block->bb_u.s.bb_blkno =cpu_to_be64 (XFS_BUF_ADDR (bp)); +uuid_copy (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); + block->bb_u.s.bb_pad =0 ; +xfs_buf_set_io_callback (bp, xfs_btree_sblock_calc_crc); + }else { + block->bb_magic =cpu_to_be32 (XFS_ABTC_MAGIC ); + } arec =XFS_ALLOC_REC_ADDR (mp, block,1 ); arec->ar_startblock =cpu_to_be32 (XFS_PREALLOC_BLOCKS (mp)); arec->ar_blockcount = cpu_to_be32(
@@ -296,11 +312,19 @@ xfs_growfs_data_private( BTOBB(mp->m_sb.sb_blocksize), 0); block =XFS_BUF_TO_BLOCK (bp);memset (block,0 , mp->m_sb.sb_blocksize); - block->bb_magic =cpu_to_be32 (XFS_IBT_MAGIC ); block->bb_level =0 ; block->bb_numrecs =0 ; block->bb_u.s.bb_leftsib =cpu_to_be32 (NULLAGBLOCK ); block->bb_u.s.bb_rightsib =cpu_to_be32 (NULLAGBLOCK ); +if (xfs_sb_version_hascrc (&mp->m_sb)) { + block->bb_magic =cpu_to_be32 (XFS_IBT_CRC_MAGIC ); + block->bb_u.s.bb_blkno =cpu_to_be64 (XFS_BUF_ADDR (bp)); +uuid_copy (&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid); + block->bb_u.s.bb_pad =0 ; +xfs_buf_set_io_callback (bp, xfs_btree_sblock_calc_crc); + }else { + block->bb_magic =cpu_to_be32 (XFS_IBT_MAGIC ); + } error =xfs_bwrite (mp, bp);if (error) { goto error0;
fs/xfs/xfs_alloc_btree.h +8 -5
@@ -31,8 +31,10 @@ struct xfs_mount;* by blockcount and blockno. All blocks look the same to make the code * simpler; if we have time later, we'll make the optimizations. */ -#define XFS_ABTB_MAGIC 0x41425442/* 'ABTB' for bno tree */ -#define XFS_ABTC_MAGIC 0x41425443/* 'ABTC' for cnt tree */ +#define XFS_ABTB_MAGIC 0x41425442/* 'ABTB' for bno tree */ +#define XFS_ABTB_CRC_MAGIC 0x4142544a +#define XFS_ABTC_MAGIC 0x41425443/* 'ABTC' for cnt tree */ +#define XFS_ABTC_CRC_MAGIC 0x4142544b/* * Data record/key structure
@@ -73,10 +75,11 @@ typedef __be32 xfs_alloc_ptr_t;/* * Btree block header size depends on a superblock flag. -* -* (not quite yet, but soon) */ -#define XFS_ALLOC_BLOCK_LEN (mp) XFS_BTREE_SBLOCK_LEN +#define XFS_ALLOC_BLOCK_LEN (mp) \ + (xfs_sb_version_hascrc(&((mp)->m_sb)) ? \ + XFS_BTREE_SBLOCK_LEN + XFS_BTREE_CRCBLOCK_ADD : \ + XFS_BTREE_SBLOCK_LEN)/* * Record, key, and pointer address macros for btree blocks.
fs/xfs/xfs_ialloc_btree.h +6 -4
@@ -29,7 +29,8 @@ struct xfs_mount;/* * There is a btree for the inode map per allocation group. */ -#define XFS_IBT_MAGIC 0x49414254/* 'IABT' */ +#define XFS_IBT_MAGIC 0x49414254/* 'IABT' */ +#define XFS_IBT_CRC_MAGIC 0x4941425ctypedef __uint64_t xfs_inofree_t ;#define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t))
@@ -91,10 +92,11 @@ typedef __be32 xfs_inobt_ptr_t;/* * Btree block header size depends on a superblock flag. -* -* (not quite yet, but soon) */ -#define XFS_INOBT_BLOCK_LEN (mp) XFS_BTREE_SBLOCK_LEN +#define XFS_INOBT_BLOCK_LEN (mp) \ + (xfs_sb_version_hascrc(&((mp)->m_sb)) ? \ + XFS_BTREE_SBLOCK_LEN + XFS_BTREE_CRCBLOCK_ADD : \ + XFS_BTREE_SBLOCK_LEN)/* * Record, key, and pointer address macros for btree blocks.
fs/xfs/xfs_log_recover.c +14 -0
@@ -31,6 +31,7 @@#include "xfs_bmap_btree.h" #include "xfs_alloc_btree.h" #include "xfs_ialloc_btree.h" +#include "xfs_btree.h" #include "xfs_dir2_sf.h" #include "xfs_attr_sf.h" #include "xfs_dinode.h"
@@ -1931,6 +1932,19 @@ xlog_recover_do_reg_buffer( bit += nbits; } +switch (be32_to_cpu (*(__be32 *)XFS_BUF_PTR (bp))) { +case XFS_ABTB_CRC_MAGIC : +case XFS_ABTC_CRC_MAGIC : +case XFS_IBT_CRC_MAGIC : +xfs_btree_sblock_calc_crc (bp); +break ; +case XFS_BMAP_CRC_MAGIC : +xfs_btree_lblock_calc_crc (bp); +break ; +default : +break ; + } +/* Shouldn't be any more regions */ ASSERT (i == item->ri_total); }
fs/xfs/xfsidbg.c +82 -0
112 lines not on this page · raw message
On Fri, Sep 26, 2008 at 12:56:33AM +0200, Christoph Hellwig wrote:
| Add support for larger btree blocks that contains a CRC32C checksum, a | filesystem uuid and block number for detecting filesystem consistency | and out of place writes. The use of these blocks is triggered by the | crc superblock patches just added. | | Note that we currently do not log the crc of the block, but re-created | it during log recovery. With the pending patch to also checksum the log | this should be safe against filesystem corruption but doesn't really | follow the end to end argument. Also poking into the buffer to find | out whether this is a btree buffer during log recovery is not a very | clean way to implement this. I'll look into how well adding crcs | to the buffer log items for every btree is going to work and hope | I can switch to that variant for the next version.
looks good... will need to put this through the QA wringer.
Signature · 8 lines
Bill O'Donnell SGI [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs