Many files:
  Checked in e2fsprogs 0.5c

diff --git a/e2fsck/.depend b/e2fsck/.depend
index e9715c6..0ffb52e 100644
--- a/e2fsck/.depend
+++ b/e2fsck/.depend
@@ -1,8 +1,8 @@
-badblocks.o : badblocks.c /usr/include/time.h /usr/include/features.h /usr/include/sys/cdefs.h \
-  ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h e2fsck.h \
+badblocks.o : ./badblocks.c /usr/include/time.h /usr/include/features.h /usr/include/sys/cdefs.h \
+  ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h ./e2fsck.h \
   /usr/include/stdio.h /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h /usr/include/unistd.h /usr/include/posix_opt.h \
-  /usr/include/gnu/types.h /usr/include/sys/types.h /usr/include/linux/types.h \
+  /usr/include/gnu/types.h /usr/include/confname.h /usr/include/sys/types.h /usr/include/linux/types.h \
   /usr/include/asm/types.h /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h /usr/include/alloca.h /usr/include/sys/stat.h \
   /usr/include/linux/stat.h /usr/include/sys/time.h /usr/include/linux/time.h \
@@ -15,12 +15,12 @@
   /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h /usr/include/linux/sysv_fs_i.h \
   /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h \
   ../lib/ext2fs/bitops.h 
-dirinfo.o : dirinfo.c ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
-  e2fsck.h /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
+dirinfo.o : ./dirinfo.c ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
+  ./e2fsck.h /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
   /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
-  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/sys/types.h \
-  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/stdlib.h /usr/include/errno.h \
-  /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
+  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/confname.h \
+  /usr/include/sys/types.h /usr/include/linux/types.h /usr/include/asm/types.h \
+  /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
   /usr/include/alloca.h /usr/include/sys/stat.h /usr/include/linux/stat.h /usr/include/sys/time.h \
   /usr/include/linux/time.h /usr/include/time.h /usr/include/linux/fs.h /usr/include/linux/linkage.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
@@ -31,35 +31,36 @@
   /usr/include/linux/nfs_fs_i.h /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h \
   /usr/include/linux/sysv_fs_i.h /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h \
   ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h ../lib/ext2fs/bitops.h 
-e2fsck.o : e2fsck.c /usr/include/string.h /usr/include/features.h /usr/include/sys/cdefs.h \
+e2fsck.o : ./e2fsck.c /usr/include/string.h /usr/include/features.h /usr/include/sys/cdefs.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h /usr/include/fcntl.h /usr/include/sys/types.h \
-  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/linux/fcntl.h \
-  /usr/include/ctype.h /usr/include/termios.h /usr/include/linux/termios.h /usr/include/time.h \
-  /usr/include/getopt.h /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h \
-  /usr/include/mntent.h /usr/include/stdio.h /usr/include/libio.h /usr/include/_G_config.h \
-  /usr/include/sys/ioctl.h /usr/include/linux/ioctl.h /usr/include/malloc.h ../lib/et/com_err.h \
-  /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h e2fsck.h /usr/include/stdlib.h \
-  /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
-  /usr/include/alloca.h /usr/include/sys/stat.h /usr/include/linux/stat.h /usr/include/sys/time.h \
-  /usr/include/linux/time.h /usr/include/linux/fs.h /usr/include/linux/linkage.h \
-  /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
-  /usr/include/linux/vfs.h /usr/include/linux/net.h /usr/include/linux/socket.h \
-  /usr/include/linux/sockios.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
-  /usr/include/linux/ext_fs_i.h /usr/include/linux/ext2_fs_i.h /usr/include/linux/hpfs_fs_i.h \
-  /usr/include/linux/msdos_fs_i.h /usr/include/linux/umsdos_fs_i.h /usr/include/linux/iso_fs_i.h \
-  /usr/include/linux/nfs_fs_i.h /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h \
-  /usr/include/linux/sysv_fs_i.h /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h \
-  ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h ../lib/ext2fs/bitops.h ../version.h 
-ehandler.o : ehandler.c /usr/include/stdlib.h /usr/include/features.h /usr/include/sys/cdefs.h \
+  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/gnu/types.h \
+  /usr/include/linux/fcntl.h /usr/include/ctype.h /usr/include/termios.h /usr/include/linux/termios.h \
+  /usr/include/time.h /usr/include/getopt.h /usr/include/unistd.h /usr/include/posix_opt.h \
+  /usr/include/confname.h /usr/include/mntent.h /usr/include/stdio.h /usr/include/libio.h \
+  /usr/include/_G_config.h /usr/include/sys/ioctl.h /usr/include/linux/ioctl.h \
+  /usr/include/malloc.h ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
+  ./e2fsck.h /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h \
+  /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h /usr/include/alloca.h /usr/include/sys/stat.h \
+  /usr/include/linux/stat.h /usr/include/sys/time.h /usr/include/linux/time.h \
+  /usr/include/linux/fs.h /usr/include/linux/linkage.h /usr/include/linux/limits.h \
+  /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
+  /usr/include/linux/net.h /usr/include/linux/socket.h /usr/include/linux/sockios.h \
+  /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
+  /usr/include/linux/ext2_fs_i.h /usr/include/linux/hpfs_fs_i.h /usr/include/linux/msdos_fs_i.h \
+  /usr/include/linux/umsdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/nfs_fs_i.h \
+  /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h /usr/include/linux/sysv_fs_i.h \
+  /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h \
+  ../lib/ext2fs/bitops.h ./../version.h 
+ehandler.o : ./ehandler.c /usr/include/stdlib.h /usr/include/features.h /usr/include/sys/cdefs.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h /usr/include/errno.h /usr/include/linux/errno.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h /usr/include/alloca.h /usr/include/unistd.h \
-  /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/sys/types.h /usr/include/linux/types.h \
-  /usr/include/asm/types.h /usr/include/string.h /usr/include/ctype.h /usr/include/termios.h \
-  /usr/include/linux/termios.h /usr/include/sys/resource.h /usr/include/sys/time.h \
-  /usr/include/linux/time.h /usr/include/time.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/limits.h \
+  /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/confname.h /usr/include/sys/types.h \
+  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/string.h /usr/include/ctype.h \
+  /usr/include/termios.h /usr/include/linux/termios.h /usr/include/sys/resource.h \
+  /usr/include/sys/time.h /usr/include/linux/time.h /usr/include/time.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/limits.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/syslimits.h /usr/include/limits.h \
   /usr/include/posix1_lim.h /usr/include/linux/limits.h /usr/include/posix2_lim.h \
-  /usr/include/linux/resource.h e2fsck.h /usr/include/stdio.h /usr/include/libio.h \
+  /usr/include/linux/resource.h ./e2fsck.h /usr/include/stdio.h /usr/include/libio.h \
   /usr/include/_G_config.h /usr/include/sys/stat.h /usr/include/linux/stat.h /usr/include/linux/fs.h \
   /usr/include/linux/linkage.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/net.h /usr/include/linux/socket.h \
@@ -70,11 +71,11 @@
   /usr/include/linux/sysv_fs_i.h /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h \
   ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h ../lib/ext2fs/io.h \
   ../lib/ext2fs/ext2_err.h ../lib/ext2fs/bitops.h 
-flushb.o : flushb.c /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
+flushb.o : ./flushb.c /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
   /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
-  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/sys/types.h \
-  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/stdlib.h /usr/include/errno.h \
-  /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
+  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/confname.h \
+  /usr/include/sys/types.h /usr/include/linux/types.h /usr/include/asm/types.h \
+  /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
   /usr/include/alloca.h /usr/include/fcntl.h /usr/include/linux/fcntl.h /usr/include/sys/ioctl.h \
   /usr/include/linux/ioctl.h /usr/include/termios.h /usr/include/linux/termios.h \
   /usr/include/linux/fs.h /usr/include/linux/linkage.h /usr/include/linux/limits.h \
@@ -84,18 +85,18 @@
   /usr/include/linux/ext2_fs_i.h /usr/include/linux/hpfs_fs_i.h /usr/include/linux/msdos_fs_i.h \
   /usr/include/linux/umsdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/nfs_fs_i.h \
   /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h /usr/include/linux/sysv_fs_i.h 
-mtrace.o : mtrace.c ./malloc.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
+mtrace.o : ./mtrace.c ././malloc.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
   /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/libio.h \
   /usr/include/_G_config.h /usr/include/string.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/limits.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/syslimits.h /usr/include/limits.h \
   /usr/include/posix1_lim.h /usr/include/linux/limits.h /usr/include/posix2_lim.h \
   /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
   /usr/include/alloca.h 
-pass1.o : pass1.c /usr/include/time.h /usr/include/features.h /usr/include/sys/cdefs.h \
-  ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h e2fsck.h \
+pass1.o : ./pass1.c /usr/include/time.h /usr/include/features.h /usr/include/sys/cdefs.h \
+  ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h ./e2fsck.h \
   /usr/include/stdio.h /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h /usr/include/unistd.h /usr/include/posix_opt.h \
-  /usr/include/gnu/types.h /usr/include/sys/types.h /usr/include/linux/types.h \
+  /usr/include/gnu/types.h /usr/include/confname.h /usr/include/sys/types.h /usr/include/linux/types.h \
   /usr/include/asm/types.h /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h /usr/include/alloca.h /usr/include/sys/stat.h \
   /usr/include/linux/stat.h /usr/include/sys/time.h /usr/include/linux/time.h \
@@ -108,11 +109,11 @@
   /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h /usr/include/linux/sysv_fs_i.h \
   /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h \
   ../lib/ext2fs/bitops.h 
-pass1b.o : pass1b.c /usr/include/time.h /usr/include/features.h /usr/include/sys/cdefs.h \
-  ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h e2fsck.h \
+pass1b.o : ./pass1b.c /usr/include/time.h /usr/include/features.h /usr/include/sys/cdefs.h \
+  ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h ./e2fsck.h \
   /usr/include/stdio.h /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h /usr/include/unistd.h /usr/include/posix_opt.h \
-  /usr/include/gnu/types.h /usr/include/sys/types.h /usr/include/linux/types.h \
+  /usr/include/gnu/types.h /usr/include/confname.h /usr/include/sys/types.h /usr/include/linux/types.h \
   /usr/include/asm/types.h /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h /usr/include/alloca.h /usr/include/sys/stat.h \
   /usr/include/linux/stat.h /usr/include/sys/time.h /usr/include/linux/time.h \
@@ -125,12 +126,12 @@
   /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h /usr/include/linux/sysv_fs_i.h \
   /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h \
   ../lib/ext2fs/bitops.h 
-pass2.o : pass2.c ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
-  e2fsck.h /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
+pass2.o : ./pass2.c ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
+  ./e2fsck.h /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
   /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
-  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/sys/types.h \
-  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/stdlib.h /usr/include/errno.h \
-  /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
+  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/confname.h \
+  /usr/include/sys/types.h /usr/include/linux/types.h /usr/include/asm/types.h \
+  /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
   /usr/include/alloca.h /usr/include/sys/stat.h /usr/include/linux/stat.h /usr/include/sys/time.h \
   /usr/include/linux/time.h /usr/include/time.h /usr/include/linux/fs.h /usr/include/linux/linkage.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
@@ -141,12 +142,12 @@
   /usr/include/linux/nfs_fs_i.h /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h \
   /usr/include/linux/sysv_fs_i.h /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h \
   ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h ../lib/ext2fs/bitops.h 
-pass3.o : pass3.c ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
-  e2fsck.h /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
+pass3.o : ./pass3.c ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
+  ./e2fsck.h /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
   /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
-  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/sys/types.h \
-  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/stdlib.h /usr/include/errno.h \
-  /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
+  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/confname.h \
+  /usr/include/sys/types.h /usr/include/linux/types.h /usr/include/asm/types.h \
+  /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
   /usr/include/alloca.h /usr/include/sys/stat.h /usr/include/linux/stat.h /usr/include/sys/time.h \
   /usr/include/linux/time.h /usr/include/time.h /usr/include/linux/fs.h /usr/include/linux/linkage.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
@@ -157,28 +158,28 @@
   /usr/include/linux/nfs_fs_i.h /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h \
   /usr/include/linux/sysv_fs_i.h /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h \
   ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h ../lib/ext2fs/bitops.h 
-pass4.o : pass4.c e2fsck.h /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
+pass4.o : ./pass4.c ./e2fsck.h /usr/include/stdio.h /usr/include/features.h \
+  /usr/include/sys/cdefs.h /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h \
+  /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h /usr/include/unistd.h /usr/include/posix_opt.h \
+  /usr/include/gnu/types.h /usr/include/confname.h /usr/include/sys/types.h /usr/include/linux/types.h \
+  /usr/include/asm/types.h /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h \
+  /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h /usr/include/alloca.h /usr/include/sys/stat.h \
+  /usr/include/linux/stat.h /usr/include/sys/time.h /usr/include/linux/time.h \
+  /usr/include/time.h /usr/include/linux/fs.h /usr/include/linux/linkage.h /usr/include/linux/limits.h \
+  /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
+  /usr/include/linux/net.h /usr/include/linux/socket.h /usr/include/linux/sockios.h \
+  /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
+  /usr/include/linux/ext2_fs_i.h /usr/include/linux/hpfs_fs_i.h /usr/include/linux/msdos_fs_i.h \
+  /usr/include/linux/umsdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/nfs_fs_i.h \
+  /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h /usr/include/linux/sysv_fs_i.h \
+  /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
+  ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h ../lib/ext2fs/bitops.h 
+pass5.o : ./pass5.c ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
+  ./e2fsck.h /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
   /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
-  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/sys/types.h \
-  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/stdlib.h /usr/include/errno.h \
-  /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
-  /usr/include/alloca.h /usr/include/sys/stat.h /usr/include/linux/stat.h /usr/include/sys/time.h \
-  /usr/include/linux/time.h /usr/include/time.h /usr/include/linux/fs.h /usr/include/linux/linkage.h \
-  /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
-  /usr/include/linux/vfs.h /usr/include/linux/net.h /usr/include/linux/socket.h \
-  /usr/include/linux/sockios.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
-  /usr/include/linux/ext_fs_i.h /usr/include/linux/ext2_fs_i.h /usr/include/linux/hpfs_fs_i.h \
-  /usr/include/linux/msdos_fs_i.h /usr/include/linux/umsdos_fs_i.h /usr/include/linux/iso_fs_i.h \
-  /usr/include/linux/nfs_fs_i.h /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h \
-  /usr/include/linux/sysv_fs_i.h /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h \
-  ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h ../lib/ext2fs/io.h \
-  ../lib/ext2fs/ext2_err.h ../lib/ext2fs/bitops.h 
-pass5.o : pass5.c ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
-  e2fsck.h /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
-  /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
-  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/sys/types.h \
-  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/stdlib.h /usr/include/errno.h \
-  /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
+  /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/confname.h \
+  /usr/include/sys/types.h /usr/include/linux/types.h /usr/include/asm/types.h \
+  /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
   /usr/include/alloca.h /usr/include/sys/stat.h /usr/include/linux/stat.h /usr/include/sys/time.h \
   /usr/include/linux/time.h /usr/include/time.h /usr/include/linux/fs.h /usr/include/linux/linkage.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
@@ -189,38 +190,38 @@
   /usr/include/linux/nfs_fs_i.h /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h \
   /usr/include/linux/sysv_fs_i.h /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h \
   ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h ../lib/ext2fs/bitops.h 
-scantest.o : scantest.c /usr/include/string.h /usr/include/features.h /usr/include/sys/cdefs.h \
+scantest.o : ./scantest.c /usr/include/string.h /usr/include/features.h /usr/include/sys/cdefs.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h /usr/include/fcntl.h /usr/include/sys/types.h \
-  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/linux/fcntl.h \
-  /usr/include/ctype.h /usr/include/termios.h /usr/include/linux/termios.h /usr/include/time.h \
-  /usr/include/getopt.h /usr/include/unistd.h /usr/include/posix_opt.h /usr/include/gnu/types.h \
-  /usr/include/mntent.h /usr/include/stdio.h /usr/include/libio.h /usr/include/_G_config.h \
-  /usr/include/sys/ioctl.h /usr/include/linux/ioctl.h /usr/include/malloc.h /usr/include/sys/resource.h \
-  /usr/include/sys/time.h /usr/include/linux/time.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/limits.h \
-  /usr/lib/gcc-lib/i486-linux/2.5.8/include/syslimits.h /usr/include/limits.h \
-  /usr/include/posix1_lim.h /usr/include/linux/limits.h /usr/include/posix2_lim.h \
-  /usr/include/linux/resource.h ../lib/et/com_err.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h \
-  ../version.h /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h \
-  /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h /usr/include/alloca.h /usr/include/sys/stat.h \
-  /usr/include/linux/stat.h /usr/include/linux/fs.h /usr/include/linux/linkage.h \
-  /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
-  /usr/include/linux/net.h /usr/include/linux/socket.h /usr/include/linux/sockios.h \
-  /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
-  /usr/include/linux/ext2_fs_i.h /usr/include/linux/hpfs_fs_i.h /usr/include/linux/msdos_fs_i.h \
-  /usr/include/linux/umsdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/nfs_fs_i.h \
-  /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h /usr/include/linux/sysv_fs_i.h \
-  /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h \
-  ../lib/ext2fs/bitops.h 
-util.o : util.c /usr/include/stdlib.h /usr/include/features.h /usr/include/sys/cdefs.h \
+  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/gnu/types.h \
+  /usr/include/linux/fcntl.h /usr/include/ctype.h /usr/include/termios.h /usr/include/linux/termios.h \
+  /usr/include/time.h /usr/include/getopt.h /usr/include/unistd.h /usr/include/posix_opt.h \
+  /usr/include/confname.h /usr/include/mntent.h /usr/include/stdio.h /usr/include/libio.h \
+  /usr/include/_G_config.h /usr/include/sys/ioctl.h /usr/include/linux/ioctl.h \
+  /usr/include/malloc.h /usr/include/sys/resource.h /usr/include/sys/time.h /usr/include/linux/time.h \
+  /usr/lib/gcc-lib/i486-linux/2.5.8/include/limits.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/syslimits.h \
+  /usr/include/limits.h /usr/include/posix1_lim.h /usr/include/linux/limits.h \
+  /usr/include/posix2_lim.h /usr/include/linux/resource.h ../lib/et/com_err.h \
+  /usr/lib/gcc-lib/i486-linux/2.5.8/include/stdarg.h ./../version.h /usr/include/stdlib.h \
+  /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
+  /usr/include/alloca.h /usr/include/sys/stat.h /usr/include/linux/stat.h /usr/include/linux/fs.h \
+  /usr/include/linux/linkage.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
+  /usr/include/linux/vfs.h /usr/include/linux/net.h /usr/include/linux/socket.h \
+  /usr/include/linux/sockios.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
+  /usr/include/linux/ext_fs_i.h /usr/include/linux/ext2_fs_i.h /usr/include/linux/hpfs_fs_i.h \
+  /usr/include/linux/msdos_fs_i.h /usr/include/linux/umsdos_fs_i.h /usr/include/linux/iso_fs_i.h \
+  /usr/include/linux/nfs_fs_i.h /usr/include/linux/nfs.h /usr/include/linux/xia_fs_i.h \
+  /usr/include/linux/sysv_fs_i.h /usr/include/linux/ext2_fs.h ../lib/ext2fs/ext2fs.h \
+  ../lib/ext2fs/io.h ../lib/ext2fs/ext2_err.h ../lib/ext2fs/bitops.h 
+util.o : ./util.c /usr/include/stdlib.h /usr/include/features.h /usr/include/sys/cdefs.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h /usr/include/errno.h /usr/include/linux/errno.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h /usr/include/alloca.h /usr/include/unistd.h \
-  /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/sys/types.h /usr/include/linux/types.h \
-  /usr/include/asm/types.h /usr/include/string.h /usr/include/ctype.h /usr/include/termios.h \
-  /usr/include/linux/termios.h /usr/include/sys/resource.h /usr/include/sys/time.h \
-  /usr/include/linux/time.h /usr/include/time.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/limits.h \
+  /usr/include/posix_opt.h /usr/include/gnu/types.h /usr/include/confname.h /usr/include/sys/types.h \
+  /usr/include/linux/types.h /usr/include/asm/types.h /usr/include/string.h /usr/include/ctype.h \
+  /usr/include/termios.h /usr/include/linux/termios.h /usr/include/sys/resource.h \
+  /usr/include/sys/time.h /usr/include/linux/time.h /usr/include/time.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/limits.h \
   /usr/lib/gcc-lib/i486-linux/2.5.8/include/syslimits.h /usr/include/limits.h \
   /usr/include/posix1_lim.h /usr/include/linux/limits.h /usr/include/posix2_lim.h \
-  /usr/include/linux/resource.h e2fsck.h /usr/include/stdio.h /usr/include/libio.h \
+  /usr/include/linux/resource.h ./e2fsck.h /usr/include/stdio.h /usr/include/libio.h \
   /usr/include/_G_config.h /usr/include/sys/stat.h /usr/include/linux/stat.h /usr/include/linux/fs.h \
   /usr/include/linux/linkage.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/net.h /usr/include/linux/socket.h \
diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog
index be0ac6c..847d9cd 100644
--- a/e2fsck/ChangeLog
+++ b/e2fsck/ChangeLog
@@ -1,3 +1,256 @@
+Thu Oct 26 12:05:30 1995    <tytso@rsts-11.mit.edu>
+
+	* Makefile.in (install): Strip programs when they are installed.
+		(e2fsck): Build e2fsck statically.
+
+Wed Oct 25 21:18:16 1995    <tytso@rsts-11.mit.edu>
+
+	* util.c (preenhalt): Preenhalt now takes an argument, which is an
+		ext2fs_filsys; this allows it to set the EXT2_ERROR_FS
+		flag in the superblock in cases where preenhalt is called.
+		All calls to preenhalt() were changed to either
+		preenhalt(fs) or preenhalt(NULL) in a few cases where the
+		fs pointer was not available.  (Most notable, for block
+		read/write errors.)
+
+Mon Sep  4 21:41:03 1995  Remy Card  <card@bbj>
+
+	* ehandler.c:
+	  util.c: Include <sys/time.h> before <sys/resource.h>.  BSD needs it.
+
+Mon Sep  4 10:14:49 1995    <tytso@rsts-11.mit.edu>
+
+	* e2fsck.c (show_stats): Show statistics about how many inodes
+		have indirect, doubly indirect, and triply indirect
+		blocks.  Allow up to 8 digits for statistics, instead of
+		merely 6, so things look pretty for large filesystems.
+
+	* pass1.c (pass1): Keep statistics about indirect, doubly
+	        indirect, and triply indirect blocks.
+
+	* pass1.c (unwind_pass1): Clear the above statistics when unwinding
+		pass 1.
+
+Fri Aug 18 15:17:10 1995  Theodore Y. Ts'o  <tytso@dcl>
+
+	* util.c, ehandler.c: Move #include of <sys/resource.h> after
+		#include of "e2fsck.h", since sys/resource.h may depend on
+		sys/time.h, which is #included in e2fsck.h.
+
+Thu Aug 17 22:33:37 1995    <tytso@rsts-11.mit.edu>
+
+	* e2fsck.c (check_mount):  Use the new ext2fs_check_if_mounted()
+		function to determine if the device is mounted.
+
+	* e2fsck.c (main):  Add better error messages if ext2fs_open()
+		fails. 
+
+Wed Aug 16 16:25:02 1995    <tytso@rsts-11.mit.edu>
+
+	* pass1.c (check_blocks): If we're clearing a directory, clear
+		pb.is_dir so we don't do the following check of making
+		sure the directory size matches; this is pointless, since
+		we've already cleared the inode.
+
+Fri Aug 11 09:08:54 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
+
+	* pass1.c (bad_primary_block): New function, called by
+		process_bad_block, which explains the facts of life to the
+		user when a block in the primary superblock or primary
+		group descriptors is bad.
+
+	* pass2.c (check_dot): Handle the case where the first directory
+		entry is used, but not ".".
+
+	* pass2.c (check_dotdot): Handle the case where the second directory
+		entry is used, but is not "..".
+
+Thu Aug 10 10:05:10 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
+
+	* e2fsck.c (check_super_block): Get the size of the physical
+		device and if it is smaller than the reported size of the
+		filesystem, report an error.
+
+Sat Aug 12 03:39:18 1995  Remy Card  <card@bbj>
+
+	* e2fsck.c (check_if_skip): Print the number of allocated files and
+		blocks on clean filesystems.
+
+Fri Aug 11 14:15:36 1995  Remy Card  <card@bbj>
+
+	* e2fsck.8: Updated date and version number.
+
+Thu Aug 10 14:26:01 1995  Remy Card  <card@bbj>
+
+	* pass1.c (check_blocks): Check that directory size matches *exactly*
+		the count of allocated blocks.
+
+Wed Aug  9 21:21:24 1995  Theodore Y. Ts'o  <tytso@dcl>
+
+	* pass1b.c (pass1d): Free the shared[] array when we're done with
+		it to avoid a memory leak.
+
+	* pass1.c (unwind_pass1): Use ext2fs_free_block_bitmap to free the
+	        block_dup_map.
+
+	* pass2.c (process_bad_inode): When clearing the inode, make sure
+		the pathname is freed, to prevent a memory leak.
+
+	* pass5.c (check_inode_bitmaps): Free free_array and dir_array
+		when we're finished with them.
+		(check_block_bitmaps): Free free_array when we're finished
+		with them.
+
+	* Makefile.in (e2fsck, flushb): Use $(LD) instead of $(CC) when
+		linking the executable.
+
+	* pass2.c (process_bad_inode): Even on OS's that don't support the
+		fragment fields, make sure the Linux equivalent fields are
+		set to zero.  If an OS wants to reuse these fields, which
+		is probably a bad idea (although we may get desperate in
+		the future) this code will have to be changed.
+
+	* pass1.c (dir_block_cmp): If the block numbers are equal, compare
+		on the inode field, and then blockcnt field.  This is just
+		to keep the ordering of dir_blocks the same on all
+		platforms when there are more than on missing directory
+		blocks, which are indicated directories with holes, which
+		are indicated with the block number being set to zero.
+
+Sun Aug  6 15:40:58 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
+
+	* pass1.c (check_blocks, process_block): check_blocks() modified
+		to call the ext2fs_block_iterate() with BLOCK_FLAG_HOLE if
+		the inode is a directory.  process_block() now checks to
+		see if a directory has a "hole", or missing block.  If so,
+		this fact is recorded in the directory block list so that
+		the problem can be resolved in pass #2.
+
+	* pass2.c (allocate_dir_block): Added allocate_dir_block() to
+		allocate new blocks for directories with "holes".  Called
+		out of check_dir_block if a block in the directory block
+		list is zero.
+
+	* pass3.c (get_lost_and_found): Move location of free(block) to
+		prevent possible memory leak.
+
+Sat Aug  5 12:42:22 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
+
+	* pass2.c (check_dir_block): Use a automatic, fixed-saize array
+		instead of alloca() --- alloca is not portable!  Check to
+		make sure the filename is not longer than EXT2_NAME_LEN,
+		and offer to fix it by truncating it, since it should
+		never happen.
+
+	* e2fsck.c (PRS): Use malloc() instead of alloca() --- alloca() is
+		not portable!!  In any case putenv() in some systems must
+		take a static character array or malloc()'ed memory;
+		passing memory allocated using alloca() to putenv() is not
+		advisable.
+
+	* pass2.c (check_dot, check_dotdot): Use malloc() instead of
+		alloca() --- alloca() is not portable!!!
+
+Tue Jul 18 20:04:02 1995    <tytso@rsx-11.mit.edu>
+
+	* pass1b.c (pass1c): 
+	* pass3.c (check_root, get_lost_and_found): 
+	* pass2.c (check_dir_block): Use ext2fs_{read,write}_dir_block
+		to read/write the directory block.
+
+Mon Jul 17 04:00:56 1995    <tytso@rsx-11.mit.edu>
+
+	* util.c (ask_yn): Apply patch supplied by Peter A. Zaitcev to
+		make sure VMIN and VTIME are set correct.
+
+Fri Jul 14 19:26:29 1995    <tytso@rsx-11.mit.edu>
+
+	* pass1.c (mark_block_used): Change to be an inline function.
+		Assume that the block validity checks are already done,
+		and use the fast variant of the bitmap functions.
+
+Thu Jul 13 08:10:55 1995    <tytso@rsx-11.mit.edu>
+
+	* pass5.c (check_block_bitmaps, check_inode_bitmaps): Check the
+		bounds of the bitmaps in advance, and then use the fast
+		variant of e2fs_test_{block,inode}_bitmap.
+
+	* pass1.c (mark_block_used): Use ext2_fast_mark_block_bitmap since
+		the bounds checking has already been done earlier.
+
+Wed Jul 12 02:22:46 1995    <tytso@rsx-11.mit.edu>
+
+	* pass1.c (pass1): Allocate and free the block_illegal_map, which
+		is used for shortcut processing in process_block.
+		(mark_table_blocks): Initialize block_illegal_map with the
+		filesystem blocks.
+		(describe_illegal_block): New helper function that
+		describes why a block is illegal.
+		(process_block): Use block_illegal_map as a shortcut
+		to determine whether a block is bad.  Use
+		describe_illegal_block to print out why the block is illegal.
+
+Mon Jun 12 19:11:06 1995  Theodore Y. Ts'o  (tytso@dcl)
+
+	* flushb.c: Don't include <linux/fs.h> if it doesn't exist.
+
+	* scantest.c: Don't include <linux/fs.h>, <getopt.h>, or
+		<mntent.h> if they don't exist.  (Mostly so that "make
+		depend" works.)
+
+	* pass1.c, pass1b.c, pass3.c, badblocks.c: Include <errno.h> (if
+		it exists).
+
+	* e2fsck.c, scantest.c: Don't include <getopt.h> if it doesn't
+		exist. 
+
+Mon Jun 12 08:37:49 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
+
+	* pass2.c (process_bad_inode, check_for_zero_long,
+	        check_for_zero_char):  Change long to u32, and char to u8.
+
+Sun Jun 11 15:05:57 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
+
+	* util.c (inode_has_valid_blocks): 
+	* pass2.c (process_bad_inode): 
+	* pass1.c (pass1, check_blocks, pass1_check_directory): Use
+		LINUX_S_IS* instead of S_IS*.
+
+	* e2fsck.h: Don't #include <sys/stat.h>
+
+	* flushb.c (main): Add #ifdef BLKFLSBUF around ioctl.  (Although
+		this program is pretty much useless if BLKFLSBUF isn't
+		supported.)
+
+	* e2fsck.c, badblocks.c: Add #include <errno.h>, since errno is
+	        used.
+
+Thu Jun  8 12:31:19 1995  Miles Bader  <miles@churchy.gnu.ai.mit.edu>
+
+	* pass2.c (check_dot, check_dotdot, check_dir_block): Use alloca
+	to allocate space for file names instead of using fixed size buffers.
+	(process_bad_inode): Only check inode frag fields if
+	HAVE_EXT2_FRAGS is defined (by configure).
+	* pass1.c (pass1): Only check the inode frag fields if
+	HAVE_EXT2_FRAGS is defined (by configure).
+
+	* e2fsck.c (check_mount): Only check for a mounted filesystem if
+	HAVE_MNTENT_H is defined (by configure).
+	(PRS): Use alloca to allocate the new path string, instead of
+	having a fixed size buffer (which was the wrong size anyway).
+	(PRS): Only support the -F (flush) option if the BLKFLSBUF ioctl
+	is defined.
+
+	* e2fsck.h: Only include <linux/fs.h> if HAVE_LINUX_FS_H is
+	defined (by configure).
+
+	* Makefile.in: Rewritten to conform to GNU coding standards and
+	support separate compilation directories.
+
+Thu Apr  6 15:04:36 1995  Remy Card  <card@bbj.ibp.fr>
+
+	* pass1.c (pass1): Test the mode in reserved inodes (must be zero).
+
 Sat Mar 11 13:12:16 1995  Theodore Y. Ts'o  <tytso@localhost>
 
 	* pass1.c (unwind_pass1): Clear the file type statistics counter
diff --git a/e2fsck/Makefile b/e2fsck/Makefile
deleted file mode 100644
index a8e0f75..0000000
--- a/e2fsck/Makefile
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# Makefile for e2fsck
-#
-
-include ../MCONFIG
-
-MK_CMDS=	../lib/ss/mk_cmds
-CFLAGS=		$(PROF) $(OPT) $(MTRACE) $(MCHECK) $(WFLAGS) -I../lib
-LDFLAGS=	$(PROF) $(OPT)
-PROGS=		e2fsck flushb
-MANPAGES=	e2fsck.8
-
-LIBS= -L../lib -lss -lcom_err -lext2fs $(CHECKLIB)
-DEPLIBS= ../lib/libss.a ../lib/libcom_err.a ../lib/libext2fs.a
-
-#
-# Flags for using Checker
-#	Note: The optimization flags must include -g
-#
-#MCHECK=	-checker
-#LIBS= -L../lib -lss -lcom_err -le2fs $(CHECKLIB)
-#DEPLIBS= ../lib/libss.a ../lib/libcom_err.a ../lib/libext2fs.a
-#CHECKLIB= /usr/lib/libchecker.o
-
-#
-# Flags for doing mtrace --- uncomment to produce mtracing e2fsck
-# 	Note:  The optimization flags must include -g
-#
-#MTRACE=	-DMTRACE
-#MTRACE_OBJ= mtrace.o
-#OPT= -g
-
-#
-# Flags for doing mcheck --- uncomment to produce mchecking e2fsck
-# 	Note:  The optimization flags must include -g
-#
-#MCHECK= -DMCHECK
-
-#
-# Flags for profiling --- uncomment to produce profiling e2fsck
-#
-#PROF=		-pg
-#LIBS= -L../lib -lss -lcom_err_p -lext2fs_p 
-#DEPLIBS= ../lib/libss.a ../lib/libcom_err_p.a ../lib/libext2fs_p.a
-
-OBJS= e2fsck.o pass1.o pass1b.o pass2.o pass3.o pass4.o pass5.o \
-	badblocks.o util.o dirinfo.o ehandler.o $(MTRACE_OBJ)
-
-all: $(PROGS)
-
-#e2fsck: $(OBJS)  $(DEPLIBS)
-#	cc $(LDFLAGS) -o e2fsck $(OBJS) $(LIBS) 
-
-e2fsck: $(OBJS)  $(DEPLIBS)
-	$(CC) $(LDFLAGS) -static -o e2fsck $(OBJS) $(LIBS) 
-
-flushb: flushb.o
-	$(CC) $(LDFLAGS) -o flushb flushb.o $(CHECKLIB)
-
-install:: $(PROGS)
-	$(INSTALLBIN) e2fsck $(SBINDIR)/e2fsck
-	$(INSTALLBIN) flushb $(USRSBINDIR)/flushb
-	ln -sf e2fsck $(SBINDIR)/fsck.ext2
-
-install:: $(MANPAGES)
-	for i in $(MANPAGES); do \
-		$(INSTALLMAN) $$i $(SMANDIR)/$$i; \
-	done
-
-install-tree:: $(PROGS)
-	for i in $(PROGS); do \
-		rm -f ../bin/$$i; \
-		cp $$i ../bin; \
-		strip ../bin/$$i; \
-		chmod 555 ../bin/$$i; \
-	done
-	ln -sf e2fsck ../bin/fsck.ext2
-
-clean:
-	rm -f $(PROGS) \#* *\# *.s *.o *.a *~ core
-
-really-clean: clean
-	rm -f .depend
-
-dep depend .depend:
-	$(CPP) $(CFLAGS) -M *.c >.depend
-
-include .depend
diff --git a/e2fsck/Makefile.in b/e2fsck/Makefile.in
new file mode 100644
index 0000000..328fc55
--- /dev/null
+++ b/e2fsck/Makefile.in
@@ -0,0 +1,167 @@
+#
+# Makefile for e2fsck
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+top_builddir = ..
+INSTALL = @INSTALL@
+LDFLAG_STATIC = @LDFLAG_STATIC@
+
+@MCONFIG@
+
+PROGS=		e2fsck extend @EXTRA_PROGS@
+MANPAGES=	e2fsck.8
+
+LIBS= -L../lib -lss -lcom_err -lext2fs $(CHECKLIB)
+DEPLIBS= ../lib/libss.a ../lib/libcom_err.a ../lib/libext2fs.a
+
+.c.o:
+	$(CC) -c $(CFLAGS) $< -o $@
+
+#
+# Flags for using Checker
+#	Note: The optimization flags must include -g
+#
+#MCHECK=	-checker
+#LIBS= -L../lib -lss -lcom_err -le2fs $(CHECKLIB)
+#DEPLIBS= ../lib/libss.a ../lib/libcom_err.a ../lib/libext2fs.a
+#CHECKLIB= /usr/lib/libchecker.o
+
+#
+# Flags for doing mtrace --- uncomment to produce mtracing e2fsck
+# 	Note:  The optimization flags must include -g
+#
+#MTRACE=	-DMTRACE
+#MTRACE_OBJ= mtrace.o
+#MTRACE_SRC= $(srcdir)/mtrace.c
+#OPT= -g
+
+#
+# Flags for doing mcheck --- uncomment to produce mchecking e2fsck
+# 	Note:  The optimization flags must include -g
+#
+#MCHECK= -DMCHECK
+
+#
+# Flags for profiling --- uncomment to produce profiling e2fsck
+#
+#PROF=		-pg
+#LIBS= -L../lib -lss -lcom_err_p -lext2fs_p 
+#DEPLIBS= ../lib/libss.a ../lib/libcom_err_p.a ../lib/libext2fs_p.a
+
+OBJS= e2fsck.o pass1.o pass1b.o pass2.o pass3.o pass4.o pass5.o \
+	badblocks.o util.o dirinfo.o ehandler.o $(MTRACE_OBJ)
+
+SRCS= $(srcdir)/e2fsck.c \
+	$(srcdir)/pass1.c \
+	$(srcdir)/pass1b.c \
+	$(srcdir)/pass2.c \
+	$(srcdir)/pass3.c \
+	$(srcdir)/pass4.c \
+	$(srcdir)/pass5.c \
+	$(srcdir)/badblocks.c \
+	$(srcdir)/util.c \
+	$(srcdir)/dirinfo.c \
+	$(srcdir)/ehandler.c \
+	$(MTRACE_SRC)
+
+all:: $(PROGS)
+
+e2fsck: $(OBJS)  $(DEPLIBS)
+	$(LD) $(LDFLAGS) $(LDFLAG_STATIC) -o e2fsck $(OBJS) $(LIBS) 
+
+extend: extend.o
+	$(LD) $(LDFLAGS) -o extend extend.o $(CHECKLIB)
+
+flushb: flushb.o
+	$(LD) $(LDFLAGS) -o flushb flushb.o $(CHECKLIB)
+
+iscan: iscan.o util.o
+	$(LD) $(LDFLAGS) -o iscan iscan.o util.o ehandler.o $(LIBS)
+
+
+installdirs:
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(sbindir) $(DESTDIR)$(man8dir) \
+		$(DESTDIR)$(cat8dir)
+
+install: $(PROGS) $(MANPAGES) installdirs
+	for i in $(PROGS); do \
+		$(INSTALL_PROGRAM) $$i $(DESTDIR)$(sbindir)/$$i; \
+		$(STRIP) $(DESTDIR)$(sbindir)/$$i; \
+	done
+	$(LN) -f $(DESTDIR)$(sbindir)/e2fsck $(DESTDIR)$(sbindir)/fsck.ext2
+	for i in $(MANPAGES); do \
+		$(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(man8dir)/$$i; \
+	done
+uninstall:
+	$(RM) -f $(sbindir)/e2fsck
+	$(RM) -f $(sbindir)/flushb
+	$(RM) -f $(sbindir)/fsck.ext2
+	for i in $(MANPAGES); do \
+		$(RM) -f $(man8dir)/$$i; \
+	done
+
+clean:
+	$(RM) -f $(PROGS) \#* *\# *.s *.o *.a *~ core
+mostlyclean: clean
+distclean: clean
+	$(RM) -f .depend Makefile
+
+# +++ Dependency line eater +++
+# 
+# Makefile dependencies follow.  This must be the last section in
+# the Makefile.in file
+#
+e2fsck.o : $(srcdir)/e2fsck.c \
+  $(top_srcdir)/lib/et/com_err.h \
+  $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h \
+  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/../version.h 
+pass1.o : $(srcdir)/pass1.c \
+  $(top_srcdir)/lib/et/com_err.h \
+  $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h 
+pass1b.o : $(srcdir)/pass1b.c \
+  $(top_srcdir)/lib/et/com_err.h \
+  $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h \
+  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h 
+pass2.o : $(srcdir)/pass2.c $(top_srcdir)/lib/et/com_err.h \
+  $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
+  $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h 
+pass3.o : $(srcdir)/pass3.c \
+  $(top_srcdir)/lib/et/com_err.h \
+  $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
+  $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h 
+pass4.o : $(srcdir)/pass4.c $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h \
+  $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/io.h \
+  $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h 
+pass5.o : $(srcdir)/pass5.c $(top_srcdir)/lib/et/com_err.h \
+  $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
+  $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h 
+badblocks.o : $(srcdir)/badblocks.c \
+  $(top_srcdir)/lib/et/com_err.h \
+  $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h \
+  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h 
+util.o : $(srcdir)/util.c \
+  $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+  $(top_srcdir)/lib/ext2fs/bitops.h 
+dirinfo.o : $(srcdir)/dirinfo.c $(top_srcdir)/lib/et/com_err.h \
+  $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
+  $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h 
+ehandler.o : $(srcdir)/ehandler.c \
+  $(srcdir)/e2fsck.h \
+  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+  $(top_srcdir)/lib/ext2fs/bitops.h 
+
diff --git a/e2fsck/badblocks.c b/e2fsck/badblocks.c
index 62f99c9..f0613d9 100644
--- a/e2fsck/badblocks.c
+++ b/e2fsck/badblocks.c
@@ -6,6 +6,9 @@
  */
 
 #include <time.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
 
 #include <et/com_err.h>
 #include "e2fsck.h"
@@ -16,7 +19,7 @@
 
 static void invalid_block(ext2_filsys fs, blk_t blk)
 {
-	printf("Bad block %lu out of range; ignored.\n", blk);
+	printf("Bad block %u out of range; ignored.\n", blk);
 	return;
 }
 
@@ -97,7 +100,7 @@
 	 */
 	if (*block_nr >= fs->super->s_blocks_count ||
 	    *block_nr < fs->super->s_first_data_block) {
-		printf("Warning illegal block %lu found in bad block inode.  Cleared.\n", *block_nr);
+		printf("Warning illegal block %u found in bad block inode.  Cleared.\n", *block_nr);
 		*block_nr = 0;
 		return BLOCK_CHANGED;
 	}
@@ -127,7 +130,7 @@
 	/*
 	 * Now run the bad blocks program
 	 */
-	sprintf(buf, "badblocks %s%s %ld", preen ? "" : "-s ",
+	sprintf(buf, "badblocks %s%s %d", preen ? "" : "-s ",
 		fs->device_name,
 		fs->super->s_blocks_count);
 	if (verbose)
diff --git a/e2fsck/e2fsck.8 b/e2fsck/e2fsck.8
index ca82963..bc12fc1 100644
--- a/e2fsck/e2fsck.8
+++ b/e2fsck/e2fsck.8
@@ -1,8 +1,8 @@
 .\" -*- nroff -*-
-.\" Copyright 1993, 1994 by Theodore Ts'o.  All Rights Reserved.
+.\" Copyright 1993, 1994, 1995 by Theodore Ts'o.  All Rights Reserved.
 .\" This file may be copied under the terms of the GNU Public License.
 .\" 
-.TH E2FSCK 8 "November 1994" "Version 0.5b"
+.TH E2FSCK 8 "October 1995" "Version 0.5c"
 .SH NAME
 e2fsck \- check a Linux second extended file system
 .SH SYNOPSIS
diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c
index 78fe3c9..e35e1ba 100644
--- a/e2fsck/e2fsck.c
+++ b/e2fsck/e2fsck.c
@@ -22,9 +22,16 @@
 #include <ctype.h>
 #include <termios.h>
 #include <time.h>
+#ifdef HAVE_GETOPT_H
 #include <getopt.h>
+#endif
 #include <unistd.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_MNTENT_H
 #include <mntent.h>
+#endif
 #include <sys/ioctl.h>
 #include <malloc.h>
 
@@ -36,6 +43,7 @@
 
 const char * program_name = "e2fsck";
 const char * device_name = NULL;
+const char * filesystem_name = NULL;
 
 /* Command line options */
 int nflag = 0;
@@ -99,24 +107,26 @@
 		       inodes_used, inodes, blocks_used, blocks);
 		return;
 	}
-	printf ("\n%6d inode%s used (%d%%)\n", inodes_used,
+	printf ("\n%8d inode%s used (%d%%)\n", inodes_used,
 		(inodes_used != 1) ? "s" : "",
 		100 * inodes_used / inodes);
-	printf ("%6d block%s used (%d%%)\n"
-		"%6d bad block%s\n", blocks_used,
+	printf ("         # of inodes with ind/dind/tind blocks: %d/%d/%d\n",
+		fs_ind_count, fs_dind_count, fs_tind_count);
+	printf ("%8d block%s used (%d%%)\n"
+		"%8d bad block%s\n", blocks_used,
 		(blocks_used != 1) ? "s" : "",
 		100 * blocks_used / blocks, fs_badblocks_count,
 		fs_badblocks_count != 1 ? "s" : "");
-	printf ("\n%6d regular file%s\n"
-		"%6d director%s\n"
-		"%6d character device file%s\n"
-		"%6d block device file%s\n"
-		"%6d fifo%s\n"
-		"%6d link%s\n"
-		"%6d symbolic link%s (%d fast symbolic link%s)\n"
-		"%6d socket%s\n"
-		"------\n"
-		"%6d file%s\n",
+	printf ("\n%8d regular file%s\n"
+		"%8d director%s\n"
+		"%8d character device file%s\n"
+		"%8d block device file%s\n"
+		"%8d fifo%s\n"
+		"%8d link%s\n"
+		"%8d symbolic link%s (%d fast symbolic link%s)\n"
+		"%8d socket%s\n"
+		"--------\n"
+		"%8d file%s\n",
 		fs_regular_count, (fs_regular_count != 1) ? "s" : "",
 		fs_directory_count, (fs_directory_count != 1) ? "ies" : "y",
 		fs_chardev_count, (fs_chardev_count != 1) ? "s" : "",
@@ -133,36 +143,26 @@
 
 static void check_mount(NOARGS)
 {
-	FILE * f;
-	struct mntent * mnt;
-	int cont;
-	int fd;
+	errcode_t	retval;
+	int		mount_flags, cont;
 
-	if ((f = setmntent (MOUNTED, "r")) == NULL)
+	retval = ext2fs_check_if_mounted(filesystem_name, &mount_flags);
+	if (retval) {
+		com_err("ext2fs_check_if_mount", retval,
+			"while determining whether %s is mounted.",
+			filesystem_name);
 		return;
-	while ((mnt = getmntent (f)) != NULL)
-		if (strcmp (device_name, mnt->mnt_fsname) == 0)
-			break;
-	endmntent (f);
-	if (!mnt)
+	}
+	if (!(mount_flags & EXT2_MF_MOUNTED))
 		return;
-
-	if  (!strcmp(mnt->mnt_dir, "/"))
-		root_filesystem = 1;
-
 	/*
 	 * If the root is mounted read-only, then /etc/mtab is
 	 * probably not correct; so we won't issue a warning based on
 	 * it.
 	 */
-	fd = open(MOUNTED, O_RDWR);
-	if (fd < 0) {
-		if (errno == EROFS) {
-			read_only_root = 1;
-			return;
-		}
-	} else
-		close(fd);
+	if ((mount_flags & EXT2_MF_ISROOT) &&
+	    (mount_flags & EXT2_MF_READONLY))
+		return;
 	
 	if (!rwflag) {
 		printf("Warning!  %s is mounted.\n", device_name);
@@ -217,6 +217,7 @@
 	blk_t	blocks_per_group = fs->super->s_blocks_per_group;
 	int	i;
 	blk_t	should_be;
+	errcode_t retval;
 
 	/*
 	 * Verify the super block constants...
@@ -241,6 +242,23 @@
 	check_super_value("r_blocks_count", s->s_r_blocks_count,
 			  MAX_CHECK, 0, s->s_blocks_count);
 
+	retval = ext2fs_get_device_size(filesystem_name, EXT2_BLOCK_SIZE(s),
+					&should_be);
+	if (retval) {
+		com_err("ext2fs_get_device_size", retval,
+			"while trying to check physical size of filesystem");
+		fatal_error(0);
+	}
+	if (should_be < s->s_blocks_count) {
+		printf("The filesystem size (according to the superblock) is %d blocks\n", s->s_blocks_count);
+		printf("The physical size of the device is %d blocks\n",
+		       should_be);
+		printf("Either the superblock or the partition table is likely to be corrupt!\n");
+		preenhalt(fs);
+		if (ask("Abort", 1))
+			fatal_error(0);
+	}
+
 	if (s->s_log_block_size != s->s_log_frag_size) {
 		printf("Superblock block_size = %d, fragsize = %d.\n",
 		       EXT2_BLOCK_SIZE(s), EXT2_FRAG_SIZE(s));
@@ -253,16 +271,16 @@
 	should_be = s->s_frags_per_group /
 		(s->s_log_block_size - s->s_log_frag_size + 1);
 	if (s->s_blocks_per_group != should_be) {
-		printf("Superblock blocks_per_group = %lu, should "
-		       "have been %lu\n", s->s_blocks_per_group,
+		printf("Superblock blocks_per_group = %u, should "
+		       "have been %u\n", s->s_blocks_per_group,
 		       should_be);
 		printf(corrupt_msg);
 	}
 
 	should_be = (s->s_log_block_size == 0) ? 1 : 0;
 	if (s->s_first_data_block != should_be) {
-		printf("Superblock first_data_block = %lu, should "
-		       "have been %lu\n", s->s_first_data_block,
+		printf("Superblock first_data_block = %u, should "
+		       "have been %u\n", s->s_first_data_block,
 		       should_be);
 		printf(corrupt_msg);
 	}
@@ -278,12 +296,12 @@
 			last_block = fs->super->s_blocks_count;
 		if ((fs->group_desc[i].bg_block_bitmap < first_block) ||
 		    (fs->group_desc[i].bg_block_bitmap >= last_block)) {
-			printf("Block bitmap %lu for group %d is "
-			       "not in group.\n",
-			       fs->group_desc[i].bg_block_bitmap, i);
-			preenhalt();
-			if (!ask("Continue (and relocate)", 1)) {
-				fatal_error(0);
+			printf("Block bitmap for group %d is not in group.  "
+			       "(block %u)\n",
+			       i, fs->group_desc[i].bg_block_bitmap);
+			preenhalt(fs);
+			if (!ask("Relocate", 1)) {
+				fatal_error("Block bitmap not in group");
 			}
 			fs->group_desc[i].bg_block_bitmap = 0;
 			invalid_block_bitmap[i]++;
@@ -291,12 +309,12 @@
 		}
 		if ((fs->group_desc[i].bg_inode_bitmap < first_block) ||
 		    (fs->group_desc[i].bg_inode_bitmap >= last_block)) {
-			printf("Warning: Inode bitmap %lu for group %d "
-			       "not in group.\n",
-			       fs->group_desc[i].bg_inode_bitmap, i);
-			preenhalt();
-			if (!ask("Continue", 1)) {
-				fatal_error(0);
+			printf("Inode bitmap group %d not in group.  "
+			       "(block %u)\n",
+			       i, fs->group_desc[i].bg_inode_bitmap);
+			preenhalt(fs);
+			if (!ask("Relocate", 1)) {
+				fatal_error("Inode bitmap not in group");
 			}
 			fs->group_desc[i].bg_inode_bitmap = 0;
 			invalid_inode_bitmap[i]++;
@@ -305,13 +323,13 @@
 		if ((fs->group_desc[i].bg_inode_table < first_block) ||
 		    ((fs->group_desc[i].bg_inode_table +
 		      fs->inode_blocks_per_group - 1) >= last_block)) {
-			printf("Warning: Inode table %lu for group %d "
-			       "not in group.\n",
-			       fs->group_desc[i].bg_inode_table, i);
+			printf("Inode table for group %d not in group.  "
+			       "(block %u)\n",
+			       i, fs->group_desc[i].bg_inode_table);
 			printf("WARNING: SEVERE DATA LOSS POSSIBLE.\n");
-			preenhalt();
-			if (!ask("Continue", 1)) {
-				fatal_error(0);
+			preenhalt(fs);
+			if (!ask("Relocate", 1)) {
+				fatal_error("Inode table not in group");
 			}
 			fs->group_desc[i].bg_inode_table = 0;
 			invalid_inode_table[i]++;
@@ -349,11 +367,17 @@
 		return;
 	}
 	if (fs->super->s_state & EXT2_VALID_FS) {
-		printf("%s is clean, no check.\n", device_name);
+		printf("%s: clean, %d/%d files, %d/%d blocks\n", device_name,
+		       fs->super->s_inodes_count - fs->super->s_free_inodes_count,
+		       fs->super->s_inodes_count,
+		       fs->super->s_blocks_count - fs->super->s_free_blocks_count,
+		       fs->super->s_blocks_count);
 		exit(FSCK_OK);
 	}
 }	
 
+#define PATH_SET "PATH=/sbin"
+
 static void PRS(int argc, char *argv[])
 {
 	int		flush = 0;
@@ -361,14 +385,21 @@
 #ifdef MTRACE
 	extern void	*mallwatch;
 #endif
-	char		*oldpath;
-	static char	newpath[PATH_MAX];
+	char		*oldpath = getenv("PATH");
 
 	/* Update our PATH to include /sbin  */
-	strcpy(newpath, "PATH=/sbin:");
-	if ((oldpath = getenv("PATH")) != NULL)
-		strcat(newpath, oldpath);
-	putenv(newpath);
+	if (oldpath) {
+		char *newpath;
+
+		newpath = malloc(sizeof (PATH_SET) + 1 + strlen (oldpath));
+		if (!newpath)
+			fatal_error("Couldn't malloc() newpath");
+		strcpy (newpath, PATH_SET);
+		strcat (newpath, ":");
+		strcat (newpath, oldpath);
+		putenv (newpath);
+	} else
+		putenv (PATH_SET);
 
 	setbuf(stdout, NULL);
 	setbuf(stderr, NULL);
@@ -376,7 +407,7 @@
 	
 	if (argc && *argv)
 		program_name = *argv;
-	while ((c = getopt (argc, argv, "panyrcB:dfvtFVM:b:I:P:l:L:")) != EOF)
+	while ((c = getopt (argc, argv, "panyrcB:dfvtFVM:b:I:P:l:L:N:")) != EOF)
 		switch (c) {
 		case 'p':
 		case 'a':
@@ -427,7 +458,11 @@
 			force = 1;
 			break;
 		case 'F':
+#ifdef BLKFLSBUF
 			flush = 1;
+#else
+			fatal_error ("-F not supported");
+#endif
 			break;
 		case 'v':
 			verbose = 1;
@@ -440,6 +475,9 @@
 			mallwatch = (void *) strtol(optarg, NULL, 0);
 			break;
 #endif
+		case 'N':
+			device_name = optarg;
+			break;
 		default:
 			usage ();
 		}
@@ -449,21 +487,27 @@
 		usage ();
 	if (nflag && !bad_blocks_file && !cflag)
 		rwflag = 0;
-	device_name = argv[optind];
+	filesystem_name = argv[optind];
+	if (device_name == 0)
+		device_name = filesystem_name;
 	if (flush) {
-		int	fd = open(device_name, O_RDONLY, 0);
+#ifdef BLKFLSBUF
+		int	fd = open(filesystem_name, O_RDONLY, 0);
 
 		if (fd < 0) {
 			com_err("open", errno, "while opening %s for flushing",
-				device_name);
+				filesystem_name);
 			exit(FSCK_ERROR);
 		}
 		if (ioctl(fd, BLKFLSBUF, 0) < 0) {
 			com_err("BLKFLSBUF", errno, "while trying to flush %s",
-				device_name);
+				filesystem_name);
 			exit(FSCK_ERROR);
 		}
 		close(fd);
+#else
+		fatal_error ("BLKFLSBUF not supported");
+#endif /* BLKFLSBUF */
 	}
 }
 					
@@ -502,12 +546,13 @@
 restart:
 	sync_disks();
 	if (superblock && blocksize) {
-		retval = ext2fs_open(device_name, rwflag ? EXT2_FLAG_RW : 0,
+		retval = ext2fs_open(filesystem_name,
+				     rwflag ? EXT2_FLAG_RW : 0,
 				     superblock, blocksize, unix_io_manager,
 				     &fs);
 	} else if (superblock) {
 		for (i=0; possible_block_sizes[i]; i++) {
-			retval = ext2fs_open(device_name,
+			retval = ext2fs_open(filesystem_name,
 					     rwflag ? EXT2_FLAG_RW : 0,
 					     superblock,
 					     possible_block_sizes[i],
@@ -516,22 +561,38 @@
 				break;
 		}
 	} else 
-		retval = ext2fs_open(device_name, rwflag ? EXT2_FLAG_RW : 0,
+		retval = ext2fs_open(filesystem_name,
+				     rwflag ? EXT2_FLAG_RW : 0,
 				     0, 0, unix_io_manager, &fs);
 	if (retval) {
 		com_err(program_name, retval, "while trying to open %s",
-			device_name);
-		if (retval == EXT2_ET_REV_TOO_HIGH)
+			filesystem_name);
+		switch (retval) {
+		case EXT2_ET_REV_TOO_HIGH:
 			printf ("Get a newer version of e2fsck!\n");
-		else
+			break;
+		case EXT2_ET_SHORT_READ:
+			printf ("Could this be a zero-length partition?\n");
+			break;
+		case EPERM:
+		case EACCES:
+			printf("You must have %s access to the "
+			       "filesystem or be root\n",
+			       rwflag ? "r/w" : "r/o");
+			break;
+		case ENXIO:
+			printf("Possibly non-existent or swap device?\n");
+			break;
+		default:
 			printf(corrupt_msg);
+		}
 		fatal_error(0);
 	}
 
 #ifdef	EXT2_CURRENT_REV
 	if (fs->super->s_rev_level > E2FSCK_CURRENT_REV) {
 		com_err(program_name, retval, "while trying to open %s",
-			device_name);
+			filesystem_name);
 		printf ("Get a newer version of e2fsck!\n");
 		fatal_error(0);
 	}
@@ -569,6 +630,9 @@
 	ext2fs_mark_valid(fs);
 	
 	pass1(fs);
+	free(invalid_inode_bitmap);
+	free(invalid_block_bitmap);
+	free(invalid_inode_table);
 	if (restart_e2fsck) {
 		ext2fs_close(fs);
 		printf("Restarting e2fsck from the beginning...\n");
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index e978844..debd56a 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -10,11 +10,12 @@
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
-#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/time.h>
 
+#ifdef HAVE_LINUX_FS_H
 #include <linux/fs.h>
+#endif
 #include <linux/ext2_fs.h>
 
 #include "ext2fs/ext2fs.h"
@@ -134,6 +135,9 @@
 extern int fs_total_count;
 extern int fs_badblocks_count;
 extern int fs_sockets_count;
+extern int fs_ind_count;
+extern int fs_dind_count;
+extern int fs_tind_count;
 
 extern struct resource_track	global_rtrack;
 
@@ -173,7 +177,7 @@
 extern void fatal_error (const char * fmt_string);
 extern void read_bitmaps(ext2_filsys fs);
 extern void write_bitmaps(ext2_filsys fs);
-extern void preenhalt(NOARGS);
+extern void preenhalt(ext2_filsys fs);
 extern void print_resource_track(struct resource_track *track);
 extern void init_resource_track(struct resource_track *track);
 extern int inode_has_valid_blocks(struct ext2_inode *inode);
diff --git a/e2fsck/ehandler.c b/e2fsck/ehandler.c
index 4873a95..131a0ab 100644
--- a/e2fsck/ehandler.c
+++ b/e2fsck/ehandler.c
@@ -11,10 +11,12 @@
 #include <string.h>
 #include <ctype.h>
 #include <termios.h>
-#include <sys/resource.h>
 
 #include "e2fsck.h"
 
+#include <sys/time.h>
+#include <sys/resource.h>
+
 static const char *operation;
 
 static errcode_t e2fsck_handle_read_error(io_channel channel,
@@ -49,7 +51,7 @@
 	else
 		printf("Error reading block %lu (%s).  ", block,
 		       error_message(error));
-	preenhalt();
+	preenhalt(NULL);
 	if (ask("Ignore error", 1))
 		return 0;
 
@@ -89,7 +91,7 @@
 	else
 		printf("Error writing block %lu (%s).  ", block,
 		       error_message(error));
-	preenhalt();
+	preenhalt(NULL);
 	if (ask("Ignore error", 1))
 		return 0;
 
diff --git a/e2fsck/extend.c b/e2fsck/extend.c
new file mode 100644
index 0000000..646348d
--- /dev/null
+++ b/e2fsck/extend.c
@@ -0,0 +1,80 @@
+/*
+ * extend.c --- extend a file so that it has at least a specified
+ * 	number of blocks.
+ * 
+ * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
+ *
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+static void usage(char *progname)
+{
+	fprintf(stderr, "%s: %s filename nblocks blocksize\n",
+		progname, progname);
+	exit(1);
+}
+
+
+int main(int argc, char **argv)
+{
+	char	*filename;
+	int	nblocks, blocksize;
+	int	fd;
+	char	*block;
+	int	ret;
+
+	if (argc != 4)
+		usage(argv[0]);
+
+	filename = argv[1];
+	nblocks = strtoul(argv[2], 0, 0) - 1;
+	blocksize = strtoul(argv[3], 0, 0);
+
+	if (nblocks < 0) {
+		fprintf(stderr, "Illegal number of blocks!\n");
+		exit(1);
+	}
+
+	block = malloc(blocksize);
+	if (block == 0) {
+		fprintf(stderr, "Couldn't allocate block buffer(size=%d)\n",
+			blocksize);
+		exit(1);
+	}
+	memset(block, 0, blocksize);
+
+	fd = open(filename, O_RDWR);
+	if (fd < 0) {
+		perror(filename);
+		exit(1);
+	}
+	ret = lseek(fd, nblocks*blocksize, SEEK_SET);
+	if (ret < 0) {
+		perror("lseek");
+		exit(1);
+	}
+	ret = read(fd, block, blocksize);
+	if (ret < 0) {
+		perror("read");
+		exit(1);
+	}
+	ret = lseek(fd, nblocks*blocksize, SEEK_SET);
+	if (ret < 0) {
+		perror("lseek #2");
+		exit(1);
+	}
+	ret = write(fd, block, blocksize);
+	if (ret < 0) {
+		perror("read");
+		exit(1);
+	}
+	exit(0);
+}
diff --git a/e2fsck/flushb.c b/e2fsck/flushb.c
index eba4e85..20b9917 100644
--- a/e2fsck/flushb.c
+++ b/e2fsck/flushb.c
@@ -9,7 +9,9 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 
+#ifdef HAVE_LINUX_FS_H
 #include <linux/fs.h>
+#endif
 
 #ifdef __STDC__
 #define NOARGS void
@@ -43,9 +45,15 @@
 	 * Note: to reread the partition table, use the ioctl
 	 * BLKRRPART instead of BLKFSLBUF.
 	 */
+#ifdef BLKFLSBUF
 	if (ioctl(fd, BLKFLSBUF, 0) < 0) {
-		perror("ioctl");
+		perror("ioctl BLKFLSBUF");
 		exit(1);
 	}
 	return 0;
+#else
+	fprintf(stderr,
+		"BLKFLSBUF ioctl not supported!  Can't flush buffers.\n");
+	return 1;
+#endif
 }
diff --git a/e2fsck/images/README b/e2fsck/images/README
deleted file mode 100644
index 73e2681..0000000
--- a/e2fsck/images/README
+++ /dev/null
@@ -1,67 +0,0 @@
-These images contain various forms of corrupted filesystem which
-e2fsck will correct.  They are used as a regression test for e2fsck.
-
-The test_script program will automatically run e2fsck against the
-filesystem images.  It will run them two times, and display the exit
-status for each run.  The meaning of the exit status codes are as
-follows:
-
-	0		No filesystem errors were detected
-	1		Filesystem errors detected, but corrected
-	2		System should be rebooted
-	4		Filesystem errors left uncorrected
-	8		Operational error (generally means internal error,
-				or filesystem error that the e2fsck was not
-				prepared to deal with)
-	16		Usage or syntax error
-
-During the regression test, the first exit code should be 1, and the
-second exit code should be 0.  In other words, all (with one
-exception) of the test filesystems in this directory have some sort of
-filesystem corruption, which e2fsck should fix on the first pass.
-After the first pass, e2fsck should leave a fully consistent
-filesystem with no detectable errors found in the second pass.  The
-exception is the okgroup.img filesystem, which contains no errors, and
-so both exit codes should be 0.
-
-NOTE: It appears that at least some versions of the original e2fsck do
-not exit with an exit status code of 1 after correcting filesystem
-errors.  So if you modify the test_script to try running these
-filesystems against the original e2fsck, you will have to inspect the
-test_script.log file manually.
-
---------------------------------------------------------------
-Here's a one-line descriptons of the various test images in this
-directory:
-
-baddir.img		Filesystem with a corrupted directory
-badbblocks.img		Filesystem with illegal blocks in the bad block inode.
-badinode.img		Filesystem with various different corrupted inode
-				entries.
-badlkcnt.img		Filesystem with deleted files with non-zero link count
-badroot.img		Filesystem with a file for a root directory
-badtable.img		Filesystem with blocks shared between the bitmaps and
-				inode table blocks and the bad block inode
-bbfile.img		Filesystem with files containing bad blocks
-bitmaps.img		Filesystem with corrupted inode and block bitmaps
-dirlink.img		Filesystem with a hard link to a directory
-dup.img			Filesystem with blocks claimed by two different files
-dup2.img		Filesystem with blocks claimed by three different files
-dupfsblks.img		Filesystem with blocks claimed by a file and
-				inode/block bitmaps and inode tables
-dupsuper.img		Filesystem with blocks claimed by a file and
-				the superblock / group descriptors
-end-bitmap.img		Filesystem with corruption at the end of the block 
-				bitmap
-expand.img		Tests e2fsck's ability to expand lost+found if 
-				necessary
-lpf.img			Filesystem with disconnected files and no /lost+found 
-				directory
-mke2fs2b.img		Filesystem with corruption similar to that
-				created by mke2fs version 0.2b
-noroot.img		Filesystem with a deleted root directory
-okgroup.img		Filesystem that's exactly 8193 blocks long 
-				(otherwise OK)
-overfsblks.img		Filesystem with overlapping inode and block bitmaps
-
-
diff --git a/e2fsck/images/badbblocks.img.gz b/e2fsck/images/badbblocks.img.gz
deleted file mode 100644
index 3fd89cb..0000000
--- a/e2fsck/images/badbblocks.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/baddir.img.gz b/e2fsck/images/baddir.img.gz
deleted file mode 100644
index c7af6c5..0000000
--- a/e2fsck/images/baddir.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/badinode.img.gz b/e2fsck/images/badinode.img.gz
deleted file mode 100644
index 7d10bc1..0000000
--- a/e2fsck/images/badinode.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/badlkcnt.img.gz b/e2fsck/images/badlkcnt.img.gz
deleted file mode 100644
index 96509f5..0000000
--- a/e2fsck/images/badlkcnt.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/badroot.img.gz b/e2fsck/images/badroot.img.gz
deleted file mode 100644
index 5724105..0000000
--- a/e2fsck/images/badroot.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/badtable.img.gz b/e2fsck/images/badtable.img.gz
deleted file mode 100644
index 72934ce..0000000
--- a/e2fsck/images/badtable.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/bbfile.img.gz b/e2fsck/images/bbfile.img.gz
deleted file mode 100644
index 1924a3f..0000000
--- a/e2fsck/images/bbfile.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/bitmapblks.img.gz b/e2fsck/images/bitmapblks.img.gz
deleted file mode 100644
index d5aa60f..0000000
--- a/e2fsck/images/bitmapblks.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/bitmaps.img.gz b/e2fsck/images/bitmaps.img.gz
deleted file mode 100644
index 7eff4fc..0000000
--- a/e2fsck/images/bitmaps.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/dirlink.img.gz b/e2fsck/images/dirlink.img.gz
deleted file mode 100644
index 7e1694a..0000000
--- a/e2fsck/images/dirlink.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/dup.img.gz b/e2fsck/images/dup.img.gz
deleted file mode 100644
index f901f19..0000000
--- a/e2fsck/images/dup.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/dup2.img.gz b/e2fsck/images/dup2.img.gz
deleted file mode 100644
index f5fcd37..0000000
--- a/e2fsck/images/dup2.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/dupfsblks.img.gz b/e2fsck/images/dupfsblks.img.gz
deleted file mode 100644
index d3fd2a1..0000000
--- a/e2fsck/images/dupfsblks.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/dupsuper.img.gz b/e2fsck/images/dupsuper.img.gz
deleted file mode 100644
index f5c2f3e..0000000
--- a/e2fsck/images/dupsuper.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/end-bitmap.img.gz b/e2fsck/images/end-bitmap.img.gz
deleted file mode 100644
index b83478f..0000000
--- a/e2fsck/images/end-bitmap.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/expand.img.gz b/e2fsck/images/expand.img.gz
deleted file mode 100644
index 0ea6729..0000000
--- a/e2fsck/images/expand.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/illfsblks.img.gz b/e2fsck/images/illfsblks.img.gz
deleted file mode 100644
index f218c57..0000000
--- a/e2fsck/images/illfsblks.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/lotsbad.img.gz b/e2fsck/images/lotsbad.img.gz
deleted file mode 100644
index 8e49295..0000000
--- a/e2fsck/images/lotsbad.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/lpf.img.gz b/e2fsck/images/lpf.img.gz
deleted file mode 100644
index 527c09b..0000000
--- a/e2fsck/images/lpf.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/messy_inode.img.gz b/e2fsck/images/messy_inode.img.gz
deleted file mode 100644
index a7eab4a..0000000
--- a/e2fsck/images/messy_inode.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/mke2fs2b.img.gz b/e2fsck/images/mke2fs2b.img.gz
deleted file mode 100644
index 9716a13..0000000
--- a/e2fsck/images/mke2fs2b.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/noroot.img.gz b/e2fsck/images/noroot.img.gz
deleted file mode 100644
index 3e597f3..0000000
--- a/e2fsck/images/noroot.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/okgroup.img.gz b/e2fsck/images/okgroup.img.gz
deleted file mode 100644
index e353032..0000000
--- a/e2fsck/images/okgroup.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/overfsblks.img.gz b/e2fsck/images/overfsblks.img.gz
deleted file mode 100644
index 15f391f..0000000
--- a/e2fsck/images/overfsblks.img.gz
+++ /dev/null
Binary files differ
diff --git a/e2fsck/images/test_script b/e2fsck/images/test_script
deleted file mode 100644
index c0842ef..0000000
--- a/e2fsck/images/test_script
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-#
-# Test script for e2fsck
-#
-
-FSCK=../e2fsck
-SECOND_FSCK=$FSCK
-FSCK_OPT=-yft
-SECOND_FSCK_OPT=$FSCK_OPT
-
-#
-# Uncomment to test against original e2fsck
-#
-#FSCK=/u4/src/e2fsprogs-0.3c/e2fsck
-#FSCK_OPT=-af
-
-OUTFILE=test_script.log
-
-cp /dev/null $OUTFILE
-
-for i in *.img.gz
-do
-	echo -n "Testing $i...	"
-	echo "Testing $i..." >> $OUTFILE
-	gunzip < $i > /tmp/$i.$$
-	echo $FSCK $FSCK_OPT /tmp/$i.$$  >> $OUTFILE
-	$FSCK $FSCK_OPT /tmp/$i.$$  >> $OUTFILE 2>&1 
-	status=$?
-	echo Exit status is $status >> $OUTFILE
-	echo " "  >> $OUTFILE
-	echo -n "Exit status $status	"
-	echo Running e2fsck again.... >> $OUTFILE
-	echo $SECOND_FSCK $SECOND_FSCK_OPT /tmp/$i.$$ >> $OUTFILE
-	$SECOND_FSCK $SECOND_FSCK_OPT /tmp/$i.$$ >> $OUTFILE 2>&1 
-	status=$?
-	echo Exit status is $status >> $OUTFILE
-	echo Exit status $status
-	rm /tmp/$i.$$
-	echo "---------------------------------------------------" >> $OUTFILE
-done
-	
-	
diff --git a/e2fsck/iscan.c b/e2fsck/iscan.c
new file mode 100644
index 0000000..d964b34
--- /dev/null
+++ b/e2fsck/iscan.c
@@ -0,0 +1,146 @@
+/*
+ * Test to see how quickly we can scan the inode table (not doing
+ * anything else)
+ */
+
+#include <string.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <termios.h>
+#include <time.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include <unistd.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_MNTENT_H
+#include <mntent.h>
+#endif
+#include <sys/ioctl.h>
+#include <malloc.h>
+
+#include "et/com_err.h"
+#include "e2fsck.h"
+#include "../version.h"
+
+extern int isatty(int);
+
+const char * program_name = "iscan";
+const char * device_name = NULL;
+
+int yflag = 0;
+int nflag = 0;
+int preen = 0;
+int inode_buffer_blocks = 0;
+int invalid_bitmaps = 0;
+
+struct resource_track	global_rtrack;
+
+static void usage(NOARGS)
+{
+	fprintf(stderr,
+		"Usage: %s [-F] [-I inode_buffer_blocks] device\n",
+		program_name);
+	exit(1);
+}
+
+static void PRS(int argc, char *argv[])
+{
+	int		flush = 0;
+	char		c;
+#ifdef MTRACE
+	extern void	*mallwatch;
+#endif
+
+	setbuf(stdout, NULL);
+	setbuf(stderr, NULL);
+	initialize_ext2_error_table();
+	
+	if (argc && *argv)
+		program_name = *argv;
+	while ((c = getopt (argc, argv, "FI")) != EOF)
+		switch (c) {
+		case 'F':
+#ifdef BLKFLSBUF
+			flush = 1;
+#else
+			fatal_error ("-F not supported");
+#endif
+			break;
+		case 'I':
+			inode_buffer_blocks = atoi(optarg);
+			break;
+		default:
+			usage ();
+		}
+	device_name = argv[optind];
+	if (flush) {
+#ifdef BLKFLSBUF
+		int	fd = open(device_name, O_RDONLY, 0);
+
+		if (fd < 0) {
+			com_err("open", errno, "while opening %s for flushing",
+				device_name);
+			exit(FSCK_ERROR);
+		}
+		if (ioctl(fd, BLKFLSBUF, 0) < 0) {
+			com_err("BLKFLSBUF", errno, "while trying to flush %s",
+				device_name);
+			exit(FSCK_ERROR);
+		}
+		close(fd);
+#else
+		fatal_error ("BLKFLSBUF not supported");
+#endif /* BLKFLSBUF */
+	}
+}
+					
+int main (int argc, char *argv[])
+{
+	errcode_t	retval = 0;
+	int		exit_value = FSCK_OK;
+	ext2_filsys	fs;
+	ino_t	ino;
+	int	num_inodes = 0;
+	struct ext2_inode inode;
+	ext2_inode_scan	scan;
+	
+	init_resource_track(&global_rtrack);
+
+	PRS(argc, argv);
+
+	retval = ext2fs_open(device_name, 0,
+			     0, 0, unix_io_manager, &fs);
+	if (retval) {
+		com_err(program_name, retval, "while trying to open %s",
+			device_name);
+		exit(1);
+	}
+
+	ehandler_init(fs->io);
+	
+	retval = ext2fs_open_inode_scan(fs, inode_buffer_blocks, &scan);
+	if (retval) {
+		com_err(program_name, retval, "while opening inode scan");
+		fatal_error(0);
+	}
+
+	while (1) {
+		retval = ext2fs_get_next_inode(scan, &ino, &inode);
+		if (retval) {
+			com_err(program_name, retval,
+				"while getting next inode");
+			fatal_error(0);
+		}
+		if (ino == 0)
+			break;
+		num_inodes++;
+	}
+	
+	print_resource_track(&global_rtrack);
+	printf("%d inodes scanned.\n", num_inodes);
+	
+	exit(0);
+}
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 7eadea8..17b0939 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -31,10 +31,19 @@
  */
 
 #include <time.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
 
 #include <et/com_err.h>
 #include "e2fsck.h"
 
+#ifdef NO_INLINE_FUNCS
+#define _INLINE_
+#else
+#define _INLINE_ inline
+#endif
+
 /* Files counts */
 int fs_directory_count = 0;
 int fs_regular_count = 0;
@@ -47,6 +56,9 @@
 int fs_total_count = 0;
 int fs_badblocks_count = 0;
 int fs_sockets_count = 0;
+int fs_ind_count = 0;
+int fs_dind_count = 0;
+int fs_tind_count = 0;
 
 ext2fs_inode_bitmap inode_used_map = 0;	/* Inodes which are in use */
 ext2fs_inode_bitmap inode_bad_map = 0;	/* Inodes which are bad in some way */
@@ -54,6 +66,7 @@
 
 ext2fs_block_bitmap block_found_map = 0;
 ext2fs_block_bitmap block_dup_map = 0;
+ext2fs_block_bitmap block_illegal_map = 0;
 
 static int fix_link_count = -1;
 
@@ -75,6 +88,7 @@
 static int dir_block_cmp(const void *a, const void *b);
 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
 				  dgrp_t group, void * private);
+static char *describe_illegal_block(ext2_filsys fs, blk_t block);
 
 struct process_block_struct {
 	ino_t	ino;
@@ -125,7 +139,7 @@
 	free(dir_blocks);	dir_blocks = 0;
 	dir_block_size = 0;
 	if (block_dup_map) {
-		free(block_dup_map); block_dup_map = 0;
+		ext2fs_free_block_bitmap(block_dup_map); block_dup_map = 0;
 	}
 
 	/* Clear statistic counters */
@@ -140,6 +154,9 @@
 	fs_total_count = 0;
 	fs_badblocks_count = 0;
 	fs_sockets_count = 0;
+	fs_ind_count = 0;
+	fs_dind_count = 0;
+	fs_tind_count = 0;
 }
 
 void pass1(ext2_filsys fs)
@@ -184,6 +201,13 @@
 			"while allocating block_found_map");
 		fatal_error(0);
 	}
+	retval = ext2fs_allocate_block_bitmap(fs, "illegal block map",
+					      &block_illegal_map);
+	if (retval) {
+		com_err("ext2fs_allocate_block_bitmap", retval,
+			"while allocating block_illegal_map");
+		fatal_error(0);
+	}
 	inode_link_info = allocate_memory((fs->super->s_inodes_count + 1) *
 					  sizeof(unsigned short),
 					  "inode link count array");
@@ -241,9 +265,9 @@
 			 * not, offer to clear it.  It will be
 			 * regnerated in pass #3.
 			 */
-			if (!S_ISDIR(inode.i_mode)) {
+			if (!LINUX_S_ISDIR(inode.i_mode)) {
 				printf("Root inode is not a directory.  ");
-				preenhalt();
+				preenhalt(fs);
 				if (ask("Clear", 1)) {
 					inode.i_dtime = time(0);
 					inode.i_links_count = 0;
@@ -281,6 +305,15 @@
 		}
 		if ((ino != EXT2_ROOT_INO) && (ino < EXT2_FIRST_INO)) {
 			ext2fs_mark_inode_bitmap(inode_used_map, ino);
+			if (inode.i_mode != 0) {
+				printf("Reserved inode %lu has bad mode.  ", ino);
+				if (ask("Clear", 1)) {
+					inode.i_mode = 0;
+					e2fsck_write_inode(fs, ino, &inode,
+							   "pass1");
+				} else 
+					ext2fs_unmark_valid(fs);
+			}
 			check_blocks(fs, ino, &inode, block_buf);
 			goto next;
 		}
@@ -329,37 +362,46 @@
 		}
 		
 		ext2fs_mark_inode_bitmap(inode_used_map, ino);
-		if (inode.i_faddr || inode.i_frag || inode.i_fsize ||
-		    inode.i_file_acl || inode.i_dir_acl) {
+		if (inode.i_faddr
+#if HAVE_EXT2_FRAGS
+		    || inode.i_frag || inode.i_fsize
+#endif
+		    || inode.i_file_acl || inode.i_dir_acl) {
 			if (!inode_bad_map)
 				alloc_bad_map(fs);
 			ext2fs_mark_inode_bitmap(inode_bad_map, ino);
 		}
 		
-		if (S_ISDIR(inode.i_mode)) {
+		if (LINUX_S_ISDIR(inode.i_mode)) {
 			ext2fs_mark_inode_bitmap(inode_dir_map, ino);
 			add_dir_info(fs, ino, 0, &inode);
 			fs_directory_count++;
-		} else if (S_ISREG (inode.i_mode))
+		} else if (LINUX_S_ISREG (inode.i_mode))
 			fs_regular_count++;
-		else if (S_ISCHR (inode.i_mode))
+		else if (LINUX_S_ISCHR (inode.i_mode))
 			fs_chardev_count++;
-		else if (S_ISBLK (inode.i_mode))
+		else if (LINUX_S_ISBLK (inode.i_mode))
 			fs_blockdev_count++;
-		else if (S_ISLNK (inode.i_mode)) {
+		else if (LINUX_S_ISLNK (inode.i_mode)) {
 			fs_symlinks_count++;
 			if (!inode.i_blocks)
 				fs_fast_symlinks_count++;
 		}
-		else if (S_ISFIFO (inode.i_mode))
+		else if (LINUX_S_ISFIFO (inode.i_mode))
 			fs_fifo_count++;
-		else if (S_ISSOCK (inode.i_mode))
+		else if (LINUX_S_ISSOCK (inode.i_mode))
 		        fs_sockets_count++;
 		else {
 			if (!inode_bad_map)
 				alloc_bad_map(fs);
 			ext2fs_mark_inode_bitmap(inode_bad_map, ino);
 		}
+		if (inode.i_block[EXT2_IND_BLOCK])
+			fs_ind_count++;
+		if (inode.i_block[EXT2_DIND_BLOCK])
+			fs_dind_count++;
+		if (inode.i_block[EXT2_TIND_BLOCK])
+			fs_tind_count++;
 		if (inode.i_block[EXT2_IND_BLOCK] ||
 		    inode.i_block[EXT2_DIND_BLOCK] ||
 		    inode.i_block[EXT2_TIND_BLOCK]) {
@@ -397,7 +439,7 @@
 	if (block_dup_map) {
 		if (preen) {
 			printf("Duplicate or bad blocks in use!\n");
-			preenhalt();
+			preenhalt(fs);
 		}
 		pass1_dupblocks(fs, block_buf);
 	}
@@ -406,6 +448,9 @@
 	free(inodes_to_process);
 endit:
 	free(block_buf);
+	ext2fs_free_block_bitmap(block_illegal_map);
+	block_illegal_map = 0;
+	
 	if (tflag > 1) {
 		printf("Pass 1: ");
 		print_resource_track(&rtrack);
@@ -446,7 +491,7 @@
 		ino = inodes_to_process[i].ino;
 		stashed_ino = ino;
 #if 0
-		printf("%lu ", ino);
+		printf("%u ", ino);
 #endif
 		sprintf(buf, "reading indirect blocks of inode %lu", ino);
 		ehandler_operation(buf);
@@ -479,7 +524,13 @@
 	const struct dir_block_struct *db_b =
 		(const struct dir_block_struct *) b;
 
-	return (db_a->blk - db_b->blk);
+	if (db_a->blk != db_b->blk)
+		return (db_a->blk - db_b->blk);
+	
+	if (db_a->ino != db_b->ino)
+		return (db_a->ino - db_b->ino);
+
+	return (db_a->blockcnt - db_b->blockcnt);
 }
 
 /*
@@ -501,12 +552,15 @@
 /*
  * Marks a block as in use, setting the dup_map if it's been set
  * already.  Called by process_block and process_bad_block.
+ *
+ * WARNING: Assumes checks have already been done to make sure block
+ * is valid.  This is true in both process_block and process_bad_block.
  */
-static void mark_block_used(ext2_filsys fs, blk_t block)
+static _INLINE_ void mark_block_used(ext2_filsys fs, blk_t block)
 {
 	errcode_t	retval;
 	
-	if (ext2fs_test_block_bitmap(block_found_map, block)) {
+	if (ext2fs_fast_test_block_bitmap(block_found_map, block)) {
 		if (!block_dup_map) {
 			retval = ext2fs_allocate_block_bitmap(fs,
 			      "multiply claimed block map", &block_dup_map);
@@ -516,9 +570,9 @@
 				fatal_error(0);
 			}
 		}
-		ext2fs_mark_block_bitmap(block_dup_map, block);
+		ext2fs_fast_mark_block_bitmap(block_dup_map, block);
 	} else {
-		ext2fs_mark_block_bitmap(block_found_map, block);
+		ext2fs_fast_mark_block_bitmap(block_found_map, block);
 	}
 }
 
@@ -539,11 +593,12 @@
 	pb.num_blocks = pb.last_block = 0;
 	pb.num_illegal_blocks = 0;
 	pb.suppress = pb.clear = 0;
-	pb.is_dir = S_ISDIR(inode->i_mode);
+	pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
 	pb.fix = -1;
 	pb.inode = inode;
-	retval = ext2fs_block_iterate(fs, ino, 0, block_buf,
-				      process_block, &pb);
+	retval = ext2fs_block_iterate(fs, ino,
+				      pb.is_dir ? BLOCK_FLAG_HOLE : 0,
+				      block_buf, process_block, &pb);
 	if (retval)
 		com_err(program_name, retval,
 			"while calling ext2fs_block_iterate in check_blocks");
@@ -575,7 +630,7 @@
 
 	pb.num_blocks *= (fs->blocksize / 512);
 #if 0
-	printf("inode %lu, i_size = %lu, last_block = %lu, i_blocks=%lu, num_blocks = %lu\n",
+	printf("inode %u, i_size = %lu, last_block = %lu, i_blocks=%lu, num_blocks = %lu\n",
 	       ino, inode->i_size, pb.last_block, inode->i_blocks,
 	       pb.num_blocks);
 #endif
@@ -589,12 +644,14 @@
 			ext2fs_unmark_inode_bitmap(inode_dir_map, ino);
 			ext2fs_unmark_inode_bitmap(inode_used_map, ino);
 			fs_directory_count--;
+			pb.is_dir = 0;
 		} else
 			ext2fs_unmark_valid(fs);
 	}
-	if (inode->i_size < pb.last_block * fs->blocksize) {
-		printf ("Inode %lu, incorrect size, %lu (counted = %u). ",
-			ino, inode->i_size,
+	if ((pb.is_dir && (inode->i_size != (pb.last_block + 1) * fs->blocksize)) ||
+	    (inode->i_size < pb.last_block * fs->blocksize)) {
+		printf ("%s %lu, incorrect size, %u (counted = %u). ",
+			pb.is_dir ? "Directory" : "Inode", ino, inode->i_size,
 			(pb.last_block+1) * fs->blocksize);
 		if (ask ("Set size to counted", 1)) {
 			inode->i_size = (pb.last_block+1) * fs->blocksize;
@@ -603,7 +660,7 @@
 			ext2fs_unmark_valid(fs);
 	}
 	if (pb.num_blocks != inode->i_blocks) {
-		printf ("Inode %lu, i_blocks wrong %lu (counted=%u).  ",
+		printf ("Inode %lu, i_blocks wrong %u (counted=%u).  ",
 			ino, inode->i_blocks, pb.num_blocks);
 		if (ask ("Set i_blocks to counted", 1)) {
 			inode->i_blocks = pb.num_blocks;
@@ -611,7 +668,57 @@
 		} else
 				ext2fs_unmark_valid(fs);
 	}
-}	
+}
+
+/*
+ * Helper function called by process block when an illegal block is
+ * found.  It returns a description about why the block is illegal
+ */
+static char *describe_illegal_block(ext2_filsys fs, blk_t block)
+{
+	blk_t	super;
+	int	i;
+	static char	problem[80];
+
+	super = fs->super->s_first_data_block;
+	strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
+	if (block < super) {
+		sprintf(problem, "< FIRSTBLOCK (%u)", super);
+		return(problem);
+	} else if (block >= fs->super->s_blocks_count) {
+		sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
+		return(problem);
+	}
+	for (i = 0; i < fs->group_desc_count; i++) {
+		if (block == super) {
+			sprintf(problem, "is the superblock in group %d", i);
+			break;
+		}
+		if (block > super &&
+		    block <= (super + fs->desc_blocks)) {
+			sprintf(problem, "is in the group descriptors "
+				"of group %d", i);
+			break;
+		}
+		if (block == fs->group_desc[i].bg_block_bitmap) {
+			sprintf(problem, "is the block bitmap of group %d", i);
+			break;
+		}
+		if (block == fs->group_desc[i].bg_inode_bitmap) {
+			sprintf(problem, "is the inode bitmap of group %d", i);
+			break;
+		}
+		if (block >= fs->group_desc[i].bg_inode_table &&
+		    (block < fs->group_desc[i].bg_inode_table
+		     + fs->inode_blocks_per_group)) {
+			sprintf(problem, "is in the inode table of group %d",
+				i);
+			break;
+		}
+		super += fs->super->s_blocks_per_group;
+	}
+	return(problem);
+}
 
 /*
  * This is a helper function for check_blocks().
@@ -622,55 +729,41 @@
 		  void *private)
 {
 	struct process_block_struct *p;
-	int	group;
-	int	illegal_block = 0;
-	char	problem[80];
-	blk_t	firstblock, group_super;
+	char	*problem;
 	blk_t	blk = *block_nr;
+	int	ret_code = 0;
 
-	if (!blk)
-		return 0;
 	p = (struct process_block_struct *) private;
 
-#if 0
-	printf("Process_block, inode %lu, block %lu, #%d\n", p->ino, blk,
-	       blockcnt);
-#endif	
-	
-	firstblock = fs->super->s_first_data_block;
-	group = (blk - firstblock) / fs->super->s_blocks_per_group;
-	group_super = ((group * fs->super->s_blocks_per_group) +
-		       fs->super->s_first_data_block);
-	if (blk < firstblock) {
-		sprintf(problem, "< FIRSTBLOCK (%lu)", firstblock);
-		illegal_block++;
-	} else if (blk >= fs->super->s_blocks_count) {
-		sprintf(problem, "> BLOCKS (%lu)", fs->super->s_blocks_count);
-		illegal_block++;
-	} else if (blk == group_super) {
-		sprintf(problem, "is the superblock in group %d", group);
-		illegal_block++;
-	} else if (blk > group_super &&
-		   blk <= (group_super + fs->desc_blocks)) {
-		sprintf(problem, "is in the group descriptors in group %d",
-			group);
-		illegal_block++;
-	} else if (blk == fs->group_desc[group].bg_block_bitmap) {
-		sprintf(problem, "is the block bitmap of group %d", group);
-		illegal_block++;
-	} else if (blk == fs->group_desc[group].bg_inode_bitmap) {
-		sprintf(problem, "is the inode bitmap of group %d", group);
-		illegal_block++;
-	} else if (blk >= fs->group_desc[group].bg_inode_table &&
-		   blk < fs->group_desc[group].bg_inode_table + fs->inode_blocks_per_group) {
-		sprintf(problem, "is in the inode table of group %d", group);
-		illegal_block++;
+	if (blk == 0) {
+		if (p->is_dir == 0) {
+			printf("process_block() called with blk == 0, "
+			       "inode %lu???", p->ino);
+			return 0;
+		}
+		if (blockcnt < 0)
+			return 0;
+		if (blockcnt * fs->blocksize < p->inode->i_size) {
+			printf("Hole found in directory inode %lu!  "
+			       "(blkcnt=%d)\n", p->ino, blockcnt);
+			goto mark_dir;
+		}
+		return 0;
 	}
-	if (illegal_block) {
+
+#if 0
+	printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
+	       blockcnt);
+#endif
+	
+	if (blk < fs->super->s_first_data_block ||
+	    blk >= fs->super->s_blocks_count ||
+	    ext2fs_test_block_bitmap(block_illegal_map, blk)) {
+		problem = describe_illegal_block(fs, blk);
 		if (preen) {
-			printf("Block %lu of inode %lu %s\n", blk, p->ino,
+			printf("Block %u of inode %lu %s\n", blk, p->ino,
 			       problem);
-			preenhalt();
+			preenhalt(fs);
 		}
 		if (p->fix == -1) {
 			printf("Remove illegal block(s) in inode %lu", p->ino);
@@ -689,28 +782,34 @@
 			}
 		}
 		if (!p->suppress)
-			printf("Block #%d (%lu) %s.  %s\n", blockcnt, blk,
+			printf("Block #%d (%u) %s.  %s\n", blockcnt, blk,
 			       problem, clear_msg[p->fix]);
 		if (p->fix) {
-			*block_nr = 0;
-			return BLOCK_CHANGED;
+			blk = *block_nr = 0;
+			ret_code = BLOCK_CHANGED;
+			goto mark_dir;
 		} else {
 			ext2fs_unmark_valid(fs);
 			return 0;
 		}
 	}
 
-	p->num_blocks++;
-	if (blockcnt > 0)
-		p->last_block = blockcnt;
 	mark_block_used(fs, blk);
+	p->num_blocks++;
+	if (blockcnt < 0)
+		return 0;
 	
-	if (p->is_dir && (blockcnt >= 0)) {
+	p->last_block = blockcnt;
+mark_dir:
+	if (p->is_dir) {
 		if (dir_block_count >= dir_block_size) {
 			dir_block_size += 100;
 			dir_blocks = realloc(dir_blocks,
 					     dir_block_size *
 					     sizeof(struct dir_block_struct));
+			if (dir_blocks == 0)
+				fatal_error("Not enough memory to "
+					    "realloc dir_blocks");
 		}
 
 		dir_blocks[dir_block_count].blk = blk;
@@ -718,19 +817,13 @@
 		dir_blocks[dir_block_count].blockcnt = blockcnt;
 		dir_block_count++;
 	}
-	
-#if 0
-	printf("process block, inode %lu, block #%d is %lu\n",
-	       p->ino, blockcnt, blk);
-#endif
-	
-	return 0;
+	return ret_code;
 }
 
-static void bad_block_indirect(blk_t blk)
+static void bad_block_indirect(ext2_filsys fs, blk_t blk)
 {
-	printf("Bad block %lu used as bad block indirect block?!?\n", blk);
-	preenhalt();
+	printf("Bad block %u used as bad block indirect block?!?\n", blk);
+	preenhalt(fs);
 	printf("\nThis inconsistency can not be fixed with "
 	       "e2fsck; to fix it, use\n"
 	       """dumpe2fs -b"" to dump out the bad block "
@@ -741,6 +834,22 @@
 	fatal_error(0);
 }
 
+static int bad_primary_block(ext2_filsys fs, blk_t *block_nr)
+{
+	printf("\nIf the block is really bad, the filesystem can not be "
+	       "fixed.\n");
+	preenhalt(fs);
+	printf("You can clear the this block from the bad block list\n");
+	printf("and hope that block is really OK, but there are no "
+	       "guarantees.\n\n");
+	if (ask("Clear (and hope for the best)", 1)) {
+		*block_nr = 0;
+		return 1;
+	}
+	ext2fs_unmark_valid(fs);
+	return 0;
+}
+
 int process_bad_block(ext2_filsys fs,
 		      blk_t *block_nr,
 		      int blockcnt,
@@ -758,12 +867,12 @@
 	if ((blk < fs->super->s_first_data_block) ||
 	    (blk >= fs->super->s_blocks_count)) {
 		if (preen) {
-			printf("Illegal block %lu in bad block inode\n", blk);
-			preenhalt();
+			printf("Illegal block %u in bad block inode\n", blk);
+			preenhalt(fs);
 		}
 		if (p->fix == -1)
 			p->fix = ask("Remove illegal block(s) in bad block inode", 1);
-		printf("Illegal block %lu in bad block inode.  %s\n", blk,
+		printf("Illegal block %u in bad block inode.  %s\n", blk,
 		       clear_msg[p->fix]);
 		if (p->fix) {
 			*block_nr = 0;
@@ -776,13 +885,13 @@
 
 	if (blockcnt < 0) {
 		if (ext2fs_test_block_bitmap(block_found_map, blk))
-			bad_block_indirect(blk);
+			bad_block_indirect(fs, blk);
 		else
 			mark_block_used(fs, blk);
 		return 0;
 	}
 #if 0 
-	printf ("DEBUG: Marking %lu as bad.\n", blk);
+	printf ("DEBUG: Marking %u as bad.\n", blk);
 #endif
 	fs_badblocks_count++;
 	/*
@@ -803,31 +912,35 @@
 	for (i = 0; i < fs->group_desc_count; i++ ) {
 		if (blk == first_block) {
 			if (i == 0) {
-				printf("The primary superblock (%lu) is "
-				       "bad.  Aiiieeee....\n", blk);
-				fatal_error(0);
+				printf("The primary superblock (%u) is "
+				       "on the bad block list.\n", blk);
+				if (bad_primary_block(fs, block_nr))
+					return BLOCK_CHANGED;
+				return 0;
 			}
 			if (!preen)
 				printf("Warning: Group %d's superblock "
-				       "(%lu) is bad.\n", i, blk);
+				       "(%u) is bad.\n", i, blk);
 			return 0;
 		}
 		if ((blk > first_block) &&
 		    (blk <= first_block + fs->desc_blocks)) {
 			if (i == 0) {
-				printf("Bad block %lu is in the primary "
-				       "group descriptors.  Aiiieeee....\n",
-				       blk);
-				fatal_error(0);
+				printf("Block %u in the primary group "
+				       "descriptors is on the bad block "
+				       "list\n", blk);
+				if (bad_primary_block(fs, block_nr))
+					return BLOCK_CHANGED;
+				return 0;
 			}
 			if (!preen)
 				printf("Warning: Group %d's copy of the "
 				       "group descriptors has a bad "
-				       "block (%lu).\n", i, blk);
+				       "block (%u).\n", i, blk);
 			return 0;
 		}
 		if (blk == fs->group_desc[i].bg_block_bitmap) {
-			printf("Group %d's block bitmap (%lu) is bad.  ",
+			printf("Group %d's block bitmap (%u) is bad.  ",
 			       i, blk);
 			if (ask("Relocate", 1)) {
 				invalid_block_bitmap[i]++;
@@ -837,7 +950,7 @@
 			return 0;
 		}
 		if (blk == fs->group_desc[i].bg_inode_bitmap) {
-			printf("Group %d's inode bitmap (%lu) is bad.  ",
+			printf("Group %d's inode bitmap (%u) is bad.  ",
 			       i, blk);
 			if (ask("Relocate", 1)) {
 				invalid_inode_bitmap[i]++;
@@ -850,7 +963,7 @@
 		    (blk < (fs->group_desc[i].bg_inode_table +
 			    fs->inode_blocks_per_group))) {
 			printf("WARNING: Severe data loss possible!!!!\n");
-			printf("Bad block %lu in group %d's inode table.  ",
+			printf("Bad block %u in group %d's inode table.  ",
 			       blk, i);
 			if (ask("Relocate", 1)) {
 				invalid_inode_table[i]++;
@@ -868,11 +981,11 @@
 	 */
 	if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
 	    p->inode->i_block[EXT2_DIND_BLOCK]) {
-		bad_block_indirect(blk);
+		bad_block_indirect(fs, blk);
 		return 0;
 	}
 	
-	printf("Programming error?  block #%lu claimed for no reason "
+	printf("Programming error?  block #%u claimed for no reason "
 	       "in process_bad_block.\n", blk);
 	return 0;
 }
@@ -904,15 +1017,15 @@
 	ext2fs_mark_super_dirty(fs);
 	printf("Relocating group %d's %s ", group, name);
 	if (old_block)
-		printf("from %lu ", old_block);
-	printf("to %lu...\n", *new_block);
+		printf("from %u ", old_block);
+	printf("to %u...\n", *new_block);
 	for (i = 0; i < num; i++) {
 		ext2fs_mark_block_bitmap(block_found_map, (*new_block)+i);
 		if (old_block) {
 			retval = io_channel_read_blk(fs->io, old_block + i,
 						     1, buf);
 			if (retval)
-				printf("Warning: could not read block %lu "
+				printf("Warning: could not read block %u "
 				       "of %s: %s\n",
 				       old_block + i, name,
 				       error_message(retval));
@@ -922,7 +1035,7 @@
 		retval = io_channel_write_blk(fs->io, (*new_block) + i,
 					      1, buf);
 		if (retval)
-			printf("Warning: could not write block %lu for %s: %s\n",
+			printf("Warning: could not write block %u for %s: %s\n",
 			       (*new_block) + i, name, error_message(retval));
 	}
 	free(buf);
@@ -977,19 +1090,23 @@
 		if (fs->group_desc[i].bg_block_bitmap) {
 			if (ext2fs_test_block_bitmap(block_found_map,
 				     fs->group_desc[i].bg_block_bitmap)) {
-				printf("Group %i's block bitmap at %lu "
+				printf("Group %i's block bitmap at %u "
 				       "conflicts with some other fs block.\n",
 				       i, fs->group_desc[i].bg_block_bitmap);
-				preenhalt();
+				preenhalt(fs);
 				if (ask("Relocate", 1)) {
 					invalid_block_bitmap[i]++;
 					invalid_bitmaps++;
 				} else {
 					ext2fs_unmark_valid(fs);
 				}
-			} else
+			} else {
 			    ext2fs_mark_block_bitmap(block_found_map,
 				     fs->group_desc[i].bg_block_bitmap);
+			    ext2fs_mark_block_bitmap(block_illegal_map,
+				     fs->group_desc[i].bg_block_bitmap);
+		    }
+			
 		}
 		/*
 		 * Mark block used for the inode bitmap 
@@ -997,19 +1114,22 @@
 		if (fs->group_desc[i].bg_inode_bitmap) {
 			if (ext2fs_test_block_bitmap(block_found_map,
 				     fs->group_desc[i].bg_inode_bitmap)) {
-				printf("Group %i's inode bitmap at %lu "
+				printf("Group %i's inode bitmap at %u "
 				       "conflicts with some other fs block.\n",
 				       i, fs->group_desc[i].bg_inode_bitmap);
-				preenhalt();
+				preenhalt(fs);
 				if (ask("Relocate", 1)) {
 					invalid_inode_bitmap[i]++;
 					invalid_bitmaps++;
 				} else {
 					ext2fs_unmark_valid(fs);
 				}
-			} else
+			} else {
 			    ext2fs_mark_block_bitmap(block_found_map,
 				     fs->group_desc[i].bg_inode_bitmap);
+			    ext2fs_mark_block_bitmap(block_illegal_map,
+				     fs->group_desc[i].bg_inode_bitmap);
+			}
 		}
 		    
 		/*
@@ -1021,20 +1141,23 @@
 			     j++, b++) {
 				if (ext2fs_test_block_bitmap(block_found_map,
 							     b)) {
-					printf("Group %i's inode table at %lu "
+					printf("Group %i's inode table at %u "
 					       "conflicts with some other "
 					       "fs block.\n",
 					       i, b);
-					preenhalt();
+					preenhalt(fs);
 					if (ask("Relocate", 1)) {
 						invalid_inode_table[i]++;
 						invalid_bitmaps++;
 					} else {
 						ext2fs_unmark_valid(fs);
 					}
-				} else
+				} else {
 				    ext2fs_mark_block_bitmap(block_found_map,
 							     b);
+				    ext2fs_mark_block_bitmap(block_illegal_map,
+							     b);
+				    }
 			}
 		}
 			    
@@ -1042,13 +1165,17 @@
 		 * Mark this group's copy of the superblock
 		 */
 		ext2fs_mark_block_bitmap(block_found_map, block);
+		ext2fs_mark_block_bitmap(block_illegal_map, block);
 		
 		/*
 		 * Mark this group's copy of the descriptors
 		 */
-		for (j = 0; j < fs->desc_blocks; j++)
+		for (j = 0; j < fs->desc_blocks; j++) {
 			ext2fs_mark_block_bitmap(block_found_map,
 						 block + j + 1);
+			ext2fs_mark_block_bitmap(block_illegal_map,
+						 block + j + 1);
+		}
 		block += fs->super->s_blocks_per_group;
 	}
 }
@@ -1077,7 +1204,7 @@
 static errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino)
 {
 	if (ino == stashed_ino) {
-		if (!S_ISDIR(stashed_inode->i_mode))
+		if (!LINUX_S_ISDIR(stashed_inode->i_mode))
 			return ENOTDIR;
 		return 0;
 	}
diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c
index c98030f..287c24f 100644
--- a/e2fsck/pass1b.c
+++ b/e2fsck/pass1b.c
@@ -24,6 +24,9 @@
  */
 
 #include <time.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
 
 #include <et/com_err.h>
 #include "e2fsck.h"
@@ -237,7 +240,7 @@
 			if (!p->dup_blocks)
 				printf("Duplicate/bad block(s) in inode %lu:",
 				       p->ino);
-			printf(" %lu", *block_nr);
+			printf(" %u", *block_nr);
 		}
 		p->dup_blocks++;
 		ext2fs_mark_block_bitmap(block_dup_map, *block_nr);
@@ -330,8 +333,8 @@
 	 * (by searching for the containing directory for that inode.)
 	 */
 	for (i=0; inodes_left && i < dir_block_count; i++) {
-		retval = io_channel_read_blk(fs->io, dir_blocks[i].blk,
-					     1, block_buf);
+		retval = ext2fs_read_dir_block(fs, dir_blocks[i].blk,
+					       block_buf);
 		entry = offset = 0;
 		while (offset < fs->blocksize) {
 			entry++;
@@ -478,6 +481,7 @@
 			ext2fs_unmark_valid(fs);
 		printf("\n");
 	}
+	free(shared);
 }
 
 static int delete_file_block(ext2_filsys fs,
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 3331cb9..cd5b267 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -31,7 +31,6 @@
  * 	- The inode_used_map bitmap
  * 	- The inode_bad_map bitmap
  * 	- The inode_dir_map bitmap
- * 	- The block_dup_map bitmap
  *
  * Pass 2 frees the following data structures
  * 	- The inode_bad_map bitmap
@@ -52,6 +51,13 @@
 static int check_dir_block(ext2_filsys fs,
 			   struct dir_block_struct *dir_blocks_info,
 			   char *buf);
+static int allocate_dir_block(ext2_filsys fs,
+			      struct dir_block_struct *dir_blocks_info,
+			      char *buf);
+static int update_dir_block(ext2_filsys fs,
+			    blk_t	*block_nr,
+			    int blockcnt,
+			    void *private);
 
 void pass2(ext2_filsys fs)
 {
@@ -100,14 +106,29 @@
 	int	status = 0;
 	int	created = 0;
 	int	new_len;
-	char	name[BLOCK_SIZE];
+	const char 	*question = 0;
 	
 	if (!dirent->inode) {
 		printf("Missing '.' in directory inode %lu.\n", ino);
+		question = "Fix";
+	} else if ((dirent->name_len != 1) ||
+		   strncmp(dirent->name, ".", dirent->name_len)) {
+		char *name = malloc(dirent->name_len + 1);
+		if (!name)
+			fatal_error("Couldn't allocate . name");
+		strncpy(name, dirent->name, dirent->name_len);
+		name[dirent->name_len] = '\0';
+		printf("First entry in directory inode %lu contains '%s' "
+		       "(inode=%u)\n", ino, name, dirent->inode);
+		printf("instead of '.'.\n");
+		free(name);
+		question = "Change to be '.'";
+	}
+	if (question) {
 		if (dirent->rec_len < 12)
 			fatal_error("Cannot fix, insufficient space to add '.'");
-		preenhalt();
-		if (ask("Fix", 1)) {
+		preenhalt(fs);
+		if (ask(question, 1)) {
 			dirent->inode = ino;
 			dirent->name_len = 1;
 			dirent->name[0] = '.';
@@ -118,19 +139,10 @@
 			return 0;
 		}
 	}
-	if ((dirent->name_len != 1) ||
-	    strncmp(dirent->name, ".", dirent->name_len)) {
-		strncpy(name, dirent->name, dirent->name_len);
-		name[dirent->name_len] = '\0';
-		printf("Missing '.' in directory inode %lu.\n", ino);
-		printf("Cannot fix, first entry in directory contains '%s'\n",
-		       name);
-		exit(FSCK_ERROR);
-	}
 	if (dirent->inode != ino) {
 		printf("Bad inode number for '.' in directory inode %lu.\n",
 		       ino);
-		preenhalt();
+		preenhalt(fs);
 		if (ask("Fix", 1)) {
 			dirent->inode = ino;
 			status = 1;
@@ -140,7 +152,7 @@
 	if (dirent->rec_len > 12) {
 		new_len = dirent->rec_len - 12;
 		if (new_len > 12) {
-			preenhalt();
+			preenhalt(fs);
 			if (created ||
 			    ask("Directory entry for '.' is big.  Split", 1)) {
 				nextdir = (struct ext2_dir_entry *)
@@ -165,15 +177,30 @@
 			struct ext2_dir_entry *dirent,
 			struct dir_info *dir)
 {
-	char	name[BLOCK_SIZE];
 	ino_t	ino = dir->ino;
+	const char	*question = 0;
 	
 	if (!dirent->inode) {
 		printf("Missing '..' in directory inode %lu.\n", ino);
+		question = "Fix";
+	} else if ((dirent->name_len != 2) ||
+	    strncmp(dirent->name, "..", dirent->name_len)) {
+		char *name = malloc(dirent->name_len + 1);
+		if (!name)
+			fatal_error("Couldn't allocate bad .. name");
+		strncpy(name, dirent->name, dirent->name_len);
+		name[dirent->name_len] = '\0';
+		printf("Second entry in directory inode %lu contains '%s' "
+		       "(inode=%u)\n", ino, name, dirent->inode);
+		printf("instead of '..'.\n");
+		free(name);
+		question = "Change to be '..'";
+	}
+	if (question) {
 		if (dirent->rec_len < 12)
 			fatal_error("Cannot fix, insufficient space to add '..'");
-		preenhalt();
-		if (ask("Fix", 1)) {
+		preenhalt(fs);
+		if (ask(question, 1)) {
 			/*
 			 * Note: we don't have the parent inode just
 			 * yet, so we will fill it in with the root
@@ -188,15 +215,6 @@
 			ext2fs_unmark_valid(fs);
 		return 0;
 	}
-	if ((dirent->name_len != 2) ||
-	    strncmp(dirent->name, "..", dirent->name_len)) {
-		strncpy(name, dirent->name, dirent->name_len);
-		name[dirent->name_len] = '\0';
-		printf("Missing '..' in directory inode %lu.\n", ino);
-		printf("Cannot fix, first entry in directory contains %s\n",
-		       name);
-		exit(FSCK_ERROR);
-	}
 	dir->dotdot = dirent->inode;
 	return 0;
 }
@@ -232,7 +250,7 @@
 					name, pathname, dir_ino);
 				if (pathname != unknown_pathname)
 					free(pathname);
-				preenhalt();
+				preenhalt(fs);
 				fixup = ask("Replace '/' or null by '.'", 1);
 			}
 			if (fixup) {
@@ -251,14 +269,14 @@
 {
 	struct dir_info		*subdir, *dir;
 	struct ext2_dir_entry 	*dirent;
-	char			name[BLOCK_SIZE];
 	int			offset = 0;
 	int			dir_modified = 0;
 	errcode_t		retval;
 	char			*path1, *path2;
-	int			dot_state;
+	int			dot_state, name_len;
 	blk_t			block_nr = db->blk;
 	ino_t 			ino = db->ino;
+	char			name[EXT2_NAME_LEN+1];
 
 	/*
 	 * Make sure the inode is still in use (could have been 
@@ -266,6 +284,12 @@
 	 */
 	if (!(ext2fs_test_inode_bitmap(inode_used_map, ino))) 
 		return 0;
+
+	if (db->blk == 0) {
+		if (allocate_dir_block(fs, db, buf))
+			return 0;
+		block_nr = db->blk;
+	}
 	
 	if (db->blockcnt)
 		dot_state = 2;
@@ -277,7 +301,7 @@
 	       db->blockcnt, ino);
 #endif
 	
-	retval = io_channel_read_blk(fs->io, block_nr, 1, buf);
+	retval = ext2fs_read_dir_block(fs, block_nr, buf);
 	if (retval) {
 		com_err(program_name, retval,
 			"while reading directory block %d", block_nr);
@@ -291,7 +315,7 @@
 		    ((dirent->name_len+8) > dirent->rec_len)) {
 			printf("Directory inode %lu, block %d, offset %d: directory corrupted\n",
 			       ino, db->blockcnt, offset);
-			preenhalt();
+			preenhalt(fs);
 			if (ask("Salvage", 1)) {
 				dirent->rec_len = fs->blocksize - offset;
 				dirent->name_len = 0;
@@ -302,8 +326,22 @@
 				return DIRENT_ABORT;
 			}
 		}
-		strncpy(name, dirent->name, dirent->name_len);
-		name[dirent->name_len] = '\0';
+
+		name_len = dirent->name_len;
+		if (dirent->name_len > EXT2_NAME_LEN) {
+			printf("Directory inode %lu, block %d, offset %d: filename too long\n",
+			       ino, db->blockcnt, offset);
+			preenhalt(fs);
+			if (ask("Truncate filename", 1)) {
+				dirent->name_len = EXT2_NAME_LEN;
+				dir_modified++;
+			}
+			name_len = EXT2_NAME_LEN;
+		}
+
+		strncpy(name, dirent->name, name_len);
+		name[name_len] = '\0';
+
 		if (dot_state == 1) {
 			if (check_dot(fs, dirent, ino))
 				dir_modified++;
@@ -324,7 +362,7 @@
 			       name, path1, ino);
 			if (path1 != unknown_pathname)
 				free(path1);
-			preenhalt();
+			preenhalt(fs);
 			if (ask("Clear", 1)) {
 				dirent->inode = 0;
 				dir_modified++;
@@ -349,11 +387,11 @@
 			retval = ext2fs_get_pathname(fs, ino, 0, &path1);
 			if (retval)
 				path1 = unknown_pathname;
-			printf("Entry '%s' in %s (%lu) has bad inode #: %lu.\n",
+			printf("Entry '%s' in %s (%lu) has bad inode #: %u.\n",
 			       name, path1, ino, dirent->inode);
 			if (path1 != unknown_pathname)
 				free(path1);
-			preenhalt();
+			preenhalt(fs);
 			if (ask("Clear", 1)) {
 				dirent->inode = 0;
 				dir_modified++;
@@ -370,7 +408,7 @@
 			retval = ext2fs_get_pathname(fs, ino, 0, &path1);
 			if (retval)
 				path1 = unknown_pathname;
-			printf("Entry '%s' in %s (%lu) has deleted/unused inode %lu.\n",
+			printf("Entry '%s' in %s (%lu) has deleted/unused inode %u.\n",
 			       name, path1, ino, dirent->inode);
 			if (path1 != unknown_pathname)
 				free(path1);
@@ -410,7 +448,7 @@
 					      dirent->inode))) {
 			subdir = get_dir_info(dirent->inode);
 			if (!subdir) {
-				printf("INTERNAL ERROR: missing dir %lu\n",
+				printf("INTERNAL ERROR: missing dir %u\n",
 				       dirent->inode);
 				fatal_error(0);
 			}
@@ -425,7 +463,7 @@
 							     &path2);
 				if (retval)
 					path2 = unknown_pathname;
-				printf("Entry '%s' in %s (%lu) is a link to directory %s (%lu).\n",
+				printf("Entry '%s' in %s (%lu) is a link to directory %s (%u).\n",
 				       name, path1, ino, path2, 
 				       dirent->inode);
 				if (path1 != unknown_pathname)
@@ -457,8 +495,7 @@
 		       dirent->rec_len - fs->blocksize + offset);
 	}
 	if (dir_modified) {
-		retval = io_channel_write_blk(fs->io, block_nr,
-					      1, buf);
+		retval = ext2fs_write_dir_block(fs, block_nr, buf);
 		if (retval) {
 			com_err(program_name, retval,
 				"while writing directory block %d", block_nr);
@@ -526,16 +563,16 @@
  * make sure that certain reserved fields are really zero.  If not,
  * prompt the user if he/she wants us to zeroize them.
  */
-static void check_for_zero_long(ext2_filsys fs, ino_t ino, char *pathname,
-				const char *name, unsigned long *val,
+static void check_for_zero_u32(ext2_filsys fs, ino_t ino, char *pathname,
+				const char *name, __u32 *val,
 				int *modified)
 {
 	char prompt[80];
 	
 	if (*val) {
-		printf("%s for inode %lu (%s) is %lu, should be zero.\n",
+		printf("%s for inode %lu (%s) is %u, should be zero.\n",
 		       name, ino, pathname, *val);
-		preenhalt();
+		preenhalt(fs);
 		sprintf(prompt, "Clear %s", name);
 		if (ask(prompt, 1)) {
 			*val = 0;
@@ -545,8 +582,8 @@
 	}
 }
 
-static void check_for_zero_char(ext2_filsys fs, ino_t ino, char *pathname,
-				const char *name, unsigned char *val,
+static void check_for_zero_u8(ext2_filsys fs, ino_t ino, char *pathname,
+				const char *name, __u8 *val,
 				int *modified)
 {
 	char prompt[80];
@@ -554,7 +591,7 @@
 	if (*val) {
 		printf("%s for inode %lu (%s) is %d, should be zero.\n",
 		       name, ino, pathname, *val);
-		preenhalt();
+		preenhalt(fs);
 		sprintf(prompt, "Clear %s", name);
 		if (ask(prompt, 1)) {
 			*val = 0;
@@ -581,28 +618,42 @@
 			ino);
 		return 0;
 	}
-	if (!S_ISDIR(inode.i_mode) && !S_ISREG(inode.i_mode) &&
-	    !S_ISCHR(inode.i_mode) && !S_ISBLK(inode.i_mode) &&
-	    !S_ISLNK(inode.i_mode) && !S_ISFIFO(inode.i_mode) &&
-	    !(S_ISSOCK(inode.i_mode))) {
+	if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
+	    !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
+	    !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
+	    !(LINUX_S_ISSOCK(inode.i_mode))) {
 		printf("Inode %lu (%s) has a bad mode (0%o).\n",
 		       ino, pathname, inode.i_mode);
-		preenhalt();
+		preenhalt(fs);
 		if (ask("Clear", 1)) {
 			deallocate_inode(fs, ino, 0);
+			free(pathname);
 			return 1;
 		} else
 			ext2fs_unmark_valid(fs);
 	}
-	check_for_zero_long(fs, ino, pathname, "i_faddr", &inode.i_faddr,
+	check_for_zero_u32(fs, ino, pathname, "i_faddr", &inode.i_faddr,
 			    &inode_modified);
-	check_for_zero_char(fs, ino, pathname, "i_frag", &inode.i_frag,
+#if HAVE_EXT2_FRAGS
+	check_for_zero_u8(fs, ino, pathname, "i_frag", &inode.i_frag,
 			    &inode_modified);
-	check_for_zero_char(fs, ino, pathname, "i_fsize", &inode.i_fsize,
+	check_for_zero_u8(fs, ino, pathname, "i_fsize", &inode.i_fsize,
 			    &inode_modified);
-	check_for_zero_long(fs, ino, pathname, "i_file_acl", &inode.i_file_acl,
+#else
+	/*
+	 * Even if the OS specific fields don't support i_frag and
+	 * i_fsize, make sure they are set to zero anyway.  This may
+	 * cause problems if on some other OS these fields are reused
+	 * for something else, but that's probably a bad idea....
+	 */
+	check_for_zero_u8(fs, ino, pathname, "i_frag",
+			  &inode.osd2.linux2.l_i_frag, &inode_modified);
+	check_for_zero_u8(fs, ino, pathname, "i_fsize",
+			  &inode.osd2.linux2.l_i_fsize, &inode_modified);
+#endif
+	check_for_zero_u32(fs, ino, pathname, "i_file_acl", &inode.i_file_acl,
 			    &inode_modified);
-	check_for_zero_long(fs, ino, pathname, "i_dir_acl", &inode.i_dir_acl,
+	check_for_zero_u32(fs, ino, pathname, "i_dir_acl", &inode.i_dir_acl,
 			    &inode_modified);
 	free(pathname);
 	if (inode_modified)
@@ -610,3 +661,107 @@
 	return 0;
 }
 
+
+/*
+ * allocate_dir_block --- this function allocates a new directory
+ * 	block for a particular inode; this is done if a directory has
+ * 	a "hole" in it, or if a directory has a illegal block number
+ * 	that was zeroed out and now needs to be replaced.
+ */
+static int allocate_dir_block(ext2_filsys fs,
+			      struct dir_block_struct *db,
+			      char *buf)
+{
+	blk_t			blk;
+	char			*block;
+	struct ext2_inode	inode;
+	errcode_t		retval;
+
+	printf("Directory inode %lu has a hole at block #%d\n",
+	       db->ino, db->blockcnt);
+	if (ask("Allocate block", 1) == 0)
+		return 1;
+
+	/*
+	 * Read the inode and block bitmaps in; we'll be messing with
+	 * them.
+	 */
+	read_bitmaps(fs);
+	
+	/*
+	 * First, find a free block
+	 */
+	retval = ext2fs_new_block(fs, 0, block_found_map, &blk);
+	if (retval) {
+		com_err("allocate_dir_block", retval,
+			"while trying to fill a hole in a directory inode");
+		return 1;
+	}
+	ext2fs_mark_block_bitmap(block_found_map, blk);
+	ext2fs_mark_block_bitmap(fs->block_map, blk);
+	ext2fs_mark_bb_dirty(fs);
+
+	/*
+	 * Now let's create the actual data block for the inode
+	 */
+	if (db->blockcnt)
+		retval = ext2fs_new_dir_block(fs, 0, 0, &block);
+	else
+		retval = ext2fs_new_dir_block(fs, db->ino, EXT2_ROOT_INO,
+					      &block);
+
+	if (retval) {
+		com_err("allocate_dir_block", retval,
+			"while creating new directory block");
+		return 1;
+	}
+
+	retval = ext2fs_write_dir_block(fs, blk, block);
+	free(block);
+	if (retval) {
+		com_err("allocate_dir_block", retval,
+			"while writing an empty directory block");
+		return 1;
+	}
+
+	/*
+	 * Update the inode block count
+	 */
+	e2fsck_read_inode(fs, db->ino, &inode, "allocate_dir_block");
+	inode.i_blocks += fs->blocksize / 512;
+	if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
+		inode.i_size = (db->blockcnt+1) * fs->blocksize;
+	e2fsck_write_inode(fs, db->ino, &inode, "allocate_dir_block");
+
+	/*
+	 * Finally, update the block pointers for the inode
+	 */
+	db->blk = blk;
+	retval = ext2fs_block_iterate(fs, db->ino, BLOCK_FLAG_HOLE,
+				      0, update_dir_block, db);
+	if (retval) {
+		com_err("allocate_dir_block", retval,
+			"while calling ext2fs_block_iterate");
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * This is a helper function for allocate_dir_block().
+ */
+static int update_dir_block(ext2_filsys fs,
+			    blk_t	*block_nr,
+			    int blockcnt,
+			    void *private)
+{
+	struct dir_block_struct *db = private;
+
+	if (db->blockcnt == blockcnt) {
+		*block_nr = db->blk;
+		return BLOCK_CHANGED;
+	}
+	return 0;
+}
+	
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 7e3ad97..df2c5bb 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -30,6 +30,9 @@
  *     	- The dirinfo directory information cache.
  */
 
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
 #include "et/com_err.h"
 
 #include "e2fsck.h"
@@ -134,7 +137,7 @@
 	}
 
 	printf("Root inode not allocated.  ");
-	preenhalt();
+	preenhalt(fs);
 	if (!ask("Rellocate", 1)) {
 		ext2fs_unmark_valid(fs);
 		fatal_error("Cannot proceed without a root inode.");
@@ -166,9 +169,9 @@
 		fatal_error(0);
 	}
 
-	retval = io_channel_write_blk(fs->io, blk, 1, block);
+	retval = ext2fs_write_dir_block(fs, blk, block);
 	if (retval) {
-		com_err("io_channel_write_blk", retval,
+		com_err("ext2fs_write_dir_block", retval,
 			"while writing the root directory block");
 		fatal_error(0);
 	}
@@ -275,7 +278,7 @@
 	printf("Unconnected directory inode %lu (%s)\n", p->ino, path1);
 	if (path1 != unknown)
 		free(path1);
-	preenhalt();
+	preenhalt(fs);
 	if (ask("Connect to /lost+found", 1)) {
 		if (reconnect_file(fs, p->ino))
 			ext2fs_unmark_valid(fs);
@@ -341,7 +344,7 @@
 		       error_message(retval));
 	else
 		printf("/lost+found not found.  ");
-	preenhalt();
+	preenhalt(fs);
 	if (!ask("Create", 1)) {
 		ext2fs_unmark_valid(fs);
 		return 0;
@@ -391,13 +394,13 @@
 		return 0;
 	}
 
-	retval = io_channel_write_blk(fs->io, blk, 1, block);
+	retval = ext2fs_write_dir_block(fs, blk, block);
+	free(block);
 	if (retval) {
-		com_err("io_channel_write_blk", retval,
+		com_err("ext2fs_write_dir_block", retval,
 			"while writing the directory block for /lost+found");
 		return 0;
 	}
-	free(block);
 
 	/*
 	 * Set up the inode structure
@@ -542,7 +545,7 @@
 	
 	retval = adjust_inode_count(fp->fs, dirent->inode, -1);
 	if (retval)
-		printf("Error while adjusting inode count on inode %lu\n",
+		printf("Error while adjusting inode count on inode %u\n",
 		       dirent->inode);
 	retval = adjust_inode_count(fp->fs, fp->parent, 1);
 	if (retval)
@@ -626,7 +629,7 @@
 		}
 		memset(block, 0, fs->blocksize);
 	}	
-	retval = io_channel_write_blk(fs->io, new_blk, 1, block);
+	retval = ext2fs_write_dir_block(fs, new_blk, block);
 	if (retval) {
 		es->err = retval;
 		return BLOCK_ABORT;
diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c
index 1075731..67a4e9e 100644
--- a/e2fsck/pass4.c
+++ b/e2fsck/pass4.c
@@ -34,7 +34,7 @@
 			 * prompt to reconnect.
 			 */
 			printf("Unattached inode %lu\n", i);
-			preenhalt();
+			preenhalt(fs);
 			if (ask("Connect to /lost+found", 1)) {
 				if (reconnect_file(fs, i))
 					ext2fs_unmark_valid(fs);
@@ -45,7 +45,7 @@
 			e2fsck_read_inode(fs, i, &inode, "pass4");
 			if (inode_link_info[i] != inode.i_links_count) {
 				printf("WARNING: PROGRAMMING BUG IN E2FSCK!\n");
-				printf("inode_link_info[%d] is %lu, "
+				printf("inode_link_info[%ld] is %u, "
 				       "inode.i_links_count is %d.  "
 				       "They should be the same!\n",
 				       i, inode_link_info[i],
diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c
index 888ac97..744aee2 100644
--- a/e2fsck/pass5.c
+++ b/e2fsck/pass5.c
@@ -61,12 +61,39 @@
 	
 	free_array = allocate_memory(fs->group_desc_count * sizeof(int),
 				     "free block count array");
-				     
+
+	if ((fs->super->s_first_data_block <
+	     ext2fs_get_block_bitmap_start(block_found_map)) ||
+	    (fs->super->s_blocks_count-1 >
+	     ext2fs_get_block_bitmap_end(block_found_map))) {
+		printf("PROGRAMMING ERROR: filesystem endpoints (%d, %d)\n\t"
+		       "don't match block_found_map endpoints (%d, %d).\n",
+		       fs->super->s_first_data_block,
+		       fs->super->s_blocks_count -1,
+		       ext2fs_get_block_bitmap_start(block_found_map),
+		       ext2fs_get_block_bitmap_end(block_found_map));
+		fatal_error(0);
+	}
+		       
+	if ((fs->super->s_first_data_block <
+	     ext2fs_get_block_bitmap_start(fs->block_map)) ||
+	    (fs->super->s_blocks_count-1 >
+	     ext2fs_get_block_bitmap_end(fs->block_map))) {
+		printf("PROGRAMMING ERROR: filesystem endpoints (%d, %d)\n\t"
+		       "don't match fs->block_map endpoints (%d, %d).\n",
+		       fs->super->s_first_data_block,
+		       fs->super->s_blocks_count -1,
+		       ext2fs_get_block_bitmap_start(fs->block_map),
+		       ext2fs_get_block_bitmap_end(fs->block_map));
+		fatal_error(0);
+	}
+		       
+		       
 	for (i = fs->super->s_first_data_block;
 	     i < fs->super->s_blocks_count;
 	     i++) {
-		actual = ext2fs_test_block_bitmap(block_found_map, i);
-		bitmap = ext2fs_test_block_bitmap(fs->block_map, i);
+		actual = ext2fs_fast_test_block_bitmap(block_found_map, i);
+		bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
 		
 		if (actual == bitmap)
 			goto do_counts;
@@ -82,7 +109,7 @@
 			 * Block not used, but marked in use in the bitmap.
 			 */
 			if (!preen)
-				printf(" -%lu", i);
+				printf(" -%u", i);
 			if (do_fix)
 				ext2fs_unmark_block_bitmap(fs->block_map,
 							   i);
@@ -91,7 +118,7 @@
 			 * Block used, but not marked in use in the bitmap.
 			 */
 			if (!preen)
-				printf(" +%lu", i);
+				printf(" +%u", i);
 			if (do_fix)
 				ext2fs_mark_block_bitmap(fs->block_map,
 							 i);
@@ -124,7 +151,7 @@
 				do_fix = ask(fix_question, 1);
 			if (!preen)
 				printf("Free blocks count wrong for "
-				       "group %lu (%u, counted=%d).  %s\n", i,
+				       "group %u (%u, counted=%d).  %s\n", i,
 				       fs->group_desc[i].bg_free_blocks_count,
 				       free_array[i], fix_msg[do_fix]);
 			if (do_fix) {
@@ -140,7 +167,7 @@
 			do_fix = ask(fix_question, 1);
 		if (!preen)
 			printf("Free blocks count wrong "
-			       "(%lu, counted=%d).  %s\n",
+			       "(%u, counted=%d).  %s\n",
 			       fs->super->s_free_blocks_count, free_blocks,
 			       fix_msg[do_fix]);
 		if (do_fix) {
@@ -149,6 +176,7 @@
 		} else
 			ext2fs_unmark_valid(fs);
 	}
+	free(free_array);
 }
 			
 static void check_inode_bitmaps(ext2_filsys fs)
@@ -170,9 +198,30 @@
 	dir_array = allocate_memory(fs->group_desc_count * sizeof(int),
 				    "directory count array");
 				     
+	if ((1 < ext2fs_get_inode_bitmap_start(inode_used_map)) ||
+	    (fs->super->s_inodes_count > 
+	     ext2fs_get_inode_bitmap_end(inode_used_map))) {
+		printf("PROGRAMMING ERROR: filesystem inode endpoints (%d, %d)\n\t"
+		       "don't match inode_used_map endpoints (%d, %d).\n",
+		       1, fs->super->s_inodes_count,
+		       ext2fs_get_inode_bitmap_start(inode_used_map),
+		       ext2fs_get_inode_bitmap_end(inode_used_map));
+		fatal_error(0);
+	}
+	if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
+	    (fs->super->s_inodes_count > 
+	     ext2fs_get_inode_bitmap_end(fs->inode_map))) {
+		printf("PROGRAMMING ERROR: filesystem inode endpoints (%d, %d)\n\t"
+		       "don't match fs->inode_map endpoints (%d, %d).\n",
+		       1, fs->super->s_inodes_count,
+		       ext2fs_get_inode_bitmap_start(fs->inode_map),
+		       ext2fs_get_inode_bitmap_end(fs->inode_map));
+		fatal_error(0);
+	}
+
 	for (i = 1; i <= fs->super->s_inodes_count; i++) {
-		actual = ext2fs_test_inode_bitmap(inode_used_map, i);
-		bitmap = ext2fs_test_inode_bitmap(fs->inode_map, i);
+		actual = ext2fs_fast_test_inode_bitmap(inode_used_map, i);
+		bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
 		
 		if (actual == bitmap)
 			goto do_counts;
@@ -265,7 +314,7 @@
 			do_fix = ask(fix_question, 1);
 		if (!preen)
 			printf("Free inodes count wrong "
-			       "(%lu, counted=%d).  %s\n",
+			       "(%u, counted=%d).  %s\n",
 			       fs->super->s_free_inodes_count, free_inodes,
 			       fix_msg[do_fix]);
 		if (do_fix) {
@@ -274,6 +323,8 @@
 		} else
 			ext2fs_unmark_valid(fs);
 	}
+	free(free_array);
+	free(dir_array);
 }
 
 static void check_inode_end(ext2_filsys fs)
diff --git a/e2fsck/scantest.c b/e2fsck/scantest.c
index a0b078d..29d1e88 100644
--- a/e2fsck/scantest.c
+++ b/e2fsck/scantest.c
@@ -7,9 +7,13 @@
 #include <ctype.h>
 #include <termios.h>
 #include <time.h>
+#ifdef HAVE_GETOPT_H
 #include <getopt.h>
+#endif
 #include <unistd.h>
+#ifdef HAVE_MNTENT_H
 #include <mntent.h>
+#endif
 #include <sys/ioctl.h>
 #include <malloc.h>
 #include <sys/resource.h>
@@ -25,7 +29,9 @@
 #include <sys/types.h>
 #include <sys/time.h>
 
+#ifdef HAVE_LINUX_FS_H
 #include <linux/fs.h>
+#endif
 #include <linux/ext2_fs.h>
 
 #include "ext2fs/ext2fs.h"
diff --git a/e2fsck/util.c b/e2fsck/util.c
index 3f5447d..9fc22e9 100644
--- a/e2fsck/util.c
+++ b/e2fsck/util.c
@@ -10,10 +10,12 @@
 #include <string.h>
 #include <ctype.h>
 #include <termios.h>
-#include <sys/resource.h>
 
 #include "e2fsck.h"
 
+#include <sys/time.h>
+#include <sys/resource.h>
+
 const char * fix_msg[2] = { "IGNORED", "FIXED" };
 const char * clear_msg[2] = { "IGNORED", "CLEARED" };
 
@@ -51,6 +53,8 @@
 	tcgetattr (0, &termios);
 	tmp = termios;
 	tmp.c_lflag &= ~(ICANON | ECHO);
+	tmp.c_cc[VMIN] = 1;
+	tmp.c_cc[VTIME] = 0;
 	tcsetattr (0, TCSANOW, &tmp);
 
 	if (def == 1)
@@ -152,24 +156,36 @@
 	}
 }
 
-void preenhalt(NOARGS)
+void preenhalt(ext2_filsys fs)
 {
 	if (!preen)
 		return;
 	fprintf(stderr, "\n\n%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
 	       device_name);
+	if (fs != NULL) {
+		fs->super->s_state |= EXT2_ERROR_FS;
+		ext2fs_mark_super_dirty(fs);
+		ext2fs_close(fs);
+	}
 	exit(FSCK_UNCORRECTED);
 }
 
 void init_resource_track(struct resource_track *track)
 {
+#ifdef HAVE_GETRUSAGE
 	struct rusage r;
+#endif
 	
 	track->brk_start = sbrk(0);
 	gettimeofday(&track->time_start, 0);
+#ifdef HAVE_GETRUSAGE
 	getrusage(RUSAGE_SELF, &r);
 	track->user_start = r.ru_utime;
 	track->system_start = r.ru_stime;
+#else
+	track->user_start.tv_sec = track->user_start.tv_usec = 0;
+	track->system_start.tv_sec = track->system_start.tv_usec = 0;
+#endif
 }
 
 static __inline__ float timeval_subtract(struct timeval *tv1,
@@ -181,10 +197,13 @@
 
 void print_resource_track(struct resource_track *track)
 {
+#ifdef HAVE_GETRUSAGE
 	struct rusage r;
+#endif
 	struct timeval time_end;
 
 	gettimeofday(&time_end, 0);
+#ifdef HAVE_GETRUSAGE
 	getrusage(RUSAGE_SELF, &r);
 
 	printf("Memory used: %d, elapsed time: %6.3f/%6.3f/%6.3f\n",
@@ -192,6 +211,11 @@
 	       timeval_subtract(&time_end, &track->time_start),
 	       timeval_subtract(&r.ru_utime, &track->user_start),
 	       timeval_subtract(&r.ru_stime, &track->system_start));
+#else
+	printf("Memory used: %d, elapsed time: %6.3f\n",
+	       (int) (((char *) sbrk(0)) - ((char *) track->brk_start)),
+	       timeval_subtract(&time_end, &track->time_start));
+#endif
 }
 
 void e2fsck_read_inode(ext2_filsys fs, unsigned long ino,
@@ -230,15 +254,15 @@
 	 * Only directories, regular files, and some symbolic links
 	 * have valid block entries.
 	 */
-	if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) &&
-	    !S_ISLNK(inode->i_mode))
+	if (!LINUX_S_ISDIR(inode->i_mode) && !LINUX_S_ISREG(inode->i_mode) &&
+	    !LINUX_S_ISLNK(inode->i_mode))
 		return 0;
 	
 	/*
 	 * If the symbolic link is a "fast symlink", then the symlink
 	 * target is stored in the block entries.
 	 */
-	if (S_ISLNK (inode->i_mode) && inode->i_blocks == 0 &&
+	if (LINUX_S_ISLNK (inode->i_mode) && inode->i_blocks == 0 &&
 	    inode->i_size < EXT2_N_BLOCKS * sizeof (unsigned long))
 		return 0;