]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
metadump: Zero literal area of unused inodes
authorEric Sandeen <sandeen@sandeen.net>
Wed, 29 Jul 2015 23:17:43 +0000 (09:17 +1000)
committerDave Chinner <david@fromorbit.com>
Wed, 29 Jul 2015 23:17:43 +0000 (09:17 +1000)
When metadump copies unused inodes it should zero out
the literal area, which may contain stale on-disk 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

index 8520f66c137518661316b99cc5d11f2543c262f0..a1e023d3615d624ad978c097ca8f8ecb1a058bc8 100644 (file)
@@ -1775,7 +1775,8 @@ static int
 process_inode(
        xfs_agnumber_t          agno,
        xfs_agino_t             agino,
-       xfs_dinode_t            *dip)
+       xfs_dinode_t            *dip,
+       bool                    free_inode)
 {
        int                     success;
        bool                    crc_was_ok = false; /* no recalc by default */
@@ -1784,13 +1785,22 @@ process_inode(
        success = 1;
        cur_ino = XFS_AGINO_TO_INO(mp, agno, agino);
 
-       /* we only care about crc recalculation if we are obfuscating names. */
-       if (obfuscate) {
+       /* we only care about crc recalculation if we will modify the inode. */
+       if (obfuscate || zero_stale_data) {
                crc_was_ok = xfs_verify_cksum((char *)dip,
                                        mp->m_sb.sb_inodesize,
                                        offsetof(struct xfs_dinode, di_crc));
        }
 
+       if (free_inode) {
+               if (zero_stale_data) {
+                       /* Zero all of the inode literal area */
+                       memset(XFS_DFORK_DPTR(dip), 0,
+                              XFS_LITINO(mp, dip->di_version));
+               }
+               goto done;
+       }
+
        /* copy appropriate data fork metadata */
        switch (be16_to_cpu(dip->di_mode) & S_IFMT) {
                case S_IFDIR:
@@ -1832,6 +1842,11 @@ process_inode(
                nametable_clear();
        }
 
+done:
+       /* Heavy handed but low cost; just do it as a catch-all. */
+       if (zero_stale_data)
+               need_new_crc = 1;
+
        if (crc_was_ok && need_new_crc)
                xfs_dinode_calc_crc(mp, dip);
        return success;
@@ -1897,13 +1912,12 @@ copy_inode_chunk(
        for (i = 0; i < XFS_INODES_PER_CHUNK; i++) {
                xfs_dinode_t            *dip;
 
-               if (XFS_INOBT_IS_FREE_DISK(rp, i))
-                       continue;
-
                dip = (xfs_dinode_t *)((char *)iocur_top->data +
                                ((off + i) << mp->m_sb.sb_inodelog));
 
-               if (!process_inode(agno, agino + i, dip))
+               /* process_inode handles free inodes, too */
+               if (!process_inode(agno, agino + i, dip,
+                                  XFS_INOBT_IS_FREE_DISK(rp, i)))
                        goto pop_out;
        }
 skip_processing: