From owner-svn-src-head@freebsd.org Sun May 13 19:29:36 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5847AFCE230; Sun, 13 May 2018 19:29:36 +0000 (UTC) (envelope-from fsu@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id EF43C70AE3; Sun, 13 May 2018 19:29:35 +0000 (UTC) (envelope-from fsu@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id D126D11B28; Sun, 13 May 2018 19:29:35 +0000 (UTC) (envelope-from fsu@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w4DJTZuo072482; Sun, 13 May 2018 19:29:35 GMT (envelope-from fsu@FreeBSD.org) Received: (from fsu@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w4DJTZtZ072481; Sun, 13 May 2018 19:29:35 GMT (envelope-from fsu@FreeBSD.org) Message-Id: <201805131929.w4DJTZtZ072481@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: fsu set sender to fsu@FreeBSD.org using -f From: Fedor Uporov Date: Sun, 13 May 2018 19:29:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333585 - head/sys/fs/ext2fs X-SVN-Group: head X-SVN-Commit-Author: fsu X-SVN-Commit-Paths: head/sys/fs/ext2fs X-SVN-Commit-Revision: 333585 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 May 2018 19:29:36 -0000 Author: fsu Date: Sun May 13 19:29:35 2018 New Revision: 333585 URL: https://svnweb.freebsd.org/changeset/base/333585 Log: Fix on-disk inode checksum calculation logic. Reviewed by: pfg MFC after: 3 months Differential Revision: https://reviews.freebsd.org/D15395 Modified: head/sys/fs/ext2fs/ext2_csum.c head/sys/fs/ext2fs/ext2_inode_cnv.c Modified: head/sys/fs/ext2fs/ext2_csum.c ============================================================================== --- head/sys/fs/ext2fs/ext2_csum.c Sun May 13 19:19:10 2018 (r333584) +++ head/sys/fs/ext2fs/ext2_csum.c Sun May 13 19:29:35 2018 (r333585) @@ -535,29 +535,42 @@ static uint32_t ext2_ei_csum(struct inode *ip, struct ext2fs_dinode *ei) { struct m_ext2fs *fs; - uint16_t old_hi; - uint32_t inum, gen, crc; + uint32_t inode_csum_seed, inum, gen, crc; + uint16_t dummy_csum = 0; + unsigned int offset, csum_size; fs = ip->i_e2fs; - - ei->e2di_chksum_lo = 0; - if ((EXT2_INODE_SIZE(ip->i_e2fs) > E2FS_REV0_INODE_SIZE && - ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) { - old_hi = ei->e2di_chksum_hi; - ei->e2di_chksum_hi = 0; - } - + offset = offsetof(struct ext2fs_dinode, e2di_chksum_lo); + csum_size = sizeof(dummy_csum); inum = ip->i_number; gen = ip->i_gen; + crc = calculate_crc32c(fs->e2fs_csum_seed, + (uint8_t *)&inum, sizeof(inum)); + inode_csum_seed = calculate_crc32c(crc, + (uint8_t *)&gen, sizeof(gen)); - crc = calculate_crc32c(fs->e2fs_csum_seed, (uint8_t *)&inum, sizeof(inum)); - crc = calculate_crc32c(crc, (uint8_t *)&gen, sizeof(gen)); - crc = calculate_crc32c(crc, (uint8_t *)ei, fs->e2fs->e2fs_inode_size); + crc = calculate_crc32c(inode_csum_seed, (uint8_t *)ei, offset); + crc = calculate_crc32c(crc, (uint8_t *)&dummy_csum, csum_size); + offset += csum_size; + crc = calculate_crc32c(crc, (uint8_t *)ei + offset, + E2FS_REV0_INODE_SIZE - offset); - if ((EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE && - ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) - ei->e2di_chksum_hi = old_hi; + if (EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE) { + offset = offsetof(struct ext2fs_dinode, e2di_chksum_hi); + crc = calculate_crc32c(crc, (uint8_t *)ei + + E2FS_REV0_INODE_SIZE, offset - E2FS_REV0_INODE_SIZE); + if ((EXT2_INODE_SIZE(ip->i_e2fs) > E2FS_REV0_INODE_SIZE && + ei->e2di_extra_isize >= EXT2_INODE_CSUM_HI_EXTRA_END)) { + crc = calculate_crc32c(crc, (uint8_t *)&dummy_csum, + csum_size); + offset += csum_size; + } + + crc = calculate_crc32c(crc, (uint8_t *)ei + offset, + EXT2_INODE_SIZE(fs) - offset); + } + return (crc); } @@ -573,10 +586,6 @@ ext2_ei_csum_verify(struct inode *ip, struct ext2fs_di if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) return (0); - /* Check case, when dinode was not initialized */ - if (!memcmp(ei, &ei_zero, sizeof(struct ext2fs_dinode))) - return (0); - provided = ei->e2di_chksum_lo; calculated = ext2_ei_csum(ip, ei); @@ -587,8 +596,17 @@ ext2_ei_csum_verify(struct inode *ip, struct ext2fs_di } else calculated &= 0xFFFF; - if (provided != calculated) + if (provided != calculated) { + /* + * If it is first time used dinode, + * it is expected that it will be zeroed + * and we will not return checksum error in this case. + */ + if (!memcmp(ei, &ei_zero, sizeof(struct ext2fs_dinode))) + return (0); + return (EIO); + } return (0); } Modified: head/sys/fs/ext2fs/ext2_inode_cnv.c ============================================================================== --- head/sys/fs/ext2fs/ext2_inode_cnv.c Sun May 13 19:19:10 2018 (r333584) +++ head/sys/fs/ext2fs/ext2_inode_cnv.c Sun May 13 19:29:35 2018 (r333585) @@ -92,10 +92,7 @@ ext2_print_inode(struct inode *in) int ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) { - struct m_ext2fs *fs; - const static struct ext2fs_dinode ei_zero; - fs = ip->i_e2fs; ip->i_nlink = ei->e2di_nlink; /* * Godmar thinks - if the link count is zero, then the inode is @@ -139,11 +136,7 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) memcpy(ip->i_data, ei->e2di_blocks, sizeof(ei->e2di_blocks)); - if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM) && - memcmp(ei, &ei_zero, EXT2_INODE_SIZE(fs))) - return (ext2_ei_csum_verify(ip, ei)); - - return (0); + return (ext2_ei_csum_verify(ip, ei)); } /*