]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
db: verify and calculate inode CRCs
authorDave Chinner <dchinner@redhat.com>
Wed, 13 Nov 2013 06:40:47 +0000 (06:40 +0000)
committerRich Johnston <rjohnston@sgi.com>
Wed, 13 Nov 2013 17:14:02 +0000 (11:14 -0600)
When we set the current IO cursor to point at an inode, verify that
the inode CRC is intact. And prior to writing such an IO cursor,
calculate the inode CRC.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Rich Johnston <rjohnston@sgi.com>
db/inode.c
db/io.c
db/io.h
include/libxfs.h
libxfs/xfs_inode_buf.c

index ec533ee5f40f7d9a06b07a43da8403ee9ff66449..4090855a839d80e366a5933414b395dc5a23aaaf 100644 (file)
@@ -655,6 +655,8 @@ set_cur_inode(
                blkbb, DB_RING_IGN, NULL);
        off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize);
        dip = iocur_top->data;
+       iocur_top->ino_crc_ok = libxfs_dinode_verify(mp, ino, dip);
+       iocur_top->ino_buf = 1;
        iocur_top->ino = ino;
        iocur_top->mode = be16_to_cpu(dip->di_mode);
        if ((iocur_top->mode & S_IFMT) == S_IFDIR)
diff --git a/db/io.c b/db/io.c
index 2d1cc5676e8c22b4b6036cd3b4fc50e9df701587..6e3282e507d24d5a85ac3afc80273ed490308547 100644 (file)
--- a/db/io.c
+++ b/db/io.c
@@ -464,6 +464,9 @@ write_cur(void)
                return;
        }
 
+       if (iocur_top->ino_buf)
+               libxfs_dinode_calc_crc(mp, iocur_top->data);
+
        if (iocur_top->bbmap)
                write_cur_bbs();
        else
@@ -536,6 +539,7 @@ set_cur(
        iocur_top->ino = ino;
        iocur_top->dirino = dirino;
        iocur_top->mode = mode;
+       iocur_top->ino_buf = 0;
 
        /* store location in ring */
        if (ring_flag)
diff --git a/db/io.h b/db/io.h
index d647284aba91fb0edc0897591c8843fbe8027df7..1f8270dcfda549950074808f4e35a0bcee7484dc 100644 (file)
--- a/db/io.h
+++ b/db/io.h
@@ -38,6 +38,8 @@ typedef struct iocur {
        const struct typ        *typ;   /* type of "data" */
        bbmap_t                 *bbmap; /* map daddr if fragmented */
        struct xfs_buf          *bp;    /* underlying buffer */
+       int                     ino_crc_ok:1;
+       int                     ino_buf:1;
 } iocur_t;
 
 #define DB_RING_ADD 1                   /* add to ring on set_cur */
@@ -62,5 +64,7 @@ extern void     ring_add(void);
 static inline bool
 iocur_crc_valid()
 {
-       return (iocur_top->bp && iocur_top->bp->b_error != EFSCORRUPTED);
+       return (iocur_top->bp &&
+               iocur_top->bp->b_error != EFSCORRUPTED &&
+               (!iocur_top->ino_buf || iocur_top->ino_crc_ok));
 }
index b097bd29db826a223b2e0335d557d9b5b48978e3..cbb5757dfd6a996d295e1f3e04a9301d2c9309a0 100644 (file)
@@ -748,6 +748,10 @@ void       xfs_dinode_from_disk(struct xfs_icdinode *,
 #define libxfs_idata_realloc           xfs_idata_realloc
 #define libxfs_idestroy_fork           xfs_idestroy_fork
 
+#define libxfs_dinode_verify           xfs_dinode_verify
+bool xfs_dinode_verify(struct xfs_mount *mp, xfs_ino_t ino,
+                      struct xfs_dinode *dip);
+
 /* xfs_sb.h */
 #define libxfs_mod_sb                  xfs_mod_sb
 #define libxfs_sb_from_disk            xfs_sb_from_disk
index 97d2329b3fbd0876649fa16f80b09f47bf19447a..d245d728ae84d5b92dbba4ca2cda256c9148c573 100644 (file)
@@ -276,10 +276,10 @@ xfs_dinode_to_disk(
        }
 }
 
-static bool
+bool
 xfs_dinode_verify(
        struct xfs_mount        *mp,
-       struct xfs_inode        *ip,
+       xfs_ino_t               ino,
        struct xfs_dinode       *dip)
 {
        if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
@@ -294,7 +294,7 @@ xfs_dinode_verify(
        if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
                              offsetof(struct xfs_dinode, di_crc)))
                return false;
-       if (be64_to_cpu(dip->di_ino) != ip->i_ino)
+       if (be64_to_cpu(dip->di_ino) != ino)
                return false;
        if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_uuid))
                return false;
@@ -346,7 +346,7 @@ xfs_iread(
                return error;
 
        /* even unallocated inodes are verified */
-       if (!xfs_dinode_verify(mp, ip, dip)) {
+       if (!xfs_dinode_verify(mp, ip->i_ino, dip)) {
                xfs_alert(mp, "%s: validation failed for inode %lld failed",
                                __func__, ip->i_ino);