diff options
Diffstat (limited to 'sbin/fsck_ffs/inode.c')
-rw-r--r-- | sbin/fsck_ffs/inode.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c index a914be8b87a5..6957a41f70c0 100644 --- a/sbin/fsck_ffs/inode.c +++ b/sbin/fsck_ffs/inode.c @@ -286,6 +286,7 @@ union dinode * ginode(ino_t inumber) { ufs2_daddr_t iblk; + union dinode *dp; if (inumber < UFS_ROOTINO || inumber > maxino) errx(EEXIT, "bad inode number %ju to ginode", @@ -301,7 +302,17 @@ ginode(ino_t inumber) if (sblock.fs_magic == FS_UFS1_MAGIC) return ((union dinode *) &pbp->b_un.b_dinode1[inumber % INOPB(&sblock)]); - return ((union dinode *)&pbp->b_un.b_dinode2[inumber % INOPB(&sblock)]); + dp = (union dinode *)&pbp->b_un.b_dinode2[inumber % INOPB(&sblock)]; + if (ffs_verify_dinode_ckhash(&sblock, (struct ufs2_dinode *)dp) != 0) { + pwarn("INODE CHECK-HASH FAILED"); + prtinode(inumber, dp); + if (preen || reply("FIX") != 0) { + if (preen) + printf(" (FIXED)\n"); + inodirty(dp); + } + } + return (dp); } /* @@ -347,6 +358,21 @@ getnextinode(ino_t inumber, int rebuildcg) nextinop += sizeof(struct ufs1_dinode); else nextinop += sizeof(struct ufs2_dinode); + if ((ckhashadd & CK_INODE) != 0) { + ffs_update_dinode_ckhash(&sblock, (struct ufs2_dinode *)dp); + dirty(&inobuf); + } + if (ffs_verify_dinode_ckhash(&sblock, (struct ufs2_dinode *)dp) != 0) { + pwarn("INODE CHECK-HASH FAILED"); + prtinode(inumber, dp); + if (preen || reply("FIX") != 0) { + if (preen) + printf(" (FIXED)\n"); + ffs_update_dinode_ckhash(&sblock, + (struct ufs2_dinode *)dp); + dirty(&inobuf); + } + } if (rebuildcg && (char *)dp == inobuf.b_un.b_buf) { /* * Try to determine if we have reached the end of the @@ -522,6 +548,8 @@ void inodirty(union dinode *dp) { + if (sblock.fs_magic == FS_UFS2_MAGIC) + ffs_update_dinode_ckhash(&sblock, (struct ufs2_dinode *)dp); dirty(pbp); } |