On Thu, 2003-08-28 at 18:55, Christopher J. PeBenito wrote: > I wasn't able to reproduce this on a small loopback fs. Just to see > what would happen, I let e2fsck clear: > > $ e2fsck -vfy /dev/sda9 > e2fsck 1.34 (25-Jul-2003) > Pass 1: Checking inodes, blocks, and sizes > Pass 2: Checking directory structure > Symlink /usr/lib/gcc-lib/powerpc-unknown-linux-gnu/3.2.3/libgcc_s.so > (inode #31561) is invalid. > Clear? yes > > Illegal block number passed to ext2fs_unmark_block_bitmap #1734502764 > for in-use block map > Illegal block number passed to ext2fs_unmark_block_bitmap #1734502764 > for block bitmap for /dev/sda9 > pid 10: killed by signal 11 > > So I guess I have some fs corruption going on. I'll see if I can find a > good way to reproduce this, and report back if I can. I'm guessing it > probably has to do with ppc being in poorer shape than x86 in 2.6. :\ This looks to me more like a bug in e2fsck than a kernel bug. You may need one of the attached patches. One idea would be to transfer the filesystem to a different machine/architecture, and to try e2fsck there. Cheers, -- Andreas Gruenbacher <agruen@xxxxxxx> SuSE Labs, SuSE Linux AG <http://www.suse.de/>
--- configure.in +++ configure.in @@ -659,6 +659,11 @@ AC_SUBST(SIZEOF_LONG_LONG) AC_C_BIGENDIAN dnl +dnl See if we have inttypes.h and if intptr_t is defined +dnl +AC_CHECK_HEADERS([inttypes.h]) +AC_CHECK_TYPE(intptr_t,long) +dnl dnl See if struct stat has a st_flags field, in which case we can get file dnl flags somewhat portably. Also check for the analogous setter, chflags(). dnl --- e2fsck/pass1b.c +++ e2fsck/pass1b.c @@ -32,6 +32,14 @@ #include <errno.h> #endif +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + +/* Needed for architectures where sizeof(int) != sizeof(void *) */ +#define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val)) +#define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr)) + #include <et/com_err.h> #include "e2fsck.h" @@ -91,10 +99,10 @@ static int dict_int_cmp(const void *a, const void *b) { - int ia, ib; + intptr_t ia, ib; - ia = (int) a; - ib = (int) b; + ia = (intptr_t)a; + ib = (intptr_t)b; return (ia-ib); } @@ -111,7 +119,7 @@ struct block_el *blk_el; struct inode_el *ino_el; - n = dict_lookup(&blk_dict, (void *) blk); + n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk)); if (n) db = (struct dup_block *) dnode_get(n); else { @@ -119,7 +127,7 @@ sizeof(struct dup_block), "duplicate block header"); db->num_bad = 0; db->inode_list = 0; - dict_alloc_insert(&blk_dict, (void *) blk, db); + dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db); } ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx, sizeof(struct inode_el), "inode element"); @@ -128,7 +136,7 @@ db->inode_list = ino_el; db->num_bad++; - n = dict_lookup(&ino_dict, (void *) ino); + n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino)); if (n) di = (struct dup_inode *) dnode_get(n); else { @@ -138,7 +146,7 @@ di->num_dupblocks = 0; di->block_list = 0; di->inode = *inode; - dict_alloc_insert(&ino_dict, (void *) ino, di); + dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di); } blk_el = (struct block_el *) e2fsck_allocate_memory(ctx, sizeof(struct block_el), "block element"); @@ -351,7 +359,7 @@ !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode)) return 0; - n = dict_lookup(&ino_dict, (void *) dirent->inode); + n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode)); if (!n) return 0; p = (struct dup_inode *) dnode_get(n); @@ -412,7 +420,7 @@ p = (struct dup_inode *) dnode_get(n); shared_len = 0; file_ok = 1; - ino = (ext2_ino_t) dnode_getkey(n); + ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n)); if (ino == EXT2_BAD_INO) continue; @@ -423,7 +431,7 @@ * get the list of inodes, and merge them together. */ for (s = p->block_list; s; s = s->next) { - m = dict_lookup(&blk_dict, (void *) s->block); + m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block)); if (!m) continue; /* Should never happen... */ q = (struct dup_block *) dnode_get(m); @@ -468,7 +476,7 @@ fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx); for (i = 0; i < shared_len; i++) { - m = dict_lookup(&ino_dict, (void *) shared[i]); + m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i])); if (!m) continue; /* should never happen */ t = (struct dup_inode *) dnode_get(m); @@ -530,7 +538,7 @@ return 0; if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) { - n = dict_lookup(&blk_dict, (void *) *block_nr); + n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr)); if (n) { p = (struct dup_block *) dnode_get(n); decrement_badcount(ctx, *block_nr, p); @@ -632,7 +640,7 @@ return 0; if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) { - n = dict_lookup(&blk_dict, (void *) *block_nr); + n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr)); if (n) { p = (struct dup_block *) dnode_get(n); retval = ext2fs_new_block(fs, 0, ctx->block_found_map, @@ -732,12 +740,12 @@ * which refered to that EA block, and modify * them to point to the new EA block. */ - n = dict_lookup(&blk_dict, (void *) blk); + n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk)); db = (struct dup_block *) dnode_get(n); for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) { if (ino_el->inode == ino) continue; - n = dict_lookup(&ino_dict, (void *) ino_el->inode); + n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode)); di = (struct dup_inode *) dnode_get(n); if (di->inode.i_file_acl == blk) { di->inode.i_file_acl = dp->inode.i_file_acl;
--- lib/ext2fs/openfs.c +++ lib/ext2fs/openfs.c @@ -109,7 +109,7 @@ if (retval) goto cleanup; retval = io_channel_read_blk(fs->io, 0, - -sizeof(struct ext2_image_hdr), + -(int)sizeof(struct ext2_image_hdr), fs->image_header); if (retval) goto cleanup;