Many files:
  Checked in e2fsprogs 1.05

diff --git a/lib/ChangeLog b/lib/ChangeLog
index 682e10c..fe60daf 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,16 @@
+Wed Aug 28 15:20:26 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* Makefile.elf-lib (installdirs-elf-lib): Renamed from installdirs
+	to avoid making random directories only neeeded when installing
+	normal libraries.
+	(install-shlibs): Use installdirs-elf-lib instead of installdirs.
+
+Thu May 23 12:40:12 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* Makefile.elf-lib: Install the .so files in /usr/lib, since the
+		.a files are stored there.  (We were installing the .so
+		files in the wrong place before.)
+
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.04
diff --git a/lib/Makefile.elf-lib b/lib/Makefile.elf-lib
index 83b59fc..ff19bc9 100644
--- a/lib/Makefile.elf-lib
+++ b/lib/Makefile.elf-lib
@@ -31,15 +31,19 @@
 	$(LN) ../$(ELF_LIB) ../$(ELF_IMAGE).so
 	$(LN) ../$(ELF_LIB) ../$(ELF_SONAME)
 
-installdirs::
-	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(ELF_INSTALL_DIR)
+installdirs-elf-lib::
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(ELF_INSTALL_DIR) \
+		$(DESTDIR)$(ulibdir)
 
-install-shlibs install:: $(ELF_LIB) installdirs
+installdirs:: installdirs-elf-lib
+
+install-shlibs install:: $(ELF_LIB) installdirs-elf-lib
 	$(INSTALL_PROGRAM) $(ELF_LIB) $(DESTDIR)$(ELF_INSTALL_DIR)/$(ELF_LIB)
 	$(STRIP) --strip-debug \
 		$(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_LIB)
-	$(LN) -sf $(ELF_LIB) $(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_SONAME)
-	$(LN) -sf $(ELF_SONAME) $(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_IMAGE).so
+	$(LN_S) -f $(ELF_LIB) $(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_SONAME)
+	$(LN_S) -f $(DLL_INSTALL_DIR)/$(ELF_SONAME) \
+		$(DESTDIR)$(ulibdir)/$(ELF_IMAGE).so
 	-ldconfig
 
 clean::
diff --git a/lib/do_substitute b/lib/do_substitute
index 262609d..e18c3f4 100644
--- a/lib/do_substitute
+++ b/lib/do_substitute
@@ -10,6 +10,7 @@
 	-e "s%@E2FSPROGS_MONTH@%$E2FSPROGS_MONTH%g" \
 	-e "s%@E2FSPROGS_YEAR@%$E2FSPROGS_YEAR%g" \
 	-e "s%@E2FSPROGS_VERSION@%$E2FSPROGS_VERSION%g" \
+	-e "s%@SIZEOF_LONG_LONG@%$SIZEOF_LONG_LONG%g" \
 	-e "s%@SIZEOF_LONG@%$SIZEOF_LONG%g" \
 	-e "s%@SIZEOF_INT@%$SIZEOF_INT%g" \
 	-e "s%@SIZEOF_SHORT@%$SIZEOF_SHORT%g" \
diff --git a/lib/e2p/ChangeLog b/lib/e2p/ChangeLog
index 2422e73..fe4fa5e 100644
--- a/lib/e2p/ChangeLog
+++ b/lib/e2p/ChangeLog
@@ -1,3 +1,20 @@
+Sat Sep  7 14:48:35 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* ls.c (interval_string): Pretty print the check interval.
+
+Tue Aug  6 14:12:36 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* ls.c (list_super): Display the OS, volume label, last mounted,
+ 		and UUID field if present.
+
+Mon Jun 24 09:55:58 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* ps.c, pf.c, pe.c, ls.c, setversion.c, setflags.c, getversion.c, 
+		fsetversion.c, fsetflags.c, fgetversion.c, fgetflags.c,
+		getflags.c: Remove include of ext2_fs.h, since it's
+		included by e2p.h; this also solves a sys/types.h vs
+		linux/types.h inclusion ordering problem with the GNU libc.
+
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.04
diff --git a/lib/e2p/MAKELOG b/lib/e2p/MAKELOG
deleted file mode 100644
index 27e4420..0000000
--- a/lib/e2p/MAKELOG
+++ /dev/null
@@ -1,181 +0,0 @@
-gcc -O2 -fomit-frame-pointer  -I.. -c pe.c
-In file included from pe.c:19:
-/usr/include/linux/ext2_fs.h:127: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:127: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:128: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:129: parse error before `aclh_acle_count'
-/usr/include/linux/ext2_fs.h:129: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:130: parse error before `aclh_first_acle'
-/usr/include/linux/ext2_fs.h:130: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:135: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:135: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:136: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:137: parse error before `acle_type'
-/usr/include/linux/ext2_fs.h:137: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:138: parse error before `acle_tag'
-/usr/include/linux/ext2_fs.h:138: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:139: parse error before `acle_pad1'
-/usr/include/linux/ext2_fs.h:139: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:140: parse error before `acle_next'
-/usr/include/linux/ext2_fs.h:140: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:149: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:149: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:150: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:151: parse error before `bg_inode_table'
-/usr/include/linux/ext2_fs.h:151: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:152: parse error before `bg_free_blocks_count'
-/usr/include/linux/ext2_fs.h:152: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:153: parse error before `bg_free_inodes_count'
-/usr/include/linux/ext2_fs.h:153: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:158: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:158: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:159: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:160: parse error before `bg_inode_table'
-/usr/include/linux/ext2_fs.h:160: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:161: parse error before `bg_free_blocks_count'
-/usr/include/linux/ext2_fs.h:161: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:162: parse error before `bg_free_inodes_count'
-/usr/include/linux/ext2_fs.h:162: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:163: parse error before `bg_used_dirs_count'
-/usr/include/linux/ext2_fs.h:163: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:164: parse error before `bg_pad'
-/usr/include/linux/ext2_fs.h:164: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:165: parse error before `bg_reserved'
-/usr/include/linux/ext2_fs.h:165: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:166: parse error before `}'
-/usr/include/linux/ext2_fs.h:213: parse error before `__u16'
-/usr/include/linux/ext2_fs.h:213: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:214: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:215: parse error before `i_size'
-/usr/include/linux/ext2_fs.h:215: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:216: parse error before `i_atime'
-/usr/include/linux/ext2_fs.h:216: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:217: parse error before `i_ctime'
-/usr/include/linux/ext2_fs.h:217: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:218: parse error before `i_mtime'
-/usr/include/linux/ext2_fs.h:218: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:219: parse error before `i_dtime'
-/usr/include/linux/ext2_fs.h:219: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:220: parse error before `i_gid'
-/usr/include/linux/ext2_fs.h:220: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:221: parse error before `i_links_count'
-/usr/include/linux/ext2_fs.h:221: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:222: parse error before `i_blocks'
-/usr/include/linux/ext2_fs.h:222: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:223: parse error before `i_flags'
-/usr/include/linux/ext2_fs.h:223: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:226: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:226: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:226: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:227: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:229: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:229: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:230: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:232: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:232: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:233: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:234: parse error before `}'
-/usr/include/linux/ext2_fs.h:234: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:235: parse error before `i_block'
-/usr/include/linux/ext2_fs.h:235: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:236: parse error before `i_version'
-/usr/include/linux/ext2_fs.h:236: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:237: parse error before `i_file_acl'
-/usr/include/linux/ext2_fs.h:237: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:238: parse error before `i_dir_acl'
-/usr/include/linux/ext2_fs.h:238: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:239: parse error before `i_faddr'
-/usr/include/linux/ext2_fs.h:239: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:242: parse error before `__u8'
-/usr/include/linux/ext2_fs.h:242: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:242: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:243: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:244: parse error before `i_pad1'
-/usr/include/linux/ext2_fs.h:244: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:245: parse error before `l_i_reserved2'
-/usr/include/linux/ext2_fs.h:245: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:246: parse error before `}'
-/usr/include/linux/ext2_fs.h:246: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:248: parse error before `__u8'
-/usr/include/linux/ext2_fs.h:248: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:249: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:250: parse error before `h_i_mode_high'
-/usr/include/linux/ext2_fs.h:250: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:251: parse error before `h_i_uid_high'
-/usr/include/linux/ext2_fs.h:251: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:252: parse error before `h_i_gid_high'
-/usr/include/linux/ext2_fs.h:252: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:253: parse error before `h_i_author'
-/usr/include/linux/ext2_fs.h:253: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:254: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:256: parse error before `__u8'
-/usr/include/linux/ext2_fs.h:256: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:257: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:258: parse error before `m_pad1'
-/usr/include/linux/ext2_fs.h:258: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:259: parse error before `m_i_reserved2'
-/usr/include/linux/ext2_fs.h:259: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:260: parse error before `}'
-/usr/include/linux/ext2_fs.h:260: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:261: parse error before `}'
-/usr/include/linux/ext2_fs.h:261: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:262: parse error before `}'
-/usr/include/linux/ext2_fs.h:329: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:329: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:330: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:331: parse error before `s_r_blocks_count'
-/usr/include/linux/ext2_fs.h:331: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:332: parse error before `s_free_blocks_count'
-/usr/include/linux/ext2_fs.h:332: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:333: parse error before `s_free_inodes_count'
-/usr/include/linux/ext2_fs.h:333: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:334: parse error before `s_first_data_block'
-/usr/include/linux/ext2_fs.h:334: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:335: parse error before `s_log_block_size'
-/usr/include/linux/ext2_fs.h:335: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:336: parse error before `s_log_frag_size'
-/usr/include/linux/ext2_fs.h:336: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:337: parse error before `s_blocks_per_group'
-/usr/include/linux/ext2_fs.h:337: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:338: parse error before `s_frags_per_group'
-/usr/include/linux/ext2_fs.h:338: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:339: parse error before `s_inodes_per_group'
-/usr/include/linux/ext2_fs.h:339: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:340: parse error before `s_mtime'
-/usr/include/linux/ext2_fs.h:340: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:341: parse error before `s_wtime'
-/usr/include/linux/ext2_fs.h:341: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:342: parse error before `s_mnt_count'
-/usr/include/linux/ext2_fs.h:342: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:343: parse error before `s_max_mnt_count'
-/usr/include/linux/ext2_fs.h:343: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:344: parse error before `s_magic'
-/usr/include/linux/ext2_fs.h:344: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:345: parse error before `s_state'
-/usr/include/linux/ext2_fs.h:345: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:346: parse error before `s_errors'
-/usr/include/linux/ext2_fs.h:346: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:347: parse error before `s_pad'
-/usr/include/linux/ext2_fs.h:347: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:348: parse error before `s_lastcheck'
-/usr/include/linux/ext2_fs.h:348: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:349: parse error before `s_checkinterval'
-/usr/include/linux/ext2_fs.h:349: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:350: parse error before `s_creator_os'
-/usr/include/linux/ext2_fs.h:350: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:351: parse error before `s_rev_level'
-/usr/include/linux/ext2_fs.h:351: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:352: parse error before `s_def_resuid'
-/usr/include/linux/ext2_fs.h:352: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:353: parse error before `s_def_resgid'
-/usr/include/linux/ext2_fs.h:353: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:354: parse error before `s_reserved'
-/usr/include/linux/ext2_fs.h:354: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:355: parse error before `}'
-/usr/include/linux/ext2_fs.h:372: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:372: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:373: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:374: parse error before `name_len'
-/usr/include/linux/ext2_fs.h:374: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:376: parse error before `}'
-make: *** [pe.o] Error 1
diff --git a/lib/e2p/Makefile.in b/lib/e2p/Makefile.in
index 97f3fbc..4c433dc 100644
--- a/lib/e2p/Makefile.in
+++ b/lib/e2p/Makefile.in
@@ -9,6 +9,7 @@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ../..
+my_dir = lib/e2p
 INSTALL = @INSTALL@
 
 @MCONFIG@
@@ -17,14 +18,15 @@
 
 OBJS=		fgetflags.o fsetflags.o fgetversion.o fsetversion.o \
 		getflags.o getversion.o iod.o ls.o pe.o pf.o ps.o \
-		setflags.o setversion.o
+		setflags.o setversion.o uuid.o
 
 SRCS=		$(srcdir)/fgetflags.c $(srcdir)/fsetflags.c \
 		$(srcdir)/fgetversion.c $(srcdir)/fsetversion.c \
 		$(srcdir)/getflags.c $(srcdir)/getversion.c \
 		$(srcdir)/iod.c $(srcdir)/ls.c $(srcdir)/pe.c \
 		$(srcdir)/pf.c $(srcdir)/ps.c \
-		$(srcdir)/setflags.c $(srcdir)/setversion.c
+		$(srcdir)/setflags.c $(srcdir)/setversion.c \
+		$(srcdir)/uuid.c
 
 LIBRARY= libe2p
 LIBDIR= e2p
@@ -38,7 +40,7 @@
 DLL_MYDIR = e2p
 DLL_INSTALL_DIR = $(libdir)
 
-ELF_VERSION = 2.1
+ELF_VERSION = 2.2
 ELF_SO_VERSION = 2
 ELF_IMAGE = libe2p
 ELF_MYDIR = e2p
@@ -90,15 +92,16 @@
 # the Makefile.in file
 #
 fgetflags.o: $(srcdir)/fgetflags.c $(srcdir)/e2p.h
-fsetflags.o: $(srcdir)/fsetflags.c $(srcdir)/e2p.h
+fsetflags.o: $(srcdir)/fsetflags.c $(srcdir)/e2p.h 
 fgetversion.o: $(srcdir)/fgetversion.c $(srcdir)/e2p.h
 fsetversion.o: $(srcdir)/fsetversion.c $(srcdir)/e2p.h
 getflags.o: $(srcdir)/getflags.c $(srcdir)/e2p.h
 getversion.o: $(srcdir)/getversion.c $(srcdir)/e2p.h
 iod.o: $(srcdir)/iod.c $(srcdir)/e2p.h
-ls.o: $(srcdir)/ls.c  $(srcdir)/e2p.h
+ls.o: $(srcdir)/ls.c $(srcdir)/e2p.h
 pe.o: $(srcdir)/pe.c $(srcdir)/e2p.h
 pf.o: $(srcdir)/pf.c $(srcdir)/e2p.h
 ps.o: $(srcdir)/ps.c $(srcdir)/e2p.h
 setflags.o: $(srcdir)/setflags.c $(srcdir)/e2p.h
 setversion.o: $(srcdir)/setversion.c $(srcdir)/e2p.h
+uuid.o: $(srcdir)/uuid.c
diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h
index dc2dbe5..fa4a03b 100644
--- a/lib/e2p/e2p.h
+++ b/lib/e2p/e2p.h
@@ -19,3 +19,6 @@
 void print_fs_state (FILE * f, unsigned short state);
 int setflags (int fd, unsigned long flags);
 int setversion (int fd, unsigned long version);
+
+int e2p_is_null_uuid(void *uu);
+void e2p_uuid_to_str(void *uu, char *out);
diff --git a/lib/e2p/fgetflags.c b/lib/e2p/fgetflags.c
index 099446d..f01de26 100644
--- a/lib/e2p/fgetflags.c
+++ b/lib/e2p/fgetflags.c
@@ -27,8 +27,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int fgetflags (const char * name, unsigned long * flags)
diff --git a/lib/e2p/fgetversion.c b/lib/e2p/fgetversion.c
index ba4eec4..fea376b 100644
--- a/lib/e2p/fgetversion.c
+++ b/lib/e2p/fgetversion.c
@@ -23,8 +23,6 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int fgetversion (const char * name, unsigned long * version)
diff --git a/lib/e2p/fsetflags.c b/lib/e2p/fsetflags.c
index 06aabba..92e558b 100644
--- a/lib/e2p/fsetflags.c
+++ b/lib/e2p/fsetflags.c
@@ -27,8 +27,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int fsetflags (const char * name, unsigned long flags)
diff --git a/lib/e2p/fsetversion.c b/lib/e2p/fsetversion.c
index 1443fb5..49c7c36 100644
--- a/lib/e2p/fsetversion.c
+++ b/lib/e2p/fsetversion.c
@@ -23,8 +23,6 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int fsetversion (const char * name, unsigned long version)
diff --git a/lib/e2p/getflags.c b/lib/e2p/getflags.c
index ac014a7..8c476a3 100644
--- a/lib/e2p/getflags.c
+++ b/lib/e2p/getflags.c
@@ -23,8 +23,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int getflags (int fd, unsigned long * flags)
diff --git a/lib/e2p/getversion.c b/lib/e2p/getversion.c
index 309dfb6..be76b60 100644
--- a/lib/e2p/getversion.c
+++ b/lib/e2p/getversion.c
@@ -19,8 +19,6 @@
 #endif
 #include <sys/ioctl.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int getversion (int fd, unsigned long * version)
diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
index 0bd217b..55e0bbe 100644
--- a/lib/e2p/ls.c
+++ b/lib/e2p/ls.c
@@ -9,16 +9,71 @@
  * Public License
  */
 
+#include <stdio.h>
 #include <sys/types.h>
+#include <string.h>
 #include <grp.h>
 #include <pwd.h>
-#include <stdio.h>
 #include <time.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
+/*
+ * The ext2fs library private definition of the ext2 superblock, so we
+ * don't have to depend on the kernel's definition of the superblock,
+ * which might not have the latest features.
+ */
+struct ext2fs_sb {
+	__u32	s_inodes_count;		/* Inodes count */
+	__u32	s_blocks_count;		/* Blocks count */
+	__u32	s_r_blocks_count;	/* Reserved blocks count */
+	__u32	s_free_blocks_count;	/* Free blocks count */
+	__u32	s_free_inodes_count;	/* Free inodes count */
+	__u32	s_first_data_block;	/* First Data Block */
+	__u32	s_log_block_size;	/* Block size */
+	__s32	s_log_frag_size;	/* Fragment size */
+	__u32	s_blocks_per_group;	/* # Blocks per group */
+	__u32	s_frags_per_group;	/* # Fragments per group */
+	__u32	s_inodes_per_group;	/* # Inodes per group */
+	__u32	s_mtime;		/* Mount time */
+	__u32	s_wtime;		/* Write time */
+	__u16	s_mnt_count;		/* Mount count */
+	__s16	s_max_mnt_count;	/* Maximal mount count */
+	__u16	s_magic;		/* Magic signature */
+	__u16	s_state;		/* File system state */
+	__u16	s_errors;		/* Behaviour when detecting errors */
+	__u16	s_minor_rev_level; 	/* minor revision level */
+	__u32	s_lastcheck;		/* time of last check */
+	__u32	s_checkinterval;	/* max. time between checks */
+	__u32	s_creator_os;		/* OS */
+	__u32	s_rev_level;		/* Revision level */
+	__u16	s_def_resuid;		/* Default uid for reserved blocks */
+	__u16	s_def_resgid;		/* Default gid for reserved blocks */
+	/*
+	 * These fields are for EXT2_DYNAMIC_REV superblocks only.
+	 *
+	 * Note: the difference between the compatible feature set and
+	 * the incompatible feature set is that if there is a bit set
+	 * in the incompatible feature set that the kernel doesn't
+	 * know about, it should refuse to mount the filesystem.
+	 * 
+	 * e2fsck's requirements are more strict; if it doesn't know
+	 * about a feature in either the compatible or incompatible
+	 * feature set, it must abort and not try to meddle with
+	 * things it doesn't understand...
+	 */
+	__u32	s_first_ino; 		/* First non-reserved inode */
+	__u16   s_inode_size; 		/* size of inode structure */
+	__u16	s_block_group_nr; 	/* block group # of this superblock */
+	__u32	s_feature_compat; 	/* compatible feature set */
+	__u32	s_feature_incompat; 	/* incompatible feature set */
+	__u32	s_feature_ro_compat; 	/* readonly-compatible feature set */
+	__u8	s_uuid[16];		/* 128-bit uuid for volume */
+	char	s_volume_name[16]; 	/* volume name */
+	char	s_last_mounted[64]; 	/* directory where last mounted */
+	__u32	s_reserved[206];	/* Padding to the end of the block */
+};
+
 static void print_user (unsigned short uid)
 {
 	struct passwd *pw;
@@ -43,6 +98,51 @@
 		printf ("(group %s)\n", gr->gr_name);
 }
 
+#define MONTH_INT (86400 * 30)
+#define WEEK_INT (86400 * 7)
+#define DAY_INT	(86400)
+#define HOUR_INT (60 * 60)
+#define MINUTE_INT (60)
+
+static char *interval_string(unsigned int secs)
+{
+	static char buf[256], tmp[80];
+	int		hr, min, num;
+
+	buf[0] = 0;
+
+	if (secs >= MONTH_INT) {
+		num = secs / MONTH_INT;
+		secs -= num*MONTH_INT;
+		sprintf(buf, "%d month%s", num, (num>1) ? "s" : "");
+	}
+	if (secs >= WEEK_INT) {
+		num = secs / WEEK_INT;
+		secs -= num*WEEK_INT;
+		sprintf(tmp, "%s%d week%s", buf[0] ? ", " : "",
+			num, (num>1) ? "s" : "");
+		strcat(buf, tmp);
+	}
+	if (secs >= DAY_INT) {
+		num = secs / DAY_INT;
+		secs -= num*DAY_INT;
+		sprintf(tmp, "%s%d day%s", buf[0] ? ", " : "",
+			num, (num>1) ? "s" : "");
+		strcat(buf, tmp);
+	}
+	if (secs > 0) {
+		hr = secs / HOUR_INT;
+		secs -= hr*HOUR_INT;
+		min = secs / MINUTE_INT;
+		secs -= min*MINUTE_INT;
+		sprintf(tmp, "%s%d:%02d:%02d", buf[0] ? ", " : "",
+			hr, min, secs);
+		strcat(buf, tmp);
+	}
+	return buf;
+}
+
+
 #ifndef EXT2_INODE_SIZE
 #define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
 #endif
@@ -50,20 +150,43 @@
 void list_super (struct ext2_super_block * s)
 {
 	int inode_blocks_per_group;
+	struct ext2fs_sb *sb = (struct ext2fs_sb *) s;
+	char buf[80];
+	const char *os;
 
 	inode_blocks_per_group = (((s->s_inodes_per_group *
 				    EXT2_INODE_SIZE(s)) +
 				   EXT2_BLOCK_SIZE(s) - 1) /
 				  EXT2_BLOCK_SIZE(s));
-	
 	printf ("Filesystem magic number:  0x%04X\n", s->s_magic);
 	printf ("Filesystem revision #:    %d\n", s->s_rev_level);
+	if (sb->s_volume_name[0]) {
+		memset(buf, 0, sizeof(buf));
+		strncpy(buf, sb->s_volume_name, sizeof(sb->s_volume_name));
+		printf("Filesystem volume name:   %s\n", buf);
+	}
+	if (sb->s_last_mounted[0]) {
+		memset(buf, 0, sizeof(buf));
+		strncpy(buf, sb->s_last_mounted, sizeof(sb->s_last_mounted));
+		printf("Last mounted on:          %s\n", buf);
+	}
+	if (!e2p_is_null_uuid(sb->s_uuid)) {
+		e2p_uuid_to_str(sb->s_uuid, buf);
+		printf("Filesystem UUID:          %s\n", buf);
+	}
 	printf ("Filesystem state:        ");
 	print_fs_state (stdout, s->s_state);
 	printf ("\n");
 	printf ("Errors behavior:          ");
 	print_fs_errors (stdout, s->s_errors);
 	printf ("\n");
+	switch (s->s_creator_os) {
+	    case EXT2_OS_LINUX: os = "Linux"; break;
+	    case EXT2_OS_HURD:  os = "GNU"; break;
+	    case EXT2_OS_MASIX: os = "Masix"; break;
+	    default:		os = "unknown"; break;
+	}
+	printf ("Filesystem OS type:       %s\n", os);
 	printf ("Inode count:              %u\n", s->s_inodes_count);
 	printf ("Block count:              %u\n", s->s_blocks_count);
 	printf ("Reserved block count:     %u\n", s->s_r_blocks_count);
@@ -81,7 +204,8 @@
 	printf ("Mount count:              %u\n", s->s_mnt_count);
 	printf ("Maximum mount count:      %d\n", s->s_max_mnt_count);
 	printf ("Last checked:             %s", ctime ((time_t *) &s->s_lastcheck));
-	printf ("Check interval:           %u\n", s->s_checkinterval);
+	printf ("Check interval:           %u (%s)\n", s->s_checkinterval,
+		interval_string(s->s_checkinterval));
 	if (s->s_checkinterval)
 	{
 		time_t next;
@@ -102,3 +226,7 @@
 	}
 #endif
 }
+
+
+
+
diff --git a/lib/e2p/pe.c b/lib/e2p/pe.c
index efc74b3..4cce691 100644
--- a/lib/e2p/pe.c
+++ b/lib/e2p/pe.c
@@ -16,8 +16,6 @@
 
 #include <stdio.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 void print_fs_errors (FILE * f, unsigned short errors)
diff --git a/lib/e2p/pf.c b/lib/e2p/pf.c
index e4f072f..ec18dcb 100644
--- a/lib/e2p/pf.c
+++ b/lib/e2p/pf.c
@@ -15,7 +15,6 @@
  */
 
 #include <stdio.h>
-#include <linux/ext2_fs.h>
 
 #include "e2p.h"
 
diff --git a/lib/e2p/ps.c b/lib/e2p/ps.c
index 441d6dc..bec8b41 100644
--- a/lib/e2p/ps.c
+++ b/lib/e2p/ps.c
@@ -16,8 +16,6 @@
 
 #include <stdio.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 void print_fs_state (FILE * f, unsigned short state)
diff --git a/lib/e2p/setflags.c b/lib/e2p/setflags.c
index 06f127f..654ec9d 100644
--- a/lib/e2p/setflags.c
+++ b/lib/e2p/setflags.c
@@ -24,8 +24,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int setflags (int fd, unsigned long flags)
diff --git a/lib/e2p/setversion.c b/lib/e2p/setversion.c
index f2c48cd..3210f51 100644
--- a/lib/e2p/setversion.c
+++ b/lib/e2p/setversion.c
@@ -19,8 +19,6 @@
 #endif
 #include <sys/ioctl.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int setversion (int fd, unsigned long version)
diff --git a/lib/e2p/uuid.c b/lib/e2p/uuid.c
new file mode 100644
index 0000000..82462e8
--- /dev/null
+++ b/lib/e2p/uuid.c
@@ -0,0 +1,65 @@
+/*
+ * uuid.c -- utility routines for manipulating UUID's.
+ */
+
+#include <stdio.h>
+#include <linux/types.h>
+
+struct uuid {
+	__u32	time_low;
+	__u16	time_mid;
+	__u16	time_hi_and_version;
+	__u16	clock_seq;
+	__u8	node[6];
+};
+
+/* Returns 1 if the uuid is the NULL uuid */
+int e2p_is_null_uuid(void *uu)
+{
+	__u8 	*cp;
+	int	i;
+
+	for (i=0, cp = uu; i < 16; i++)
+		if (*cp)
+			return 0;
+	return 1;
+}
+
+static void e2p_unpack_uuid(void *in, struct uuid *uu)
+{
+	__u8	*ptr = in;
+	__u32	tmp;
+
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->time_low = tmp;
+
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->time_mid = tmp;
+	
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->time_hi_and_version = tmp;
+
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->clock_seq = tmp;
+
+	memcpy(uu->node, ptr, 6);
+}
+
+void e2p_uuid_to_str(void *uu, char *out)
+{
+	struct uuid uuid;
+
+	e2p_unpack_uuid(uu, &uuid);
+	sprintf(out,
+		"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
+		uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
+		uuid.node[0], uuid.node[1], uuid.node[2],
+		uuid.node[3], uuid.node[4], uuid.node[5]);
+}
diff --git a/lib/et/Makefile.in b/lib/et/Makefile.in
index 49c4fca..627ef4d 100644
--- a/lib/et/Makefile.in
+++ b/lib/et/Makefile.in
@@ -6,6 +6,7 @@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ../..
+my_dir = lib/ss
 INSTALL = @INSTALL@
 
 @MCONFIG@
diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog
index 90de2b5..41c9c54 100644
--- a/lib/ext2fs/ChangeLog
+++ b/lib/ext2fs/ChangeLog
@@ -1,3 +1,87 @@
+Sat Sep  7 07:36:03 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* initialize.c: Override the kernel's idea of default
+		checkinterval from 0 (never) to 180 days.
+
+Wed Aug 28 03:20:03 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* namei.c (ext2fs_namei_follow): New function which follows
+		symbolic link (if any) at the target.
+
+Tue Aug 27 01:48:43 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* inode.c (ext2fs_read_inode, ext2fs_write_inode): Add support
+		for shortcut function fs->read_inode() and fs->write_inode().
+		Added inode_cache to reduce CPU time spent in doing
+		byte swapping.
+
+	* swapfs.c (ext2fs_swap_super): Swap the new fields in a V2
+	 	superblock.
+
+	* namei.c (ext2fs_follow_link): New function.
+		(ext2fs_namei): Extended to have support for chasing
+ 		symbolic links.  ext2fs_namei() still returns an inode
+ 		which is a symbolic link.  Symbolic links are only chased
+ 		while resolving the containing directory.  To chase
+ 		symbolic links of the final result, use
+ 		ext2fs_follow_link().
+
+Mon Aug 26 23:46:07 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* ext2_err.et.in: Added new error code EXT2_ET_SYMLINK_LOOP.
+
+	* bitops.h (ext2fs_set_bit, ext2fs_celar_bit): Use asm inlines
+		provided by Pete A. Zaitcev (zaitcev@lab.sun.mcst.ru).
+
+Thu Aug 22 00:40:18 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* initialize.c (ext2fs_initialize): On systems where the byte
+		order is not i386 compatible, set the swap_byte flag.
+
+	* inode.c (inocpy_with_swap): Check to see if inode contains a
+		fast symlink before swapping the inode block fields.  This
+		required adding a new argument to inocpy_with_swap to
+		determine whether the mode field is in host order or not.
+
+Wed Aug 21 00:45:42 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* bitops.h (ext2fs_set_bit, ext2fs_clear_bit, ext2fs_test_bit): On
+		the sparc, if EXT2_STD_BITOPS set, use the standard
+		i386-compatible bitmask operations, instead on the
+		non-standard native bitmask operators.
+
+Fri Aug  9 11:11:35 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* block.c (ext2fs_block_iterate): Cause block iterator to return
+		the HURD translator block (along with everything else).
+		If the flag BLOCK_FLAG_DATA_ONLY is passed to the block
+		iterator, then don't return any meta data blocks
+		(including the HURD translator).
+
+Wed Jul 17 17:13:34 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* gen_uuid.c: New file, which generates DCE-compatible UUIDs.
+
+	* uuid.c: New file, containing UUID utility functions.
+
+Tue Jul 16 10:19:16 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* ext2fs.h: Add a definition of the "real" ext2 superblock.
+
+Fri May 24 14:54:55 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* ext2fs.h: Fix erroneous ino_t type used in block_bitmap type.
+
+Sun May 19 15:39:03 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* openfs.c (ext2fs_open): If the blocksize in the superblock is
+		zero, return the error EXT2_ET_CORRUPT_SUPERBLOCK, since
+		that's a basic value that must be correct for the rest of
+		the library to work.
+
+	* ext2_err.et.in (EXT2_ET_CORRUPT_SUPERBLOCK): Added new error
+	 	code.
+
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.04
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 2666977..5319ce5 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -2,6 +2,7 @@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ../..
+my_dir = lib/ext2fs
 INSTALL = @INSTALL@
 
 @MCONFIG@
@@ -29,6 +30,7 @@
 	llseek.o \
 	mkdir.o \
 	namei.o \
+	native.o \
 	newdir.o \
 	openfs.o \
 	read_bb.o \
@@ -60,6 +62,7 @@
 	$(srcdir)/llseek.c \
 	$(srcdir)/mkdir.c \
 	$(srcdir)/namei.c \
+	$(srcdir)/native.c \
 	$(srcdir)/newdir.c \
 	$(srcdir)/openfs.c \
 	$(srcdir)/read_bb.c \
@@ -83,7 +86,7 @@
 DLL_MYDIR = ext2fs
 DLL_INSTALL_DIR = $(libdir)
 
-ELF_VERSION = 2.0
+ELF_VERSION = 2.1
 ELF_SO_VERSION = 2
 ELF_IMAGE = libext2fs
 ELF_MYDIR = ext2fs
@@ -154,88 +157,90 @@
 # 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.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
 badblocks.o: $(srcdir)/badblocks.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
 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
+ $(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)/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
 bitops.o: $(srcdir)/bitops.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
 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
+ $(top_srcdir)/lib/et/com_err.h  $(srcdir)/bitops.h \
+ $(srcdir)/io.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
+ $(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)/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
 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
+ $(top_srcdir)/lib/et/com_err.h  $(srcdir)/bitops.h \
+ $(srcdir)/io.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
 freefs.o: $(srcdir)/freefs.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_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
+ $(top_srcdir)/lib/et/com_err.h  $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
 inode.o: $(srcdir)/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
+ $(top_srcdir)/lib/et/com_err.h  $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+llseek.o: $(srcdir)/llseek.c $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.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
+ $(top_srcdir)/lib/et/com_err.h  $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+native.o: $(srcdir)/native.c $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h  $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.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
-
diff --git a/lib/ext2fs/bitmaps.c b/lib/ext2fs/bitmaps.c
index d5ef0ec..7aaf549 100644
--- a/lib/ext2fs/bitmaps.c
+++ b/lib/ext2fs/bitmaps.c
@@ -22,27 +22,25 @@
 
 #include "ext2fs.h"
 
-errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
-				       const char *descr,
-				       ext2fs_inode_bitmap *ret)
+errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+					 __u32 end,
+					 __u32 real_end,
+					 const char *descr,
+					 ext2fs_generic_bitmap *ret)
 {
 	ext2fs_inode_bitmap bitmap;
 	int	size;
 
-	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-
-	fs->write_bitmaps = ext2fs_write_bitmaps;
-
-	bitmap = malloc(sizeof(struct ext2fs_struct_inode_bitmap));
+	bitmap = malloc(sizeof(struct ext2fs_struct_generic_bitmap));
 	if (!bitmap)
 		return ENOMEM;
 
-	bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
-	bitmap->fs = fs;
-	bitmap->start = 1;
-	bitmap->end = fs->super->s_inodes_count;
-	bitmap->real_end = (EXT2_INODES_PER_GROUP(fs->super)
-			    * fs->group_desc_count);
+	bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+	bitmap->fs = NULL;
+	bitmap->start = start;
+	bitmap->end = end;
+	bitmap->real_end = real_end;
+	bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
 	if (descr) {
 		bitmap->description = malloc(strlen(descr)+1);
 		if (!bitmap->description) {
@@ -66,46 +64,61 @@
 	return 0;
 }
 
-errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
+errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
 				       const char *descr,
-				       ext2fs_block_bitmap *ret)
+				       ext2fs_inode_bitmap *ret)
 {
-	ext2fs_block_bitmap bitmap;
-	int	size;
+	ext2fs_inode_bitmap bitmap;
+	errcode_t	retval;
+	__u32		start, end, real_end;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
 	fs->write_bitmaps = ext2fs_write_bitmaps;
 
-	bitmap = malloc(sizeof(struct ext2fs_struct_inode_bitmap));
-	if (!bitmap)
-		return ENOMEM;
+	start = 1;
+	end = fs->super->s_inodes_count;
+	real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count);
+
+	retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+						descr, &bitmap);
+	if (retval)
+		return retval;
+	
+	bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
+	bitmap->fs = fs;
+	bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
+	
+	*ret = bitmap;
+	return 0;
+}
+
+errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
+				       const char *descr,
+				       ext2fs_block_bitmap *ret)
+{
+	ext2fs_block_bitmap bitmap;
+	errcode_t	retval;
+	__u32		start, end, real_end;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	fs->write_bitmaps = ext2fs_write_bitmaps;
+
+	start = fs->super->s_first_data_block;
+	end = fs->super->s_blocks_count-1;
+	real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)  
+		    * fs->group_desc_count)-1 + start;
+	
+	retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+						descr, &bitmap);
+	if (retval)
+		return retval;
 
 	bitmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
 	bitmap->fs = fs;
-	bitmap->start = fs->super->s_first_data_block;
-	bitmap->end = fs->super->s_blocks_count-1;
-	bitmap->real_end = (EXT2_BLOCKS_PER_GROUP(fs->super) 
-			    * fs->group_desc_count)-1 + bitmap->start;
-	if (descr) {
-		bitmap->description = malloc(strlen(descr)+1);
-		if (!bitmap->description) {
-			free(bitmap);
-			return ENOMEM;
-		}
-		strcpy(bitmap->description, descr);
-	} else
-		bitmap->description = 0;
-
-	size = ((bitmap->real_end - bitmap->start) / 8) + 1;
-	bitmap->bitmap = malloc(size);
-	if (!bitmap->bitmap) {
-		free(bitmap->description);
-		free(bitmap);
-		return ENOMEM;
-	}
-
-	memset(bitmap->bitmap, 0, size);
+	bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
+	
 	*ret = bitmap;
 	return 0;
 }
diff --git a/lib/ext2fs/bitops.c b/lib/ext2fs/bitops.c
index da69e3b..6f256e5 100644
--- a/lib/ext2fs/bitops.c
+++ b/lib/ext2fs/bitops.c
@@ -72,3 +72,13 @@
 		com_err(0, errcode, "#%u", arg);
 }
 
+void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+			    int code, unsigned long arg)
+{
+	if (bitmap->description)
+		com_err(0, bitmap->base_error_code+code,
+			"#%u for %s", arg, bitmap->description);
+	else
+		com_err(0, bitmap->base_error_code + code, "#%u", arg);
+}
+
diff --git a/lib/ext2fs/bitops.h b/lib/ext2fs/bitops.h
index e98e2d2..e967c87 100644
--- a/lib/ext2fs/bitops.h
+++ b/lib/ext2fs/bitops.h
@@ -27,6 +27,8 @@
 extern const char *ext2fs_test_string;
 extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
 			       const char *description);
+extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+				int code, unsigned long arg);
 
 extern void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
 extern void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
@@ -172,6 +174,84 @@
 
 #define _EXT2_HAVE_ASM_BITOPS_
 
+#ifndef EXT2_OLD_BITOPS
+
+/*
+ * Do the bitops so that we are compatible with the standard i386
+ * convention.
+ */
+
+_INLINE_ int ext2fs_set_bit(int nr,void * addr)
+{
+#if 1
+	int		mask;
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	__asm__ __volatile__("ldub	[%0], %%g6\n\t"
+			     "or	%%g6, %2, %%g5\n\t"
+			     "stb	%%g5, [%0]\n\t"
+			     "and	%%g6, %2, %0\n"
+	: "=&r" (ADDR)
+	: "0" (ADDR), "r" (mask)
+	: "g5", "g6");
+	return (int) ADDR;
+#else
+	int		mask, retval;
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+#if 1
+	int		mask;
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	__asm__ __volatile__("ldub	[%0], %%g6\n\t"
+			     "andn	%%g6, %2, %%g5\n\t"
+			     "stb	%%g5, [%0]\n\t"
+			     "and	%%g6, %2, %0\n"
+	: "=&r" (ADDR)
+	: "0" (ADDR), "r" (mask)
+	: "g5", "g6");
+	return (int) ADDR;
+	
+#else
+	int		mask, retval;
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+	int			mask;
+	const unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#else
+
+/* Do things the old, unplesant way. */
+
 _INLINE_ int ext2fs_set_bit(int nr, void *addr)
 {
 	int		mask, retval;
@@ -205,6 +285,7 @@
 	mask = 1 << (nr & 31);
 	return ((mask & *ADDR) != 0);
 }
+#endif
 
 #endif /* __sparc__ */
 
@@ -223,70 +304,72 @@
 
 #endif /* !_EXT2_HAVE_ASM_SWAB */
 
+_INLINE_ void ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+				       __u32 bitno)
+{
+	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+		ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
+		return;
+	}
+	ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+					 blk_t bitno)
+{
+	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+		ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
+		return;
+	}
+	ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+				       blk_t bitno)
+{
+	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+		ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
+		return 0;
+	}
+	return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
 _INLINE_ void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
 				       blk_t block)
 {
-	if ((block < bitmap->start) || (block > bitmap->end)) {
-		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
-				   bitmap->description);
-		return;
-	}
-	ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
+	ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
 }
 
 _INLINE_ void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
 					 blk_t block)
 {
-	if ((block < bitmap->start) || (block > bitmap->end)) {
-		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
-				   block, bitmap->description);
-		return;
-	}
-	ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
+	ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
 }
 
 _INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
 				       blk_t block)
 {
-	if ((block < bitmap->start) || (block > bitmap->end)) {
-		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
-				   block, bitmap->description);
-		return 0;
-	}
-	return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
+	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
+					  block);
 }
 
 _INLINE_ void ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
 				       ino_t inode)
 {
-	if ((inode < bitmap->start) || (inode > bitmap->end)) {
-		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
-				   inode, bitmap->description);
-		return;
-	}
-	ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
+	ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
 }
 
 _INLINE_ void ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
 					 ino_t inode)
 {
-	if ((inode < bitmap->start) || (inode > bitmap->end)) {
-		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
-				   inode, bitmap->description);
-		return;
-	}
-	ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
+	ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
 }
 
 _INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
 				       ino_t inode)
 {
-	if ((inode < bitmap->start) || (inode > bitmap->end)) {
-		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
-				   inode, bitmap->description);
-		return 0;
-	}
-	return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
+	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
+					  inode);
 }
 
 _INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
diff --git a/lib/ext2fs/block.c b/lib/ext2fs/block.c
index fe112b3..5138534 100644
--- a/lib/ext2fs/block.c
+++ b/lib/ext2fs/block.c
@@ -39,8 +39,10 @@
 	int	i, flags, limit;
 	blk_t	*block_nr;
 
-	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE))
-		ret = (*ctx->func)(ctx->fs, ind_block, -1, ctx->private);
+	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
+		ret = (*ctx->func)(ctx->fs, ind_block,
+				   BLOCK_COUNT_IND, ctx->private);
 	if (!*ind_block || (ret & BLOCK_ABORT))
 		return ret;
 	if (*ind_block >= ctx->fs->super->s_blocks_count ||
@@ -56,7 +58,8 @@
 		return ret;
 	}
 	limit = ctx->fs->blocksize >> 2;
-	if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+	if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+	    (ctx->fs->flags & EXT2_SWAP_BYTES_READ)) {
 		block_nr = (blk_t *) ctx->ind_buf;
 		for (i = 0; i < limit; i++, block_nr++)
 			*block_nr = ext2fs_swab32(*block_nr);
@@ -86,7 +89,8 @@
 		}
 	}
 	if (changed & BLOCK_CHANGED) {
-		if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+		if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+		    (ctx->fs->flags & EXT2_SWAP_BYTES_WRITE)) {
 			block_nr = (blk_t *) ctx->ind_buf;
 			for (i = 0; i < limit; i++, block_nr++)
 				*block_nr = ext2fs_swab32(*block_nr);
@@ -97,8 +101,10 @@
 			ret |= BLOCK_ERROR | BLOCK_ABORT;
 	}
 	if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
 	    !(ret & BLOCK_ABORT))
-		ret |= (*ctx->func)(ctx->fs, ind_block, -1, ctx->private);
+		ret |= (*ctx->func)(ctx->fs, ind_block,
+				    BLOCK_COUNT_IND, ctx->private);
 	return ret;
 }
 	
@@ -108,8 +114,10 @@
 	int	i, flags, limit;
 	blk_t	*block_nr;
 
-	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE))
-		ret = (*ctx->func)(ctx->fs, dind_block, -2, ctx->private);
+	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
+		ret = (*ctx->func)(ctx->fs, dind_block,
+				   BLOCK_COUNT_DIND, ctx->private);
 	if (!*dind_block || (ret & BLOCK_ABORT))
 		return ret;
 	if (*dind_block >= ctx->fs->super->s_blocks_count ||
@@ -125,7 +133,8 @@
 		return ret;
 	}
 	limit = ctx->fs->blocksize >> 2;
-	if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+	if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+	    (ctx->fs->flags & EXT2_SWAP_BYTES_READ)) {
 		block_nr = (blk_t *) ctx->dind_buf;
 		for (i = 0; i < limit; i++, block_nr++)
 			*block_nr = ext2fs_swab32(*block_nr);
@@ -153,7 +162,8 @@
 		}
 	}
 	if (changed & BLOCK_CHANGED) {
-		if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+		if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+		    (ctx->fs->flags & EXT2_SWAP_BYTES_WRITE)) {
 			block_nr = (blk_t *) ctx->dind_buf;
 			for (i = 0; i < limit; i++, block_nr++)
 				*block_nr = ext2fs_swab32(*block_nr);
@@ -164,8 +174,10 @@
 			ret |= BLOCK_ERROR | BLOCK_ABORT;
 	}
 	if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
 	    !(ret & BLOCK_ABORT))
-		ret |= (*ctx->func)(ctx->fs, dind_block, -2, ctx->private);
+		ret |= (*ctx->func)(ctx->fs, dind_block,
+				    BLOCK_COUNT_DIND, ctx->private);
 	return ret;
 }
 	
@@ -175,8 +187,10 @@
 	int	i, flags, limit;
 	blk_t	*block_nr;
 
-	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE))
-		ret = (*ctx->func)(ctx->fs, tind_block, -3, ctx->private);
+	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
+		ret = (*ctx->func)(ctx->fs, tind_block,
+				   BLOCK_COUNT_TIND, ctx->private);
 	if (!*tind_block || (ret & BLOCK_ABORT))
 		return ret;
 	if (*tind_block >= ctx->fs->super->s_blocks_count ||
@@ -192,7 +206,8 @@
 		return ret;
 	}
 	limit = ctx->fs->blocksize >> 2;
-	if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+	if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+	    (ctx->fs->flags & EXT2_SWAP_BYTES_READ)) {
 		block_nr = (blk_t *) ctx->tind_buf;
 		for (i = 0; i < limit; i++, block_nr++)
 			*block_nr = ext2fs_swab32(*block_nr);
@@ -220,7 +235,8 @@
 		}
 	}
 	if (changed & BLOCK_CHANGED) {
-		if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+		if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+		    (ctx->fs->flags & EXT2_SWAP_BYTES_WRITE)) {
 			block_nr = (blk_t *) ctx->tind_buf;
 			for (i = 0; i < limit; i++, block_nr++)
 				*block_nr = ext2fs_swab32(*block_nr);
@@ -231,8 +247,10 @@
 			ret |= BLOCK_ERROR | BLOCK_ABORT;
 	}
 	if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
 	    !(ret & BLOCK_ABORT))
-		ret |= (*ctx->func)(ctx->fs, tind_block, -3, ctx->private);
+		ret |= (*ctx->func)(ctx->fs, tind_block,
+				    BLOCK_COUNT_TIND, ctx->private);
 	
 	return ret;
 }
@@ -248,6 +266,7 @@
 			       void *private)
 {
 	int	i;
+	int	got_inode = 0;
 	int	ret = 0;
 	struct block_context ctx;
 	blk_t	blocks[EXT2_N_BLOCKS];	/* directory data blocks */
@@ -274,7 +293,26 @@
 	}
 	ctx.dind_buf = ctx.ind_buf + fs->blocksize;
 	ctx.tind_buf = ctx.dind_buf + fs->blocksize;
+
+	/*
+	 * Iterate over the HURD translator block (if present)
+	 */
+	if ((fs->super->s_creator_os == EXT2_OS_HURD) &&
+	    !(flags & BLOCK_FLAG_DATA_ONLY) &&
+	    inode.osd1.hurd1.h_i_translator) {
+		ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
+		if (ctx.errcode)
+			goto abort;
+		got_inode = 1;
+		ret |= (*func)(fs, &inode.osd1.hurd1.h_i_translator,
+			       BLOCK_COUNT_TRANSLATOR, private);
+		if (ret & BLOCK_ABORT)
+			goto abort;
+	}
 	
+	/*
+	 * Iterate over normal data blocks
+	 */
 	for (i = 0; i < EXT2_NDIR_BLOCKS ; i++, ctx.bcount++) {
 		if (blocks[i] || (flags & BLOCK_FLAG_APPEND)) {
 			ret |= (*func)(fs, &blocks[i], ctx.bcount, private);
@@ -292,14 +330,19 @@
 		if (ret & BLOCK_ABORT)
 			goto abort;
 	}
-	if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND))
+	if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
 		ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK, &ctx);
+		if (ret & BLOCK_ABORT)
+			goto abort;
+	}
 
 abort:
 	if (ret & BLOCK_CHANGED) {
-		retval = ext2fs_read_inode(fs, ino, &inode);
-		if (retval)
-			return retval;
+		if (!got_inode) {
+			retval = ext2fs_read_inode(fs, ino, &inode);
+			if (retval)
+				return retval;
+		}
 		for (i=0; i < EXT2_N_BLOCKS; i++)
 			inode.i_block[i] = blocks[i];
 		retval = ext2fs_write_inode(fs, ino, &inode);
diff --git a/lib/ext2fs/dirblock.c b/lib/ext2fs/dirblock.c
index bb2f717..3d5dbb2 100644
--- a/lib/ext2fs/dirblock.c
+++ b/lib/ext2fs/dirblock.c
@@ -27,7 +27,7 @@
  	retval = io_channel_read_blk(fs->io, block, 1, buf);
 	if (retval)
 		return retval;
-	if ((fs->flags & EXT2_SWAP_BYTES) == 0)
+	if ((fs->flags & (EXT2_SWAP_BYTES|EXT2_SWAP_BYTES_READ)) == 0)
 		return 0;
 	p = buf;
 	end = (char *) buf + fs->blocksize;
@@ -49,7 +49,8 @@
 	char		*buf = 0;
 	struct ext2_dir_entry *dirent;
 
-	if (fs->flags & EXT2_SWAP_BYTES) {
+	if ((fs->flags & EXT2_SWAP_BYTES) ||
+	    (fs->flags & EXT2_SWAP_BYTES_WRITE)) {
 		write_buf = buf = malloc(fs->blocksize);
 		if (!buf)
 			return ENOMEM;
diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
index 71153ce..81e0c1e 100644
--- a/lib/ext2fs/ext2_err.et.in
+++ b/lib/ext2fs/ext2_err.et.in
@@ -34,8 +34,8 @@
 ec	EXT2_ET_MAGIC_INODE_BITMAP,
 	"Wrong magic number for inode_bitmap structure"
 
-ec	EXT2_ET_MAGIC_RESERVED_1,
-	"Wrong magic number --- RESERVED_1"
+ec	EXT2_ET_MAGIC_GENERIC_BITMAP,
+	"Wrong magic number for generic_bitmap structure"
 
 ec	EXT2_ET_MAGIC_RESERVED_2,
 	"Wrong magic number --- RESERVED_2"
@@ -191,7 +191,24 @@
 	"Illegal or malformed device name"
 
 ec	EXT2_ET_MISSING_INODE_TABLE,
-	"A block group is missing an inode table."
+	"A block group is missing an inode table"
+
+ec	EXT2_ET_CORRUPT_SUPERBLOCK,
+	"The ext2 superblock is corrupt"
+
+ec	EXT2_ET_BAD_GENERIC_MARK,
+	"Illegal generic bit number passed to ext2fs_mark_generic_bitmap"
+
+ec	EXT2_ET_BAD_GENERIC_UNMARK,
+	"Illegal generic bit number passed to ext2fs_unmark_generic_bitmap"
+
+ec	EXT2_ET_BAD_GENERIC_TEST,
+	"Illegal generic bit number passed to ext2fs_test_generic_bitmap"
+
+ec	EXT2_ET_SYMLINK_LOOP,
+	"Too many symbolic links encountered."
+
+ec	EXT2_ET_CALLBACK_NOTHANDLED,
+	"The callback function will not handle this case"
 
 	end
-
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 73194c0..f385770 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -21,6 +21,7 @@
  */
 #define EXT2_LIB_CURRENT_REV	0
 
+#include <sys/types.h>
 #include <linux/types.h>
 
 typedef __u32		blk_t;
@@ -32,29 +33,26 @@
 
 typedef struct struct_ext2_filsys *ext2_filsys;
 
-struct ext2fs_struct_inode_bitmap {
-	int	magic;
-	ext2_filsys fs;
-	ino_t	start, end;
-	ino_t	real_end;
-	char	*description;
-	char	*bitmap;
-	int	reserved[8];
+struct ext2fs_struct_generic_bitmap {
+	int		magic;
+	ext2_filsys 	fs;
+	__u32		start, end;
+	__u32		real_end;
+	char	*	description;
+	char	*	bitmap;
+	errcode_t	base_error_code;
+	__u32		reserved[7];
 };
 
-typedef struct ext2fs_struct_inode_bitmap *ext2fs_inode_bitmap;
+#define EXT2FS_MARK_ERROR 	0
+#define EXT2FS_UNMARK_ERROR 	1
+#define EXT2FS_TEST_ERROR	2
 
-struct ext2fs_struct_block_bitmap {
-	int	magic;
-	ext2_filsys fs;
-	blk_t	start, end;
-	ino_t	real_end;
-	char	*description;
-	char	*bitmap;
-	int	reserved[8];
-};
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
 
-typedef struct ext2fs_struct_block_bitmap *ext2fs_block_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
+
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
 
 #ifdef EXT2_DYNAMIC_REV
 #define EXT2_FIRST_INODE(s)	EXT2_FIRST_INO(s)
@@ -74,6 +72,8 @@
 #define EXT2_FLAG_IB_DIRTY	0x10
 #define EXT2_FLAG_BB_DIRTY	0x20
 #define EXT2_SWAP_BYTES		0x40
+#define EXT2_SWAP_BYTES_READ	0x80
+#define EXT2_SWAP_BYTES_WRITE	0x100
 
 /*
  * Special flag in the ext2 inode i_flag field that means that this is
@@ -98,7 +98,11 @@
 	errcode_t (*get_blocks)(ext2_filsys fs, ino_t ino, blk_t *blocks);
 	errcode_t (*check_directory)(ext2_filsys fs, ino_t ino);
 	errcode_t (*write_bitmaps)(ext2_filsys fs);
-	int				reserved[16];
+	errcode_t (*read_inode)(ext2_filsys fs, ino_t ino,
+				struct ext2_inode *inode);
+	errcode_t (*write_inode)(ext2_filsys fs, ino_t ino,
+				struct ext2_inode *inode);
+	__u32				reserved[14];
 
 	/*
 	 * Not used by ext2fs library; reserved for the use of the
@@ -156,10 +160,22 @@
  * of the blocks containined in the indirect blocks are processed.
  * This is useful if you are going to be deallocating blocks from an
  * inode.
+ *
+ * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
+ * called for data blocks only.
  */
 #define BLOCK_FLAG_APPEND	1
 #define BLOCK_FLAG_HOLE		1
 #define BLOCK_FLAG_DEPTH_TRAVERSE	2
+#define BLOCK_FLAG_DATA_ONLY	4
+
+/*
+ * Magic "block count" return values for the block iterator function.
+ */
+#define BLOCK_COUNT_IND		(-1)
+#define BLOCK_COUNT_DIND	(-2)
+#define BLOCK_COUNT_TIND	(-3)
+#define BLOCK_COUNT_TRANSLATOR	(-4)
 
 /*
  * Return flags for the directory iterator functions
@@ -224,6 +240,21 @@
 #define LINUX_S_ISGID  0002000
 #define LINUX_S_ISVTX  0001000
 
+#define LINUX_S_IRWXU 00700
+#define LINUX_S_IRUSR 00400
+#define LINUX_S_IWUSR 00200
+#define LINUX_S_IXUSR 00100
+
+#define LINUX_S_IRWXG 00070
+#define LINUX_S_IRGRP 00040
+#define LINUX_S_IWGRP 00020
+#define LINUX_S_IXGRP 00010
+
+#define LINUX_S_IRWXO 00007
+#define LINUX_S_IROTH 00004
+#define LINUX_S_IWOTH 00002
+#define LINUX_S_IXOTH 00001
+
 #define LINUX_S_ISLNK(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
 #define LINUX_S_ISREG(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
 #define LINUX_S_ISDIR(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
@@ -238,6 +269,63 @@
 
 #define EXT2_CHECK_MAGIC(struct, code) \
 	  if ((struct)->magic != (code)) return (code)
+
+
+/*
+ * The ext2fs library private definition of the ext2 superblock, so we
+ * don't have to depend on the kernel's definition of the superblock,
+ * which might not have the latest features.
+ */
+struct ext2fs_sb {
+	__u32	s_inodes_count;		/* Inodes count */
+	__u32	s_blocks_count;		/* Blocks count */
+	__u32	s_r_blocks_count;	/* Reserved blocks count */
+	__u32	s_free_blocks_count;	/* Free blocks count */
+	__u32	s_free_inodes_count;	/* Free inodes count */
+	__u32	s_first_data_block;	/* First Data Block */
+	__u32	s_log_block_size;	/* Block size */
+	__s32	s_log_frag_size;	/* Fragment size */
+	__u32	s_blocks_per_group;	/* # Blocks per group */
+	__u32	s_frags_per_group;	/* # Fragments per group */
+	__u32	s_inodes_per_group;	/* # Inodes per group */
+	__u32	s_mtime;		/* Mount time */
+	__u32	s_wtime;		/* Write time */
+	__u16	s_mnt_count;		/* Mount count */
+	__s16	s_max_mnt_count;	/* Maximal mount count */
+	__u16	s_magic;		/* Magic signature */
+	__u16	s_state;		/* File system state */
+	__u16	s_errors;		/* Behaviour when detecting errors */
+	__u16	s_minor_rev_level; 	/* minor revision level */
+	__u32	s_lastcheck;		/* time of last check */
+	__u32	s_checkinterval;	/* max. time between checks */
+	__u32	s_creator_os;		/* OS */
+	__u32	s_rev_level;		/* Revision level */
+	__u16	s_def_resuid;		/* Default uid for reserved blocks */
+	__u16	s_def_resgid;		/* Default gid for reserved blocks */
+	/*
+	 * These fields are for EXT2_DYNAMIC_REV superblocks only.
+	 *
+	 * Note: the difference between the compatible feature set and
+	 * the incompatible feature set is that if there is a bit set
+	 * in the incompatible feature set that the kernel doesn't
+	 * know about, it should refuse to mount the filesystem.
+	 * 
+	 * e2fsck's requirements are more strict; if it doesn't know
+	 * about a feature in either the compatible or incompatible
+	 * feature set, it must abort and not try to meddle with
+	 * things it doesn't understand...
+	 */
+	__u32	s_first_ino; 		/* First non-reserved inode */
+	__u16   s_inode_size; 		/* size of inode structure */
+	__u16	s_block_group_nr; 	/* block group # of this superblock */
+	__u32	s_feature_compat; 	/* compatible feature set */
+	__u32	s_feature_incompat; 	/* incompatible feature set */
+	__u32	s_feature_ro_compat; 	/* readonly-compatible feature set */
+	__u8	s_uuid[16];		/* 128-bit uuid for volume */
+	char	s_volume_name[16]; 	/* volume name */
+	char	s_last_mounted[64]; 	/* directory where last mounted */
+	__u32	s_reserved[206];	/* Padding to the end of the block */
+};
   
 /*
  * function prototypes
@@ -272,6 +360,11 @@
 extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
 extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
 extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+						__u32 end,
+						__u32 real_end,
+						const char *descr,
+						ext2fs_generic_bitmap *ret);
 extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
 					      const char *descr,
 					      ext2fs_block_bitmap *ret);
@@ -323,6 +416,7 @@
 
 /* freefs.c */
 extern void ext2fs_free(ext2_filsys fs);
+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);
 
@@ -378,6 +472,13 @@
 			 int namelen, char *buf, ino_t *inode);
 extern errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd,
 			const char *name, ino_t *inode);
+errcode_t ext2fs_namei_follow(ext2_filsys fs, ino_t root, ino_t cwd,
+			      const char *name, ino_t *inode);
+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ino_t root, ino_t cwd,
+			ino_t inode, ino_t *res_inode);
+
+/* native.c */
+int ext2fs_native_flag(void);
 
 /* newdir.c */
 extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ino_t dir_ino,
@@ -414,6 +515,9 @@
 /* swapfs.c */
 extern void ext2fs_swap_super(struct ext2_super_block * super);
 extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
+extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
+			      struct ext2_inode *f, int hostorder);
+
 
 /* inline functions */
 extern void ext2fs_mark_super_dirty(ext2_filsys fs);
diff --git a/lib/ext2fs/freefs.c b/lib/ext2fs/freefs.c
index 63b5235..5c70983 100644
--- a/lib/ext2fs/freefs.c
+++ b/lib/ext2fs/freefs.c
@@ -33,9 +33,9 @@
 	free(fs);
 }
 
-void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
+void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
 {
-	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
+	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_GENERIC_BITMAP))
 		return;
 
 	bitmap->magic = 0;
@@ -50,20 +50,21 @@
 	free(bitmap);
 }
 
+void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
+{
+	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
+		return;
+
+	bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+	ext2fs_free_generic_bitmap(bitmap);
+}
+
 void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap)
 {
 	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
 		return;
 
-	bitmap->magic = 0;
-	if (bitmap->description) {
-		free(bitmap->description);
-		bitmap->description = 0;
-	}
-	if (bitmap->bitmap) {
-		free(bitmap->bitmap);
-		bitmap->bitmap = 0;
-	}
-	free(bitmap);
+	bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+	ext2fs_free_generic_bitmap(bitmap);
 }
 
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index cc7abd0..4108093 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -1,6 +1,11 @@
 /*
  * initialize.c --- initialize a filesystem handle given superblock
  * 	parameters.  Used by mke2fs when initializing a filesystem.
+ * 
+ * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
+ * 
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
  */
 
 #include <stdio.h>
@@ -31,6 +36,19 @@
 #define CREATOR_OS EXT2_OS_LINUX /* by default */
 #endif
 
+/*
+ * Note we override the kernel include file's idea of what the default
+ * check interval (never) should be.  It's a good idea to check at
+ * least *occasionally*, specially since servers will never rarely get
+ * to reboot, since Linux is so robust these days.  :-)
+ * 
+ * 180 days (six months) seems like a good value.
+ */
+#ifdef EXT2_DFL_CHECKINTERVAL
+#undef EXT2_DFL_CHECKINTERVAL
+#endif
+#define EXT2_DFL_CHECKINTERVAL (86400 * 180)
+
 errcode_t ext2fs_initialize(const char *name, int flags,
 			    struct ext2_super_block *param,
 			    io_manager manager, ext2_filsys *ret_fs)
@@ -55,7 +73,7 @@
 	
 	memset(fs, 0, sizeof(struct struct_ext2_filsys));
 	fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
-	fs->flags = flags | EXT2_FLAG_RW;
+	fs->flags = flags | EXT2_FLAG_RW | ext2fs_native_flag();
 	retval = manager->open(name, IO_FLAG_RW, &fs->io);
 	if (retval)
 		goto cleanup;
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index 04c5e4d..7d25ae1 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -19,8 +19,6 @@
 
 #include "ext2fs.h"
 
-static void inocpy_with_swap(struct ext2_inode *t, struct ext2_inode *f);
-
 errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
 				 ext2_inode_scan *ret_scan)
 {
@@ -151,15 +149,17 @@
 		scan->ptr += scan->inode_size - extra_bytes;
 		scan->bytes_left -= scan->inode_size - extra_bytes;
 
-		if (scan->fs->flags & EXT2_SWAP_BYTES)
-			inocpy_with_swap(inode, (struct ext2_inode *)
-					 scan->temp_buffer);
+		if ((scan->fs->flags & EXT2_SWAP_BYTES) ||
+		    (scan->fs->flags & EXT2_SWAP_BYTES_READ))
+			ext2fs_swap_inode(scan->fs, inode,
+				 (struct ext2_inode *) scan->temp_buffer, 0);
 		else
 			*inode = *((struct ext2_inode *) scan->temp_buffer);
 	} else {
-		if (scan->fs->flags & EXT2_SWAP_BYTES)
-			inocpy_with_swap(inode, (struct ext2_inode *)
-					 scan->ptr);
+		if ((scan->fs->flags & EXT2_SWAP_BYTES) ||
+		    (scan->fs->flags & EXT2_SWAP_BYTES_READ))
+			ext2fs_swap_inode(scan->fs, inode,
+				 (struct ext2_inode *) scan->ptr, 0);
 		else
 			*inode = *((struct ext2_inode *) scan->ptr);
 		scan->ptr += scan->inode_size;
@@ -178,6 +178,15 @@
 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, unsigned long ino,
 			     struct ext2_inode * inode)
@@ -185,10 +194,29 @@
 	unsigned long 	group, block, block_nr, offset;
 	char 		*ptr;
 	errcode_t	retval;
-	int 		clen, length;
+	int 		clen, length, i;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
+	/* Check to see if user has an override function */
+	if (fs->read_inode) {
+		retval = (fs->read_inode)(fs, ino, inode);
+		if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
+			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;
+			return 0;
+		}
+	}
+#endif
 	if (ino > fs->super->s_inodes_count)
 		return EXT2_ET_BAD_INODE_NUM;
 	if (inode_buffer_size != fs->blocksize) {
@@ -238,8 +266,16 @@
 	} else
 		memcpy((char *) inode, ptr, length);
 	
-	if (fs->flags & EXT2_SWAP_BYTES)
-		inocpy_with_swap(inode, inode);
+	if ((fs->flags & EXT2_SWAP_BYTES) ||
+	    (fs->flags & EXT2_SWAP_BYTES_READ))
+		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
 
 	return 0;
 }
@@ -251,10 +287,25 @@
 	errcode_t	retval;
 	struct ext2_inode temp_inode;
 	char *ptr;
-	int i, clen, length;
+	int clen, length, i;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
+	/* Check to see if user provided an override function */
+	if (fs->write_inode) {
+		retval = (fs->write_inode)(fs, ino, inode);
+		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;
+		}
+	}
+#endif
 	if (!(fs->flags & EXT2_FLAG_RW))
 		return EXT2_ET_RO_FILSYS;
 
@@ -271,8 +322,9 @@
 		inode_buffer_size = fs->blocksize;
 		inode_buffer_block = 0;
 	}
-	if (fs->flags & EXT2_SWAP_BYTES)
-		inocpy_with_swap(&temp_inode, inode);
+	if ((fs->flags & EXT2_SWAP_BYTES) ||
+	    (fs->flags & EXT2_SWAP_BYTES_WRITE))
+		ext2fs_swap_inode(fs, &temp_inode, inode, 1);
 	else
 		memcpy(&temp_inode, inode, sizeof(struct ext2_inode));
 	
@@ -367,32 +419,7 @@
 	if (retval)
 		return retval;
 	if (!LINUX_S_ISDIR(inode.i_mode))
-		return ENOTDIR;
+	return ENOTDIR;
 	return 0;
 }
 
-static void inocpy_with_swap(struct ext2_inode *t, struct ext2_inode *f)
-{
-	unsigned i;
-	
-	t->i_mode = ext2fs_swab16(f->i_mode);
-	t->i_uid = ext2fs_swab16(f->i_uid);
-	t->i_size = ext2fs_swab32(f->i_size);
-	t->i_atime = ext2fs_swab32(f->i_atime);
-	t->i_ctime = ext2fs_swab32(f->i_ctime);
-	t->i_mtime = ext2fs_swab32(f->i_mtime);
-	t->i_dtime = ext2fs_swab32(f->i_dtime);
-	t->i_gid = ext2fs_swab16(f->i_gid);
-	t->i_links_count = ext2fs_swab16(f->i_links_count);
-	t->i_blocks = ext2fs_swab32(f->i_blocks);
-	t->i_flags = ext2fs_swab32(f->i_flags);
-	for (i = 0; i < EXT2_N_BLOCKS; i++)
-		t->i_block[i] = ext2fs_swab32(f->i_block[i]);
-	t->i_version = ext2fs_swab32(f->i_version);
-	t->i_file_acl = ext2fs_swab32(f->i_file_acl);
-	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
-	t->i_faddr = ext2fs_swab32(f->i_faddr);
-	t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
-	t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
-	t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
-}
diff --git a/lib/ext2fs/namei.c b/lib/ext2fs/namei.c
index 496c726..8fc71b0 100644
--- a/lib/ext2fs/namei.c
+++ b/lib/ext2fs/namei.c
@@ -13,6 +13,8 @@
 #include <errno.h>
 #endif
 
+/* #define NAMEI_DEBUG */
+
 #include <linux/ext2_fs.h>
 
 #include "ext2fs.h"
@@ -173,43 +175,186 @@
 	return (ls.found) ? 0 : ENOENT;
 }
 
-errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd, const char *name,
-		       ino_t *inode)
-{
-	ino_t		dir = cwd;
-	char		*buf;
-	const char	*p = name, *q;
-	int		len;
-	errcode_t	retval;
 
+static errcode_t open_namei(ext2_filsys fs, ino_t root, ino_t base,
+			    const char *pathname, int pathlen, int follow,
+			    int link_count, char *buf, ino_t *res_inode);
+
+static errcode_t follow_link(ext2_filsys fs, ino_t root, ino_t dir,
+			     ino_t inode, int link_count,
+			     char *buf, ino_t *res_inode)
+{
+	char *pathname;
+	char *buffer = 0;
+	errcode_t retval;
+	struct ext2_inode ei;
+
+#ifdef NAMEI_DEBUG
+	printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
+	       root, dir, inode, link_count);
+	
+#endif
+	retval = ext2fs_read_inode (fs, inode, &ei);
+	if (retval) return retval;
+	if (!LINUX_S_ISLNK (ei.i_mode)) {
+		*res_inode = inode;
+		return 0;
+	}
+	if (link_count++ > 5) {
+		return EXT2_ET_SYMLINK_LOOP;
+	}
+	if (ei.i_blocks) {
+		buffer = malloc (fs->blocksize);
+		if (!buffer)
+			return ENOMEM;
+		retval = io_channel_read_blk(fs->io, ei.i_block[0], 1, buffer);
+		if (retval) {
+			free(buffer);
+			return retval;
+		}
+		pathname = buffer;
+	} else
+		pathname = (char *)&(ei.i_block[0]);
+	retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
+			    link_count, buf, res_inode);
+	if (buffer)
+		free (buffer);
+	return retval;
+}
+
+/*
+ * This routine interprets a pathname in the context of the current
+ * directory and the root directory, and returns the inode of the
+ * containing directory, and a pointer to the filename of the file
+ * (pointing into the pathname) and the length of the filename.
+ */
+static errcode_t dir_namei(ext2_filsys fs, ino_t root, ino_t dir,
+			   const char *pathname, int pathlen,
+			   int link_count, char *buf,
+			   const char **name, int *namelen, ino_t *res_inode)
+{
+	char c;
+	const char *thisname;
+	int len;
+	ino_t inode;
+	errcode_t retval;
+
+	if ((c = *pathname) == '/') {
+        	dir = root;
+		pathname++;
+		pathlen--;
+	}
+	while (1) {
+        	thisname = pathname;
+		for (len=0; --pathlen >= 0;len++) {
+			c = *(pathname++);
+			if (c == '/')
+				break;
+		}
+		if (pathlen < 0)
+			break;
+		retval = ext2fs_lookup (fs, dir, thisname, len, buf, &inode);
+		if (retval) return retval;
+        	retval = follow_link (fs, root, dir, inode,
+				      link_count, buf, &dir);
+        	if (retval) return retval;
+    	}
+	*name = thisname;
+	*namelen = len;
+	*res_inode = dir;
+	return 0;
+}
+
+static errcode_t open_namei(ext2_filsys fs, ino_t root, ino_t base,
+			    const char *pathname, int pathlen, int follow,
+			    int link_count, char *buf, ino_t *res_inode)
+{
+	const char *basename;
+	int namelen;
+	ino_t dir, inode;
+	errcode_t retval;
+
+#ifdef NAMEI_DEBUG
+	printf("open_namei: root=%lu, dir=%lu, path=%*s, lc=%d\n",
+	       root, base, pathlen, pathname, link_count);
+#endif
+	retval = dir_namei(fs, root, base, pathname, pathlen,
+			   link_count, buf, &basename, &namelen, &dir);
+	if (retval) return retval;
+	if (!namelen) {                     /* special case: '/usr/' etc */
+		*res_inode=dir;
+		return 0;
+	}
+	retval = ext2fs_lookup (fs, dir, basename, namelen, buf, &inode);
+	if (retval)
+		return retval;
+	if (follow) {
+		retval = follow_link(fs, root, dir, inode, link_count,
+				     buf, &inode);
+		if (retval)
+			return retval;
+	}
+#ifdef NAMEI_DEBUG
+	printf("open_namei: (link_count=%d) returns %lu\n",
+	       link_count, inode);
+#endif
+	*res_inode = inode;
+	return 0;
+}
+
+errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd,
+		       const char *name, ino_t *inode)
+{
+	char *buf;
+	errcode_t retval;
+	
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
 	buf = malloc(fs->blocksize);
 	if (!buf)
 		return ENOMEM;
-	if (*p == '/') {
-		p++;
-		dir = root;
-	}
-	while (*p) {
-		q = strchr(p, '/');
-		if (q)
-			len = q - p;
-		else
-			len = strlen(p);
-		if (len) {
-			retval = ext2fs_lookup(fs, dir, p, len, buf, &dir);
-			if (retval) {
-				free(buf);
-				return retval;
-			}
-		}
-		if (q)
-			p = q+1;
-		else
-			break;
-	}
-	*inode = dir;
+	
+	retval = open_namei(fs, root, cwd, name, strlen(name), 0, 0,
+			    buf, inode);
+
 	free(buf);
-	return 0;
+	return retval;
 }
+
+errcode_t ext2fs_namei_follow(ext2_filsys fs, ino_t root, ino_t cwd,
+			      const char *name, ino_t *inode)
+{
+	char *buf;
+	errcode_t retval;
+	
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	buf = malloc(fs->blocksize);
+	if (!buf)
+		return ENOMEM;
+	
+	retval = open_namei(fs, root, cwd, name, strlen(name), 1, 0,
+			    buf, inode);
+
+	free(buf);
+	return retval;
+}
+
+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ino_t root, ino_t cwd,
+			ino_t inode, ino_t *res_inode)
+{
+	char *buf;
+	errcode_t retval;
+	
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	buf = malloc(fs->blocksize);
+	if (!buf)
+		return ENOMEM;
+	
+	retval = follow_link(fs, root, cwd, inode, 0, buf, res_inode);
+
+	free(buf);
+	return retval;
+}
+
diff --git a/lib/ext2fs/native.c b/lib/ext2fs/native.c
new file mode 100644
index 0000000..aa371ce
--- /dev/null
+++ b/lib/ext2fs/native.c
@@ -0,0 +1,31 @@
+/*
+ * native.c --- returns the ext2_flag for a native byte order
+ * 
+ * Copyright (C) 1996 Theodore Ts'o.
+ * 
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ */
+
+#include <stdio.h>
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+
+static int i386_byteorder(void)
+{
+	int one = 1;
+	char *cp = (char *) &one;
+
+	return (*cp == 1);
+}
+
+int ext2fs_native_flag(void)
+{
+	if (i386_byteorder())
+		return 0;
+	return EXT2_SWAP_BYTES;
+}
+
+	
+	
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index e8b01e2..74bf279 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -113,6 +113,10 @@
 #endif
 #endif
 	fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
+	if (fs->blocksize == 0) {
+		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+		goto cleanup;
+	}
 	fs->fragsize = EXT2_FRAG_SIZE(fs->super);
 	fs->inode_blocks_per_group = ((fs->super->s_inodes_per_group *
 				       EXT2_INODE_SIZE(fs->super) +
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index 371b8f9..968f41c 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -16,6 +16,8 @@
 
 void ext2fs_swap_super(struct ext2_super_block * super)
 {
+	struct ext2fs_sb *s = (struct ext2fs_sb *) super;
+	
 	super->s_inodes_count = ext2fs_swab32(super->s_inodes_count);
 	super->s_blocks_count = ext2fs_swab32(super->s_blocks_count);
 	super->s_r_blocks_count = ext2fs_swab32(super->s_r_blocks_count);
@@ -34,6 +36,7 @@
 	super->s_magic = ext2fs_swab16(super->s_magic);
 	super->s_state = ext2fs_swab16(super->s_state);
 	super->s_errors = ext2fs_swab16(super->s_errors);
+	s->s_minor_rev_level = ext2fs_swab16(s->s_minor_rev_level);
 	super->s_lastcheck = ext2fs_swab32(super->s_lastcheck);
 	super->s_checkinterval = ext2fs_swab32(super->s_checkinterval);
 	super->s_creator_os = ext2fs_swab32(super->s_creator_os);
@@ -42,6 +45,12 @@
 	super->s_def_resuid = ext2fs_swab16(super->s_def_resuid);
 	super->s_def_resgid = ext2fs_swab16(super->s_def_resgid);
 #endif
+	s->s_first_ino = ext2fs_swab32(s->s_first_ino);
+	s->s_inode_size = ext2fs_swab16(s->s_inode_size);
+	s->s_block_group_nr = ext2fs_swab16(s->s_block_group_nr);
+	s->s_feature_compat = ext2fs_swab32(s->s_feature_compat);
+	s->s_feature_incompat = ext2fs_swab32(s->s_feature_incompat);
+	s->s_feature_ro_compat = ext2fs_swab32(s->s_feature_ro_compat);
 }
 
 void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
@@ -54,5 +63,64 @@
 	gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
 }
 
+void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
+		       struct ext2_inode *f, int hostorder)
+{
+	unsigned i;
+	int islnk = 0;
 	
+	if (hostorder && LINUX_S_ISLNK(f->i_mode))
+		islnk = 1;
+	t->i_mode = ext2fs_swab16(f->i_mode);
+	if (!hostorder && LINUX_S_ISLNK(t->i_mode))
+		islnk = 1;
+	t->i_uid = ext2fs_swab16(f->i_uid);
+	t->i_size = ext2fs_swab32(f->i_size);
+	t->i_atime = ext2fs_swab32(f->i_atime);
+	t->i_ctime = ext2fs_swab32(f->i_ctime);
+	t->i_mtime = ext2fs_swab32(f->i_mtime);
+	t->i_dtime = ext2fs_swab32(f->i_dtime);
+	t->i_gid = ext2fs_swab16(f->i_gid);
+	t->i_links_count = ext2fs_swab16(f->i_links_count);
+	t->i_blocks = ext2fs_swab32(f->i_blocks);
+	t->i_flags = ext2fs_swab32(f->i_flags);
+	if (!islnk || f->i_blocks) {
+		for (i = 0; i < EXT2_N_BLOCKS; i++)
+			t->i_block[i] = ext2fs_swab32(f->i_block[i]);
+	} else if (t != f) {
+		for (i = 0; i < EXT2_N_BLOCKS; i++)
+			t->i_block[i] = f->i_block[i];
+	}
+	t->i_version = ext2fs_swab32(f->i_version);
+	t->i_file_acl = ext2fs_swab32(f->i_file_acl);
+	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
+	t->i_faddr = ext2fs_swab32(f->i_faddr);
 
+	switch (fs->super->s_creator_os) {
+	case EXT2_OS_LINUX:
+		t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
+		t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
+		t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
+		break;
+	case EXT2_OS_HURD:
+		t->osd1.hurd1.h_i_translator =
+		  ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
+		t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
+		t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
+		t->osd2.hurd2.h_i_mode_high =
+		  ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
+		t->osd2.hurd2.h_i_uid_high =
+		  ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
+		t->osd2.hurd2.h_i_gid_high =
+		  ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
+		t->osd2.hurd2.h_i_author =
+		  ext2fs_swab32 (f->osd2.hurd2.h_i_author);
+		break;
+	case EXT2_OS_MASIX:
+		t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
+		t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
+		t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
+		break;
+	}
+}
+	
diff --git a/lib/ss/ChangeLog b/lib/ss/ChangeLog
index 7943820..96b3612 100644
--- a/lib/ss/ChangeLog
+++ b/lib/ss/ChangeLog
@@ -1,3 +1,15 @@
+Fri Aug 30 22:36:48 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* invocation.c (ss_create_invocation): Change function prototype
+ 		of invocation so that the first two arguments are const
+ 		char *, and that the info_ptr is a void *, not a char *.
+
+	* ss.h: Added declaration of ss_execute_line()
+
+Sat Aug 10 00:17:14 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* listen.c (ss_listen): Fix -Wall flames.
+
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.04
diff --git a/lib/ss/Makefile.in b/lib/ss/Makefile.in
index 9af2c2f..777c34b 100644
--- a/lib/ss/Makefile.in
+++ b/lib/ss/Makefile.in
@@ -6,6 +6,7 @@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ../..
+my_dir = lib/ss
 INSTALL = @INSTALL@
 
 @MCONFIG@
diff --git a/lib/ss/error.c b/lib/ss/error.c
index 80ebc82..7f2e96f 100644
--- a/lib/ss/error.c
+++ b/lib/ss/error.c
@@ -75,7 +75,7 @@
     va_dcl
 #endif
 {
-    register char const *whoami;
+    register char *whoami;
     va_list pvar;
 #ifndef HAVE_STDARG_H
     int sci_idx;
diff --git a/lib/ss/execute_cmd.c b/lib/ss/execute_cmd.c
index be13dd8..74b5969 100644
--- a/lib/ss/execute_cmd.c
+++ b/lib/ss/execute_cmd.c
@@ -151,7 +151,7 @@
  * Notes:
  */
 
-ss_execute_command(sci_idx, argv)
+int ss_execute_command(sci_idx, argv)
 	int sci_idx;
 	register char *argv[];
 {
diff --git a/lib/ss/invocation.c b/lib/ss/invocation.c
index c4c15ca..c4aecf1 100644
--- a/lib/ss/invocation.c
+++ b/lib/ss/invocation.c
@@ -13,8 +13,8 @@
 
 int ss_create_invocation(subsystem_name, version_string, info_ptr,
 			 request_table_ptr, code_ptr)
-	char *subsystem_name, *version_string;
-	char *info_ptr;
+	const char *subsystem_name, *version_string;
+	void *info_ptr;
 	ss_request_table *request_table_ptr;
 	int *code_ptr;
 {
diff --git a/lib/ss/listen.c b/lib/ss/listen.c
index 765b757..aab8733 100644
--- a/lib/ss/listen.c
+++ b/lib/ss/listen.c
@@ -29,7 +29,7 @@
 static ss_data *current_info;
 static jmp_buf listen_jmpb;
 
-static sigret_t print_prompt()
+static sigret_t print_prompt(int sig)
 {
 #ifdef BSD
     /* put input into a reasonable mode */
@@ -45,19 +45,18 @@
     (void) fflush(stdout);
 }
 
-static sigret_t listen_int_handler()
+static sigret_t listen_int_handler(int sig)
 {
     putc('\n', stdout);
     signal(SIGINT, listen_int_handler);
     longjmp(listen_jmpb, 1);
 }
 
-int ss_listen (sci_idx)
-    int sci_idx;
+int ss_listen (int sci_idx)
 {
     char *cp;
     ss_data *info;
-    sigret_t (*sig_int)(), (*sig_cont)(), (*old_sig_cont)();
+    sigret_t (*sig_int)(int), (*sig_cont)(int), (*old_sig_cont)(int);
     char input[BUFSIZ];
     char buffer[BUFSIZ];
     char *end = buffer;
@@ -71,7 +70,7 @@
     ss_data *old_info = current_info;
     
     current_info = info = ss_info(sci_idx);
-    sig_cont = (sigret_t (*)()) 0;
+    sig_cont = (sigret_t (*)(int)) 0;
     info->abort = 0;
 #ifdef POSIX_SIGNALS
     sigemptyset(&igmask);
@@ -89,7 +88,7 @@
     (void) sigsetmask(mask);
 #endif
     while(!info->abort) {
-	print_prompt();
+	print_prompt(0);
 	*end = '\0';
 	old_sig_cont = sig_cont;
 	sig_cont = signal(SIGCONT, print_prompt);
@@ -133,20 +132,14 @@
     return code;
 }
 
-void ss_abort_subsystem(sci_idx, code)
-    int sci_idx;
-    int code;
+void ss_abort_subsystem(int sci_idx, int code)
 {
     ss_info(sci_idx)->abort = 1;
     ss_info(sci_idx)->exit_status = code;
     
 }
 
-int ss_quit(argc, argv, sci_idx, infop)
-    int argc;
-    char **argv;
-    int sci_idx;
-    pointer infop;
+void ss_quit(int argc, const char * const *argv, int sci_idx, pointer infop)
 {
     ss_abort_subsystem(sci_idx, 0);
 }
diff --git a/lib/ss/requests.c b/lib/ss/requests.c
index 9da9607..c214213 100644
--- a/lib/ss/requests.c
+++ b/lib/ss/requests.c
@@ -11,9 +11,11 @@
 #include "ss_internal.h"
 
 #ifdef __STDC__
-#define	DECLARE(name) void name(int argc,char **argv, int sci_idx)
+#define	DECLARE(name) void name(int argc,const char * const *argv, \
+				int sci_idx, void *infop)
 #else
-#define	DECLARE(name) void name(argc,argv,sci_idx)int argc,sci_idx;char **argv;
+#define	DECLARE(name) void name(argc,argv,sci_idx,info)int argc,sci_idx;char **argv;void *infop;
+
 #endif
 	
 /*
diff --git a/lib/ss/ss.h b/lib/ss/ss.h
index f992bd9..3b86f87 100644
--- a/lib/ss/ss.h
+++ b/lib/ss/ss.h
@@ -54,12 +54,22 @@
 char *ss_name(int sci_idx);
 void ss_error (int, long, char const *, ...);
 void ss_perror (int, long, char const *);
-int ss_create_invocation(char *, char *, char *, ss_request_table *, int *);
+int ss_create_invocation(const char *, const char *, void *,
+			 ss_request_table *, int *);
 void ss_delete_invocation(int);
 int ss_listen(int);
+int ss_execute_line(int, char *);
 void ss_add_request_table(int, ss_request_table *, int, int *);
 void ss_delete_request_table(int, ss_request_table *, int *);
 void ss_abort_subsystem(int sci_idx, int code);
+void ss_quit(int argc, const char * const *argv, int sci_idx, void *infop);
+void ss_self_identify(int argc, const char * const *argv, int sci_idx, void *infop);
+void ss_subsystem_name(int argc, const char * const *argv,
+		       int sci_idx, void *infop);
+void ss_subsystem_version(int argc, const char * const *argv,
+			  int sci_idx, void *infop);
+void ss_unimplemented(int argc, const char * const *argv,
+		      int sci_idx, void *infop);
 #else
 char *ss_name();
 void ss_error ();
@@ -67,9 +77,15 @@
 int ss_create_invocation();
 void ss_delete_invocation();
 int ss_listen();
+int ss_execute_line();
 void ss_add_request_table();
 void ss_delete_request_table();
 void ss_abort_subsystem();
+void ss_quit();
+void ss_self_identify();
+void ss_subsystem_name();
+void ss_subsystem_version();
+void ss_unimplemented();
 #endif
 extern ss_request_table ss_std_requests;
 #endif /* _ss_h */
diff --git a/lib/ss/ss_internal.h b/lib/ss/ss_internal.h
index 388a376..3bd5987 100644
--- a/lib/ss/ss_internal.h
+++ b/lib/ss/ss_internal.h
@@ -70,8 +70,8 @@
 
 typedef struct _ss_data {	/* init values */
     /* this subsystem */
-    char *subsystem_name;
-    char *subsystem_version;
+    const char *subsystem_name;
+    const char *subsystem_version;
     /* current request info */
     int argc;
     char **argv;		/* arg list */
diff --git a/lib/ss/test_ss.c b/lib/ss/test_ss.c
index aa4c7f3..3eddbab 100644
--- a/lib/ss/test_ss.c
+++ b/lib/ss/test_ss.c
@@ -9,8 +9,8 @@
  * $Locker$
  *
  * $Log$
- * Revision 1.7  1997/04/29 14:34:41  tytso
- * Checked in e2fsprogs 1.04.
+ * Revision 1.8  1997/04/29 14:52:31  tytso
+ * Checked in e2fsprogs 1.05
  *
  * Revision 1.1  1993/06/03  12:31:25  tytso
  * Initial revision
diff --git a/lib/substitute_sh.in b/lib/substitute_sh.in
index f3b1680..f80d4d9 100644
--- a/lib/substitute_sh.in
+++ b/lib/substitute_sh.in
@@ -9,6 +9,7 @@
 E2FSPROGS_MONTH=@E2FSPROGS_MONTH@
 E2FSPROGS_YEAR=@E2FSPROGS_YEAR@
 E2FSPROGS_VERSION=@E2FSPROGS_VERSION@
+SIZEOF_LONG_LONG=@SIZEOF_LONG_LONG@
 SIZEOF_LONG=@SIZEOF_LONG@
 SIZEOF_INT=@SIZEOF_INT@
 SIZEOF_SHORT=@SIZEOF_SHORT@
diff --git a/lib/uuid/ChangeLog b/lib/uuid/ChangeLog
new file mode 100644
index 0000000..8803ded
--- /dev/null
+++ b/lib/uuid/ChangeLog
@@ -0,0 +1,10 @@
+Tue Aug 27 16:50:43 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* uuid/gen_uuid.c [HAVE_NET_IF_H] <net/if.h>: Include guarded.
+	[HAVE_NETINET_IN_H] <netinet/in.h>: Include guarded.
+	(get_node_id): Surround bulk of function with #ifdef HAVE_NET_IF_H.
+
+Tue Aug 27 16:50:16 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* gen_uuid.c (get_node_id): Add a specific ifdef for the HURD,
+		since it is broken w.r.t getting hardware addresses.
diff --git a/lib/uuid/Makefile.in b/lib/uuid/Makefile.in
new file mode 100644
index 0000000..c226197
--- /dev/null
+++ b/lib/uuid/Makefile.in
@@ -0,0 +1,118 @@
+# Makefile for the second extended file system utility functions
+#
+# Copyright (C) 1993 Remy Card (card@masi.ibp.fr)
+#
+# This file can be redistributed under the terms of the GNU General
+# Public License
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+top_builddir = ../..
+my_dir = lib/uuid
+INSTALL = @INSTALL@
+
+@MCONFIG@
+
+all:: 
+
+OBJS=		clear.o \
+		compare.o \
+		copy.o \
+		gen_uuid.o \
+		isnull.o \
+		pack.o \
+		parse.o \
+		unpack.o \
+		unparse.o
+
+SRCS=		$(srcdir)/clear.c \
+		$(srcdir)/compare.c \
+		$(srcdir)/copy.c \
+		$(srcdir)/gen_uuid.c \
+		$(srcdir)/isnull.c \
+		$(srcdir)/pack.c \
+		$(srcdir)/parse.c \
+		$(srcdir)/unpack.c \
+		$(srcdir)/unparse.c
+
+LIBRARY= libuuid
+LIBDIR= uuid
+
+DLL_ADDRESS = 0x66980000
+DLL_JUMPSIZE = 0x1000
+DLL_GOTSIZE  = 0x1000
+DLL_VERSION = 1.0
+DLL_IMAGE = libuuid
+DLL_STUB = libuuid
+DLL_MYDIR = uuid
+DLL_INSTALL_DIR = $(libdir)
+
+ELF_VERSION = 1.0
+ELF_SO_VERSION = 1
+ELF_IMAGE = libuuid
+ELF_MYDIR = uuid
+ELF_INSTALL_DIR = $(libdir)
+
+BSDLIB_VERSION = 1.0
+BSDLIB_IMAGE = libuuid
+BSDLIB_MYDIR = uuid
+BSDLIB_INSTALL_DIR = $(libdir)
+
+@MAKEFILE_LIBRARY@
+@MAKEFILE_DLL@
+@MAKEFILE_ELF@
+@MAKEFILE_BSDLIB@
+@MAKEFILE_PROFILE@
+@MAKEFILE_CHECKER@
+
+.c.o:
+	$(CC) $(ALL_CFLAGS) -c $< -o $@
+@PROFILE_CMT@	$(CC) $(ALL_CFLAGS) -pg -o profiled/$*.o -c $<
+@CHECKER_CMT@	$(CC) $(ALL_CFLAGS) -checker -g -o checker/$*.o -c $<
+@DLL_CMT@	(export JUMP_DIR=`pwd`/jump; $(CC) -B$(JUMP_PREFIX) $(ALL_CFLAGS) \
+@DLL_CMT@		-o jump/$*.o -c $<)
+@ELF_CMT@	$(CC) $(ALL_CFLAGS) -fPIC -o elfshared/$*.o -c $<
+@BSDLIB_CMT@	$(CC) $(ALL_CFLAGS) -fpic -o pic/$*.o -c $<
+
+all:: tst_uuid
+
+tst_uuid: tst_uuid.o $(LIBUUID)
+	$(CC) $(ALL_LDFLAGS) -o tst_uuid tst_uuid.o $(LIBUUID)
+
+installdirs::
+	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(ulibdir)  \
+		$(DESTDIR)$(includedir)/uuid
+
+install:: all installdirs 
+	$(INSTALL_DATA) libuuid.a $(DESTDIR)$(ulibdir)/libuuid.a
+	$(CHMOD) 644 $(DESTDIR)$(ulibdir)/libuuid.a
+	-$(RANLIB) $(DESTDIR)$(ulibdir)/libuuid.a
+	$(CHMOD) $(LIBMODE) $(DESTDIR)$(ulibdir)/libuuid.a
+	$(INSTALL_DATA) $(srcdir)/uuid.h $(DESTDIR)$(includedir)/uuid/uuid.h
+
+uninstall::
+	$(RM) -f $(ulibdir)/libuuid.a
+
+clean::
+	$(RM) -f \#* *.s *.o *.a *~ *.bak core profiled/* checker/*
+	$(RM) -f ../libuuid.a ../libuuid_p.a tst_uuid
+
+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
+#
+clear.o: $(srcdir)/clear.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+compare.o: $(srcdir)/compare.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+copy.o: $(srcdir)/copy.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+gen_uuid.o: $(srcdir)/gen_uuid.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+isnull.o: $(srcdir)/isnull.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+pack.o: $(srcdir)/pack.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+parse.o: $(srcdir)/parse.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+unpack.o: $(srcdir)/unpack.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+unparse.o: $(srcdir)/unparse.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
diff --git a/lib/uuid/clear.c b/lib/uuid/clear.c
new file mode 100644
index 0000000..5127e01
--- /dev/null
+++ b/lib/uuid/clear.c
@@ -0,0 +1,11 @@
+/*
+ * clear.c -- Clear a UUID
+ */
+
+#include "uuidP.h"
+
+void uuid_clear(uuid_t uu)
+{
+	memset(uu, 0, 16);
+}
+
diff --git a/lib/uuid/compare.c b/lib/uuid/compare.c
new file mode 100644
index 0000000..44052c3
--- /dev/null
+++ b/lib/uuid/compare.c
@@ -0,0 +1,19 @@
+/*
+ * compare.c --- compare whether or not two UUID's are the same
+ *
+ * Returns 0 if the two UUID's are different, and 1 if they are the same.
+ */
+
+#include "uuidP.h"
+
+int uuid_compare(uuid_t uu1, uuid_t uu2)
+{
+	unsigned char 	*cp1, *cp2;
+	int		i;
+
+	for (i=0, cp1 = uu1, cp2 = uu2; i < 16; i++)
+		if (*cp1++ != *cp2++)
+			return 0;
+	return 1;
+}
+
diff --git a/lib/uuid/copy.c b/lib/uuid/copy.c
new file mode 100644
index 0000000..739e2dd
--- /dev/null
+++ b/lib/uuid/copy.c
@@ -0,0 +1,14 @@
+/*
+ * copy.c --- copy UUIDs
+ */
+
+#include "uuidP.h"
+
+void uuid_copy(uuid_t uu1, uuid_t uu2)
+{
+	unsigned char 	*cp1, *cp2;
+	int		i;
+
+	for (i=0, cp1 = uu1, cp2 = uu2; i < 16; i++)
+		*cp1++ = *cp2++;
+}
diff --git a/lib/uuid/gen_uuid.c b/lib/uuid/gen_uuid.c
new file mode 100644
index 0000000..8eaab4a
--- /dev/null
+++ b/lib/uuid/gen_uuid.c
@@ -0,0 +1,198 @@
+/*
+ * gen_uuid.c --- generate a DCE-compatible uuid
+ */
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "uuidP.h"
+
+#ifdef HAVE_SRANDOM
+#define srand(x) 	srandom(x)
+#define rand() 		random()
+#endif
+
+/*
+ * Generate a series of random bytes.  Use /dev/urandom if possible,
+ * and if not, use srandom/random.
+ */
+static void get_random_bytes(void *buf, int nbytes)
+{
+	static int fd = -2;
+	int i;
+	char *cp = (char *) buf;
+
+	if (fd == -2) {
+		fd = open("/dev/urandom", O_RDONLY);
+		srand((getpid() << 16) ^ getuid() ^ time(0));
+	}
+	if (fd > 0) {
+		i = read(fd, cp, nbytes);
+		if (i == nbytes)
+			return;
+		if (i > 0) {
+			nbytes -= i;
+			cp += i;
+		}
+	}
+	for (i=0; i < nbytes; i++)
+		*cp++ = rand() & 0xFF;
+}
+
+/*
+ * Get the ethernet hardware address, if we can find it...
+ */
+static int get_node_id(unsigned char *node_id)
+{
+#ifdef HAVE_NET_IF_H
+	int 		sd;
+	struct ifreq 	ifr, *ifrp;
+	struct ifconf 	ifc;
+	char buf[1024];
+	int		n, i;
+	unsigned char 	*a;
+	
+/*
+ * BSD 4.4 defines the size of an ifreq to be
+ * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
+ * However, under earlier systems, sa_len isn't present, so the size is 
+ * just sizeof(struct ifreq)
+ */
+#ifdef HAVE_SA_LEN
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#define ifreq_size(i) max(sizeof(struct ifreq),\
+     sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
+#else
+#define ifreq_size(i) sizeof(struct ifreq)
+#endif /* HAVE_SA_LEN*/
+
+	sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+	if (sd < 0) {
+		return -1;
+	}
+	memset(buf, 0, sizeof(buf));
+	ifc.ifc_len = sizeof(buf);
+	ifc.ifc_buf = buf;
+	if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
+		close(sd);
+		return -1;
+	}
+	n = ifc.ifc_len;
+	for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
+		ifrp = (struct ifreq *)((caddr_t) ifc.ifc_buf+i);
+		strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
+#ifdef SIOCGIFHWADDR
+		if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
+			continue;
+		a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
+#else
+#ifdef SIOCGENADDR
+		if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
+			continue;
+		a = (unsigned char *) ifr.ifr_enaddr;
+#else
+		/*
+		 * XXX we don't have a way of getting the hardware
+		 * address
+		 */
+		close(sd);
+		return 0;
+#endif /* SIOCGENADDR */
+#endif /* SIOCGIFHWADDR */
+		if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
+			continue;
+		if (node_id) {
+			memcpy(node_id, a, 6);
+			close(sd);
+			return 1;
+		}
+	}
+	close(sd);
+#endif
+	return 0;
+}
+
+/* Assume that the gettimeofday() has microsecond granularity */
+#define MAX_ADJUSTMENT 10
+
+static int get_clock(__u32 *clock_high, __u32 *clock_low, __u16 *ret_clock_seq)
+{
+	static int			adjustment = 0;
+	static struct timeval		last = {0, 0};
+	static __u16			clock_seq;
+	struct timeval 			tv;
+	unsigned long long		clock;
+	
+try_again:
+	gettimeofday(&tv, 0);
+	if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
+		get_random_bytes(&clock_seq, sizeof(clock_seq));
+		clock_seq &= 0x1FFF;
+		last = tv;
+		last.tv_sec--;
+	}
+	if ((tv.tv_sec < last.tv_sec) ||
+	    ((tv.tv_sec == last.tv_sec) &&
+	     (tv.tv_usec < last.tv_usec))) {
+		clock_seq = (clock_seq+1) & 0x1FFF;
+		adjustment = 0;
+	} else if ((tv.tv_sec == last.tv_sec) &&
+	    (tv.tv_usec == last.tv_usec)) {
+		if (adjustment >= MAX_ADJUSTMENT)
+			goto try_again;
+		adjustment++;
+	} else
+		adjustment = 0;
+	
+	clock = tv.tv_usec*10 + adjustment;
+	clock += ((unsigned long long) tv.tv_sec)*10000000;
+	clock += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
+
+	*clock_high = clock >> 32;
+	*clock_low = clock;
+	*ret_clock_seq = clock_seq;
+	return 0;
+}
+
+void uuid_generate(uuid_t out)
+{
+	static unsigned char node_id[6];
+	static int has_init = 0;
+	struct uuid uu;
+	__u32	clock_mid;
+
+	if (!has_init) {
+		if (get_node_id(node_id) <= 0)
+			get_random_bytes(node_id, 6);
+		has_init = 1;
+	}
+	get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
+	uu.clock_seq |= 0x8000;
+	uu.time_mid = (__u16) clock_mid;
+	uu.time_hi_and_version = (clock_mid >> 16) | 0x1000;
+	memcpy(uu.node, node_id, 6);
+	uuid_pack(&uu, out);
+}
diff --git a/lib/uuid/isnull.c b/lib/uuid/isnull.c
new file mode 100644
index 0000000..f72e8fb
--- /dev/null
+++ b/lib/uuid/isnull.c
@@ -0,0 +1,18 @@
+/*
+ * isnull.c --- Check whether or not the UUID is null
+ */
+
+#include "uuidP.h"
+
+/* Returns 1 if the uuid is the NULL uuid */
+int uuid_is_null(uuid_t uu)
+{
+	unsigned char 	*cp;
+	int		i;
+
+	for (i=0, cp = uu; i < 16; i++)
+		if (*cp++)
+			return 0;
+	return 1;
+}
+
diff --git a/lib/uuid/pack.c b/lib/uuid/pack.c
new file mode 100644
index 0000000..476b7a1
--- /dev/null
+++ b/lib/uuid/pack.c
@@ -0,0 +1,38 @@
+/*
+ * Internal routine for packing UUID's
+ */
+
+#include "uuidP.h"
+
+void uuid_pack(struct uuid *uu, uuid_t ptr)
+{
+	__u32	tmp;
+	unsigned char	*out = ptr;
+
+	tmp = uu->time_low;
+	out[3] = (unsigned char) tmp;
+	tmp >>= 8;
+	out[2] = (unsigned char) tmp;
+	tmp >>= 8;
+	out[1] = (unsigned char) tmp;
+	tmp >>= 8;
+	out[0] = (unsigned char) tmp;
+	
+	tmp = uu->time_mid;
+	out[5] = (unsigned char) tmp;
+	tmp >>= 8;
+	out[4] = (unsigned char) tmp;
+
+	tmp = uu->time_hi_and_version;
+	out[7] = (unsigned char) tmp;
+	tmp >>= 8;
+	out[6] = (unsigned char) tmp;
+
+	tmp = uu->clock_seq;
+	out[9] = (unsigned char) tmp;
+	tmp >>= 8;
+	out[8] = (unsigned char) tmp;
+
+	memcpy(out+10, uu->node, 6);
+}
+
diff --git a/lib/uuid/parse.c b/lib/uuid/parse.c
new file mode 100644
index 0000000..ce3f88d
--- /dev/null
+++ b/lib/uuid/parse.c
@@ -0,0 +1,42 @@
+/*
+ * parse.c --- UUID parsing
+ */
+
+#include <stdio.h>
+
+#include "uuidP.h"
+
+int uuid_parse(char *in, uuid_t uu)
+{
+	struct uuid uuid;
+	int i;
+	char *cp, buf[3];
+
+	if (strlen(in) != 36)
+		return -1;
+	for (i=0, cp = in; i <= 36; i++,cp++) {
+		if ((i == 8) || (i == 13) || (i == 18) ||
+		    (i == 23))
+			if (*cp == '-')
+				continue;
+		if (i== 36)
+			if (*cp == 0)
+				continue;
+		if (!isxdigit(*cp))
+			return -1;
+	}
+	uuid.time_low = strtoul(in, NULL, 16);
+	uuid.time_mid = strtoul(in+9, NULL, 16);
+	uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
+	uuid.clock_seq = strtoul(in+19, NULL, 16);
+	cp = in+24;
+	buf[2] = 0;
+	for (i=0; i < 6; i++) {
+		buf[0] = *cp++;
+		buf[1] = *cp++;
+		uuid.node[i] = strtoul(buf, NULL, 16);
+	}
+	
+	uuid_pack(&uuid, uu);
+	return 0;
+}
diff --git a/lib/uuid/tst_uuid.c b/lib/uuid/tst_uuid.c
new file mode 100644
index 0000000..068eea8
--- /dev/null
+++ b/lib/uuid/tst_uuid.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <linux/ext2_fs.h>
+
+#include "uuid.h"
+
+int
+main(int argc, char *argv)
+{
+	uuid_t		buf, tst;
+	char		str[100];
+	unsigned char	*cp;
+	int i;
+	int failed = 0;
+
+	uuid_generate(buf);
+	uuid_unparse(buf, str);
+	printf("UUID string = %s\n", str);
+	printf("UUID: ");
+	for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
+		printf("%02x", *cp++);
+	}
+	printf("\n");
+	uuid_parse(str, tst);
+	if (uuid_compare(buf, tst))
+		printf("UUID parse and compare succeeded.\n");
+	else {
+		printf("UUID parse and compare failed!\n");
+		failed++;
+	}
+	uuid_clear(tst);
+	if (uuid_is_null(tst))
+		printf("UUID clear and is null succeeded.\n");
+	else {
+		printf("UUID clear and is null failed!\n");
+		failed++;
+	}
+	uuid_copy(buf, tst);
+	if (uuid_compare(buf, tst))
+		printf("UUID copy and compare succeeded.\n");
+	else {
+		printf("UUID copy and compare failed!\n");
+		failed++;
+	}
+	if (failed) {
+		printf("%d failures.\n", failed);
+		exit(1);
+	}
+	return 0;
+}
+
+	
+
diff --git a/lib/uuid/unpack.c b/lib/uuid/unpack.c
new file mode 100644
index 0000000..406587d
--- /dev/null
+++ b/lib/uuid/unpack.c
@@ -0,0 +1,32 @@
+/*
+ * Internal routine for unpacking UUID
+ */
+
+#include "uuidP.h"
+
+void uuid_unpack(uuid_t in, struct uuid *uu)
+{
+	__u8	*ptr = in;
+	__u32	tmp;
+
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->time_low = tmp;
+
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->time_mid = tmp;
+	
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->time_hi_and_version = tmp;
+
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->clock_seq = tmp;
+
+	memcpy(uu->node, ptr, 6);
+}
+
diff --git a/lib/uuid/unparse.c b/lib/uuid/unparse.c
new file mode 100644
index 0000000..32f7995
--- /dev/null
+++ b/lib/uuid/unparse.c
@@ -0,0 +1,21 @@
+/*
+ * uuid_to_str.c -- convert a UUID to string
+ */
+
+#include <stdio.h>
+
+#include "uuidP.h"
+
+void uuid_unparse(uuid_t uu, char *out)
+{
+	struct uuid uuid;
+
+	uuid_unpack(uu, &uuid);
+	sprintf(out,
+		"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
+		uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
+		uuid.node[0], uuid.node[1], uuid.node[2],
+		uuid.node[3], uuid.node[4], uuid.node[5]);
+}
+
diff --git a/lib/uuid/uuid.h b/lib/uuid/uuid.h
new file mode 100644
index 0000000..9568c03
--- /dev/null
+++ b/lib/uuid/uuid.h
@@ -0,0 +1,29 @@
+/*
+ * Public include file for the UUID library
+ */
+
+typedef unsigned char uuid_t[16];
+
+/* clear.c */
+void uuid_clear(uuid_t uu);
+
+/* compare.c */
+int uuid_compare(uuid_t uu1, uuid_t uu2);
+
+/* copy.c */
+void uuid_copy(uuid_t uu1, uuid_t uu2);
+
+/* gen_uuid.c */
+void uuid_generate(uuid_t out);
+
+/* isnull.c */
+int uuid_is_null(uuid_t uu);
+
+/* parse.c */
+int uuid_parse(char *in, uuid_t uu);
+
+/* unparse.c */
+void uuid_unparse(uuid_t uu, char *out);
+
+
+
diff --git a/lib/uuid/uuidP.h b/lib/uuid/uuidP.h
new file mode 100644
index 0000000..0ef9261
--- /dev/null
+++ b/lib/uuid/uuidP.h
@@ -0,0 +1,33 @@
+/*
+ * uuid.h -- private header file for uuids
+ */
+
+#include <sys/types.h>
+#include <linux/types.h>
+
+#include "uuid.h"
+
+/*
+ * Offset between 15-Oct-1582 and 1-Jan-70
+ */
+#define TIME_OFFSET_HIGH 0x01B21DD2
+#define TIME_OFFSET_LOW  0x13814000
+
+struct uuid {
+	__u32	time_low;
+	__u16	time_mid;
+	__u16	time_hi_and_version;
+	__u16	clock_seq;
+	__u8	node[6];
+};
+
+
+/*
+ * prototypes
+ */
+void uuid_pack(struct uuid *uu, uuid_t ptr);
+void uuid_unpack(uuid_t in, struct uuid *uu);
+
+
+
+