e2fsprogs/ext2resize-byteorder.patch

370 lines
13 KiB
Diff

--- BUILD/ext2resize-1.1.19/configure.in
+++ BUILD/ext2resize-1.1.19/configure.in
@@ -26,6 +26,7 @@
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)
--- BUILD/ext2resize-1.1.19/src/Makefile.am
+++ BUILD/ext2resize-1.1.19/src/Makefile.am
@@ -6,8 +6,9 @@
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
--- BUILD/ext2resize-1.1.19/src/ext2.c
+++ BUILD/ext2resize-1.1.19/src/ext2.c
@@ -1,6 +1,7 @@
/*
ext2.c -- generic ext2 stuff
Copyright (C) 1998, 1999, 2000 Lennert Buytenhek <buytenh@gnu.org>
+ 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 <sct@redhat.com>
*/
static const char _ext2_c[] = "$Id: ext2.c,v 1.29 2004/09/30 14:01:40 sct Exp $";
@@ -254,6 +257,9 @@
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 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 @@
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 @@
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;
--- BUILD/ext2resize-1.1.19/src/ext2.h
+++ BUILD/ext2resize-1.1.19/src/ext2.h
@@ -38,7 +38,7 @@
#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 @@
/* 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,
--- BUILD/ext2resize-1.1.19/src/ext2_fs.h
+++ BUILD/ext2resize-1.1.19/src/ext2_fs.h
@@ -459,8 +459,15 @@
__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 */
};
/*
--- BUILD/ext2resize-1.1.19/src/ext2online.c
+++ BUILD/ext2resize-1.1.19/src/ext2online.c
@@ -238,10 +238,12 @@
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;
@@ -253,16 +255,17 @@
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;
@@ -340,7 +343,9 @@
}
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;
--- BUILD/ext2resize-1.1.19/src/swapfs.c
+++ BUILD/ext2resize-1.1.19/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 <sct@redhat.com>
+ */
+
+#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;
+ }
+}