tags 285257 + patch
thanks

The following patch was found in the fedora version of ext2resize, and
claim to fix all endian issues with the package.  When it is inserted
instead of the 01_fix-endianess patch in debian version 1.1.19-3 of
ext2resize, it should solve this bug.  Can anyone test and verify that
it solves the problem?

I also found this comment and patch in fedora:

  * Wed Dec 22 2004 Stephen C. Tweedie <[EMAIL PROTECTED]>
  - Disable offline resize for now: resize2fs is incompatible with
    online resize, and can result in corrupt filesystems.

--- e2fsprogs-1.35/ext2resize-1.1.17/src/ext2online.c.=K0003=.orig
+++ e2fsprogs-1.35/ext2resize-1.1.17/src/ext2online.c
@@ -506,9 +506,9 @@ static blk_t ext2_online_primary(struct
         */
        if (ext2_ioctl(fs, EXT2_IOC_GROUP_EXTEND, &size))
                fs->flags |= FL_IOCTL;
-       else if (errno != ENOTTY)
+       else
                return 0;


Perhaps something we should do as well, and tell users to use
resize2fs for offline resizing?

#! /bin/sh /usr/share/dpatch/dpatch-run
## 01_endianess-fixes-fedora.dpatch
#
## DP: fix byte order issues.  This should solve bug 285257.
## DP: This patch was fetched from the fedora e2fsprogs package version
## DP: 1.37 release: 4

--- ext2resize-1.1.17/configure.in.=K0000=.orig
+++ ext2resize-1.1.17/configure.in
@@ -26,6 +26,7 @@ AC_CHECK_TYPE(__u16, u_int16_t)
 AC_CHECK_TYPE(__s32, int32_t)
 AC_CHECK_TYPE(__u32, u_int32_t)
 AC_CHECK_TYPE(loff_t, unsigned)
+AC_C_BIGENDIAN
 
 dnl Checks for library functions.
 AC_CHECK_FUNCS(open64)
--- ext2resize-1.1.17/src/Makefile.am.=K0000=.orig
+++ ext2resize-1.1.17/src/Makefile.am
@@ -6,8 +6,9 @@ sbin_PROGRAMS = ext2resize ext2prepare e
 
 noinst_LIBRARIES = libext2resize.a
 
-libext2resize_a_SOURCES = ext2.c ext2_block_relocator.c ext2_buffer.c llseek.c \
-	ext2_inode_relocator.c ext2_meta.c ext2_resize.c ext2_unix_io.c tune.c
+libext2resize_a_SOURCES = ext2.c ext2_block_relocator.c ext2_buffer.c llseek.c\
+	ext2_inode_relocator.c ext2_meta.c ext2_resize.c ext2_unix_io.c tune.c\
+	swapfs.c
 
 #libext2resize_a_SOURCES += ext2_journal.c ext2_mkfs.c
 
--- ext2resize-1.1.17/src/ext2.c.=K0000=.orig
+++ ext2resize-1.1.17/src/ext2.c
@@ -1,6 +1,7 @@
 /*
     ext2.c -- generic ext2 stuff
     Copyright (C) 1998, 1999, 2000 Lennert Buytenhek <[EMAIL PROTECTED]>
+    Portions copyright (C) Red Hat, Inc., 2004
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -15,6 +16,8 @@
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    Byte-ordering fixes: Stephen C. Tweedie <[EMAIL PROTECTED]>
 */
 
 static const char _ext2_c[] = "$Id: ext2.c,v 1.28 2004/04/19 14:48:59 sct Exp $";
@@ -254,6 +257,9 @@ void ext2_read_inode(struct ext2_fs *fs,
 	bh = ext2_bread(fs, blk);
 	memcpy(inode, bh->data + off, sizeof(struct ext2_inode));
 	ext2_brelse(bh, 0);
+#ifdef WORDS_BIGENDIAN
+	ext2fs_swap_inode(fs, inode, inode, 0);
+#endif
 }
 
 void ext2_set_inode_state(struct ext2_fs *fs, ino_t ino, int state,
@@ -771,10 +777,10 @@ int ext2_ioctl(struct ext2_fs *fs, int i
 	int ret = 1;
 
 	if (fs->flags & FL_DEBUG) {
-		if (ioc == EXT2_IOC_GROUP_EXTEND)
+		if (ioc == (int) EXT2_IOC_GROUP_EXTEND)
 			printf("%s: EXTEND group to %u blocks\n",
 			       __FUNCTION__, *(__u32 *)arg);
-		else if (ioc == EXT2_IOC_GROUP_ADD)
+		else if (ioc == (int) EXT2_IOC_GROUP_ADD)
 			printf("%s: ADD group %u\n", 
 			       __FUNCTION__, *(__u32 *)arg);
 		else
@@ -890,6 +896,12 @@ struct ext2_fs *ext2_open(struct ext2_de
 	handle->ops->set_blocksize(handle->cookie, 10);
 
 	ext2_read_blocks(fs, &fs->sb, 1, 1);
+	/* This will not work with "alien" byte-ordering (ie. bigendian
+	 * on-disk), only ext2-standard little-endian on disk.  We
+	 * should deal OK with bigendian hosts, though. */
+#ifdef WORDS_BIGENDIAN
+	ext2fs_swap_super(&fs->sb);
+#endif
 	if (fs->sb.s_magic != EXT2_SUPER_MAGIC) {
 		fprintf(stderr, "%s: ext2_open: invalid superblock\n",fs->prog);
 		goto error_free_fs;
@@ -1012,6 +1024,14 @@ struct ext2_fs *ext2_open(struct ext2_de
 		goto error_free_bcache;
 	}
 	ext2_read_blocks(fs, fs->gd, fs->sb.s_first_data_block+1, fs->gdblocks);
+#ifdef WORDS_BIGENDIAN
+	{
+		int i;
+		
+		for (i=0; i<fs->numgroups; i++)
+			ext2fs_swap_group_desc(&fs->gd[i]);
+	}
+#endif
 
 	if (!ext2_determine_itoffset(fs))
 		goto error_free_gd;
--- ext2resize-1.1.17/src/ext2.h.=K0000=.orig
+++ ext2resize-1.1.17/src/ext2.h
@@ -38,7 +38,7 @@ static const char _ext2_h[] = "$Id: ext2
 #define min(a,b)	(((a)<(b))?(a):(b))
 #endif
 
-#if __BYTE_ORDER__ == __BIG_ENDIAN
+#ifdef WORDS_BIGENDIAN
 #define le16_to_cpu(a)	((((a) & 0x00ffU) << 8) | (((a) & 0xff00) >> 8))
 #define le32_to_cpu(a)	((((a) & 0x000000ffU) << 24)|(((a) & 0x0000ff00U) << 8)\
 			|(((a) & 0xff000000U) >> 24)|(((a) & 0x00ff0000U) >> 8))
@@ -237,6 +237,13 @@ struct ext2_fs *ext2_mkfs(struct ext2_de
 /* resize */
 int ext2_resize_fs(struct ext2_fs *fs);
 
+/* fs byte-swap */
+void ext2fs_swap_super(struct ext2_super_block * sb);
+void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
+void ext2fs_swap_inode(struct ext2_fs *fs,
+		       struct ext2_inode *t, struct ext2_inode *f, 
+		       int hostorder);
+
 /* unix I/O */
 loff_t ext2_llseek(unsigned int fd, loff_t offset, unsigned int whence);
 struct ext2_dev_handle *ext2_make_dev_handle_from_file(char *dev, char *dir,
--- ext2resize-1.1.17/src/ext2_fs.h.=K0000=.orig
+++ ext2resize-1.1.17/src/ext2_fs.h
@@ -459,8 +459,15 @@ struct ext2_super_block {
 	__u32	s_journal_inum;		/* inode number of journal file */
 	__u32	s_journal_dev;		/* device number of journal file */
 	__u32	s_last_orphan;		/* start of list of inodes to delete */
-
-	__u32	s_reserved[197];	/* Padding to the end of the block */
+	__u32	s_hash_seed[4];		/* HTREE hash seed */
+	__u8	s_def_hash_version;	/* Default hash version to use */
+	__u8	s_jnl_backup_type; 	/* Default type of journal backup */
+	__u16	s_reserved_word_pad;
+	__u32	s_default_mount_opts;
+	__u32	s_first_meta_bg;	/* First metablock group */
+	__u32	s_mkfs_time;		/* When the filesystem was created */
+	__u32	s_jnl_blocks[17]; 	/* Backup of the journal inode */
+	__u32	s_reserved[172];	/* Padding to the end of the block */
 };
 
 /*
--- ext2resize-1.1.17/src/ext2online.c.=K0000=.orig
+++ ext2resize-1.1.17/src/ext2online.c
@@ -235,10 +235,12 @@ static int ext2_check_one_rsv(struct ext
 		unsigned int three = 1, five = 5, seven = 7;
 		unsigned int group;
 		int last = 0;
-
-		if (dindir_buf[gdb_num % apb] != pri_blk) {
+		blk_t dblk;
+		
+		dblk = le32_to_cpu(dindir_buf[gdb_num % apb]);
+		if (dblk != pri_blk) {
 			fprintf(stderr, "found %d not %d at %d[%d]\n",
-				dindir_buf[gdb_num % apb], pri_blk,
+				dblk, pri_blk,
 				fs->resize.i_block[EXT2_DIND_BLOCK],
 				gdb_num % apb);
 			ret = 0;
@@ -250,16 +252,17 @@ static int ext2_check_one_rsv(struct ext
 		while ((group = ext2_list_backups(fs, &three, &five, &seven)) <
 		       fs->numgroups) {
 			__u32 *pri_buf = (__u32 *)(pri_bh->data);
-			blk_t bku_blk;
+			blk_t bku_blk, pblk;
 
 			bku_blk = pri_blk + group * fs->sb.s_blocks_per_group;
 
 			if (fs->flags & FL_DEBUG)
 				printf("checking for group block %d in Bond\n",
 				       bku_blk);
-			if (pri_buf[last] != bku_blk) {
+			pblk = le32_to_cpu(pri_buf[last]);
+			if (pblk != bku_blk) {
 				fprintf(stderr, "found %d not %d at %d[%d]\n",
-					pri_buf[last], bku_blk, pri_blk, last);
+					pblk, bku_blk, pri_blk, last);
 				ext2_brelse(pri_bh, 0);
 				ret = 0;
 				goto exit_dind;
@@ -337,7 +340,9 @@ static blk_t ext2_make_group(struct ext2
 	}
 	gdp = (struct ext2_group_desc *)bh->data +
 	      (group % (fs->blocksize/sizeof(struct ext2_group_desc)));
-
+#ifdef WORDS_BIGENDIAN
+	ext2fs_swap_group_desc(gdp);
+#endif
 	gdp->bg_block_bitmap = start + new_bb;
 	gdp->bg_inode_bitmap = start + new_ib;
 	gdp->bg_inode_table  = start + fs->itoffset;
--- /dev/null
+++ ext2resize-1.1.17/src/swapfs.c
@@ -0,0 +1,177 @@
+/*
+ * swapfs.c --- swap ext2 filesystem data structures
+ * 
+ * Copyright (C) 1995, 1996, 2002 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ *
+ * Taken from e2fsprogs for ext2online by Stephen Tweedie <[EMAIL PROTECTED]>
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "config.h"
+#include "ext2.h"
+#include "ext2_fs.h"
+
+#define LINUX_S_IFMT	00170000
+#define LINUX_S_IFLNK	00120000
+#define LINUX_S_ISLNK(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
+
+static inline __u16 ext2fs_swab16(__u16 val)
+{
+	return (val >> 8) | (val << 8);
+}
+
+static inline __u32 ext2fs_swab32(__u32 val)
+{
+	return ((val>>24) | ((val>>8)&0xFF00) |
+		((val<<8)&0xFF0000) | (val<<24));
+}
+
+static inline blk_t ext2fs_inode_data_blocks(struct ext2_fs *fs,
+					     struct ext2_inode *inode)
+{
+       return inode->i_blocks -
+              (inode->i_file_acl ? fs->blocksize >> 9 : 0);
+}
+
+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);
+	sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count);
+	sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count);
+	sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block);
+	sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size);
+	sb->s_log_frag_size = ext2fs_swab32(sb->s_log_frag_size);
+	sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group);
+	sb->s_frags_per_group = ext2fs_swab32(sb->s_frags_per_group);
+	sb->s_inodes_per_group = ext2fs_swab32(sb->s_inodes_per_group);
+	sb->s_mtime = ext2fs_swab32(sb->s_mtime);
+	sb->s_wtime = ext2fs_swab32(sb->s_wtime);
+	sb->s_mnt_count = ext2fs_swab16(sb->s_mnt_count);
+	sb->s_max_mnt_count = ext2fs_swab16(sb->s_max_mnt_count);
+	sb->s_magic = ext2fs_swab16(sb->s_magic);
+	sb->s_state = ext2fs_swab16(sb->s_state);
+	sb->s_errors = ext2fs_swab16(sb->s_errors);
+	sb->s_minor_rev_level = ext2fs_swab16(sb->s_minor_rev_level);
+	sb->s_lastcheck = ext2fs_swab32(sb->s_lastcheck);
+	sb->s_checkinterval = ext2fs_swab32(sb->s_checkinterval);
+	sb->s_creator_os = ext2fs_swab32(sb->s_creator_os);
+	sb->s_rev_level = ext2fs_swab32(sb->s_rev_level);
+	sb->s_def_resuid = ext2fs_swab16(sb->s_def_resuid);
+	sb->s_def_resgid = ext2fs_swab16(sb->s_def_resgid);
+	sb->s_first_ino = ext2fs_swab32(sb->s_first_ino);
+	sb->s_inode_size = ext2fs_swab16(sb->s_inode_size);
+	sb->s_block_group_nr = ext2fs_swab16(sb->s_block_group_nr);
+	sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat);
+	sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat);
+	sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat);
+	sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap);
+	sb->s_reserved_gdt_blocks = ext2fs_swab16(sb->s_reserved_gdt_blocks);
+	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);
+	sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts);
+	sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
+	sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time);
+	for (i=0; i < 4; i++)
+		sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
+	for (i=0; i < 17; i++)
+		sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
+
+}
+
+void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
+{
+	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);
+}
+
+void ext2fs_swap_inode(struct ext2_fs *fs,
+		       struct ext2_inode *t, struct ext2_inode *f, 
+		       int hostorder)
+{
+	unsigned i;
+	int islnk = 0;
+	
+	if (hostorder && LINUX_S_ISLNK(f->i_mode))
+		islnk = 1;
+	t->i_mode = ext2fs_swab16(f->i_mode);
+	if (!hostorder && LINUX_S_ISLNK(t->i_mode))
+		islnk = 1;
+	t->i_uid = ext2fs_swab16(f->i_uid);
+	t->i_size = ext2fs_swab32(f->i_size);
+	t->i_atime = ext2fs_swab32(f->i_atime);
+	t->i_ctime = ext2fs_swab32(f->i_ctime);
+	t->i_mtime = ext2fs_swab32(f->i_mtime);
+	t->i_dtime = ext2fs_swab32(f->i_dtime);
+	t->i_gid = ext2fs_swab16(f->i_gid);
+	t->i_links_count = ext2fs_swab16(f->i_links_count);
+	t->i_blocks = ext2fs_swab32(f->i_blocks);
+	t->i_flags = ext2fs_swab32(f->i_flags);
+	t->i_file_acl = ext2fs_swab32(f->i_file_acl);
+	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
+	if (!islnk || ext2fs_inode_data_blocks(fs, t)) {
+		for (i = 0; i < EXT2_N_BLOCKS; i++)
+			t->i_block[i] = ext2fs_swab32(f->i_block[i]);
+	} else if (t != f) {
+		for (i = 0; i < EXT2_N_BLOCKS; i++)
+			t->i_block[i] = f->i_block[i];
+	}
+	t->i_generation = ext2fs_swab32(f->i_generation);
+	t->i_faddr = ext2fs_swab32(f->i_faddr);
+
+	switch (fs->sb.s_creator_os) {
+	case EXT2_OS_LINUX:
+		t->osd1.linux1.l_i_reserved1 =
+			ext2fs_swab32(f->osd1.linux1.l_i_reserved1);
+		t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
+		t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
+		t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
+		t->osd2.linux2.l_i_uid_high =
+		  ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
+		t->osd2.linux2.l_i_gid_high =
+		  ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
+		t->osd2.linux2.l_i_reserved2 =
+			ext2fs_swab32(f->osd2.linux2.l_i_reserved2);
+		break;
+	case EXT2_OS_HURD:
+		t->osd1.hurd1.h_i_translator =
+		  ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
+		t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
+		t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
+		t->osd2.hurd2.h_i_mode_high =
+		  ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
+		t->osd2.hurd2.h_i_uid_high =
+		  ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
+		t->osd2.hurd2.h_i_gid_high =
+		  ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
+		t->osd2.hurd2.h_i_author =
+		  ext2fs_swab32 (f->osd2.hurd2.h_i_author);
+		break;
+	case EXT2_OS_MASIX:
+		t->osd1.masix1.m_i_reserved1 =
+			ext2fs_swab32(f->osd1.masix1.m_i_reserved1);
+		t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
+		t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
+		t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
+		t->osd2.masix2.m_i_reserved2[0] =
+			ext2fs_swab32(f->osd2.masix2.m_i_reserved2[0]);
+		t->osd2.masix2.m_i_reserved2[1] =
+			ext2fs_swab32(f->osd2.masix2.m_i_reserved2[1]);
+		break;
+	}
+}

Reply via email to