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 130eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#if HAVE_SYS_TYPES_H 140eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#include <sys/types.h> 150eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#endif 160eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o 17ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#include "ext2_fs.h" 18ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#include "ext2fs.h" 19ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#include "crc16.h" 20ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#include <assert.h> 21ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 22ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#ifndef offsetof 23ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 24ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#endif 25ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 26ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#ifdef DEBUG 27ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#define STATIC 28ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#else 29ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#define STATIC static 30ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#endif 31ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 32e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall__u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group) 33ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 34e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct ext2_group_desc *desc = ext2fs_group_desc(fs, fs->group_desc, 35e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall group); 36e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall size_t size = EXT2_DESC_SIZE(fs->super); 37e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall size_t offset; 38e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall __u16 crc; 39ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 40ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { 41e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall size_t offset = offsetof(struct ext2_group_desc, bg_checksum); 42ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 43ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#ifdef WORDS_BIGENDIAN 44e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct ext4_group_desc swabdesc; 45e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall size_t save_size = size; 46e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall const size_t ext4_bg_size = sizeof(struct ext4_group_desc); 47e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct ext2_group_desc *save_desc = desc; 48ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 49ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos /* Have to swab back to little-endian to do the checksum */ 50e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (size > ext4_bg_size) 51e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall size = ext4_bg_size; 52e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall memcpy(&swabdesc, desc, size); 53e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_swap_group_desc2(fs, 54e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall (struct ext2_group_desc *) &swabdesc); 55e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall desc = (struct ext2_group_desc *) &swabdesc; 56ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 57ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos group = ext2fs_swab32(group); 58ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#endif 59c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o crc = ext2fs_crc16(~0, fs->super->s_uuid, 60c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o sizeof(fs->super->s_uuid)); 61c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o crc = ext2fs_crc16(crc, &group, sizeof(group)); 62c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o crc = ext2fs_crc16(crc, desc, offset); 63ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos offset += sizeof(desc->bg_checksum); /* skip checksum */ 64ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos /* for checksum of struct ext4_group_desc do the rest...*/ 65e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (offset < size) { 66c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o crc = ext2fs_crc16(crc, (char *)desc + offset, 67e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall size - offset); 68ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos } 69e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef WORDS_BIGENDIAN 70e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall /* 71e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * If the size of the bg descriptor is greater than 64 72e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * bytes, which is the size of the traditional ext4 bg 73e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * descriptor, checksum the rest of the descriptor here 74e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall */ 75e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (save_size > ext4_bg_size) 76e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall crc = ext2fs_crc16(crc, 77e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall (char *)save_desc + ext4_bg_size, 78e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall save_size - ext4_bg_size); 79e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 80ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos } 81ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 82ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return crc; 83ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 84ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 85ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santosint ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group) 86ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 874729455f0a68f2fa0a83ec8460d1d4bccba9dcfaTheodore Ts'o if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 884729455f0a68f2fa0a83ec8460d1d4bccba9dcfaTheodore Ts'o EXT4_FEATURE_RO_COMPAT_GDT_CSUM) && 89e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall (ext2fs_bg_checksum(fs, group) != 904729455f0a68f2fa0a83ec8460d1d4bccba9dcfaTheodore Ts'o ext2fs_group_desc_csum(fs, group))) 91ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return 0; 92ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 93ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return 1; 94ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 95ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 96ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santosvoid ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group) 97ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 98e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 99e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) 100e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return; 101e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 102e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall /* ext2fs_bg_checksum_set() sets the actual checksum field but 103e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * does not calculate the checksum itself. */ 104e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_checksum_set(fs, group, ext2fs_group_desc_csum(fs, group)); 105ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 106ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 107ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santosstatic __u32 find_last_inode_ingrp(ext2fs_inode_bitmap bitmap, 108ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos __u32 inodes_per_grp, dgrp_t grp_no) 109ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 110ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos ext2_ino_t i, start_ino, end_ino; 111ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 112ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos start_ino = grp_no * inodes_per_grp + 1; 113ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos end_ino = start_ino + inodes_per_grp - 1; 114ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 115ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos for (i = end_ino; i >= start_ino; i--) { 116e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ext2fs_fast_test_inode_bitmap2(bitmap, i)) 117ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return i - start_ino + 1; 118ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos } 119ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return inodes_per_grp; 120ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 121ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 122ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos/* update the bitmap flags, set the itable high watermark, and calculate 123ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * checksums for the group descriptors */ 124f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilgererrcode_t ext2fs_set_gdt_csum(ext2_filsys fs) 125ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 126ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos struct ext2_super_block *sb = fs->super; 1278895f43a60269464f654e9d87c28768875cd703aTheodore Ts'o int dirty = 0; 128ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos dgrp_t i; 129ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 130f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilger if (!fs->inode_map) 131f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilger return EXT2_ET_NO_INODE_BITMAP; 132f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilger 13316b851cdae98244e117fe91d93b267fcad1102b3Theodore Ts'o if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 13416b851cdae98244e117fe91d93b267fcad1102b3Theodore Ts'o EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) 135f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilger return 0; 136ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 137e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall for (i = 0; i < fs->group_desc_count; i++) { 138e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall __u32 old_csum = ext2fs_bg_checksum(fs, i); 139e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall __u32 old_unused = ext2fs_bg_itable_unused(fs, i); 140e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall __u32 old_flags = ext2fs_bg_flags(fs, i); 141e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall __u32 old_free_inodes_count = ext2fs_bg_free_inodes_count(fs, i); 142ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 143e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (old_free_inodes_count == sb->s_inodes_per_group) { 144e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT); 145e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_itable_unused_set(fs, i, sb->s_inodes_per_group); 14616b851cdae98244e117fe91d93b267fcad1102b3Theodore Ts'o } else { 147e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int unused = 148e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall sb->s_inodes_per_group - 149ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos find_last_inode_ingrp(fs->inode_map, 150e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall sb->s_inodes_per_group, i); 151e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 152e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_flags_clear(fs, i, EXT2_BG_INODE_UNINIT); 153e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_itable_unused_set(fs, i, unused); 154ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos } 155ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 156ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos ext2fs_group_desc_csum_set(fs, i); 157e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (old_flags != ext2fs_bg_flags(fs, i)) 15880fc4e698a308de22ace6179f45e0bb67befa74bAndreas Dilger dirty = 1; 159e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (old_unused != ext2fs_bg_itable_unused(fs, i)) 16080fc4e698a308de22ace6179f45e0bb67befa74bAndreas Dilger dirty = 1; 161e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (old_csum != ext2fs_bg_checksum(fs, i)) 162ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos dirty = 1; 163ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos } 164ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos if (dirty) 165ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos ext2fs_mark_super_dirty(fs); 166f628acea2671dda839fc086f1017718e41e34ecaAndreas Dilger return 0; 167ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 168470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 169470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o#ifdef DEBUG 170c816ecb204a32e67788738e050ff2b14a721672bEric Sandeen#include "e2p/e2p.h" 171c816ecb204a32e67788738e050ff2b14a721672bEric Sandeen 172470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'ovoid print_csum(const char *msg, ext2_filsys fs, dgrp_t group) 173470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o{ 174470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o __u16 crc1, crc2, crc3; 175470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o dgrp_t swabgroup; 176e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct ext2_group_desc *desc = ext2fs_group_desc(fs, fs->group_desc, 177e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall group); 178e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall size_t size = EXT2_DESC_SIZE(fs->super); 179470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o struct ext2_super_block *sb = fs->super; 180e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int offset = offsetof(struct ext2_group_desc, bg_checksum); 1811d18a55c528adf997d8edee60bd8003c822c55e8Theodore Ts'o#ifdef WORDS_BIGENDIAN 182e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct ext4_group_desc swabdesc; 183e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct ext2_group_desc *save_desc = desc; 184e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall const size_t ext4_bg_size = sizeof(struct ext4_group_desc); 185e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall size_t save_size = size; 186e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 18765f0aab98b20b5994a726ab90d355248bcddfffdJP Abgrall 188e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef WORDS_BIGENDIAN 189470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o /* Have to swab back to little-endian to do the checksum */ 190e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (size > ext4_bg_size) 191e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall size = ext4_bg_size; 192e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall memcpy(&swabdesc, desc, size); 193e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_swap_group_desc2(fs, (struct ext2_group_desc *) &swabdesc); 194e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall desc = (struct ext2_group_desc *) &swabdesc; 195470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 196470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o swabgroup = ext2fs_swab32(group); 197470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o#else 198470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o swabgroup = group; 199470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o#endif 200470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 201470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o crc1 = ext2fs_crc16(~0, sb->s_uuid, sizeof(fs->super->s_uuid)); 202470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o crc2 = ext2fs_crc16(crc1, &swabgroup, sizeof(swabgroup)); 203e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall crc3 = ext2fs_crc16(crc2, desc, offset); 204e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall offset += sizeof(desc->bg_checksum); /* skip checksum */ 205e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall /* for checksum of struct ext4_group_desc do the rest...*/ 206e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (offset < size) 207e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall crc3 = ext2fs_crc16(crc3, (char *)desc + offset, size - offset); 208e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef WORDS_BIGENDIAN 209e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (save_size > ext4_bg_size) 210e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall crc3 = ext2fs_crc16(crc3, (char *)save_desc + ext4_bg_size, 211e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall save_size - ext4_bg_size); 212e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 213e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 214e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall printf("%s UUID %s=%04x, grp %u=%04x: %04x=%04x\n", 215e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall msg, e2p_uuid2str(sb->s_uuid), crc1, group, crc2, crc3, 216c816ecb204a32e67788738e050ff2b14a721672bEric Sandeen ext2fs_group_desc_csum(fs, group)); 217470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o} 218470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 219470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'ounsigned char sb_uuid[16] = { 0x4f, 0x25, 0xe8, 0xcf, 0xe7, 0x97, 0x48, 0x23, 220470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 0xbe, 0xfa, 0xa7, 0x88, 0x4b, 0xae, 0xec, 0xdb }; 221470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 222470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'oint main(int argc, char **argv) 223470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o{ 224470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o struct ext2_super_block param; 225470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o errcode_t retval; 226470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o ext2_filsys fs; 227470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o int i; 228470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o __u16 csum1, csum2, csum_known = 0xd3a4; 229470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 230470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o memset(¶m, 0, sizeof(param)); 231e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_blocks_count_set(¶m, 32768); 232e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#if 0 233e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_64BIT; 234e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall param.s_desc_size = 128; 235e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall csum_known = 0x5b6e; 236e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 237470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 238e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, ¶m, 239470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o test_io_manager, &fs); 240470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (retval) { 241470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o com_err("setup", retval, 242470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o "While initializing filesystem"); 243470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 244470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 245470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o memcpy(fs->super->s_uuid, sb_uuid, 16); 246470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o fs->super->s_feature_ro_compat = EXT4_FEATURE_RO_COMPAT_GDT_CSUM; 247470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 248470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o for (i=0; i < fs->group_desc_count; i++) { 249e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_block_bitmap_loc_set(fs, i, 124); 250e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_inode_bitmap_loc_set(fs, i, 125); 251e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_inode_table_loc_set(fs, i, 126); 252e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_free_blocks_count_set(fs, i, 31119); 253e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_free_inodes_count_set(fs, i, 15701); 254e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_used_dirs_count_set(fs, i, 2); 255e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_flags_zap(fs, i); 256470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o }; 257470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 258470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o csum1 = ext2fs_group_desc_csum(fs, 0); 259470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csum0000", fs, 0); 260470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 261470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (csum1 != csum_known) { 262470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksum for group 0 should be %04x\n", csum_known); 263470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 264470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 265470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o csum2 = ext2fs_group_desc_csum(fs, 1); 266470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csum0001", fs, 1); 267470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (csum1 == csum2) { 268470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums for different groups shouldn't match\n"); 269470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 270470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 271470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o csum2 = ext2fs_group_desc_csum(fs, 2); 272470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csumffff", fs, 2); 273470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (csum1 == csum2) { 274470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums for different groups shouldn't match\n"); 275470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 276470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 277e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_checksum_set(fs, 0, csum1); 278470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o csum2 = ext2fs_group_desc_csum(fs, 0); 279470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csum_set", fs, 0); 280470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (csum1 != csum2) { 281470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums should not depend on checksum field\n"); 282470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 283470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 284470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (!ext2fs_group_desc_csum_verify(fs, 0)) { 285470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums should verify against gd_checksum\n"); 286470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 287470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 288470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o memset(fs->super->s_uuid, 0x30, sizeof(fs->super->s_uuid)); 289470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("new_uuid", fs, 0); 290470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (ext2fs_group_desc_csum_verify(fs, 0) != 0) { 291470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums for different filesystems shouldn't match\n"); 292470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 293470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 294e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall csum1 = ext2fs_group_desc_csum(fs, 0); 295e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_checksum_set(fs, 0, csum1); 296470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csum_new", fs, 0); 297e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_bg_free_blocks_count_set(fs, 0, 1); 298470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o csum2 = ext2fs_group_desc_csum(fs, 0); 299470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o print_csum("csum_blk", fs, 0); 300470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o if (csum1 == csum2) { 301470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o printf("checksums for different data shouldn't match\n"); 302470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o exit(1); 303470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o } 304470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o 305470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o return 0; 306470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o} 307470e737a872918afd9067de1ce92d571d5671d40Theodore Ts'o#endif 308