csum.c revision 2bc30417541deffca795db8ec4e7f7ccb616dc3f
1ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos/* 2ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * csum.c --- checksumming of ext3 structures 3ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * 4ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * Copyright (C) 2006 Cluster File Systems, Inc. 5470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o * Copyright (C) 2006, 2007 by Andreas Dilger <adilger@clusterfs.com> 6ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * 7ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * %Begin-Header% 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 9543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 10ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * %End-Header% 11ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos */ 12ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 13d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h" 140eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#if HAVE_SYS_TYPES_H 150eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#include <sys/types.h> 160eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#endif 170eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o 18ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#include "ext2_fs.h" 19ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#include "ext2fs.h" 20ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#include "crc16.h" 21ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#include <assert.h> 22ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 23ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#ifndef offsetof 24ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 25ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#endif 26ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 27ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#ifdef DEBUG 28ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#define STATIC 29ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#else 30ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#define STATIC static 31ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#endif 32ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 3387141781aabb4dc01359428d2feecdc7f43eeac0Theodore Ts'o__u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group) 34ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 352bc30417541deffca795db8ec4e7f7ccb616dc3fAndreas Dilger struct ext2_group_desc *desc = ext2fs_group_desc(fs, fs->group_desc, 362bc30417541deffca795db8ec4e7f7ccb616dc3fAndreas Dilger group); 372bc30417541deffca795db8ec4e7f7ccb616dc3fAndreas Dilger size_t size = EXT2_DESC_SIZE(fs->super); 382bc30417541deffca795db8ec4e7f7ccb616dc3fAndreas Dilger size_t offset; 392bc30417541deffca795db8ec4e7f7ccb616dc3fAndreas Dilger __u16 crc; 40ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 41ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { 42d32c915abfb224f6f6659e9cada7e9f759b7e3d2Theodore Ts'o size_t offset = offsetof(struct ext2_group_desc, bg_checksum); 43ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 44ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#ifdef WORDS_BIGENDIAN 451d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o struct ext4_group_desc swabdesc; 46ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 47ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos /* Have to swab back to little-endian to do the checksum */ 481d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o memcpy(&swabdesc, desc, size); 491d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o ext2fs_swap_group_desc2(fs, 501d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o (struct ext2_group_desc *) &swabdesc); 511d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o desc = (struct ext2_group_desc *) &swabdesc; 52ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 53ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos group = ext2fs_swab32(group); 54ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#endif 55c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o crc = ext2fs_crc16(~0, fs->super->s_uuid, 56c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o sizeof(fs->super->s_uuid)); 57c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o crc = ext2fs_crc16(crc, &group, sizeof(group)); 58c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o crc = ext2fs_crc16(crc, desc, offset); 59ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos offset += sizeof(desc->bg_checksum); /* skip checksum */ 60ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos /* for checksum of struct ext4_group_desc do the rest...*/ 611d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o if (offset < size) { 62c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o crc = ext2fs_crc16(crc, (char *)desc + offset, 631d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o size - offset); 64ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos } 65ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos } 66ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 67ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return crc; 68ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 69ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 70ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santosint ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group) 71ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 724729455f0a68f2fa0a83ec8460d1d4bccba9dcfaTheodore Ts'o if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 734729455f0a68f2fa0a83ec8460d1d4bccba9dcfaTheodore Ts'o EXT4_FEATURE_RO_COMPAT_GDT_CSUM) && 74d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson (ext2fs_bg_checksum(fs, group) != 754729455f0a68f2fa0a83ec8460d1d4bccba9dcfaTheodore Ts'o ext2fs_group_desc_csum(fs, group))) 76ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return 0; 77ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 78ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return 1; 79ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 80ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 81ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santosvoid ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group) 82ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 83d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 84d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) 85d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson return; 86d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson 87d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson /* ext2fs_bg_checksum_set() sets the actual checksum field but 88d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson * does not calculate the checksum itself. */ 89d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_checksum_set(fs, group, ext2fs_group_desc_csum(fs, group)); 90ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 91ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 92ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santosstatic __u32 find_last_inode_ingrp(ext2fs_inode_bitmap bitmap, 93ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos __u32 inodes_per_grp, dgrp_t grp_no) 94ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 95ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos ext2_ino_t i, start_ino, end_ino; 96ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 97ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos start_ino = grp_no * inodes_per_grp + 1; 98ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos end_ino = start_ino + inodes_per_grp - 1; 99ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 100ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos for (i = end_ino; i >= start_ino; i--) { 1018f82ef9860339039b54a324be137fbc09b762358Valerie Aurora Henson if (ext2fs_fast_test_inode_bitmap2(bitmap, i)) 102ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return i - start_ino + 1; 103ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos } 104ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return inodes_per_grp; 105ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 106ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 107ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos/* update the bitmap flags, set the itable high watermark, and calculate 108ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * checksums for the group descriptors */ 109f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilgererrcode_t ext2fs_set_gdt_csum(ext2_filsys fs) 110ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 111ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos struct ext2_super_block *sb = fs->super; 1128895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o int dirty = 0; 113ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos dgrp_t i; 114ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 115f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilger if (!fs->inode_map) 116f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilger return EXT2_ET_NO_INODE_BITMAP; 117f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilger 11816b851cdae98244e117fe91d93b267fcad1102b3Theodore Ts'o if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 11916b851cdae98244e117fe91d93b267fcad1102b3Theodore Ts'o EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) 120f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilger return 0; 121ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 122d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson for (i = 0; i < fs->group_desc_count; i++) { 123d32c915abfb224f6f6659e9cada7e9f759b7e3d2Theodore Ts'o __u32 old_csum = ext2fs_bg_checksum(fs, i); 124d32c915abfb224f6f6659e9cada7e9f759b7e3d2Theodore Ts'o __u32 old_unused = ext2fs_bg_itable_unused(fs, i); 125d32c915abfb224f6f6659e9cada7e9f759b7e3d2Theodore Ts'o __u32 old_flags = ext2fs_bg_flags(fs, i); 126d32c915abfb224f6f6659e9cada7e9f759b7e3d2Theodore Ts'o __u32 old_free_inodes_count = ext2fs_bg_free_inodes_count(fs, i); 127ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 128d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson if (old_free_inodes_count == sb->s_inodes_per_group) { 129d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT); 130d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_itable_unused_set(fs, i, sb->s_inodes_per_group); 13116b851cdae98244e117fe91d93b267fcad1102b3Theodore Ts'o } else { 132d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson int unused = 133d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson sb->s_inodes_per_group - 134ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos find_last_inode_ingrp(fs->inode_map, 135d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson sb->s_inodes_per_group, i); 136d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson 137d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_flags_clear(fs, i, EXT2_BG_INODE_UNINIT); 138d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_itable_unused_set(fs, i, unused); 139ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos } 140ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 141ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos ext2fs_group_desc_csum_set(fs, i); 142d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson if (old_flags != ext2fs_bg_flags(fs, i)) 14380fc4e698a308de22ace6179f45e0bb67befa74bAndreas Dilger dirty = 1; 144d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson if (old_unused != ext2fs_bg_itable_unused(fs, i)) 14580fc4e698a308de22ace6179f45e0bb67befa74bAndreas Dilger dirty = 1; 146d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson if (old_csum != ext2fs_bg_checksum(fs, i)) 147ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos dirty = 1; 148ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos } 149ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos if (dirty) 150ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos ext2fs_mark_super_dirty(fs); 151f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilger return 0; 152ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 153470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 154470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o#ifdef DEBUG 155c816ecb204a32e67788738e050ff2b14a721672bEric Sandeen#include "e2p/e2p.h" 156c816ecb204a32e67788738e050ff2b14a721672bEric Sandeen 157470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'ovoid print_csum(const char *msg, ext2_filsys fs, dgrp_t group) 158470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o{ 159470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o __u16 crc1, crc2, crc3; 160470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o dgrp_t swabgroup; 161f797cf3e37b476aac593fe9a9f4630448d335332Andreas Dilger struct ext2_group_desc *desc; 1621d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o size_t size; 163470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o struct ext2_super_block *sb = fs->super; 1641d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o int offset = offsetof(struct ext2_group_desc, bg_checksum); 165470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o#ifdef WORDS_BIGENDIAN 1661d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o struct ext4_group_desc swabdesc; 1671d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o#endif 168470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 169f797cf3e37b476aac593fe9a9f4630448d335332Andreas Dilger desc = ext2fs_group_desc(fs, fs->group_desc, group); 1702bc30417541deffca795db8ec4e7f7ccb616dc3fAndreas Dilger size = EXT2_DESC_SIZE(fs->super); 1711d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o#ifdef WORDS_BIGENDIAN 172470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o /* Have to swab back to little-endian to do the checksum */ 1731d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o memcpy(&swabdesc, desc, size); 1741d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o ext2fs_swap_group_desc2(fs, (struct ext2_group_desc *) &swabdesc); 1751d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o desc = (struct ext2_group_desc *) &swabdesc; 176470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 177470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o swabgroup = ext2fs_swab32(group); 178470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o#else 179470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o swabgroup = group; 180470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o#endif 181470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 182470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o crc1 = ext2fs_crc16(~0, sb->s_uuid, sizeof(fs->super->s_uuid)); 183470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o crc2 = ext2fs_crc16(crc1, &swabgroup, sizeof(swabgroup)); 1841d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o crc3 = ext2fs_crc16(crc2, desc, offset); 1851d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o offset += sizeof(desc->bg_checksum); /* skip checksum */ 1861d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o /* for checksum of struct ext4_group_desc do the rest...*/ 1871d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o if (offset < size) 1881d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o crc3 = ext2fs_crc16(crc3, (char *)desc + offset, size - offset); 1891d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o 190f797cf3e37b476aac593fe9a9f4630448d335332Andreas Dilger printf("%s UUID %s=%04x, grp %u=%04x: %04x=%04x\n", 191562f264243f4d4385910b6f06872730214977736Theodore Ts'o msg, e2p_uuid2str(sb->s_uuid), crc1, group, crc2, crc3, 192c816ecb204a32e67788738e050ff2b14a721672bEric Sandeen ext2fs_group_desc_csum(fs, group)); 193470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o} 194470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 195470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'ounsigned char sb_uuid[16] = { 0x4f, 0x25, 0xe8, 0xcf, 0xe7, 0x97, 0x48, 0x23, 196470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 0xbe, 0xfa, 0xa7, 0x88, 0x4b, 0xae, 0xec, 0xdb }; 197470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 198470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'oint main(int argc, char **argv) 199470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o{ 200470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o struct ext2_super_block param; 201470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o errcode_t retval; 202470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o ext2_filsys fs; 203470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o int i; 204470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o __u16 csum1, csum2, csum_known = 0xd3a4; 205470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 206470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o memset(¶m, 0, sizeof(param)); 2074efbac6fed75c29d3d5f1b676b932754653a2ac5Valerie Aurora Henson ext2fs_blocks_count_set(¶m, 32768); 208470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 2098f82ef9860339039b54a324be137fbc09b762358Valerie Aurora Henson retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, ¶m, 210470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o test_io_manager, &fs); 211470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (retval) { 212470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o com_err("setup", retval, 213470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o "While initializing filesystem"); 214470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 215470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 216470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o memcpy(fs->super->s_uuid, sb_uuid, 16); 217470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o fs->super->s_feature_ro_compat = EXT4_FEATURE_RO_COMPAT_GDT_CSUM; 218470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 219470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o for (i=0; i < fs->group_desc_count; i++) { 220d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_block_bitmap_loc_set(fs, i, 124); 221d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_inode_bitmap_loc_set(fs, i, 125); 222d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_inode_table_loc_set(fs, i, 126); 223d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_free_blocks_count_set(fs, i, 31119); 224d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_free_inodes_count_set(fs, i, 15701); 225d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_used_dirs_count_set(fs, i, 2); 226e633b58ac75f2f544b7d6572e37d4b63da31e59cEric Sandeen ext2fs_bg_flags_zap(fs, i); 227470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o }; 228470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 229470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o csum1 = ext2fs_group_desc_csum(fs, 0); 230470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csum0000", fs, 0); 231470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 232470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (csum1 != csum_known) { 233470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksum for group 0 should be %04x\n", csum_known); 234470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 235470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 236470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o csum2 = ext2fs_group_desc_csum(fs, 1); 237470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csum0001", fs, 1); 238470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (csum1 == csum2) { 239470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums for different groups shouldn't match\n"); 240470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 241470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 242470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o csum2 = ext2fs_group_desc_csum(fs, 2); 243470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csumffff", fs, 2); 244470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (csum1 == csum2) { 245470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums for different groups shouldn't match\n"); 246470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 247470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 248d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_checksum_set(fs, 0, csum1); 249470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o csum2 = ext2fs_group_desc_csum(fs, 0); 250470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csum_set", fs, 0); 251470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (csum1 != csum2) { 252470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums should not depend on checksum field\n"); 253470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 254470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 255470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (!ext2fs_group_desc_csum_verify(fs, 0)) { 256470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums should verify against gd_checksum\n"); 257470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 258470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 259470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o memset(fs->super->s_uuid, 0x30, sizeof(fs->super->s_uuid)); 260470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("new_uuid", fs, 0); 261470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (ext2fs_group_desc_csum_verify(fs, 0) != 0) { 262470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums for different filesystems shouldn't match\n"); 263470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 264470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 265d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson csum1 = ext2fs_group_desc_csum(fs, 0); 266d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_checksum_set(fs, 0, csum1); 267470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csum_new", fs, 0); 268d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson ext2fs_bg_free_blocks_count_set(fs, 0, 1); 269470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o csum2 = ext2fs_group_desc_csum(fs, 0); 270470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csum_blk", fs, 0); 271470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (csum1 == csum2) { 272470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums for different data shouldn't match\n"); 273470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 274470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 275470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 276470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o return 0; 277470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o} 278470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o#endif 279