Whamcloud - gitweb
Fix endian problems in the htree code for e2fsck and debugfs.
authorTheodore Ts'o <tytso@mit.edu>
Thu, 3 Oct 2002 02:07:17 +0000 (22:07 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 3 Oct 2002 02:07:17 +0000 (22:07 -0400)
When byte-swapping a filesystem on a PPC architecture, byte-swap
the bitmaps since the historical big-endian ext2 variant had
byte-swapped bitmaps, and the ext2fs library assumes this.  Otherwise
the regression test suite will fail...

debugfs/ChangeLog
debugfs/htree.c
e2fsck/ChangeLog
e2fsck/pass2.c
e2fsck/swapfs.c
lib/ext2fs/ChangeLog
lib/ext2fs/rw_bitmaps.c
lib/ext2fs/swapfs.c

index 6f17d31..a038554 100644 (file)
@@ -1,3 +1,8 @@
+2002-10-02  Theodore Y. Ts'o  <tytso@mit.edu>
+
+       * htree.c (htree_dump_leaf_node): Use ext2fs_read_dir_block2 so
+               that the directory entries are appropriately byte-swapped.
+
 2001-09-24  Theodore Tso  <tytso@mit.edu>
 
        * Release of E2fsprogs 1.29
index c719e4e..9ae2f11 100644 (file)
@@ -49,7 +49,7 @@ static void htree_dump_leaf_node(ext2_filsys fs, ext2_ino_t ino,
                return;
        }
 
-       errcode = io_channel_read_blk(current_fs->io, pblk, 1, buf);
+       errcode = ext2fs_read_dir_block2(current_fs, pblk, buf, 0);
        if (errcode) {
                com_err("htree_dump_leaf_node", errcode,
                        "while  reading block %d\n", blk);
index 8feceff..3f19a40 100644 (file)
@@ -1,3 +1,14 @@
+2002-10-02  Theodore Y. Ts'o  <tytso@mit.edu>
+       
+       * pass2.c (parse_int_node, check_dir_block): Add byte-swap
+               functions around the htree code, so that it works on
+               big-endian machines.
+
+       * swapfs.c (swap_filesys): For PPC machines, byte-swap the bitmap,
+               since PPC big-endian filesystems were historically wierd.
+               This is just for the regression test, since no one
+               actually uses them anymore...
+
 2002-09-30  Theodore Ts'o  <tytso@mit.edu>
 
        * problem.c, problem.h (PR_2_HTREE_BAD_LIMIT,
index b08223c..1555f5a 100644 (file)
@@ -543,20 +543,22 @@ static void parse_int_node(ext2_filsys fs,
        limit = (struct ext2_dx_countlimit *) ent;
 
 #ifdef DX_DEBUG
-       printf("Number of entries (count): %d\n", limit->count);
-       printf("Number of entries (limit): %d\n", limit->limit);
+       printf("Number of entries (count): %d\n", 
+              ext2fs_le16_to_cpu(limit->count));
+       printf("Number of entries (limit): %d\n", 
+              ext2fs_le16_to_cpu(limit->limit));
 #endif
 
-       count = limit->count;
+       count = ext2fs_le16_to_cpu(limit->count);
        expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
                sizeof(struct ext2_dx_entry);
-       if (limit->limit != expect_limit) {
-               cd->pctx.num = limit->limit;
+       if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
+               cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
                if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
                        goto clear_and_exit;
        }
-       if (limit->count > expect_limit) {
-               cd->pctx.num = limit->count;
+       if (count > expect_limit) {
+               cd->pctx.num = count;
                if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
                        goto clear_and_exit;
                count = expect_limit;
@@ -564,12 +566,12 @@ static void parse_int_node(ext2_filsys fs,
        
        for (i=0; i < count; i++) {
                prev_hash = hash;
-               hash = i ? (ent[i].hash & ~1) : 0;
+               hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
 #ifdef DX_DEBUG
                printf("Entry #%d: Hash 0x%08x, block %d\n", i,
-                      hash, ent[i].block);
+                      hash, ext2fs_le32_to_cpu(ent[i].block));
 #endif
-               blk = ent[i].block & 0x0ffffff;
+               blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
                /* Check to make sure the block is valid */
                if (blk > dx_dir->numblocks) {
                        cd->pctx.blk = blk;
@@ -592,8 +594,9 @@ static void parse_int_node(ext2_filsys fs,
                if (hash > max_hash)
                        max_hash = hash;
                dx_db->node_min_hash = hash;
-               if ((i+1) < limit->count)
-                       dx_db->node_max_hash = (ent[i+1].hash & ~1);
+               if ((i+1) < count)
+                       dx_db->node_max_hash = 
+                         ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
                else {
                        dx_db->node_max_hash = 0xfffffffe;
                        dx_db->flags |= DX_FLAG_LAST;
@@ -782,8 +785,9 @@ static int check_dir_block(ext2_filsys fs,
                } else if ((dirent->inode == 0) &&
                           (dirent->rec_len == fs->blocksize) &&
                           (dirent->name_len == 0) &&
-                          (limit->limit == ((fs->blocksize-8) /
-                                            sizeof(struct ext2_dx_entry))))
+                          (ext2fs_le16_to_cpu(limit->limit) == 
+                           ((fs->blocksize-8) / 
+                            sizeof(struct ext2_dx_entry))))
                        dx_db->type = DX_DIRBLOCK_NODE;
        }
 #endif /* ENABLE_HTREE */
index 513859b..b59079c 100644 (file)
@@ -183,6 +183,31 @@ static void swap_inodes(e2fsck_t ctx)
        e2fsck_use_inode_shortcuts(ctx, 0);
 }
 
+#if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
+/*
+ * On the PowerPC, the big-endian variant of the ext2 filesystem
+ * has its bitmaps stored as 32-bit words with bit 0 as the LSB
+ * of each word.  Thus a bitmap with only bit 0 set would be, as
+ * a string of bytes, 00 00 00 01 00 ...
+ * To cope with this, we byte-reverse each word of a bitmap if
+ * we have a big-endian filesystem, that is, if we are *not*
+ * byte-swapping other word-sized numbers.
+ */
+#define EXT2_BIG_ENDIAN_BITMAPS
+#endif
+
+#ifdef EXT2_BIG_ENDIAN_BITMAPS
+static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
+{
+       __u32 *p = (__u32 *) bmap->bitmap;
+       int n, nbytes = (bmap->end - bmap->start + 7) / 8;
+               
+       for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
+               *p = ext2fs_swab32(*p);
+}
+#endif
+
+
 void swap_filesys(e2fsck_t ctx)
 {
        ext2_filsys fs = ctx->fs;
@@ -222,6 +247,13 @@ void swap_filesys(e2fsck_t ctx)
                fs->flags |= EXT2_FLAG_SWAP_BYTES;
        fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
                       EXT2_FLAG_SWAP_BYTES_WRITE);
+
+#ifdef EXT2_BIG_ENDIAN_BITMAPS
+       e2fsck_read_bitmaps(ctx);
+       ext2fs_swap_bitmap(fs->inode_map);
+       ext2fs_swap_bitmap(fs->block_map);
+       fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
+#endif
        ext2fs_flush(fs);
        
 #ifdef RESOURCE_TRACK
index b70364c..320643f 100644 (file)
@@ -1,3 +1,13 @@
+2002-10-02  Theodore Y. Ts'o  <tytso@mit.edu>
+
+       * rw_bitmaps.c (ext2fs_write_block_bitmap,
+               ext2fs_read_block_bitmap): Don't set the CHANGED bit just
+               because the bitmap is getting written to disk.  Make
+               ext2fs_swap_bitmap be a static function, since it's not
+               intended to be exported.
+
+       * swapfs.c (ext2fs_swap_super): Byte-swap the hash seed
+
 2001-09-24  Theodore Tso  <tytso@mit.edu>
 
        * Release of E2fsprogs 1.29
index 89557db..4d47da4 100644 (file)
@@ -41,7 +41,7 @@
 #endif
 
 #ifdef EXT2_BIG_ENDIAN_BITMAPS
-void ext2fs_swap_bitmap(ext2_filsys fs, char *bitmap, int nbytes)
+static void ext2fs_swap_bitmap(ext2_filsys fs, char *bitmap, int nbytes)
 {
        __u32 *p = (__u32 *) bitmap;
        int n;
@@ -88,7 +88,6 @@ errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs)
                }
                inode_bitmap += nbytes;
        }
-       fs->flags |= EXT2_FLAG_CHANGED;
        fs->flags &= ~EXT2_FLAG_IB_DIRTY;
        ext2fs_free_mem((void **) &bitmap_block);
        return 0;
@@ -141,7 +140,6 @@ errcode_t ext2fs_write_block_bitmap (ext2_filsys fs)
                }
                block_bitmap += nbytes;
        }
-       fs->flags |= EXT2_FLAG_CHANGED;
        fs->flags &= ~EXT2_FLAG_BB_DIRTY;
        ext2fs_free_mem((void **) &bitmap_block);
        return 0;
index f50a795..14165cb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * swapfs.c --- swap ext2 filesystem data structures
  * 
- * Copyright (C) 1995, 1996 Theodore Ts'o.
+ * Copyright (C) 1995, 1996, 2002 Theodore Ts'o.
  *
  * %Begin-Header%
  * This file may be redistributed under the terms of the GNU Public
@@ -21,6 +21,7 @@
 #ifdef EXT2FS_ENABLE_SWAPFS
 void ext2fs_swap_super(struct ext2_super_block * sb)
 {
+       int i;
        sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count);
        sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count);
        sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count);
@@ -56,6 +57,8 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
        sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
        sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
        sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
+       for (i=0; i < 4; i++)
+               sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
 }
 
 void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)