void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp) { struct ext4_group_desc *gdp4 = (struct ext4_group_desc *)gdp; /* Do the 32-bit parts first */ gdp->bg_block_bitmap = ext2fs_swab32(gdp->bg_block_bitmap); gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap); gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table); gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count); gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count); gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count); gdp->bg_flags = ext2fs_swab16(gdp->bg_flags); gdp->bg_exclude_bitmap_lo = ext2fs_swab32(gdp->bg_exclude_bitmap_lo); gdp->bg_block_bitmap_csum_lo = ext2fs_swab16(gdp->bg_block_bitmap_csum_lo); gdp->bg_inode_bitmap_csum_lo = ext2fs_swab16(gdp->bg_inode_bitmap_csum_lo); gdp->bg_itable_unused = ext2fs_swab16(gdp->bg_itable_unused); gdp->bg_checksum = ext2fs_swab16(gdp->bg_checksum); /* If we're 32-bit, we're done */ if (fs == NULL || EXT2_DESC_SIZE(fs->super) < EXT2_MIN_DESC_SIZE_64BIT) return; /* Swap the 64-bit parts */ gdp4->bg_block_bitmap_hi = ext2fs_swab32(gdp4->bg_block_bitmap_hi); gdp4->bg_inode_bitmap_hi = ext2fs_swab32(gdp4->bg_inode_bitmap_hi); gdp4->bg_inode_table_hi = ext2fs_swab32(gdp4->bg_inode_table_hi); gdp4->bg_free_blocks_count_hi = ext2fs_swab16(gdp4->bg_free_blocks_count_hi); gdp4->bg_free_inodes_count_hi = ext2fs_swab16(gdp4->bg_free_inodes_count_hi); gdp4->bg_used_dirs_count_hi = ext2fs_swab16(gdp4->bg_used_dirs_count_hi); gdp4->bg_itable_unused_hi = ext2fs_swab16(gdp4->bg_itable_unused_hi); gdp4->bg_exclude_bitmap_hi = ext2fs_swab16(gdp4->bg_exclude_bitmap_hi); gdp4->bg_block_bitmap_csum_hi = ext2fs_swab16(gdp4->bg_block_bitmap_csum_hi); gdp4->bg_inode_bitmap_csum_hi = ext2fs_swab16(gdp4->bg_inode_bitmap_csum_hi); }
// Return a pointer to the first block group descriptor in a filesystem. Real // ext2 filesystems will have several of these, but, for simplicity, we will // assume there is only one. struct ext2_group_desc * get_block_group(void * fs, __u32 block_group_num) { return fs + SUPERBLOCK_OFFSET + SUPERBLOCK_SIZE + block_group_num * EXT2_DESC_SIZE(get_super_block(fs)); }
/* * This routine sanity checks the group descriptors */ errcode_t ext2fs_check_desc(ext2_filsys fs) { ext2fs_block_bitmap bmap; errcode_t retval; dgrp_t i; blk64_t first_block = fs->super->s_first_data_block; blk64_t last_block = ext2fs_blocks_count(fs->super)-1; blk64_t blk, b; unsigned int j; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); if (EXT2_DESC_SIZE(fs->super) & (EXT2_DESC_SIZE(fs->super) - 1)) return EXT2_ET_BAD_DESC_SIZE; retval = ext2fs_allocate_subcluster_bitmap(fs, "check_desc map", &bmap); if (retval) return retval; for (i = 0; i < fs->group_desc_count; i++) ext2fs_reserve_super_and_bgd(fs, i, bmap); for (i = 0; i < fs->group_desc_count; i++) { if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { first_block = ext2fs_group_first_block2(fs, i); last_block = ext2fs_group_last_block2(fs, i); } /* * Check to make sure the block bitmap for group is sane */ blk = ext2fs_block_bitmap_loc(fs, i); if (blk < first_block || blk > last_block || ext2fs_test_block_bitmap2(bmap, blk)) { retval = EXT2_ET_GDESC_BAD_BLOCK_MAP; goto errout; } ext2fs_mark_block_bitmap2(bmap, blk); /* * Check to make sure the inode bitmap for group is sane */ blk = ext2fs_inode_bitmap_loc(fs, i); if (blk < first_block || blk > last_block || ext2fs_test_block_bitmap2(bmap, blk)) { retval = EXT2_ET_GDESC_BAD_INODE_MAP; goto errout; } ext2fs_mark_block_bitmap2(bmap, blk); /* * Check to make sure the inode table for group is sane */ blk = ext2fs_inode_table_loc(fs, i); if (blk < first_block || ((blk + fs->inode_blocks_per_group - 1) > last_block)) { retval = EXT2_ET_GDESC_BAD_INODE_TABLE; goto errout; } for (j = 0, b = blk; j < fs->inode_blocks_per_group; j++, b++) { if (ext2fs_test_block_bitmap2(bmap, b)) { retval = EXT2_ET_GDESC_BAD_INODE_TABLE; goto errout; } ext2fs_mark_block_bitmap2(bmap, b); } } errout: ext2fs_free_block_bitmap(bmap); return retval; }