]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
metadump: Zero unused portions of inode, BMAP, and allocation btree blocks
authorEric Sandeen <sandeen@sandeen.net>
Wed, 29 Jul 2015 23:21:08 +0000 (09:21 +1000)
committerDave Chinner <david@fromorbit.com>
Wed, 29 Jul 2015 23:21:08 +0000 (09:21 +1000)
Zero out the unused regions of these btree blocks, as
they may contain stale data.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
db/metadump.c
db/type.c
db/type.h

index d2935810733b1e775d9e3868c101a0d561a459da..238f86407a278f728e35cf234a213f1fe3c62153 100644 (file)
@@ -245,6 +245,124 @@ write_buf(
        return seenint() ? -EINTR : 0;
 }
 
+static void
+zero_btree_node(
+       struct xfs_btree_block  *block,
+       typnm_t                 btype)
+{
+       int                     nrecs;
+       xfs_bmbt_ptr_t          *bpp;
+       xfs_bmbt_key_t          *bkp;
+       xfs_inobt_ptr_t         *ipp;
+       xfs_inobt_key_t         *ikp;
+       xfs_alloc_ptr_t         *app;
+       xfs_alloc_key_t         *akp;
+       void                    *zp1, *zp2;
+       int                     zlen1, zlen2;
+
+       nrecs = be16_to_cpu(block->bb_numrecs);
+
+       switch (btype) {
+       case TYP_BMAPBTA:
+       case TYP_BMAPBTD:
+               bkp = XFS_BMBT_KEY_ADDR(mp, block, 1);
+               bpp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
+               zp1 = &bkp[nrecs];
+               zlen1 = (char *)&bpp[0] - (char *)&bkp[nrecs];
+               zp2 = &bpp[nrecs];
+               zlen2 = (char *)block + mp->m_sb.sb_blocksize -
+                                                       (char *)&bpp[nrecs];
+               break;
+       case TYP_INOBT:
+       case TYP_FINOBT:
+               ikp = XFS_INOBT_KEY_ADDR(mp, block, 1);
+               ipp = XFS_INOBT_PTR_ADDR(mp, block, 1, mp->m_inobt_mxr[1]);
+               zp1 = &ikp[nrecs];
+               zlen1 = (char *)&ipp[0] - (char *)&ikp[nrecs];
+               zp2 = &ipp[nrecs];
+               zlen2 = (char *)block + mp->m_sb.sb_blocksize -
+                                                       (char *)&ipp[nrecs];
+               break;
+       case TYP_BNOBT:
+       case TYP_CNTBT:
+               akp = XFS_ALLOC_KEY_ADDR(mp, block, 1);
+               app = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]);
+               zp1 = &akp[nrecs];
+               zlen1 = (char *)&app[0] - (char *)&akp[nrecs];
+               zp2 = &app[nrecs];
+               zlen2 = (char *)block + mp->m_sb.sb_blocksize -
+                                                       (char *)&app[nrecs];
+               break;
+       default:
+               zp1 = NULL;
+               break;
+       }
+
+       if (zp1 && zp2) {
+               /* Zero from end of keys to beginning of pointers */
+               memset(zp1, 0, zlen1);
+               /* Zero from end of pointers to end of block */
+               memset(zp2, 0, zlen2);
+       }
+}
+
+static void
+zero_btree_leaf(
+       struct xfs_btree_block  *block,
+       typnm_t                 btype)
+{
+       int                     nrecs;
+       struct xfs_bmbt_rec     *brp;
+       struct xfs_inobt_rec    *irp;
+       struct xfs_alloc_rec    *arp;
+       void                    *zp;
+       int                     zlen;
+
+       nrecs = be16_to_cpu(block->bb_numrecs);
+
+       switch (btype) {
+       case TYP_BMAPBTA:
+       case TYP_BMAPBTD:
+               brp = XFS_BMBT_REC_ADDR(mp, block, 1);
+               zp = &brp[nrecs];
+               zlen = (char *)block + mp->m_sb.sb_blocksize - (char *)&brp[nrecs];
+               break;
+       case TYP_INOBT:
+       case TYP_FINOBT:
+               irp = XFS_INOBT_REC_ADDR(mp, block, 1);
+               zp = &irp[nrecs];
+               zlen = (char *)block + mp->m_sb.sb_blocksize - (char *)&irp[nrecs];
+               break;
+       case TYP_BNOBT:
+       case TYP_CNTBT:
+               arp = XFS_ALLOC_REC_ADDR(mp, block, 1);
+               zp = &arp[nrecs];
+               zlen = (char *)block + mp->m_sb.sb_blocksize - (char *)&arp[nrecs];
+               break;
+       default:
+               zp = NULL;
+               break;
+       }
+
+       /* Zero from end of records to end of block */
+       if (zp && zlen < mp->m_sb.sb_blocksize)
+               memset(zp, 0, zlen);
+}
+
+static void
+zero_btree_block(
+       struct xfs_btree_block  *block,
+       typnm_t                 btype)
+{
+       int                     level;
+
+       level = be16_to_cpu(block->bb_level);
+
+       if (level > 0)
+               zero_btree_node(block, btype);
+       else
+               zero_btree_leaf(block, btype);
+}
 
 static int
 scan_btree(
@@ -271,6 +389,12 @@ scan_btree(
                rval = !stop_on_read_error;
                goto pop_out;
        }
+
+       if (zero_stale_data) {
+               zero_btree_block(iocur_top->data, btype);
+               iocur_top->need_crc = 1;
+       }
+
        if (write_buf(iocur_top))
                goto pop_out;
 
index b29f2a47a5907ebf42246129b64e9b338a264ec1..0aa3137f5f891d1e15e6796eac2467eb79f6a798 100644 (file)
--- a/db/type.c
+++ b/db/type.c
@@ -70,6 +70,7 @@ static const typ_t    __typtab[] = {
        { TYP_SB, "sb", handle_struct, sb_hfld, NULL },
        { TYP_SYMLINK, "symlink", handle_string, NULL, NULL },
        { TYP_TEXT, "text", handle_text, NULL, NULL },
+       { TYP_FINOBT, "finobt", handle_struct, inobt_hfld, NULL },
        { TYP_NONE, NULL }
 };
 
@@ -104,6 +105,8 @@ static const typ_t  __typtab_crc[] = {
        { TYP_SYMLINK, "symlink", handle_struct, symlink_crc_hfld,
                &xfs_symlink_buf_ops },
        { TYP_TEXT, "text", handle_text, NULL, NULL },
+       { TYP_FINOBT, "finobt", handle_struct, inobt_crc_hfld,
+               &xfs_inobt_buf_ops },
        { TYP_NONE, NULL }
 };
 
index 3bb26f1744160ee2a38d3b28538666600c099aee..e8d8df718ac9de868d78ded13d5087d3fa8987c6 100644 (file)
--- a/db/type.h
+++ b/db/type.h
@@ -27,7 +27,7 @@ typedef enum typnm
        TYP_BMAPBTD, TYP_BNOBT, TYP_CNTBT, TYP_DATA,
        TYP_DIR2, TYP_DQBLK, TYP_INOBT, TYP_INODATA, TYP_INODE,
        TYP_LOG, TYP_RTBITMAP, TYP_RTSUMMARY, TYP_SB, TYP_SYMLINK,
-       TYP_TEXT, TYP_NONE
+       TYP_TEXT, TYP_FINOBT, TYP_NONE
 } typnm_t;
 
 #define DB_WRITE 1