--- 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 + 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 */ 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; inumgroups; 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 + */ + +#include +#include +#include + +#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; + } +}