]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
libext2fs: Byte-swap 64-bit block group descriptors
authorTheodore Ts'o <tytso@mit.edu>
Mon, 26 Oct 2009 01:46:01 +0000 (21:46 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 26 Oct 2009 01:46:01 +0000 (21:46 -0400)
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
lib/ext2fs/closefs.c
lib/ext2fs/csum.c
lib/ext2fs/ext2fs.h
lib/ext2fs/openfs.c
lib/ext2fs/swapfs.c

index 8b2e0966f4e21a5d4fc342b2043d893f24f6efbf..4781c3482afe8c2ebd5a28bc44ef355d88ae92b7 100644 (file)
@@ -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;
index f02d676c31679dd40d99e988f95f08589fb0d5bb..60bdc117be32be5cd5da4293f95c06b7a65778bb 100644 (file)
@@ -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);
index 2112a681026610424b554db033c5e89690ddf399..213a81908d918c8e9566f5613863e056154844f6 100644 (file)
@@ -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);
index 52f56c05a8a3edc42b3b106c0f0c675681817d51..7b325a1c23c44c511c2b6218c354f5f639738d9c 100644 (file)
@@ -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;
        }
index 42bc01e915151bd27ad021d6d2528b40738ff38c..849f547917705f3079f53d168052f3b97f34339d 100644 (file)
@@ -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)
 {