From: Theodore Ts'o Date: Mon, 26 Oct 2009 01:46:01 +0000 (-0400) Subject: libext2fs: Byte-swap 64-bit block group descriptors X-Git-Tag: v1.42-WIP-0702~126 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cf828f1a72ec1eb0c1e819307137879447c909b7;p=thirdparty%2Fe2fsprogs.git libext2fs: Byte-swap 64-bit block group descriptors Signed-off-by: "Theodore Ts'o" --- diff --git a/lib/ext2fs/closefs.c b/lib/ext2fs/closefs.c index 8b2e0966f..4781c3482 100644 --- a/lib/ext2fs/closefs.c +++ b/lib/ext2fs/closefs.c @@ -270,7 +270,7 @@ errcode_t ext2fs_flush(ext2_filsys fs) struct ext2_super_block *super_shadow = 0; struct ext2_group_desc *group_shadow = 0; #ifdef WORDS_BIGENDIAN - struct ext2_group_desc *s, *t; + ext2_group_desc *gdp; dgrp_t j; #endif char *group_ptr; @@ -293,14 +293,13 @@ errcode_t ext2fs_flush(ext2_filsys fs) &group_shadow); if (retval) goto errout; - memset(group_shadow, 0, (size_t) fs->blocksize * + memcpy(group_shadow, fs->group_desc, (size_t) fs->blocksize * fs->desc_blocks); /* swap the group descriptors */ - for (j=0, s=fs->group_desc, t=group_shadow; - j < fs->group_desc_count; j++, t++, s++) { - *t = *s; - ext2fs_swap_group_desc(t); + for (j=0; j < fs->group_desc_count; j++) { + gdp = ext2fs_group_desc(fs, group_shadow, j); + ext2fs_swap_group_desc2(fs, gdp); } #else super_shadow = fs->super; diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c index f02d676c3..60bdc117b 100644 --- a/lib/ext2fs/csum.c +++ b/lib/ext2fs/csum.c @@ -43,7 +43,7 @@ STATIC __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group) struct ext2_group_desc swabdesc = *desc; /* Have to swab back to little-endian to do the checksum */ - ext2fs_swap_group_desc(&swabdesc); + ext2fs_swap_group_desc2(fs, &swabdesc); desc = &swabdesc; group = ext2fs_swab32(group); @@ -152,14 +152,14 @@ void print_csum(const char *msg, ext2_filsys fs, dgrp_t group) { __u16 crc1, crc2, crc3; dgrp_t swabgroup; - struct ext2_group_desc *desc = &fs->group_desc[group]; + struct ext2_group_desc *desc = ext2fs_group_desc(fs, fs->group_desc, group); struct ext2_super_block *sb = fs->super; #ifdef WORDS_BIGENDIAN struct ext2_group_desc swabdesc = fs->group_desc[group]; /* Have to swab back to little-endian to do the checksum */ - ext2fs_swap_group_desc(&swabdesc); + ext2fs_swap_group_desc2(fs, fs->group_desc, &swabdesc); desc = &swabdesc; swabgroup = ext2fs_swab32(group); diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 2112a6810..213a81908 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -1272,6 +1272,7 @@ extern void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry, struct ext2_ext_attr_entry *from_entry); extern void ext2fs_swap_super(struct ext2_super_block * super); extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp); +extern void ext2fs_swap_group_desc2(ext2_filsys, struct ext2_group_desc *gdp); extern void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t, struct ext2_inode_large *f, int hostorder, int bufsize); diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c index 52f56c05a..7b325a1c2 100644 --- a/lib/ext2fs/openfs.c +++ b/lib/ext2fs/openfs.c @@ -322,7 +322,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, #ifdef WORDS_BIGENDIAN gdp = (struct ext2_group_desc *) dest; for (j=0; j < groups_per_block*first_meta_bg; j++) - ext2fs_swap_group_desc(gdp++); + ext2fs_swap_group_desc2(fs, gdp++); #endif dest += fs->blocksize*first_meta_bg; } @@ -332,9 +332,11 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, if (retval) goto cleanup; #ifdef WORDS_BIGENDIAN - gdp = (struct ext2_group_desc *) dest; - for (j=0; j < groups_per_block; j++) - ext2fs_swap_group_desc(gdp++); + for (j=0; j < groups_per_block; j++) { + /* The below happens to work... be careful. */ + gdp = ext2fs_group_desc(fs, blk, j); + ext2fs_swap_group_desc2(fs, gdp); + } #endif dest += fs->blocksize; } diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c index 42bc01e91..849f54791 100644 --- a/lib/ext2fs/swapfs.c +++ b/lib/ext2fs/swapfs.c @@ -78,8 +78,9 @@ void ext2fs_swap_super(struct ext2_super_block * sb) } -void ext2fs_swap_group_desc(struct ext2_group_desc *gdp) +void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_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); @@ -89,8 +90,30 @@ void ext2fs_swap_group_desc(struct ext2_group_desc *gdp) gdp->bg_flags = ext2fs_swab16(gdp->bg_flags); 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 && (!fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT)) + return; + + /* Swap the 64-bit parts */ + struct ext4_group_desc *gdp4 = (struct ext4_group_desc *) gdp; + 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); +} + +void ext2fs_swap_group_desc(struct ext2_group_desc *gdp) +{ + return ext2fs_swap_group_desc2(0, gdp); } + void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header, struct ext2_ext_attr_header *from_header) {