Many files:
  Checkin of e2fsprogs 1.10

diff --git a/debugfs/ChangeLog b/debugfs/ChangeLog
index e7aca8d..aa703ab 100644
--- a/debugfs/ChangeLog
+++ b/debugfs/ChangeLog
@@ -1,3 +1,11 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08
diff --git a/doc/libext2fs.texinfo b/doc/libext2fs.texinfo
index 49094d5..8a5b64b 100644
--- a/doc/libext2fs.texinfo
+++ b/doc/libext2fs.texinfo
@@ -1,7 +1,7 @@
 \input texinfo    @c -*-texinfo-*-
 @c %**start of header
 @setfilename libext2fs.info
-@settitle The EXT2FS Library (version 1.09)
+@settitle The EXT2FS Library (version 1.10)
 @synindex tp fn
 @comment %**end of header
 
@@ -60,7 +60,7 @@
 
 @title The EXT2FS Library
 @subtitle The EXT2FS Library
-@subtitle Version 1.09
+@subtitle Version 1.10
 @subtitle April 1997
 
 @author by Theodore Ts'o
@@ -101,7 +101,7 @@
 
 @top The EXT2FS Library
 
-This manual documents the EXT2FS Library, version 1.09.
+This manual documents the EXT2FS Library, version 1.10.
 
 @end ifinfo
 
diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog
index 0c0435b..82ec56b 100644
--- a/e2fsck/ChangeLog
+++ b/e2fsck/ChangeLog
@@ -1,3 +1,17 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Mon Apr 21 22:43:08 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* pass1b.c (pass1b): While scanning for inodes, simply skip inodes
+ 		where ext2fs_get_next_inode returns the 
+ 		EXT2_ET_BAD_BLOCK_IN_INODE_TABLE error.
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08
diff --git a/e2fsck/Makefile.in b/e2fsck/Makefile.in
index 4c4166c..24a9efb 100644
--- a/e2fsck/Makefile.in
+++ b/e2fsck/Makefile.in
@@ -147,34 +147,26 @@
 # 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 \
+e2fsck.o: $(srcdir)/e2fsck.c $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/uuid/uuid.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)/problem.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 \
+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 $(srcdir)/problem.h
-pass1b.o: $(srcdir)/pass1b.c \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.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 $(srcdir)/problem.h
-pass2.o: $(srcdir)/pass2.c $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/e2fsck.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 \
  $(srcdir)/problem.h
-pass3.o: $(srcdir)/pass3.c \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.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 $(srcdir)/problem.h
 pass4.o: $(srcdir)/pass4.c $(srcdir)/e2fsck.h \
@@ -182,31 +174,26 @@
  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.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 \
+ $(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 \
+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  
+ $(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 \
+ $(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  
-problem.o: $(srcdir)/problem.c \
- $(srcdir)/e2fsck.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h 
+problem.o: $(srcdir)/problem.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 $(srcdir)/problem.h
diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c
index 50865c1..0edefde 100644
--- a/e2fsck/pass1b.c
+++ b/e2fsck/pass1b.c
@@ -203,6 +203,8 @@
 		
 	next:
 		retval = ext2fs_get_next_inode(scan, &ino, &inode);
+		if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
+			goto next;
 		if (retval) {
 			com_err(program_name, retval,
 				"while doing inode scan");
diff --git a/include/linux/ChangeLog b/include/linux/ChangeLog
index 5bfd698..36bac49 100644
--- a/include/linux/ChangeLog
+++ b/include/linux/ChangeLog
@@ -1,3 +1,11 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08
diff --git a/install-utils/ChangeLog b/install-utils/ChangeLog
index 62d249c..0cd8cb1 100644
--- a/install-utils/ChangeLog
+++ b/install-utils/ChangeLog
@@ -1,3 +1,11 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08
diff --git a/lib/ChangeLog b/lib/ChangeLog
index aa5a2f8..6d23efd 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,11 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08
diff --git a/lib/e2p/ChangeLog b/lib/e2p/ChangeLog
index 0656914..9bb5ae5 100644
--- a/lib/e2p/ChangeLog
+++ b/lib/e2p/ChangeLog
@@ -1,3 +1,15 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Wed Apr 23 22:41:55 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* ls.c (list_super): Add #ifdef's so it will compile under 1.2.13
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08
diff --git a/lib/e2p/dll/jump.params b/lib/e2p/dll/jump.params
index ebaa892..f35d02c 100644
--- a/lib/e2p/dll/jump.params
+++ b/lib/e2p/dll/jump.params
@@ -3,4 +3,4 @@
 Data=0x00000000
 Jump=0x00001000
 GOT=0x00001000
-Version=1.2.0
+Version=1.3.0
diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
index 2cbe3d5..31695b8 100644
--- a/lib/e2p/ls.c
+++ b/lib/e2p/ls.c
@@ -156,6 +156,10 @@
 #define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
 #endif
 
+#ifndef EXT2_GOOD_OLD_REV
+#define EXT2_GOOD_OLD_REV 0
+#endif
+
 void list_super (struct ext2_super_block * s)
 {
 	int inode_blocks_per_group;
@@ -195,12 +199,14 @@
 #endif
 	} else
 		printf("\n");
+#ifdef EXT2_DYNAMIC_REV
 	printf ("Filesystem features:      ");
 	if (s->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
 		printf("sparse_super");
 	else
 		printf("(none)");
 	printf("\n");
+#endif
 	printf ("Filesystem state:        ");
 	print_fs_state (stdout, s->s_state);
 	printf ("\n");
diff --git a/lib/et/ChangeLog b/lib/et/ChangeLog
index e33cab7..3ffe363 100644
--- a/lib/et/ChangeLog
+++ b/lib/et/ChangeLog
@@ -1,3 +1,11 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08
diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog
index a30b2ba..d48c305 100644
--- a/lib/ext2fs/ChangeLog
+++ b/lib/ext2fs/ChangeLog
@@ -1,3 +1,84 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 24 10:13:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* alloc_tables.c (ext2fs_allocate_tables): Correctly place the
+		inode and block bitmaps based on the RAID 0 stride
+		parameter (which is passed by mke2fs).
+
+	* ext2fs.h: Add "stride" parameter to ext2_filsys, to be used by
+ 		mke2fs to communicate the stride length to
+ 		ext2fs_allocate_tables()
+
+Wed Apr 23 21:50:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* initialize.c (ext2fs_initialize): Fix to compile under Linux 1.2
+		systems.  (We can't assume that the new filesystem types
+		are supported.)
+
+Wed Apr 23 18:40:53 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* alloc_tables.c (ext2fs_allocate_tables): Make sure that we
+		allocate the inode and block bitmaps inside block group at
+		all times.
+
+Mon Apr 21 00:06:28 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* alloc.c (ext2fs_new_block): Fix bug where if goal==0 and the
+		filesystem has no free blocks, ext2fs_new_block would loop
+		forever.
+
+	* dupfs.c (ext2fs_dup_handle): Duplicate an ext2 filesystem handle
+
+	* freefs.c (ext2fs_free_inode_cache): Decrement refcount and only
+		free if refcount goes to zero.
+
+	* inode.c (create_icache): Initialize refcount to 1.
+
+	* ext2fsP.h: Added refcount to ext2_inode_cache
+
+	* dblist.c (ext2fs_copy_dblist): New function to copy a directory
+		block list.
+
+	* badblocks.c (ext2fs_badblocks_copy): New function to copy a
+		badblocks structure.
+
+Sun Apr 20 23:19:51 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* bitmaps.c (ext2fs_copy_bitmap): New function to copy a bitmap.
+
+	* unix_io.c, test_io.c (unix_open, test_open): Initialize the
+ 	 	refcount to 1.
+		(unix_close, test_close): Decrement the refcount and only
+ 		close the io_channel if the refcount goes to 0.
+
+	* io.h: Add refcount to the io_channel structure.  Add new macro
+		interface io_channel_bumpcount() to bump the refcount.
+
+Thu Apr 17 20:25:03 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* inode.c (ext2fs_read_inode, ext2fs_write_inode): Use the inode
+		cache in the filesystem handle, instead of the inode cache
+		in a static variable.
+
+	* freefs.c: Added static function to free the inode cache (called by
+		ext2fs_free). 
+
+	* ext2fsP.h: Added definition of the ext2_inode_cache structures.
+
+	* ext2fs.h: Added pointer to the inode_cache structure.
+
+	* block.c (block_iterate_ind, block_iterate_dind, 
+		block_iterate_tind): If there are holes in the indirect,
+		doubly indirect, or triply indirect blocks, increment the
+		block count field automatically.
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Mon Apr 14 20:38:56 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* version.c (ext2fs_parse_version_string): Check the passed in
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 348d622..4e220c6 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -24,6 +24,7 @@
 	dblist_dir.o \
 	dirblock.o \
 	dir_iterate.o \
+	dupfs.o \
 	expanddir.o \
 	freefs.o \
 	get_pathname.o \
@@ -70,6 +71,7 @@
 	$(srcdir)/dblist_dir.c \
 	$(srcdir)/dirblock.c \
 	$(srcdir)/dir_iterate.c \
+	$(srcdir)/dupfs.c \
 	$(srcdir)/expanddir.c \
 	$(srcdir)/freefs.c \
 	$(srcdir)/get_pathname.c \
@@ -197,155 +199,132 @@
 # the Makefile.in file
 #
 ext2_err.o: ext2_err.c
-alloc.o: $(srcdir)/alloc.c \
- $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-alloc_tables.o: $(srcdir)/alloc_tables.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-badblocks.o: $(srcdir)/badblocks.c $(srcdir)/ext2fsP.h \
- $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-bb_compat.o: $(srcdir)/bb_compat.c $(srcdir)/ext2fsP.h \
- $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-bb_inode.o: $(srcdir)/bb_inode.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-bitmaps.o: $(srcdir)/bitmaps.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-bitops.o: $(srcdir)/bitops.c $(srcdir)/ext2fs.h \
+alloc.o: $(srcdir)/alloc.c $(srcdir)/ext2fs.h \
  $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
  $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
-block.o: $(srcdir)/block.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+alloc_tables.o: $(srcdir)/alloc_tables.c $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+badblocks.o: $(srcdir)/badblocks.c $(srcdir)/ext2fsP.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h $(srcdir)/bitops.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h
+bb_compat.o: $(srcdir)/bb_compat.c $(srcdir)/ext2fsP.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+bb_inode.o: $(srcdir)/bb_inode.c $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+bitmaps.o: $(srcdir)/bitmaps.c $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+bitops.o: $(srcdir)/bitops.c $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+block.o: $(srcdir)/block.c $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 brel_ma.o: $(srcdir)/brel_ma.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h $(srcdir)/brel.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h $(srcdir)/bitops.h \
+ $(srcdir)/brel.h $(top_builddir)/lib/ext2fs/ext2_err.h
 check_desc.o: $(srcdir)/check_desc.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-closefs.o: $(srcdir)/closefs.c $(srcdir)/ext2fsP.h \
- $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+closefs.o: $(srcdir)/closefs.c $(srcdir)/ext2fsP.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
 cmp_bitmaps.o: $(srcdir)/cmp_bitmaps.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-dblist.o: $(srcdir)/dblist.c $(srcdir)/ext2fsP.h \
- $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-dblist_dir.o: $(srcdir)/dblist_dir.c $(srcdir)/ext2fsP.h \
- $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+dblist.o: $(srcdir)/dblist.c $(srcdir)/ext2fsP.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h $(srcdir)/bitops.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h 
+dblist_dir.o: $(srcdir)/dblist_dir.c $(srcdir)/ext2fsP.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h $(srcdir)/bitops.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h 
 dirblock.o: $(srcdir)/dirblock.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 dir_iterate.o: $(srcdir)/dir_iterate.c $(srcdir)/ext2fsP.h \
  $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-expanddir.o: $(srcdir)/expanddir.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-freefs.o: $(srcdir)/freefs.c $(srcdir)/ext2fs.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+dupfs.o: $(srcdir)/dupfs.c $(srcdir)/ext2fsP.h $(srcdir)/ext2fs.h \
  $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
  $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+expanddir.o: $(srcdir)/expanddir.c $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+freefs.o: $(srcdir)/freefs.c $(srcdir)/ext2fsP.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 get_pathname.o: $(srcdir)/get_pathname.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 getsize.o: $(srcdir)/getsize.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 icount.o: $(srcdir)/icount.c $(top_srcdir)/lib/et/com_err.h \
  $(srcdir)/ext2fs.h $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(srcdir)/bitops.h
-initialize.o: $(srcdir)/initialize.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
+initialize.o: $(srcdir)/initialize.c \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(srcdir)/bitops.h
 inline.o: $(srcdir)/inline.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 inode.o: $(srcdir)/inode.c $(srcdir)/ext2fsP.h \
  $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(srcdir)/bitops.h
 irel_ma.o: $(srcdir)/irel_ma.c $(srcdir)/ext2fs.h \
  $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h $(srcdir)/irel.h
+ $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h $(srcdir)/irel.h
 ismounted.o: $(srcdir)/ismounted.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 link.o: $(srcdir)/link.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
-llseek.o: $(srcdir)/llseek.c $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h  
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+llseek.o: $(srcdir)/llseek.c $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h  
 lookup.o: $(srcdir)/lookup.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
-mkdir.o: $(srcdir)/mkdir.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+mkdir.o: $(srcdir)/mkdir.c $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 namei.o: $(srcdir)/namei.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 native.o: $(srcdir)/native.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 newdir.o: $(srcdir)/newdir.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 openfs.o: $(srcdir)/openfs.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 read_bb.o: $(srcdir)/read_bb.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 read_bb_file.o: $(srcdir)/read_bb_file.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 rs_bitmap.o: $(srcdir)/rs_bitmap.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 rw_bitmaps.o: $(srcdir)/rw_bitmaps.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 swapfs.o: $(srcdir)/swapfs.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 test_io.o: $(srcdir)/test_io.c $(top_srcdir)/lib/et/com_err.h \
  $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/io.h
 unix_io.o: $(srcdir)/unix_io.c $(top_srcdir)/lib/et/com_err.h \
  $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/io.h
 unlink.o: $(srcdir)/unlink.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
 valid_blk.o: $(srcdir)/valid_blk.c $(srcdir)/ext2fs.h \
  $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
  $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
diff --git a/lib/ext2fs/alloc.c b/lib/ext2fs/alloc.c
index 0bc637d..50cee77 100644
--- a/lib/ext2fs/alloc.c
+++ b/lib/ext2fs/alloc.c
@@ -73,7 +73,7 @@
 errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
 			   ext2fs_block_bitmap map, blk_t *ret)
 {
-	blk_t	i = goal;
+	blk_t	i;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
@@ -81,8 +81,9 @@
 		map = fs->block_map;
 	if (!map)
 		return EXT2_ET_NO_BLOCK_BITMAP;
-	if (!i)
-		i = fs->super->s_first_data_block;
+	if (!goal || (goal >= fs->super->s_blocks_count))
+		goal = fs->super->s_first_data_block;
+	i = goal;
 	do {
 		if (!ext2fs_test_block_bitmap(map, i)) {
 			*ret = i;
diff --git a/lib/ext2fs/alloc_tables.c b/lib/ext2fs/alloc_tables.c
index 65c129f..6a60bf7 100644
--- a/lib/ext2fs/alloc_tables.c
+++ b/lib/ext2fs/alloc_tables.c
@@ -42,6 +42,8 @@
 		 * Allocate the inode table
 		 */
 		start_blk = group_blk + 3 + fs->desc_blocks;
+		if (start_blk > last_blk)
+			start_blk = group_blk;
 		retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
 						fs->inode_blocks_per_group,
 						fs->block_map, &new_blk);
@@ -56,8 +58,15 @@
 		/*
 		 * Allocate the block and inode bitmaps
 		 */
-		start_blk += fs->inode_blocks_per_group +
-			((2 * i) % (last_blk - start_blk));
+		if (fs->stride) {
+			start_blk += fs->inode_blocks_per_group;
+			start_blk += ((fs->stride * i) %
+				      (last_blk - start_blk));
+			if (start_blk > last_blk)
+				 /* should never happen */
+				start_blk = group_blk;
+		} else
+			start_blk = group_blk;
 		retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
 						1, fs->block_map, &new_blk);
 		if (retval)
diff --git a/lib/ext2fs/badblocks.c b/lib/ext2fs/badblocks.c
index 722af8d..f8a562a 100644
--- a/lib/ext2fs/badblocks.c
+++ b/lib/ext2fs/badblocks.c
@@ -26,26 +26,58 @@
 #include "ext2fsP.h"
 
 /*
- * This procedure create an empty badblocks list.
+ * Helper function for making a badblocks list
  */
-errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
+static errcode_t make_badblocks_list(int size, int num, blk_t *list,
+				     ext2_badblocks_list *ret)
 {
 	ext2_badblocks_list	bb;
-
+	
 	bb = malloc(sizeof(struct ext2_struct_badblocks_list));
 	if (!bb)
 		return ENOMEM;
 	memset(bb, 0, sizeof(struct ext2_struct_badblocks_list));
 	bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
 	bb->size = size ? size : 10;
+	bb->num = num;
 	bb->list = malloc(bb->size * sizeof(blk_t));
 	if (!bb->list) {
 		free(bb);
 		return ENOMEM;
 	}
+	if (list)
+		memcpy(bb->list, list, bb->size * sizeof(blk_t));
+	else
+		memset(bb->list, 0, bb->size * sizeof(blk_t));
 	*ret = bb;
 	return 0;
 }
+	
+
+/*
+ * This procedure creates an empty badblocks list.
+ */
+errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
+{
+	return make_badblocks_list(size, 0, 0, ret);
+}
+
+/*
+ * This procedure copies a badblocks list
+ */
+errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
+				ext2_badblocks_list *dest)
+{
+	errcode_t	retval;
+	
+	retval = make_badblocks_list(src->size, src->num, src->list,
+				     dest);
+	if (retval)
+		return retval;
+	(*dest)->badblocks_flags = src->badblocks_flags;
+	return 0;
+}
+
 
 /*
  * This procedure frees a badblocks list.
diff --git a/lib/ext2fs/bitmaps.c b/lib/ext2fs/bitmaps.c
index 3ef5666..c3a778d 100644
--- a/lib/ext2fs/bitmaps.c
+++ b/lib/ext2fs/bitmaps.c
@@ -26,11 +26,9 @@
 
 #include "ext2fs.h"
 
-errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
-					 __u32 end,
-					 __u32 real_end,
-					 const char *descr,
-					 ext2fs_generic_bitmap *ret)
+static errcode_t make_bitmap(__u32 start, __u32 end, __u32 real_end,
+			     const char *descr, char *init_map,
+			     ext2fs_generic_bitmap *ret)
 {
 	ext2fs_generic_bitmap bitmap;
 	int	size;
@@ -63,11 +61,40 @@
 		return ENOMEM;
 	}
 
-	memset(bitmap->bitmap, 0, size);
+	if (init_map)
+		memcpy(bitmap->bitmap, init_map, size);
+	else
+		memset(bitmap->bitmap, 0, size);
 	*ret = bitmap;
 	return 0;
 }
 
+errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+					 __u32 end,
+					 __u32 real_end,
+					 const char *descr,
+					 ext2fs_generic_bitmap *ret)
+{
+	return make_bitmap(start, end, real_end, descr, 0, ret);
+}
+
+errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
+			     ext2fs_generic_bitmap *dest)
+{
+	errcode_t		retval;
+	ext2fs_generic_bitmap	new;
+
+	retval = make_bitmap(src->start, src->end, src->real_end,
+			     src->description, src->bitmap, &new);
+	if (retval)
+		return retval;
+	new->magic = src->magic;
+	new->fs = src->fs;
+	new->base_error_code = src->base_error_code;
+	return 0;
+}
+
+
 errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
 				       const char *descr,
 				       ext2fs_inode_bitmap *ret)
diff --git a/lib/ext2fs/block.c b/lib/ext2fs/block.c
index 3552dab..03bf5f3 100644
--- a/lib/ext2fs/block.c
+++ b/lib/ext2fs/block.c
@@ -46,13 +46,16 @@
 	int	i, flags, limit, offset;
 	blk_t	*block_nr;
 
+	limit = ctx->fs->blocksize >> 2;
 	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
 	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
 		ret = (*ctx->func)(ctx->fs, ind_block,
 				   BLOCK_COUNT_IND, ref_block,
 				   ref_offset, ctx->private);
-	if (!*ind_block || (ret & BLOCK_ABORT))
+	if (!*ind_block || (ret & BLOCK_ABORT)) {
+		ctx->bcount += limit;
 		return ret;
+	}
 	if (*ind_block >= ctx->fs->super->s_blocks_count ||
 	    *ind_block < ctx->fs->super->s_first_data_block) {
 		ctx->errcode = EXT2_ET_BAD_IND_BLOCK;
@@ -65,7 +68,6 @@
 		ret |= BLOCK_ERROR;
 		return ret;
 	}
-	limit = ctx->fs->blocksize >> 2;
 	if ((ctx->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
 	    (ctx->fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) {
 		block_nr = (blk_t *) ctx->ind_buf;
@@ -129,13 +131,16 @@
 	int	i, flags, limit, offset;
 	blk_t	*block_nr;
 
+	limit = ctx->fs->blocksize >> 2;
 	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
 	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
 		ret = (*ctx->func)(ctx->fs, dind_block,
 				   BLOCK_COUNT_DIND, ref_block,
 				   ref_offset, ctx->private);
-	if (!*dind_block || (ret & BLOCK_ABORT))
+	if (!*dind_block || (ret & BLOCK_ABORT)) {
+		ctx->bcount += limit*limit;
 		return ret;
+	}
 	if (*dind_block >= ctx->fs->super->s_blocks_count ||
 	    *dind_block < ctx->fs->super->s_first_data_block) {
 		ctx->errcode = EXT2_ET_BAD_DIND_BLOCK;
@@ -148,7 +153,6 @@
 		ret |= BLOCK_ERROR;
 		return ret;
 	}
-	limit = ctx->fs->blocksize >> 2;
 	if ((ctx->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
 	    (ctx->fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) {
 		block_nr = (blk_t *) ctx->dind_buf;
@@ -171,8 +175,10 @@
 		}
 	} else {
 		for (i = 0; i < limit; i++, block_nr++) {
-			if (*block_nr == 0)
+			if (*block_nr == 0) {
+				ctx->bcount += limit;
 				continue;
+			}
 			flags = block_iterate_ind(block_nr,
 						  *dind_block, offset,
 						  ctx);
@@ -212,13 +218,16 @@
 	int	i, flags, limit, offset;
 	blk_t	*block_nr;
 
+	limit = ctx->fs->blocksize >> 2;
 	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
 	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
 		ret = (*ctx->func)(ctx->fs, tind_block,
 				   BLOCK_COUNT_TIND, ref_block,
 				   ref_offset, ctx->private);
-	if (!*tind_block || (ret & BLOCK_ABORT))
+	if (!*tind_block || (ret & BLOCK_ABORT)) {
+		ctx->bcount += limit*limit*limit;
 		return ret;
+	}
 	if (*tind_block >= ctx->fs->super->s_blocks_count ||
 	    *tind_block < ctx->fs->super->s_first_data_block) {
 		ctx->errcode = EXT2_ET_BAD_TIND_BLOCK;
@@ -231,7 +240,6 @@
 		ret |= BLOCK_ERROR;
 		return ret;
 	}
-	limit = ctx->fs->blocksize >> 2;
 	if ((ctx->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
 	    (ctx->fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) {
 		block_nr = (blk_t *) ctx->tind_buf;
@@ -254,8 +262,10 @@
 		}
 	} else {
 		for (i = 0; i < limit; i++, block_nr++) {
-			if (*block_nr == 0)
+			if (*block_nr == 0) {
+				ctx->bcount += limit*limit;
 				continue;
+			}
 			flags = block_iterate_dind(block_nr,
 						   *tind_block,
 						   offset, ctx);
diff --git a/lib/ext2fs/closefs.c b/lib/ext2fs/closefs.c
index a61f878..4678d9e 100644
--- a/lib/ext2fs/closefs.c
+++ b/lib/ext2fs/closefs.c
@@ -190,33 +190,3 @@
 	return 0;
 }
 
-/*
- * This procedure frees a badblocks list.
- */
-void ext2fs_badblocks_list_free(ext2_badblocks_list bb)
-{
-	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
-		return;
-
-	if (bb->list)
-		free(bb->list);
-	bb->list = 0;
-	free(bb);
-}
-
-/*
- * Close a directory block list
- */
-void ext2fs_free_dblist(ext2_dblist dblist)
-{
-	if (!dblist || (dblist->magic != EXT2_ET_MAGIC_DBLIST))
-		return;
-
-	if (dblist->list)
-		free(dblist->list);
-	dblist->list = 0;
-	if (dblist->fs && dblist->fs->dblist == dblist)
-		dblist->fs->dblist = 0;
-	dblist->magic = 0;
-	free(dblist);
-}
diff --git a/lib/ext2fs/dblist.c b/lib/ext2fs/dblist.c
index 76c847f..f990c10 100644
--- a/lib/ext2fs/dblist.c
+++ b/lib/ext2fs/dblist.c
@@ -47,12 +47,16 @@
 }
 
 /*
- * Initialize a directory block list
+ * helper function for making a new directory block list (for
+ * initialize and copy).
  */
-errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist)
+static errcode_t make_dblist(ext2_filsys fs, ino_t size, ino_t count,
+			     struct ext2_db_entry *list,
+			     ext2_dblist *ret_dblist)
 {
 	ext2_dblist	dblist;
 	errcode_t	retval;
+	size_t		len;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
@@ -67,27 +71,68 @@
 
 	dblist->magic = EXT2_ET_MAGIC_DBLIST;
 	dblist->fs = fs;
-	retval = ext2fs_get_num_dirs(fs, &dblist->size);
-	if (retval)
-		goto cleanup;
-
-	dblist->count = 0;
-	dblist->sorted = 1;
-	dblist->list = malloc(sizeof(struct ext2_db_entry) * dblist->size);
+	if (size)
+		dblist->size = size;
+	else {
+		retval = ext2fs_get_num_dirs(fs, &dblist->size);
+		if (retval)
+			goto cleanup;
+	}
+	len = sizeof(struct ext2_db_entry) * dblist->size;
+	dblist->count = count;
+	dblist->list = malloc(len);
 	if (dblist->list == NULL) {
 		retval = ENOMEM;
 		goto cleanup;
 	}
+	if (list)
+		memcpy(dblist->list, list, len);
+	else
+		memset(dblist->list, 0, len);
+	*ret_dblist = dblist;
+	return 0;
+cleanup:
+	if (dblist)
+		free(dblist);
+	return retval;
+}
+
+/*
+ * Initialize a directory block list
+ */
+errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist)
+{
+	ext2_dblist	dblist;
+	errcode_t	retval;
+
+	retval = make_dblist(fs, 0, 0, 0, &dblist);
+	if (retval)
+		return retval;
+
+	dblist->sorted = 1;
 	if (ret_dblist)
 		*ret_dblist = dblist;
 	else
 		fs->dblist = dblist;
 
 	return 0;
-cleanup:
-	if (dblist)
-		free(dblist);
-	return retval;
+}
+
+/*
+ * Copy a directory block list
+ */
+errcode_t ext2fs_copy_dblist(ext2_dblist src, ext2_dblist *dest)
+{
+	ext2_dblist	dblist;
+	errcode_t	retval;
+
+	retval = make_dblist(src->fs, src->size, src->count, src->list,
+			     &dblist);
+	if (retval)
+		return retval;
+	dblist->sorted = src->sorted;
+	*dest = dblist;
+	return 0;
 }
 
 /*
diff --git a/lib/ext2fs/dll/jump.funcs b/lib/ext2fs/dll/jump.funcs
index 6084372..680a64d 100644
--- a/lib/ext2fs/dll/jump.funcs
+++ b/lib/ext2fs/dll/jump.funcs
@@ -142,3 +142,11 @@
 00000000 T _ext2fs_get_library_version		libext2fs	version
 00000000 T _ext2fs_parse_version_string		libext2fs	version
 00000000 T _ext2fs_set_dir_block		libext2fs	dblist
+00000000 T _ext2fs_badblocks_copy 		libext2fs       badblocks
+00000000 T _ext2fs_copy_bitmap			libext2fs       bitmaps
+00000000 T _ext2fs_bg_has_super 		libext2fs       closefs
+00000000 T _ext2fs_copy_dblist  		libext2fs       dblist
+00000000 T _ext2fs_dup_handle   		libext2fs       dupfs
+00000000 T _ext2fs_icount_validate		libext2fs       icount
+00000000 T _ext2fs_resize_inode_bitmap 		libext2fs       rs_bitmap
+00000000 T _ext2fs_resize_block_bitmap 		libext2fs       rs_bitmap
diff --git a/lib/ext2fs/dll/jump.params b/lib/ext2fs/dll/jump.params
index cc96847..d4d1b33 100644
--- a/lib/ext2fs/dll/jump.params
+++ b/lib/ext2fs/dll/jump.params
@@ -3,4 +3,4 @@
 Data=0x00000000
 Jump=0x00001000
 GOT=0x00001000
-Version=1.1.0
+Version=1.2.0
diff --git a/lib/ext2fs/dupfs.c b/lib/ext2fs/dupfs.c
new file mode 100644
index 0000000..b2eee0b
--- /dev/null
+++ b/lib/ext2fs/dupfs.c
@@ -0,0 +1,93 @@
+/*
+ * dupfs.c --- duplicate a ext2 filesystem handle
+ * 
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fsP.h"
+
+errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest)
+{
+	ext2_filsys	fs;
+	errcode_t	retval;
+
+	EXT2_CHECK_MAGIC(src, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+	
+	fs = (ext2_filsys) malloc(sizeof(struct struct_ext2_filsys));
+	if (!fs)
+		return ENOMEM;
+
+	*fs = *src;
+	fs->device_name = 0;
+	fs->super = 0;
+	fs->group_desc = 0;
+	fs->inode_map = 0;
+	fs->block_map = 0;
+	fs->badblocks = 0;
+	fs->dblist = 0;
+
+	io_channel_bumpcount(fs->io);
+	if (fs->icache)
+		fs->icache->refcount++;
+
+	retval = ENOMEM;
+	fs->device_name = malloc(strlen(src->device_name)+1);
+	if (!fs->device_name)
+		goto errout;
+	strcpy(fs->device_name, src->device_name);
+
+	fs->super = malloc(SUPERBLOCK_SIZE);
+	if (!fs->super)
+		goto errout;
+	memcpy(fs->super, src->super, SUPERBLOCK_SIZE);
+
+	fs->group_desc = malloc(fs->desc_blocks * fs->blocksize);
+	if (!fs->group_desc)
+		goto errout;
+	memcpy(fs->group_desc, src->group_desc,
+	       fs->desc_blocks * fs->blocksize);
+
+	if (src->inode_map) {
+		retval = ext2fs_copy_bitmap(src->inode_map, &fs->inode_map);
+		if (retval)
+			goto errout;
+	}
+	if (src->block_map) {
+		retval = ext2fs_copy_bitmap(src->block_map, &fs->block_map);
+		if (retval)
+			goto errout;
+	}
+	if (src->badblocks) {
+		retval = ext2fs_badblocks_copy(src->badblocks, &fs->badblocks);
+		if (retval)
+			goto errout;
+	}
+	if (src->dblist) {
+		retval = ext2fs_copy_dblist(src->dblist, &fs->dblist);
+		if (retval)
+			goto errout;
+	}
+	*dest = fs;
+	return 0;
+errout:
+	ext2fs_free(fs);
+	return retval;
+	
+}
+
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 4e14fd6..2e68c4c 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -141,16 +141,21 @@
 				struct ext2_inode *inode);
 	badblocks_list			badblocks;
 	ext2_dblist			dblist;
+	__u32				stride;	/* for mke2fs */
 	/*
 	 * Reserved for future expansion
 	 */
-	__u32				reserved[12];
+	__u32				reserved[11];
 
 	/*
-	 * Not used by ext2fs library; reserved for the use of the
-	 * calling application.
+	 * Reserved for the use of the calling application.
 	 */
-	void *				private; 
+	void *				private;
+
+	/*
+	 * Inode cache
+	 */
+	struct ext2_inode_cache		*icache;
 };
 
 #include "ext2fs/bitops.h"
@@ -374,7 +379,6 @@
 /* badblocks.c */
 extern errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret,
 					    int size);
-extern void ext2fs_badblocks_list_free(ext2_badblocks_list bb);
 extern errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb,
 					   blk_t blk);
 extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
@@ -385,16 +389,18 @@
 extern int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter,
 					 blk_t *blk);
 extern void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter);
+extern errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
+				       ext2_badblocks_list *dest);
 
 /* bb_compat */
 extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
-extern void badblocks_list_free(badblocks_list bb);
 extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
 extern int badblocks_list_test(badblocks_list bb, blk_t blk);
 extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
 					      badblocks_iterate *ret);
 extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
 extern void badblocks_list_iterate_end(badblocks_iterate iter);
+extern void badblocks_list_free(badblocks_list bb);
 
 /* bb_inode.c */
 extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
@@ -464,18 +470,18 @@
 
 /* dblist.c */
 
-errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ino_t *ret_num_dirs);
-errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
-void ext2fs_free_dblist(ext2_dblist dblist);
-errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ino_t ino, blk_t blk,
-			     int blockcnt);
-errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
-				int (*func)(ext2_filsys fs,
-					    struct ext2_db_entry *db_info,
-					    void	*private),
-				void *private);
-errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ino_t ino, blk_t blk,
-			       int blockcnt);
+extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ino_t *ret_num_dirs);
+extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
+extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ino_t ino,
+				      blk_t blk, int blockcnt);
+extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
+	int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info,
+		    void	*private),
+       void *private);
+extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ino_t ino,
+				      blk_t blk, int blockcnt);
+extern errcode_t ext2fs_copy_dblist(ext2_dblist src,
+				    ext2_dblist *dest);
 
 /* dblist_dir.c */
 extern errcode_t
@@ -514,6 +520,8 @@
 				    int		blockcnt,
 				    void		*private);
 
+/* dupfs.c */
+extern errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest);
 
 /* expanddir.c */
 extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ino_t dir);
@@ -523,6 +531,8 @@
 extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
 extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
 extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
+extern void ext2fs_free_dblist(ext2_dblist dblist);
+extern void ext2fs_badblocks_list_free(badblocks_list bb);
 
 /* getsize.c */
 extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
@@ -631,6 +641,8 @@
 					    ext2fs_inode_bitmap bmap);
 extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
 					    ext2fs_block_bitmap bmap);
+extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
+				    ext2fs_generic_bitmap *dest);
 
 /* swapfs.c */
 extern void ext2fs_swap_super(struct ext2_super_block * super);
diff --git a/lib/ext2fs/ext2fsP.h b/lib/ext2fs/ext2fsP.h
index 5cf83b5..113a9b6 100644
--- a/lib/ext2fs/ext2fsP.h
+++ b/lib/ext2fs/ext2fsP.h
@@ -64,6 +64,22 @@
 	errcode_t	errcode;
 };
 
+/*
+ * Inode cache structure
+ */
+struct ext2_inode_cache {
+	void *				buffer;
+	blk_t				buffer_blk;
+	int				cache_last;
+	int				cache_size;
+	int				refcount;
+	struct ext2_inode_cache_ent	*cache;
+};
+
+struct ext2_inode_cache_ent {
+	ino_t	ino;
+	struct ext2_inode inode;
+};
 
 /* Function prototypes */
 
diff --git a/lib/ext2fs/freefs.c b/lib/ext2fs/freefs.c
index 215d1fb..43331ab 100644
--- a/lib/ext2fs/freefs.c
+++ b/lib/ext2fs/freefs.c
@@ -15,7 +15,9 @@
 
 #include <linux/ext2_fs.h>
 
-#include "ext2fs.h"
+#include "ext2fsP.h"
+
+static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache);
 
 void ext2fs_free(ext2_filsys fs)
 {
@@ -41,6 +43,9 @@
 
 	if (fs->dblist)
 		ext2fs_free_dblist(fs->dblist);
+
+	if (fs->icache)
+		ext2fs_free_inode_cache(fs->icache);
 	
 	fs->magic = 0;
 
@@ -82,3 +87,49 @@
 	ext2fs_free_generic_bitmap(bitmap);
 }
 
+/*
+ * Free the inode cache structure
+ */
+static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache)
+{
+	if (--icache->refcount)
+		return;
+	if (icache->buffer)
+		free(icache->buffer);
+	if (icache->cache)
+		free(icache->cache);
+	icache->buffer_blk = 0;
+	free(icache);
+}
+
+/*
+ * This procedure frees a badblocks list.
+ */
+void ext2fs_badblocks_list_free(ext2_badblocks_list bb)
+{
+	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
+		return;
+
+	if (bb->list)
+		free(bb->list);
+	bb->list = 0;
+	free(bb);
+}
+
+/*
+ * Free a directory block list
+ */
+void ext2fs_free_dblist(ext2_dblist dblist)
+{
+	if (!dblist || (dblist->magic != EXT2_ET_MAGIC_DBLIST))
+		return;
+
+	if (dblist->list)
+		free(dblist->list);
+	dblist->list = 0;
+	if (dblist->fs && dblist->fs->dblist == dblist)
+		dblist->fs->dblist = 0;
+	dblist->magic = 0;
+	free(dblist);
+}
+
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index 874b118..f9e744b 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -58,7 +58,6 @@
 	ext2_filsys	fs;
 	errcode_t	retval;
 	struct ext2_super_block *super;
-	struct ext2fs_sb	*s;
 	int		frags_per_block;
 	int		rem;
 	int		overhead = 0;
@@ -92,12 +91,9 @@
 		goto cleanup;
 	}
 	memset(super, 0, SUPERBLOCK_SIZE);
-	s = (struct ext2fs_sb *) super;
 
 #define set_field(field, default) (super->field = param->field ? \
 				   param->field : (default))
-#define set_ext2_field(field, default) (s->field = param->field ? \
-					param->field : (default))
 
 	super->s_magic = EXT2_SUPER_MAGIC;
 	super->s_state = EXT2_VALID_FS;
@@ -107,15 +103,15 @@
 	set_field(s_first_data_block, super->s_log_block_size ? 0 : 1);
 	set_field(s_max_mnt_count, EXT2_DFL_MAX_MNT_COUNT);
 	set_field(s_errors, EXT2_ERRORS_DEFAULT);
-	set_ext2_field(s_feature_compat, 0);
-	set_ext2_field(s_feature_incompat, 0);
-	set_ext2_field(s_feature_ro_compat, 0);
-	if (s->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)
+#ifdef EXT2_DYNAMIC_REV
+	set_field(s_feature_compat, 0);
+	set_field(s_feature_incompat, 0);
+	set_field(s_feature_ro_compat, 0);
+	if (super->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)
 		return EXT2_ET_UNSUPP_FEATURE;
-	if (s->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)
+	if (super->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)
 		return EXT2_ET_RO_UNSUPP_FEATURE;
 
-#ifdef EXT2_DYNAMIC_REV
 	set_field(s_rev_level, EXT2_GOOD_OLD_REV);
 	if (super->s_rev_level >= EXT2_DYNAMIC_REV) {
 		set_field(s_first_ino, EXT2_GOOD_OLD_FIRST_INO);
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index 7194fb0..be882ad 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -46,6 +46,35 @@
 	int			reserved[6];
 };
 
+static errcode_t create_icache(ext2_filsys fs)
+{
+	int	i;
+	
+	if (fs->icache)
+		return 0;
+	fs->icache = malloc(sizeof(struct ext2_inode_cache));
+	memset(fs->icache, 0, sizeof(struct ext2_inode_cache));
+	fs->icache->buffer = malloc(fs->blocksize);
+	if (!fs->icache->buffer) {
+		free(fs->icache);
+		return ENOMEM;
+	}
+	fs->icache->buffer_blk = 0;
+	fs->icache->cache_last = -1;
+	fs->icache->cache_size = 4;
+	fs->icache->refcount = 1;
+	fs->icache->cache = malloc(sizeof(struct ext2_inode_cache_ent)
+				   * fs->icache->cache_size);
+	if (!fs->icache->cache) {
+		free(fs->icache->buffer);
+		free(fs->icache);
+		return ENOMEM;
+	}
+	for (i=0; i < fs->icache->cache_size; i++)
+		fs->icache->cache[i].ino = 0;
+	return 0;
+}
+
 errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
 				 ext2_inode_scan *ret_scan)
 {
@@ -377,19 +406,6 @@
 /*
  * Functions to read and write a single inode.
  */
-static char *inode_buffer = 0;
-static blk_t inode_buffer_block = 0;
-static int inode_buffer_size = 0;
-#define INODE_CACHE_SIZE 4
-#ifdef INODE_CACHE_SIZE
-static int cache_last = -1;
-static struct {
-	ino_t	inode;
-	struct ext2_inode value;
-} inode_cache[INODE_CACHE_SIZE];
-#endif
-
-
 errcode_t ext2fs_read_inode (ext2_filsys fs, ino_t ino,
 			     struct ext2_inode * inode)
 {
@@ -406,32 +422,21 @@
 		if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
 			return retval;
 	}
+	/* Create inode cache if not present */
+	if (!fs->icache) {
+		retval = create_icache(fs);
+		if (retval)
+			return retval;
+	}
 	/* Check to see if it's in the inode cache */
-#ifdef INODE_CACHE_SIZE
-	if (cache_last == -1) {
-		for (i=0; i < INODE_CACHE_SIZE; i++)
-			inode_cache[i].inode = 0;
-		cache_last = INODE_CACHE_SIZE-1;
-	} else for (i=0; i < INODE_CACHE_SIZE; i++) {
-		if (inode_cache[i].inode == ino) {
-			*inode = inode_cache[i].value;
+	for (i=0; i < fs->icache->cache_size; i++) {
+		if (fs->icache->cache[i].ino == ino) {
+			*inode = fs->icache->cache[i].inode;
 			return 0;
 		}
 	}
-#endif
 	if (ino > fs->super->s_inodes_count)
 		return EXT2_ET_BAD_INODE_NUM;
-	if (inode_buffer_size != fs->blocksize) {
-		if (inode_buffer)
-			free(inode_buffer);
-		inode_buffer_size = 0;
-		inode_buffer = malloc(fs->blocksize);
-		if (!inode_buffer)
-			return ENOMEM;
-		inode_buffer_size = fs->blocksize;
-		inode_buffer_block = 0;
-	}
-		
 	group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
 	offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
 		EXT2_INODE_SIZE(fs->super);
@@ -439,15 +444,15 @@
 	if (!fs->group_desc[group].bg_inode_table)
 		return EXT2_ET_MISSING_INODE_TABLE;
 	block_nr = fs->group_desc[group].bg_inode_table + block;
-	if (block_nr != inode_buffer_block) {
+	if (block_nr != fs->icache->buffer_blk) {
 		retval = io_channel_read_blk(fs->io, block_nr, 1,
-					     inode_buffer);
+					     fs->icache->buffer);
 		if (retval)
 			return retval;
-		inode_buffer_block = block_nr;
+		fs->icache->buffer_blk = block_nr;
 	}
 	offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
-	ptr = ((char *) inode_buffer) + offset;
+	ptr = ((char *) fs->icache->buffer) + offset;
 
 	memset(inode, 0, sizeof(struct ext2_inode));
 	length = EXT2_INODE_SIZE(fs->super);
@@ -460,13 +465,15 @@
 		length -= clen;
 		
 		retval = io_channel_read_blk(fs->io, block_nr+1, 1,
-					     inode_buffer);
-		if (retval)
+					     fs->icache->buffer);
+		if (retval) {
+			fs->icache->buffer_blk = 0;
 			return retval;
-		inode_buffer_block = block_nr+1;
+		}
+		fs->icache->buffer_blk = block_nr+1;
 		
 		memcpy(((char *) inode) + clen,
-		       inode_buffer, length);
+		       fs->icache->buffer, length);
 	} else
 		memcpy((char *) inode, ptr, length);
 	
@@ -475,12 +482,11 @@
 		ext2fs_swap_inode(fs, inode, inode, 0);
 
 	/* Update the inode cache */
-#ifdef INODE_CACHE_SIZE
-	cache_last = (cache_last + 1) % INODE_CACHE_SIZE;
-	inode_cache[cache_last].inode = ino;
-	inode_cache[cache_last].value = *inode;
-#endif
-
+	fs->icache->cache_last = (fs->icache->cache_last + 1) %
+		fs->icache->cache_size;
+	fs->icache->cache[fs->icache->cache_last].ino = ino;
+	fs->icache->cache[fs->icache->cache_last].inode = *inode;
+	
 	return 0;
 }
 
@@ -501,31 +507,27 @@
 		if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
 			return retval;
 	}
+
 	/* Check to see if the inode cache needs to be updated */
-#ifdef INODE_CACHE_SIZE
-	for (i=0; i < INODE_CACHE_SIZE; i++) {
-		if (inode_cache[i].inode == ino) {
-			inode_cache[i].value = *inode;
-			break;
+	if (fs->icache) {
+		for (i=0; i < fs->icache->cache_size; i++) {
+			if (fs->icache->cache[i].ino == ino) {
+				fs->icache->cache[i].inode = *inode;
+				break;
+			}
 		}
+	} else {
+		retval = create_icache(fs);
+		if (retval)
+			return retval;
 	}
-#endif
+		
 	if (!(fs->flags & EXT2_FLAG_RW))
 		return EXT2_ET_RO_FILSYS;
 
 	if (ino > fs->super->s_inodes_count)
 		return EXT2_ET_BAD_INODE_NUM;
 
-	if (inode_buffer_size != fs->blocksize) {
-		if (inode_buffer)
-			free(inode_buffer);
-		inode_buffer_size = 0;
-		inode_buffer = malloc(fs->blocksize);
-		if (!inode_buffer)
-			return ENOMEM;
-		inode_buffer_size = fs->blocksize;
-		inode_buffer_block = 0;
-	}
 	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
 	    (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
 		ext2fs_swap_inode(fs, &temp_inode, inode, 1);
@@ -540,19 +542,19 @@
 		return EXT2_ET_MISSING_INODE_TABLE;
 	block_nr = fs->group_desc[group].bg_inode_table + block;
 	offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
-	ptr = (char *) inode_buffer + offset;
+	ptr = (char *) fs->icache->buffer + offset;
 
 	length = EXT2_INODE_SIZE(fs->super);
 	clen = length;
 	if (length > sizeof(struct ext2_inode))
 		length = sizeof(struct ext2_inode);
 	
-	if (inode_buffer_block != block_nr) {
+	if (fs->icache->buffer_blk != block_nr) {
 		retval = io_channel_read_blk(fs->io, block_nr, 1,
-					     inode_buffer);
+					     fs->icache->buffer);
 		if (retval)
 			return retval;
-		inode_buffer_block = block_nr;
+		fs->icache->buffer_blk = block_nr;
 	}
 	
 	if ((offset + length) > EXT2_BLOCK_SIZE(fs->super)) {
@@ -562,22 +564,23 @@
 		length = 0;
 	}
 	memcpy(ptr, &temp_inode, clen);
-	retval = io_channel_write_blk(fs->io, block_nr, 1, inode_buffer);
+	retval = io_channel_write_blk(fs->io, block_nr, 1, fs->icache->buffer);
 	if (retval)
 		return retval;
 
 	if (length) {
 		retval = io_channel_read_blk(fs->io, ++block_nr, 1,
-					     inode_buffer);
+					     fs->icache->buffer);
 		if (retval) {
-			inode_buffer_block = 0;
+			fs->icache->buffer_blk = 0;
 			return retval;
 		}
-		inode_buffer_block = block_nr;
-		memcpy(inode_buffer, ((char *) &temp_inode) + clen, length);
+		fs->icache->buffer_blk = block_nr;
+		memcpy(fs->icache->buffer, ((char *) &temp_inode) + clen,
+		       length);
 
 		retval = io_channel_write_blk(fs->io, block_nr, 1,
-					      inode_buffer);
+					      fs->icache->buffer);
 		if (retval)
 			return retval;
 	}
diff --git a/lib/ext2fs/io.h b/lib/ext2fs/io.h
index 6b28fee..fcd1a01 100644
--- a/lib/ext2fs/io.h
+++ b/lib/ext2fs/io.h
@@ -43,7 +43,8 @@
 				       size_t size,
 				       int actual_bytes_written,
 				       errcode_t error);
-	int		reserved[16];
+	int		refcount;
+	int		reserved[15];
 	void		*private_data;
 };
 
@@ -71,6 +72,7 @@
 #define io_channel_read_blk(c,b,n,d)	((c)->manager->read_blk((c),b,n,d))
 #define io_channel_write_blk(c,b,n,d)	((c)->manager->write_blk((c),b,n,d))
 #define io_channel_flush(c) 		((c)->manager->flush((c)))
+#define io_channel_bumpcount(c)		((c)->refcount++)
 	
 /* unix_io.c */
 extern io_manager unix_io_manager;
diff --git a/lib/ext2fs/test_io.c b/lib/ext2fs/test_io.c
index 1bd09b1..a82f094 100644
--- a/lib/ext2fs/test_io.c
+++ b/lib/ext2fs/test_io.c
@@ -104,6 +104,7 @@
 	io->block_size = 1024;
 	io->read_error = 0;
 	io->write_error = 0;
+	io->refcount = 1;
 
 	memset(data, 0, sizeof(struct test_private_data));
 	data->magic = EXT2_ET_MAGIC_TEST_IO_CHANNEL;
@@ -138,6 +139,9 @@
 	data = (struct test_private_data *) channel->private_data;
 	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
 
+	if (--channel->refcount > 0)
+		return 0;
+	
 	if (data->real)
 		retval = io_channel_close(data->real);
 	
diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c
index 5083771..ef00902 100644
--- a/lib/ext2fs/unix_io.c
+++ b/lib/ext2fs/unix_io.c
@@ -94,6 +94,7 @@
 	io->block_size = 1024;
 	io->read_error = 0;
 	io->write_error = 0;
+	io->refcount = 1;
 
 	memset(data, 0, sizeof(struct unix_private_data));
 	data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL;
@@ -130,6 +131,9 @@
 	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
 	data = (struct unix_private_data *) channel->private_data;
 	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+
+	if (--channel->refcount > 0)
+		return 0;
 	
 	if (close(data->dev) < 0)
 		retval = errno;
diff --git a/lib/ss/ChangeLog b/lib/ss/ChangeLog
index d5b9e25..32983b6 100644
--- a/lib/ss/ChangeLog
+++ b/lib/ss/ChangeLog
@@ -1,3 +1,11 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08
diff --git a/lib/ss/test_ss.c b/lib/ss/test_ss.c
index 98cb263..4b67357 100644
--- a/lib/ss/test_ss.c
+++ b/lib/ss/test_ss.c
@@ -9,8 +9,8 @@
  * $Locker$
  *
  * $Log$
- * Revision 1.12  1997/04/29 17:56:52  tytso
- * Checked in e2fsprogs 1.09
+ * Revision 1.13  1997/04/29 21:26:37  tytso
+ * Checkin of e2fsprogs 1.10
  *
  * Revision 1.1  1993/06/03  12:31:25  tytso
  * Initial revision
diff --git a/lib/uuid/ChangeLog b/lib/uuid/ChangeLog
index 9e97cf2..13bf858 100644
--- a/lib/uuid/ChangeLog
+++ b/lib/uuid/ChangeLog
@@ -1,3 +1,11 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08
diff --git a/misc/ChangeLog b/misc/ChangeLog
index 66ab5a4..7ad397a 100644
--- a/misc/ChangeLog
+++ b/misc/ChangeLog
@@ -1,3 +1,28 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 24 09:52:47 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* mke2fs.c: Added new option -R, which specifies RAID options.
+  		Currently the only supported RAID option is "stride" which
+ 		specifies the stripe width in RAID filesystem.  This is
+ 		used to aid in the placement of the inode and block
+ 		bitmaps.
+
+	* mke2fs.8.in, tune2fs.8.in: Added warnings that the sparse
+ 		superblock option isn't yet supported by most kernels.
+
+Wed Apr 23 22:42:51 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* mke2fs.c (PRS): Make the default filesystem revision be 0, not
+ 		1.  (Since some people are still worried about 1.2.13
+ 		compatibility).
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:57:24 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* chattr.1.in: Updated man page so that the 'A' attribute is
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 768ff56..b0d06a2 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -161,11 +161,11 @@
 # Makefile dependencies follow.  This must be the last section in
 # the Makefile.in file
 #
-tune2fs.o: $(srcdir)/tune2fs.c \
- $(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 $(top_srcdir)/lib/uuid/uuid.h \
- $(top_srcdir)/lib/e2p/e2p.h $(srcdir)/../version.h
+tune2fs.o: $(srcdir)/tune2fs.c $(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 \
+ $(top_srcdir)/lib/uuid/uuid.h $(top_srcdir)/lib/e2p/e2p.h \
+ $(srcdir)/../version.h
 mklost+found.o: $(srcdir)/mklost+found.c $(srcdir)/../version.h
 mke2fs.o: $(srcdir)/mke2fs.c $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/uuid/uuid.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
index ab139a4..de08f44 100644
--- a/misc/mke2fs.8.in
+++ b/misc/mke2fs.8.in
@@ -40,6 +40,12 @@
 .B \-q
 ]
 [
+.B \-r fs-revision-level
+]
+[
+.B -R raid_options
+]
+[
 .B -s sparse-super-flag
 ]
 [
@@ -120,7 +126,11 @@
 .I -s sparse-super-flag
 If sparse-super-flag is 1, then turn on the sparse superblock flag.  
 If 0, then turn off the sparse superblock flag.  (Currently, the sparse 
-superblock flag defaults to off.)
+superblock flag defaults to off.)  
+.B Warning:
+The Linux 2.0 kernel does not properly support this feature.  Neither do
+all Linux 2.1 kernels; please don't use this unless you know what you're
+doing!
 .TP
 .I -v
 Verbose execution.
@@ -137,6 +147,17 @@
 for the sake of utilities that key off of the last mounted directory to 
 determine where the filesytem should be mounted.
 .TP
+.I -r revision
+Set the filesystem revision for the new filesystem.  Note that 1.2
+kernels only support revision 0 filesystems.
+.TP
+.I -R raid_options
+Set raid-related options for the filesystem.  Raid options are common
+separated, and may take an argument using the equals ('=')  sign.
+Currently the only supported argument is 
+.I stride
+which takes as its argument the number of blocks in a RAID stripe.
+.TP
 .I -S
 Write superblock and group descriptors only.  This is useful if all of
 the superblock and backup superblocks are corrupted, and a last-ditch
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 475397d..5541246 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -74,6 +74,7 @@
 int	super_only = 0;
 int	force = 0;
 char	*bad_blocks_filename = 0;
+__u32	fs_stride = 0;
 
 struct ext2_super_block param;
 char *creator_os = NULL;
@@ -86,7 +87,8 @@
 	"[-f fragment-size]\n\t[-i bytes-per-inode] "
 	"[-m reserved-blocks-percentage] [-qvS]\n\t"
 	"[-o creator-os] [-g blocks-per-group] [-L volume-label]\n\t"
-	"[-M last-mounted-directory] device [blocks-count]\n",
+	"[-M last-mounted-directory] [-r fs-revision] [-R raid_opts]\n\t"
+	"device [blocks-count]\n",
 		program_name);
 	exit(1);
 }
@@ -536,6 +538,59 @@
 
 #define PATH_SET "PATH=/sbin"
 
+static parse_raid_opts(const char *opts)
+{
+	char	*buf, *token, *next, *p, *arg;
+	int	len;
+	int	raid_usage = 0;
+
+	len = strlen(opts);
+	buf = malloc(len+1);
+	if (!buf) {
+		fprintf(stderr, "Couldn't allocate memory to parse "
+			"raid options!\n");
+		exit(1);
+	}
+	strcpy(buf, opts);
+	for (token = buf; token && *token; token = next) {
+		p = strchr(token, ',');
+		next = 0;
+		if (p) {
+			*p = 0;
+			next = p+1;
+		} 
+		arg = strchr(token, '=');
+		if (arg) {
+			*arg = 0;
+			arg++;
+		}
+		if (strcmp(token, "stride") == 0) {
+			if (!arg) {
+				raid_usage++;
+				continue;
+			}
+			fs_stride = strtoul(arg, &p, 0);
+			if (*p || (fs_stride == 0)) {
+				fprintf(stderr, "Invalid stride parameter.\n");
+				raid_usage++;
+				continue;
+			}
+		} else
+			raid_usage++;
+	}
+	if (raid_usage) {
+		fprintf(stderr, "\nBad raid options specified.\n\n"
+			"Raid options are separated by commas, "
+			"and may take an argument which\n"
+			"\tis set off by an equals ('=') sign.\n\n"
+			"Valid raid options are:\n"
+			"\tstride=<stride length in blocks>\n\n");
+		exit(1);
+	}
+}	
+
+
+
 static void PRS(int argc, char *argv[])
 {
 	char	c;
@@ -548,6 +603,7 @@
 	int	sparse_option = -1;
 	char	*oldpath = getenv("PATH");
 	struct ext2fs_sb *param_ext2 = (struct ext2fs_sb *) &param;
+	char	*raid_opts = 0;
 	
 	/* Update our PATH to include /sbin  */
 	if (oldpath) {
@@ -565,9 +621,6 @@
 	setbuf(stderr, NULL);
 	initialize_ext2_error_table();
 	memset(&param, 0, sizeof(struct ext2_super_block));
-#ifdef EXT2_DYNAMIC_REV
-	param.s_rev_level = EXT2_DYNAMIC_REV;
-#endif
 	
 	fprintf (stderr, "mke2fs %s, %s for EXT2 FS %s, %s\n",
 		 E2FSPROGS_VERSION, E2FSPROGS_DATE,
@@ -575,7 +628,7 @@
 	if (argc && *argv)
 		program_name = *argv;
 	while ((c = getopt (argc, argv,
-			    "b:cf:g:i:l:m:o:qr:s:tvI:SFL:M:")) != EOF)
+			    "b:cf:g:i:l:m:o:qr:R:s:tvI:SFL:M:")) != EOF)
 		switch (c) {
 		case 'b':
 			size = strtoul(optarg, &tmp, 0);
@@ -673,6 +726,9 @@
 		case 'M':
 			mount_dir = optarg;
 			break;
+		case 'R':
+			raid_opts = optarg;
+			break;
 		case 'S':
 			super_only = 1;
 			break;
@@ -694,6 +750,9 @@
 	if (optind < argc)
 		usage();
 
+	if (raid_opts)
+		parse_raid_opts(raid_opts);
+
 	if (!force)
 		check_plausibility();
 	check_mount();
@@ -807,6 +866,7 @@
 		test_disk(fs, &bb_list);
 
 	handle_bad_blocks(fs, bb_list);
+	fs->stride = fs_stride;
 	retval = ext2fs_allocate_tables(fs);
 	if (retval) {
 		com_err(program_name, retval,
diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in
index 0e34085..e65f3b5 100644
--- a/misc/tune2fs.8.in
+++ b/misc/tune2fs.8.in
@@ -103,6 +103,10 @@
 .I -s sparse_super_flag
 sets and resets the sparse_superblock flag.  The sparse_superblock feature
 saves space on really big filesystems.
+.B Warning:
+The Linux 2.0 kernel does not properly support this feature.  Neither do
+all Linux 2.1 kernels; please don't use this unless you know what you're
+doing!
 .TP
 .I -u user
 set the user who can benefit from the reserved blocks.
diff --git a/tests/ChangeLog b/tests/ChangeLog
index fd27671..d668efd 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,11 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08
diff --git a/tests/progs/ChangeLog b/tests/progs/ChangeLog
index 2ddbf50..31e34c1 100644
--- a/tests/progs/ChangeLog
+++ b/tests/progs/ChangeLog
@@ -1,3 +1,11 @@
+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
+
+	* Release of E2fsprogs version 1.10
+
+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Release of E2fsprogs version 1.09
+
 Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.08