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; + } +}