Index: BOOK/final-system/sparc64-64-chapter.xml
===================================================================
--- BOOK/final-system/sparc64-64-chapter.xml	(revision cbe40efbabfe8a2b10c4d6fdf06a3d2733011487)
+++ BOOK/final-system/sparc64-64-chapter.xml	(revision 711fda6399a27324c9ead48533f16ba15b862cc1)
@@ -74,5 +74,5 @@
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="common/vim.xml"/>
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="sparc64/elftoaout.xml"/>
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="sparc/silo.xml"/>
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="sparc64-64/silo.xml"/>
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="common/aboutdebug.xml"/>
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="common/stripping.xml"/>
Index: BOOK/final-system/sparc64-64/silo.xml
===================================================================
--- BOOK/final-system/sparc64-64/silo.xml	(revision cbe40efbabfe8a2b10c4d6fdf06a3d2733011487)
+++ BOOK/final-system/sparc64-64/silo.xml	(revision 711fda6399a27324c9ead48533f16ba15b862cc1)
@@ -33,7 +33,7 @@
     xpointer="xpointer(//*[@os='b'])"/>
 
-    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
-    href="../sparc/silo.xml"
-    xpointer="xpointer(//*[@os='c'])"/>
+    <para os="c">Compile the Silo package:</para>
+
+<screen><userinput>make CC="gcc ${BUILD64}" LD="ld -m elf64_sparc"</userinput></screen>
 
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
@@ -45,11 +45,4 @@
     xpointer="xpointer(//*[@os='e'])"/>
 
-   <para os="f">Due to a compile issue with the current toolchains, we are going
-   to use the precompiled boot files. This is a temporary fix to the book, but
-   will give us a functional system. As soon as a fix is released, this section
-   will be removed. Here is how you install the precompiled files:</para>
-
-<screen os="g"><userinput>tar -xvf silo-loaders-&silo-version;.tar.gz -C /</userinput></screen>
-
   </sect2>
 
Index: BOOK/final-system/sparc64-chapter.xml
===================================================================
--- BOOK/final-system/sparc64-chapter.xml	(revision cbe40efbabfe8a2b10c4d6fdf06a3d2733011487)
+++ BOOK/final-system/sparc64-chapter.xml	(revision 711fda6399a27324c9ead48533f16ba15b862cc1)
@@ -99,5 +99,5 @@
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="multilib/vim.xml"/>
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="sparc64/elftoaout.xml"/>
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="sparc/silo.xml"/>
+  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="sparc64-64/silo.xml"/>
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="multilib/aboutdebug.xml"/>
   <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="multilib/stripping.xml"/>
Index: BOOK/general.ent
===================================================================
--- BOOK/general.ent	(revision cbe40efbabfe8a2b10c4d6fdf06a3d2733011487)
+++ BOOK/general.ent	(revision 711fda6399a27324c9ead48533f16ba15b862cc1)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 
-<!ENTITY month "08"> <!-- Use two digits -->
+<!ENTITY month "09"> <!-- Use two digits -->
 <!ENTITY month_name "August">
-<!ENTITY day "30"> <!-- Use two digits -->
+<!ENTITY day "01"> <!-- Use two digits -->
 <!ENTITY year "2012"> <!-- Use four digits -->
 
Index: BOOK/introduction/sparc/changelog.xml
===================================================================
--- BOOK/introduction/sparc/changelog.xml	(revision cbe40efbabfe8a2b10c4d6fdf06a3d2733011487)
+++ BOOK/introduction/sparc/changelog.xml	(revision 711fda6399a27324c9ead48533f16ba15b862cc1)
@@ -33,4 +33,12 @@
 
 -->
+    <listitem>
+      <para>01 September 2012</para>
+      <itemizedlist>
+        <listitem>
+          <para>[William Harrington] - Updated SILO 1.4.14 fixes patch.</para>
+        </listitem>
+      </itemizedlist>
+    </listitem>
 
     <listitem>
Index: BOOK/introduction/sparc64-64/changelog.xml
===================================================================
--- BOOK/introduction/sparc64-64/changelog.xml	(revision cbe40efbabfe8a2b10c4d6fdf06a3d2733011487)
+++ BOOK/introduction/sparc64-64/changelog.xml	(revision 711fda6399a27324c9ead48533f16ba15b862cc1)
@@ -33,5 +33,17 @@
 
 -->
-    <listitem>
+   <listitem>
+      <para>01 September 2012</para>
+      <itemizedlist>
+        <listitem>
+          <para>[William Harrington] - Updated SILO 1.4.14 fixes patch.</para>
+        </listitem>
+        <listitem>
+          <para>[William Harrington] - Update make command to build properly for 64 bit v9/ultrasparc.</para>
+        </listitem>
+      </itemizedlist>
+   </listitem>
+
+   <listitem>
       <para>30 August 2012</para>
       <itemizedlist>
Index: BOOK/introduction/sparc64/changelog.xml
===================================================================
--- BOOK/introduction/sparc64/changelog.xml	(revision cbe40efbabfe8a2b10c4d6fdf06a3d2733011487)
+++ BOOK/introduction/sparc64/changelog.xml	(revision 711fda6399a27324c9ead48533f16ba15b862cc1)
@@ -33,5 +33,17 @@
 
 -->
-    <listitem>
+   <listitem>
+      <para>01 September 2012</para>
+      <itemizedlist>
+        <listitem>
+          <para>[William Harrington] - Updated SILO 1.4.14 fixes patch.</para>
+        </listitem>
+        <listitem>
+          <para>[William Harrington] - Update make command to build properly for 64 bit v9/ultrasparc.</para>
+        </listitem>
+      </itemizedlist>
+   </listitem>
+
+   <listitem>
       <para>26 August 2012</para>
       <itemizedlist>
Index: BOOK/patches.ent
===================================================================
--- BOOK/patches.ent	(revision cbe40efbabfe8a2b10c4d6fdf06a3d2733011487)
+++ BOOK/patches.ent	(revision 711fda6399a27324c9ead48533f16ba15b862cc1)
@@ -170,5 +170,5 @@
 <!ENTITY elftoaout-fixes-patch-size "6 KB">
 
-<!ENTITY silo-fixes-patch "silo-&silo-version;-fixes-2.patch">
-<!ENTITY silo-fixes-patch-md5 "b4ad6f61614df6ed7d17f086a5319134">
-<!ENTITY silo-fixes-patch-size "700 KB">
+<!ENTITY silo-fixes-patch "silo-&silo-version;-fixes-3.patch">
+<!ENTITY silo-fixes-patch-md5 "9a98957c90089be65f6cc72fcf40faa4">
+<!ENTITY silo-fixes-patch-size "32 KB">
Index: tches/silo-1.4.14-fixes-2.patch
===================================================================
--- patches/silo-1.4.14-fixes-2.patch	(revision cbe40efbabfe8a2b10c4d6fdf06a3d2733011487)
+++ 	(revision )
@@ -1,25415 +1,0 @@
-Submitted By: Joe Ciccone <jciccone@gmail.com>
-Date: 2009-01-07
-Initial Package Version: 1.4.14
-Upstream Status: Unknown
-Origin: Rocklinux, Jim Gifford, Joe Ciccone, and Blue Square Linux
-Description: Fixes cross-compilation issues and silo no longer links to
-        libext2fs.so, it is integrated instead. Also allows silo to build
-        and work properly on pure64 systems. Now works with 2.6.25.x
-        kernel headers. Updated to work with newer libc headers.
-
-        Rediffed for 1.4.14
-
-diff -Naur silo-1.4.14.orig/Makefile silo-1.4.14/Makefile
---- silo-1.4.14.orig/Makefile	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/Makefile	2011-01-10 21:59:35.398906853 -0500
-@@ -3,7 +3,7 @@
- 
- # These only get built on Linux
- ifeq ($(OPSYS),Linux)
--  SUBDIRS  = common first second first-isofs tilo
-+  SUBDIRS  = common first libext2fs second first-isofs tilo
-   MANPAGES = maketilo.1 tilo.1
- endif
- 
-diff -Naur silo-1.4.14.orig/Rules.make silo-1.4.14/Rules.make
---- silo-1.4.14.orig/Rules.make	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/Rules.make	2011-01-10 21:59:35.398906853 -0500
-@@ -2,12 +2,14 @@
- IMGVERSION=0.99
- SHELL=/bin/bash
- RM=rm -f
--# We want to force 32-bit builds
--CC=gcc -m32
--LD=ld -m elf32_sparc
--AS=as
--STRIP=strip
--NM=nm
-+CC=$(CROSS_COMPILE)gcc
-+CC-SILO=$(CC) -m32 -Wa,-32 -I../include/emul_32
-+BUILD_CC=gcc
-+LD=$(CROSS_COMPILE)ld -m elf32_sparc
-+AS=$(CROSS_COMPILE)as
-+STRIP=$(CROSS_COMPILE)strip
-+NM=$(CROSS_COMPILE)nm
-+
- ELFTOAOUT=elftoaout
- BIN2H=../common/bin2h
- 
-diff -Naur silo-1.4.14.orig/common/Makefile silo-1.4.14/common/Makefile
---- silo-1.4.14.orig/common/Makefile	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/common/Makefile	2011-01-10 21:59:35.398906853 -0500
-@@ -5,19 +5,22 @@
- include ../Rules.make
- 
- .c.o:
--	$(CC) $(CFLAGS) -c $*.c
-+	$(CC-SILO) $(CFLAGS) -c $*.c
- 
- .S.o:
--	$(CC) $(CFLAGS) -c $*.S
-+	$(CC-SILO) $(CFLAGS) -c $*.S
- 
- OBJS = sdiv.o rem.o udiv.o urem.o jmp.o printf.o console.o prom.o tree.o stringops2.o\
- 	stringops1.o ffs.o divdi3.o udivdi3.o
--PROGRAMS = bin2h
- 
--all: $(OBJS) $(PROGRAMS)
-+bin2h:
-+	$(BUILD_CC) $(CFLAGS) -o bin2h bin2h.c
-+
-+all: $(OBJS) bin2h
- 
- prom.o: prom.c
--	$(CC) $(CFLAGS) -c -Wa,-Av9 -o prom.o prom.c
-+	$(CC-SILO) $(CFLAGS) -c -Wa,-Av9 -o prom.o prom.c
- 
- clean:
--	$(RM) $(PROGRAMS) *.o
-+	$(RM) bin2h *.o
-+
-diff -Naur silo-1.4.14.orig/first/Makefile silo-1.4.14/first/Makefile
---- silo-1.4.14.orig/first/Makefile	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/first/Makefile	2011-01-10 21:59:35.398906853 -0500
-@@ -1,4 +1,4 @@
--##
-+#
- ## Linux Loader for SPARC
- ##
- #
-@@ -13,7 +13,7 @@
- LDFLAGS=-N -Ttext 0x4000
- 
- .S.o:
--	$(CC) $(CFLAGS) -c $*.S
-+	$(CC-SILO) $(CFLAGS) -c $*.S
- 
- all: first.b first.h ultra.b ultra.h generic.b generic.h fd.b ieee32.b
- 
-@@ -33,7 +33,7 @@
- 	sed -n 's/^\(000000000000\|0000\)4\([0-9a-f][0-9a-f][0-9a-f]\) .*letter_here.*$$/#define FD_LETTER_OFFSET_TMP 0x\2/p' < fd.map >> fd.h
- 
- first.o: first.S
--	$(CC) $(CFLAGS) -c first.S -o first.o
-+	$(CC-SILO) $(CFLAGS) -c first.S -o first.o
- 
- first: first.o
- 	$(LD) $(LDFLAGS) -o first first.o
-@@ -46,7 +46,7 @@
- 	$(DD) if=/dev/zero of=first.b bs=4 count=1 seek=127
- 
- ultra.o: ultra.S
--	$(CC) $(CFLAGS) -c -Wa,-Av9a ultra.S
-+	$(CC-SILO) $(CFLAGS) -c -Wa,-Av9a ultra.S
- 
- ultra: ultra.o
- 	$(LD) $(LDFLAGS) -o ultra ultra.o
-@@ -56,11 +56,11 @@
- ultra.b: ultra
- 	$(ELFTOAOUT) -o ultra.b ultra
- 	printf 'SILO'$(IMGVERSION) | $(DD) of=ultra.b bs=8 conv=notrunc seek=3 count=1
--	printf '\340' | $(DD) of=ultra.b bs=1 count=1 seek=7 conv=notrunc
-+	printf '\0340' | $(DD) of=ultra.b bs=1 count=1 seek=7 conv=notrunc
- 	$(DD) if=/dev/zero of=ultra.b bs=4 count=1 seek=127
- 
- generic.o: generic.S
--	$(CC) $(CFLAGS) -c -Wa,-Av9a generic.S
-+	$(CC-SILO) $(CFLAGS) -c -Wa,-Av9a generic.S
- 
- generic: generic.o
- 	$(LD) $(LDFLAGS) -o generic generic.o
-@@ -70,11 +70,11 @@
- generic.b: generic
- 	$(ELFTOAOUT) -o generic.b generic
- 	printf 'SILO'$(IMGVERSION) | $(DD) of=generic.b bs=8 conv=notrunc seek=3 count=1
--	printf '\340' | $(DD) of=generic.b bs=1 count=1 seek=7 conv=notrunc
-+	printf '\0340' | $(DD) of=generic.b bs=1 count=1 seek=7 conv=notrunc
- 	$(DD) if=/dev/zero of=generic.b bs=4 count=1 seek=255
- 
- fd.o: fd.S
--	$(CC) $(CFLAGS) -c -Wa,-Av9a fd.S
-+	$(CC-SILO) $(CFLAGS) -c -Wa,-Av9a fd.S
- 
- fd: fd.o
- 	$(LD) $(LDFLAGS) -o fd fd.o
-@@ -84,11 +84,11 @@
- fd.b: fd
- 	$(ELFTOAOUT) -o fd.b fd
- 	printf 'SILO'$(IMGVERSION) | $(DD) of=fd.b bs=8 conv=notrunc seek=3 count=1
--	printf '\340' | $(DD) of=fd.b bs=1 count=1 seek=7 conv=notrunc
-+	printf '\0340' | $(DD) of=fd.b bs=1 count=1 seek=7 conv=notrunc
- 	$(DD) if=/dev/zero of=fd.b bs=4 count=1 seek=255
- 
- ieee32.o: ieee32.S ieee32.h
--	$(CC) $(CFLAGS) -DIMGVERSION='"SILO$(IMGVERSION)"' -c ieee32.S
-+	$(CC-SILO) $(CFLAGS) -DIMGVERSION='"SILO$(IMGVERSION)"' -c ieee32.S
- 
- ieee32.b: ieee32.o
- 	$(LD) $(LDFLAGS) -o ieee32.b ieee32.o
-diff -Naur silo-1.4.14.orig/first-isofs/Makefile silo-1.4.14/first-isofs/Makefile
---- silo-1.4.14.orig/first-isofs/Makefile	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/first-isofs/Makefile	2011-01-10 21:59:35.398906853 -0500
-@@ -11,10 +11,10 @@
- all: $(NAME).b
- 
- .c.o:
--	$(CC) $(CFLAGS) -c $*.c
-+	$(CC-SILO) $(CFLAGS) -c $*.c
- 
- .S.o:
--	$(CC) $(CFLAGS) -c $*.S
-+	$(CC-SILO) $(CFLAGS) -c $*.S
- 
- OBJS_COMMON = ../common/prom.o ../common/console.o ../common/tree.o
- OBJS = crt0.o $(NAME).o $(OBJS_COMMON)
-@@ -28,7 +28,7 @@
- 	cat $<.aout >> $@
- 
- crt0.o:	crt0.S
--	$(CC) $(CFLAGS) -c -Wa,-Av9 -o $@ $<
-+	$(CC-SILO) $(CFLAGS) -c -Wa,-Av9 -o $@ $<
- 
- clean:
- 	$(RM) *.o $(NAME) $(NAME).b $(NAME).aout
-diff -Naur silo-1.4.14.orig/include/asm/page.h silo-1.4.14/include/asm/page.h
---- silo-1.4.14.orig/include/asm/page.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/include/asm/page.h	2011-01-10 21:59:35.398906853 -0500
-@@ -0,0 +1,15 @@
-+/* File autogenerated by 'make headers_install' */
-+#ifndef __ASM_STUB_PAGE_H
-+#define __ASM_STUB_PAGE_H
-+# if defined __sparc__ && defined __arch64__
-+#ifndef _SPARC_PAGE_H
-+#define _SPARC_PAGE_H
-+#endif 
-+# elif defined __sparc__ && !defined __arch64__
-+#ifndef _SPARC64_PAGE_H
-+#define _SPARC64_PAGE_H
-+#endif
-+# else
-+#  warning This machine appears to be neither sparc64 nor sparc.
-+# endif
-+#endif /* __ASM_STUB_PAGE_H */
-diff -Naur silo-1.4.14.orig/include/emul_32/asm/elf.h silo-1.4.14/include/emul_32/asm/elf.h
---- silo-1.4.14.orig/include/emul_32/asm/elf.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/include/emul_32/asm/elf.h	2011-01-10 21:59:35.398906853 -0500
-@@ -0,0 +1,162 @@
-+#ifndef __ASMSPARC_ELF_H
-+#define __ASMSPARC_ELF_H
-+
-+/*
-+ * ELF register definitions..
-+ */
-+
-+
-+/*
-+ * Sparc section types
-+ */
-+#define STT_REGISTER		13
-+
-+/*
-+ * Sparc ELF relocation types
-+ */
-+#define	R_SPARC_NONE		0
-+#define	R_SPARC_8		1
-+#define	R_SPARC_16		2
-+#define	R_SPARC_32		3
-+#define	R_SPARC_DISP8		4
-+#define	R_SPARC_DISP16		5
-+#define	R_SPARC_DISP32		6
-+#define	R_SPARC_WDISP30		7
-+#define	R_SPARC_WDISP22		8
-+#define	R_SPARC_HI22		9
-+#define	R_SPARC_22		10
-+#define	R_SPARC_13		11
-+#define	R_SPARC_LO10		12
-+#define	R_SPARC_GOT10		13
-+#define	R_SPARC_GOT13		14
-+#define	R_SPARC_GOT22		15
-+#define	R_SPARC_PC10		16
-+#define	R_SPARC_PC22		17
-+#define	R_SPARC_WPLT30		18
-+#define	R_SPARC_COPY		19
-+#define	R_SPARC_GLOB_DAT	20
-+#define	R_SPARC_JMP_SLOT	21
-+#define	R_SPARC_RELATIVE	22
-+#define	R_SPARC_UA32		23
-+#define R_SPARC_PLT32		24
-+#define R_SPARC_HIPLT22		25
-+#define R_SPARC_LOPLT10		26
-+#define R_SPARC_PCPLT32		27
-+#define R_SPARC_PCPLT22		28
-+#define R_SPARC_PCPLT10		29
-+#define R_SPARC_10		30
-+#define R_SPARC_11		31
-+#define R_SPARC_64		32
-+#define R_SPARC_OLO10		33
-+#define R_SPARC_WDISP16		40
-+#define R_SPARC_WDISP19		41
-+#define R_SPARC_7		43
-+#define R_SPARC_5		44
-+#define R_SPARC_6		45
-+
-+/* Bits present in AT_HWCAP, primarily for Sparc32.  */
-+
-+#define HWCAP_SPARC_FLUSH       1    /* CPU supports flush instruction. */
-+#define HWCAP_SPARC_STBAR       2
-+#define HWCAP_SPARC_SWAP        4
-+#define HWCAP_SPARC_MULDIV      8
-+#define HWCAP_SPARC_V9		16
-+#define HWCAP_SPARC_ULTRA3	32
-+
-+/* For the most part we present code dumps in the format
-+ * Solaris does.
-+ */
-+typedef unsigned long elf_greg_t;
-+#define ELF_NGREG 38
-+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-+
-+/* Format is:
-+ * 	G0 --> G7
-+ *	O0 --> O7
-+ *	L0 --> L7
-+ *	I0 --> I7
-+ *	PSR, PC, nPC, Y, WIM, TBR
-+ */
-+#define ELF_CORE_COPY_REGS(__elf_regs, __pt_regs)	\
-+do {	unsigned long *dest = &(__elf_regs[0]);		\
-+	struct pt_regs *src = (__pt_regs);		\
-+	unsigned long *sp;				\
-+	memcpy(&dest[0], &src->u_regs[0],		\
-+	       sizeof(unsigned long) * 16);		\
-+	/* Don't try this at home kids... */		\
-+	sp = (unsigned long *) src->u_regs[14];		\
-+	copy_from_user(&dest[16], sp,			\
-+		       sizeof(unsigned long) * 16);	\
-+	dest[32] = src->psr;				\
-+	dest[33] = src->pc;				\
-+	dest[34] = src->npc;				\
-+	dest[35] = src->y;				\
-+	dest[36] = dest[37] = 0; /* XXX */		\
-+} while(0); /* Janitors: Don't touch this colon. */
-+
-+typedef struct {
-+	union {
-+		unsigned long	pr_regs[32];
-+		double		pr_dregs[16];
-+	} pr_fr;
-+	unsigned long __unused;
-+	unsigned long	pr_fsr;
-+	unsigned char	pr_qcnt;
-+	unsigned char	pr_q_entrysize;
-+	unsigned char	pr_en;
-+	unsigned int	pr_q[64];
-+} elf_fpregset_t;
-+
-+#define ELF_CORE_COPY_TASK_REGS(__tsk, __elf_regs)	\
-+	({ ELF_CORE_COPY_REGS((*(__elf_regs)), (__tsk)->thread.kregs); 1; })
-+
-+/*
-+ * This is used to ensure we don't load something for the wrong architecture.
-+ */
-+#define elf_check_arch(x) ((x)->e_machine == EM_SPARC)
-+
-+/*
-+ * These are used to set parameters in the core dumps.
-+ */
-+#define ELF_ARCH	EM_SPARC
-+#define ELF_CLASS	ELFCLASS32
-+#define ELF_DATA	ELFDATA2MSB
-+
-+#define USE_ELF_CORE_DUMP
-+#ifndef CONFIG_SUN4
-+#define ELF_EXEC_PAGESIZE	4096
-+#else
-+#define ELF_EXEC_PAGESIZE	8192
-+#endif
-+
-+
-+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
-+   use of this is to invoke "./ld.so someprog" to test out a new version of
-+   the loader.  We need to make sure that it is out of the way of the program
-+   that it will "exec", and that there is sufficient room for the brk.  */
-+
-+#define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
-+
-+/* This yields a mask that user programs can use to figure out what
-+   instruction set this cpu supports.  This can NOT be done in userspace
-+   on Sparc.  */
-+
-+/* Sun4c has none of the capabilities, most sun4m's have them all.
-+ * XXX This is gross, set some global variable at boot time. -DaveM
-+ */
-+#define ELF_HWCAP	((ARCH_SUN4C_SUN4) ? 0 : \
-+			 (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \
-+			  HWCAP_SPARC_SWAP | \
-+			  ((srmmu_modtype != Cypress && \
-+			    srmmu_modtype != Cypress_vE && \
-+			    srmmu_modtype != Cypress_vD) ? \
-+			   HWCAP_SPARC_MULDIV : 0)))
-+
-+/* This yields a string that ld.so will use to load implementation
-+   specific libraries for optimization.  This is more specific in
-+   intent than poking at uname or /proc/cpuinfo. */
-+
-+#define ELF_PLATFORM	(NULL)
-+
-+
-+#endif /* !(__ASMSPARC_ELF_H) */
-diff -Naur silo-1.4.14.orig/include/emul_32/asm/posix_types.h silo-1.4.14/include/emul_32/asm/posix_types.h
---- silo-1.4.14.orig/include/emul_32/asm/posix_types.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/include/emul_32/asm/posix_types.h	2011-01-10 21:59:35.398906853 -0500
-@@ -0,0 +1,122 @@
-+#ifndef __ARCH_SPARC_POSIX_TYPES_H
-+#define __ARCH_SPARC_POSIX_TYPES_H
-+
-+/*
-+ * This file is generally used by user-level software, so you need to
-+ * be a little careful about namespace pollution etc.  Also, we cannot
-+ * assume GCC is being used.
-+ */
-+
-+typedef unsigned int           __kernel_size_t;
-+typedef int                    __kernel_ssize_t;
-+typedef long int               __kernel_ptrdiff_t;
-+typedef long                   __kernel_time_t;
-+typedef long		       __kernel_suseconds_t;
-+typedef long                   __kernel_clock_t;
-+typedef int                    __kernel_pid_t;
-+typedef unsigned short         __kernel_ipc_pid_t;
-+typedef unsigned short         __kernel_uid_t;
-+typedef unsigned short         __kernel_gid_t;
-+typedef unsigned long          __kernel_ino_t;
-+typedef unsigned short         __kernel_mode_t;
-+typedef unsigned short         __kernel_umode_t;
-+typedef short                  __kernel_nlink_t;
-+typedef long                   __kernel_daddr_t;
-+typedef long                   __kernel_off_t;
-+typedef char *                 __kernel_caddr_t;
-+typedef unsigned short	       __kernel_uid16_t;
-+typedef unsigned short	       __kernel_gid16_t;
-+typedef unsigned int	       __kernel_uid32_t;
-+typedef unsigned int	       __kernel_gid32_t;
-+typedef unsigned short	       __kernel_old_uid_t;
-+typedef unsigned short	       __kernel_old_gid_t;
-+typedef unsigned short	       __kernel_old_dev_t;
-+typedef int                    __kernel_clockid_t;
-+typedef int                    __kernel_timer_t;
-+
-+#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || (__STDC_VERSION__ >= 199901L)
-+typedef long long	__kernel_loff_t;
-+#endif
-+
-+typedef struct {
-+#if defined(__KERNEL__) || defined(__USE_ALL)
-+	int	val[2];
-+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-+	int     __val[2];
-+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-+} __kernel_fsid_t;
-+
-+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-+
-+#undef __FD_SET
-+static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-+{
-+	unsigned long _tmp = fd / __NFDBITS;
-+	unsigned long _rem = fd % __NFDBITS;
-+	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-+}
-+
-+#undef __FD_CLR
-+static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-+{
-+	unsigned long _tmp = fd / __NFDBITS;
-+	unsigned long _rem = fd % __NFDBITS;
-+	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-+}
-+
-+#undef __FD_ISSET
-+static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
-+{ 
-+	unsigned long _tmp = fd / __NFDBITS;
-+	unsigned long _rem = fd % __NFDBITS;
-+	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-+}
-+
-+/*
-+ * This will unroll the loop for the normal constant cases (8 or 32 longs,
-+ * for 256 and 1024-bit fd_sets respectively)
-+ */
-+#undef __FD_ZERO
-+static __inline__ void __FD_ZERO(__kernel_fd_set *p)
-+{
-+	unsigned long *tmp = p->fds_bits;
-+	int i;
-+
-+	if (__builtin_constant_p(__FDSET_LONGS)) {
-+		switch (__FDSET_LONGS) {
-+			case 32:
-+			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-+			  tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-+			  tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-+			  tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-+			  tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0;
-+			  tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0;
-+			  tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0;
-+			  tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0;
-+			  return;
-+			case 16:
-+			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-+			  tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-+			  tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-+			  tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-+			  return;
-+			case 8:
-+			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-+			  tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-+			  return;
-+			case 4:
-+			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-+			  return;
-+		}
-+	}
-+	i = __FDSET_LONGS;
-+	while (i) {
-+		i--;
-+		*tmp = 0;
-+		tmp++;
-+	}
-+}
-+
-+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
-+
-+#endif /* !(__ARCH_SPARC_POSIX_TYPES_H) */
-diff -Naur silo-1.4.14.orig/include/emul_32/asm/types.h silo-1.4.14/include/emul_32/asm/types.h
---- silo-1.4.14.orig/include/emul_32/asm/types.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/include/emul_32/asm/types.h	2011-01-10 21:59:35.398906853 -0500
-@@ -0,0 +1,41 @@
-+#ifndef _SPARC_TYPES_H
-+#define _SPARC_TYPES_H
-+
-+/*
-+ * _xx is ok: it doesn't pollute the POSIX namespace. Use these in the
-+ * header files exported to user space.
-+ */
-+
-+/*
-+ * This file is never included by application software unless
-+ * explicitly requested (e.g., via linux/types.h) in which case the
-+ * application is Linux specific so (user-) name space pollution is
-+ * not a major issue.  However, for interoperability, libraries still
-+ * need to be careful to avoid a name clashes.
-+ */
-+
-+#ifndef __ASSEMBLY__
-+
-+typedef unsigned short umode_t;
-+
-+typedef __signed__ char __s8;
-+typedef unsigned char __u8;
-+
-+typedef __signed__ short __s16;
-+typedef unsigned short __u16;
-+
-+typedef __signed__ int __s32;
-+typedef unsigned int __u32;
-+
-+#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || (__STDC_VERSION__ >= 199901L)
-+typedef __signed__ long long __s64;
-+typedef unsigned long long __u64;
-+#endif
-+
-+#if (defined(__STRICT_ANSI__) && !defined(inline))
-+#define inline __inline__
-+#endif
-+
-+#endif /* __ASSEMBLY__ */
-+
-+#endif /* defined(_SPARC_TYPES_H) */
-diff -Naur silo-1.4.14.orig/include/ext2fs/ext2_err.h silo-1.4.14/include/ext2fs/ext2_err.h
---- silo-1.4.14.orig/include/ext2fs/ext2_err.h	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/include/ext2fs/ext2_err.h	2011-01-10 21:59:35.398906853 -0500
-@@ -3,6 +3,8 @@
-  * This file is automatically generated; please do not edit it.
-  */
- 
-+#include <et/com_err.h>
-+
- #define EXT2_ET_BASE                             (2133571328L)
- #define EXT2_ET_MAGIC_EXT2FS_FILSYS              (2133571329L)
- #define EXT2_ET_MAGIC_BADBLOCKS_LIST             (2133571330L)
-@@ -19,8 +21,8 @@
- #define EXT2_ET_MAGIC_ICOUNT                     (2133571341L)
- #define EXT2_ET_MAGIC_PQ_IO_CHANNEL              (2133571342L)
- #define EXT2_ET_MAGIC_EXT2_FILE                  (2133571343L)
--#define EXT2_ET_MAGIC_RESERVED_7                 (2133571344L)
--#define EXT2_ET_MAGIC_RESERVED_8                 (2133571345L)
-+#define EXT2_ET_MAGIC_E2IMAGE                    (2133571344L)
-+#define EXT2_ET_MAGIC_INODE_IO_CHANNEL           (2133571345L)
- #define EXT2_ET_MAGIC_RESERVED_9                 (2133571346L)
- #define EXT2_ET_BAD_MAGIC                        (2133571347L)
- #define EXT2_ET_REV_TOO_HIGH                     (2133571348L)
-@@ -86,7 +88,25 @@
- #define EXT2_ET_UNIMPLEMENTED                    (2133571408L)
- #define EXT2_ET_CANCEL_REQUESTED                 (2133571409L)
- #define EXT2_ET_FILE_TOO_BIG                     (2133571410L)
-+#define EXT2_ET_JOURNAL_NOT_BLOCK                (2133571411L)
-+#define EXT2_ET_NO_JOURNAL_SB                    (2133571412L)
-+#define EXT2_ET_JOURNAL_TOO_SMALL                (2133571413L)
-+#define EXT2_ET_JOURNAL_UNSUPP_VERSION           (2133571414L)
-+#define EXT2_ET_LOAD_EXT_JOURNAL                 (2133571415L)
-+#define EXT2_ET_NO_JOURNAL                       (2133571416L)
-+#define EXT2_ET_DIRHASH_UNSUPP                   (2133571417L)
-+#define EXT2_ET_BAD_EA_BLOCK_NUM                 (2133571418L)
-+#define EXT2_ET_TOO_MANY_INODES                  (2133571419L)
-+#define EXT2_ET_NOT_IMAGE_FILE                   (2133571420L)
-+#define EXT2_ET_RES_GDT_BLOCKS                   (2133571421L)
-+#define EXT2_ET_RESIZE_INODE_CORRUPT             (2133571422L)
-+#define EXT2_ET_SET_BMAP_NO_IND                  (2133571423L)
-+extern const struct error_table et_ext2_error_table;
- extern void initialize_ext2_error_table(void);
-+
-+/* For compatibility with Heimdal */
-+extern void initialize_ext2_error_table_r(struct et_list **list);
-+
- #define ERROR_TABLE_BASE_ext2 (2133571328L)
- 
- /* for compatibility with older versions... */
-diff -Naur silo-1.4.14.orig/include/ext2fs/ext2_io.h silo-1.4.14/include/ext2fs/ext2_io.h
---- silo-1.4.14.orig/include/ext2fs/ext2_io.h	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/include/ext2fs/ext2_io.h	2011-01-10 21:59:35.398906853 -0500
-@@ -27,6 +27,8 @@
- typedef struct struct_io_manager *io_manager;
- typedef struct struct_io_channel *io_channel;
- 
-+#define CHANNEL_FLAGS_WRITETHROUGH	0x01
-+
- struct struct_io_channel {
- 	errcode_t	magic;
- 	io_manager	manager;
-@@ -47,7 +49,8 @@
- 				       int actual_bytes_written,
- 				       errcode_t error);
- 	int		refcount;
--	int		reserved[15];
-+	int		flags;
-+	int		reserved[14];
- 	void		*private_data;
- 	void		*app_data;
- };
-@@ -63,7 +66,11 @@
- 	errcode_t (*write_blk)(io_channel channel, unsigned long block,
- 			       int count, const void *data);
- 	errcode_t (*flush)(io_channel channel);
--	int		reserved[16];
-+	errcode_t (*write_byte)(io_channel channel, unsigned long offset,
-+				int count, const void *data);
-+	errcode_t (*set_option)(io_channel channel, const char *option, 
-+				const char *arg);
-+	int		reserved[14];
- };
- 
- #define IO_FLAG_RW	1
-@@ -78,6 +85,13 @@
- #define io_channel_flush(c) 		((c)->manager->flush((c)))
- #define io_channel_bumpcount(c)		((c)->refcount++)
- 	
-+/* io_manager.c */
-+extern errcode_t io_channel_set_options(io_channel channel, 
-+					const char *options);
-+extern errcode_t io_channel_write_byte(io_channel channel, 
-+				       unsigned long offset,
-+				       int count, const void *data);
-+
- /* unix_io.c */
- extern io_manager unix_io_manager;
- 
-diff -Naur silo-1.4.14.orig/include/linux/ufs_fs.h silo-1.4.14/include/linux/ufs_fs.h
---- silo-1.4.14.orig/include/linux/ufs_fs.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/include/linux/ufs_fs.h	2011-01-10 21:59:35.403016722 -0500
-@@ -0,0 +1,953 @@
-+/*
-+ *  linux/include/linux/ufs_fs.h
-+ *
-+ * Copyright (C) 1996
-+ * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
-+ * Laboratory for Computer Science Research Computing Facility
-+ * Rutgers, The State University of New Jersey
-+ *
-+ * Clean swab support by Fare <fare@tunes.org>
-+ * just hope no one is using NNUUXXI on __?64 structure elements
-+ * 64-bit clean thanks to Maciej W. Rozycki <macro@ds2.pg.gda.pl>
-+ *
-+ * 4.4BSD (FreeBSD) support added on February 1st 1998 by
-+ * Niels Kristian Bech Jensen <nkbj@image.dk> partially based
-+ * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>.
-+ *
-+ * NeXTstep support added on February 5th 1998 by
-+ * Niels Kristian Bech Jensen <nkbj@image.dk>.
-+ *
-+ * Write support by Daniel Pirkl <daniel.pirkl@email.cz>
-+ *
-+ * HP/UX hfs filesystem support added by
-+ * Martin K. Petersen <mkp@mkp.net>, August 1999
-+ *
-+ * UFS2 (of FreeBSD 5.x) support added by
-+ * Niraj Kumar <niraj17@iitbombay.org>  , Jan 2004
-+ *
-+ */
-+
-+#ifndef __LINUX_UFS_FS_H
-+#define __LINUX_UFS_FS_H
-+
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/stat.h>
-+#include <linux/fs.h>
-+
-+#ifndef __KERNEL__
-+typedef __u64 __fs64;
-+typedef __u32 __fs32;
-+typedef __u16 __fs16;
-+#else
-+#include <asm/div64.h>
-+typedef __u64 __bitwise __fs64;
-+typedef __u32 __bitwise __fs32;
-+typedef __u16 __bitwise __fs16;
-+#endif
-+
-+#define UFS_BBLOCK 0
-+#define UFS_BBSIZE 8192
-+#define UFS_SBLOCK 8192
-+#define UFS_SBSIZE 8192
-+
-+#define UFS_SECTOR_SIZE 512
-+#define UFS_SECTOR_BITS 9
-+#define UFS_MAGIC  0x00011954
-+#define UFS2_MAGIC 0x19540119
-+#define UFS_CIGAM  0x54190100 /* byteswapped MAGIC */
-+
-+/* Copied from FreeBSD */
-+/*
-+ * Each disk drive contains some number of filesystems.
-+ * A filesystem consists of a number of cylinder groups.
-+ * Each cylinder group has inodes and data.
-+ *
-+ * A filesystem is described by its super-block, which in turn
-+ * describes the cylinder groups.  The super-block is critical
-+ * data and is replicated in each cylinder group to protect against
-+ * catastrophic loss.  This is done at `newfs' time and the critical
-+ * super-block data does not change, so the copies need not be
-+ * referenced further unless disaster strikes.
-+ *
-+ * For filesystem fs, the offsets of the various blocks of interest
-+ * are given in the super block as:
-+ *      [fs->fs_sblkno]         Super-block
-+ *      [fs->fs_cblkno]         Cylinder group block
-+ *      [fs->fs_iblkno]         Inode blocks
-+ *      [fs->fs_dblkno]         Data blocks
-+ * The beginning of cylinder group cg in fs, is given by
-+ * the ``cgbase(fs, cg)'' macro.
-+ *
-+ * Depending on the architecture and the media, the superblock may
-+ * reside in any one of four places. For tiny media where every block
-+ * counts, it is placed at the very front of the partition. Historically,
-+ * UFS1 placed it 8K from the front to leave room for the disk label and
-+ * a small bootstrap. For UFS2 it got moved to 64K from the front to leave
-+ * room for the disk label and a bigger bootstrap, and for really piggy
-+ * systems we check at 256K from the front if the first three fail. In
-+ * all cases the size of the superblock will be SBLOCKSIZE. All values are
-+ * given in byte-offset form, so they do not imply a sector size. The
-+ * SBLOCKSEARCH specifies the order in which the locations should be searched.
-+ */
-+#define SBLOCK_FLOPPY        0
-+#define SBLOCK_UFS1       8192
-+#define SBLOCK_UFS2      65536
-+#define SBLOCK_PIGGY    262144
-+#define SBLOCKSIZE        8192
-+#define SBLOCKSEARCH \
-+        { SBLOCK_UFS2, SBLOCK_UFS1, SBLOCK_FLOPPY, SBLOCK_PIGGY, -1 }
-+
-+
-+/* HP specific MAGIC values */
-+
-+#define UFS_MAGIC_LFN   0x00095014 /* fs supports filenames > 14 chars */
-+#define UFS_CIGAM_LFN   0x14500900 /* srahc 41 < semanelif stroppus sf */
-+
-+#define UFS_MAGIC_SEC   0x00612195 /* B1 security fs */
-+#define UFS_CIGAM_SEC   0x95216100
-+
-+#define UFS_MAGIC_FEA   0x00195612 /* fs_featurebits supported */
-+#define UFS_CIGAM_FEA   0x12561900
-+
-+#define UFS_MAGIC_4GB   0x05231994 /* fs > 4 GB && fs_featurebits */
-+#define UFS_CIGAM_4GB   0x94192305
-+
-+/* Seems somebody at HP goofed here. B1 and lfs are both 0x2 !?! */
-+#define UFS_FSF_LFN     0x00000001 /* long file names */
-+#define UFS_FSF_B1      0x00000002 /* B1 security */
-+#define UFS_FSF_LFS     0x00000002 /* large files */
-+#define UFS_FSF_LUID    0x00000004 /* large UIDs */
-+
-+/* End of HP stuff */
-+
-+
-+#define UFS_BSIZE	8192
-+#define UFS_MINBSIZE	4096
-+#define UFS_FSIZE	1024
-+#define UFS_MAXFRAG	(UFS_BSIZE / UFS_FSIZE)
-+
-+#define UFS_NDADDR 12
-+#define UFS_NINDIR 3
-+
-+#define UFS_IND_BLOCK	(UFS_NDADDR + 0)
-+#define UFS_DIND_BLOCK	(UFS_NDADDR + 1)
-+#define UFS_TIND_BLOCK	(UFS_NDADDR + 2)
-+
-+#define UFS_NDIR_FRAGMENT (UFS_NDADDR << uspi->s_fpbshift)
-+#define UFS_IND_FRAGMENT (UFS_IND_BLOCK << uspi->s_fpbshift)
-+#define UFS_DIND_FRAGMENT (UFS_DIND_BLOCK << uspi->s_fpbshift)
-+#define UFS_TIND_FRAGMENT (UFS_TIND_BLOCK << uspi->s_fpbshift)
-+
-+#define UFS_ROOTINO 2
-+#define UFS_FIRST_INO (UFS_ROOTINO + 1)
-+
-+#define UFS_USEEFT  ((__u16)65535)
-+
-+#define UFS_FSOK      0x7c269d38
-+#define UFS_FSACTIVE  ((__s8)0x00)
-+#define UFS_FSCLEAN   ((__s8)0x01)
-+#define UFS_FSSTABLE  ((__s8)0x02)
-+#define UFS_FSOSF1    ((__s8)0x03)	/* is this correct for DEC OSF/1? */
-+#define UFS_FSBAD     ((__s8)0xff)
-+
-+/* From here to next blank line, s_flags for ufs_sb_info */
-+/* directory entry encoding */
-+#define UFS_DE_MASK		0x00000010	/* mask for the following */
-+#define UFS_DE_OLD		0x00000000
-+#define UFS_DE_44BSD		0x00000010
-+/* uid encoding */
-+#define UFS_UID_MASK		0x00000060	/* mask for the following */
-+#define UFS_UID_OLD		0x00000000
-+#define UFS_UID_44BSD		0x00000020
-+#define UFS_UID_EFT		0x00000040
-+/* superblock state encoding */
-+#define UFS_ST_MASK		0x00000700	/* mask for the following */
-+#define UFS_ST_OLD		0x00000000
-+#define UFS_ST_44BSD		0x00000100
-+#define UFS_ST_SUN		0x00000200 /* Solaris */
-+#define UFS_ST_SUNOS		0x00000300
-+#define UFS_ST_SUNx86		0x00000400 /* Solaris x86 */
-+/*cylinder group encoding */
-+#define UFS_CG_MASK		0x00003000	/* mask for the following */
-+#define UFS_CG_OLD		0x00000000
-+#define UFS_CG_44BSD		0x00002000
-+#define UFS_CG_SUN		0x00001000
-+/* filesystem type encoding */
-+#define UFS_TYPE_MASK		0x00010000	/* mask for the following */
-+#define UFS_TYPE_UFS1		0x00000000
-+#define UFS_TYPE_UFS2		0x00010000
-+
-+
-+/* fs_inodefmt options */
-+#define UFS_42INODEFMT	-1
-+#define UFS_44INODEFMT	2
-+
-+/*
-+ * MINFREE gives the minimum acceptable percentage of file system
-+ * blocks which may be free. If the freelist drops below this level
-+ * only the superuser may continue to allocate blocks. This may
-+ * be set to 0 if no reserve of free blocks is deemed necessary,
-+ * however throughput drops by fifty percent if the file system
-+ * is run at between 95% and 100% full; thus the minimum default
-+ * value of fs_minfree is 5%. However, to get good clustering
-+ * performance, 10% is a better choice. hence we use 10% as our
-+ * default value. With 10% free space, fragmentation is not a
-+ * problem, so we choose to optimize for time.
-+ */
-+#define UFS_MINFREE         5
-+#define UFS_DEFAULTOPT      UFS_OPTTIME
-+            
-+/*
-+ * Turn file system block numbers into disk block addresses.
-+ * This maps file system blocks to device size blocks.
-+ */
-+#define ufs_fsbtodb(uspi, b)	((b) << (uspi)->s_fsbtodb)
-+#define	ufs_dbtofsb(uspi, b)	((b) >> (uspi)->s_fsbtodb)
-+
-+/*
-+ * Cylinder group macros to locate things in cylinder groups.
-+ * They calc file system addresses of cylinder group data structures.
-+ */
-+#define	ufs_cgbase(c)	(uspi->s_fpg * (c))
-+#define ufs_cgstart(c)	((uspi)->fs_magic == UFS2_MAGIC ?  ufs_cgbase(c) : \
-+	(ufs_cgbase(c)  + uspi->s_cgoffset * ((c) & ~uspi->s_cgmask)))
-+#define	ufs_cgsblock(c)	(ufs_cgstart(c) + uspi->s_sblkno)	/* super blk */
-+#define	ufs_cgcmin(c)	(ufs_cgstart(c) + uspi->s_cblkno)	/* cg block */
-+#define	ufs_cgimin(c)	(ufs_cgstart(c) + uspi->s_iblkno)	/* inode blk */
-+#define	ufs_cgdmin(c)	(ufs_cgstart(c) + uspi->s_dblkno)	/* 1st data */
-+
-+/*
-+ * Macros for handling inode numbers:
-+ *     inode number to file system block offset.
-+ *     inode number to cylinder group number.
-+ *     inode number to file system block address.
-+ */
-+#define	ufs_inotocg(x)		((x) / uspi->s_ipg)
-+#define	ufs_inotocgoff(x)	((x) % uspi->s_ipg)
-+#define	ufs_inotofsba(x)	(((u64)ufs_cgimin(ufs_inotocg(x))) + ufs_inotocgoff(x) / uspi->s_inopf)
-+#define	ufs_inotofsbo(x)	((x) % uspi->s_inopf)
-+
-+/*
-+ * Compute the cylinder and rotational position of a cyl block addr.
-+ */
-+#define ufs_cbtocylno(bno) \
-+	((bno) * uspi->s_nspf / uspi->s_spc)
-+#define ufs_cbtorpos(bno) \
-+	((((bno) * uspi->s_nspf % uspi->s_spc / uspi->s_nsect \
-+	* uspi->s_trackskew + (bno) * uspi->s_nspf % uspi->s_spc \
-+	% uspi->s_nsect * uspi->s_interleave) % uspi->s_nsect \
-+	* uspi->s_nrpos) / uspi->s_npsect)
-+
-+/*
-+ * The following macros optimize certain frequently calculated
-+ * quantities by using shifts and masks in place of divisions
-+ * modulos and multiplications.
-+ */
-+#define ufs_blkoff(loc)		((loc) & uspi->s_qbmask)
-+#define ufs_fragoff(loc)	((loc) & uspi->s_qfmask)
-+#define ufs_lblktosize(blk)	((blk) << uspi->s_bshift)
-+#define ufs_lblkno(loc)		((loc) >> uspi->s_bshift)
-+#define ufs_numfrags(loc)	((loc) >> uspi->s_fshift)
-+#define ufs_blkroundup(size)	(((size) + uspi->s_qbmask) & uspi->s_bmask)
-+#define ufs_fragroundup(size)	(((size) + uspi->s_qfmask) & uspi->s_fmask)
-+#define ufs_fragstoblks(frags)	((frags) >> uspi->s_fpbshift)
-+#define ufs_blkstofrags(blks)	((blks) << uspi->s_fpbshift)
-+#define ufs_fragnum(fsb)	((fsb) & uspi->s_fpbmask)
-+#define ufs_blknum(fsb)		((fsb) & ~uspi->s_fpbmask)
-+
-+#define	UFS_MAXNAMLEN 255
-+#define UFS_MAXMNTLEN 512
-+#define UFS2_MAXMNTLEN 468
-+#define UFS2_MAXVOLLEN 32
-+#define UFS_MAXCSBUFS 31
-+#define UFS_LINK_MAX 32000
-+/*
-+#define	UFS2_NOCSPTRS	((128 / sizeof(void *)) - 4)
-+*/
-+#define	UFS2_NOCSPTRS	28
-+
-+/*
-+ * UFS_DIR_PAD defines the directory entries boundaries
-+ * (must be a multiple of 4)
-+ */
-+#define UFS_DIR_PAD			4
-+#define UFS_DIR_ROUND			(UFS_DIR_PAD - 1)
-+#define UFS_DIR_REC_LEN(name_len)	(((name_len) + 1 + 8 + UFS_DIR_ROUND) & ~UFS_DIR_ROUND)
-+
-+struct ufs_timeval {
-+	__fs32	tv_sec;
-+	__fs32	tv_usec;
-+};
-+
-+struct ufs_dir_entry {
-+	__fs32  d_ino;			/* inode number of this entry */
-+	__fs16  d_reclen;		/* length of this entry */
-+	union {
-+		__fs16	d_namlen;		/* actual length of d_name */
-+		struct {
-+			__u8	d_type;		/* file type */
-+			__u8	d_namlen;	/* length of string in d_name */
-+		} d_44;
-+	} d_u;
-+	__u8	d_name[UFS_MAXNAMLEN + 1];	/* file name */
-+};
-+
-+struct ufs_csum {
-+	__fs32	cs_ndir;	/* number of directories */
-+	__fs32	cs_nbfree;	/* number of free blocks */
-+	__fs32	cs_nifree;	/* number of free inodes */
-+	__fs32	cs_nffree;	/* number of free frags */
-+};
-+struct ufs2_csum_total {
-+	__fs64	cs_ndir;	/* number of directories */
-+	__fs64	cs_nbfree;	/* number of free blocks */
-+	__fs64	cs_nifree;	/* number of free inodes */
-+	__fs64	cs_nffree;	/* number of free frags */
-+	__fs64   cs_numclusters;	/* number of free clusters */
-+	__fs64   cs_spare[3];	/* future expansion */
-+};
-+
-+struct ufs_csum_core {
-+	__u64	cs_ndir;	/* number of directories */
-+	__u64	cs_nbfree;	/* number of free blocks */
-+	__u64	cs_nifree;	/* number of free inodes */
-+	__u64	cs_nffree;	/* number of free frags */
-+	__u64   cs_numclusters;	/* number of free clusters */
-+};
-+
-+/*
-+ * File system flags
-+ */
-+#define UFS_UNCLEAN      0x01    /* file system not clean at mount (unused) */
-+#define UFS_DOSOFTDEP    0x02    /* file system using soft dependencies */
-+#define UFS_NEEDSFSCK    0x04    /* needs sync fsck (FreeBSD compat, unused) */
-+#define UFS_INDEXDIRS    0x08    /* kernel supports indexed directories */
-+#define UFS_ACLS         0x10    /* file system has ACLs enabled */
-+#define UFS_MULTILABEL   0x20    /* file system is MAC multi-label */
-+#define UFS_FLAGS_UPDATED 0x80   /* flags have been moved to new location */
-+
-+#if 0
-+/*
-+ * This is the actual superblock, as it is laid out on the disk.
-+ * Do NOT use this structure, because of sizeof(ufs_super_block) > 512 and
-+ * it may occupy several blocks, use
-+ * struct ufs_super_block_(first,second,third) instead.
-+ */
-+struct ufs_super_block {
-+	union {
-+		struct {
-+			__fs32	fs_link;	/* UNUSED */
-+		} fs_42;
-+		struct {
-+			__fs32	fs_state;	/* file system state flag */
-+		} fs_sun;
-+	} fs_u0;
-+	__fs32	fs_rlink;	/* UNUSED */
-+	__fs32	fs_sblkno;	/* addr of super-block in filesys */
-+	__fs32	fs_cblkno;	/* offset of cyl-block in filesys */
-+	__fs32	fs_iblkno;	/* offset of inode-blocks in filesys */
-+	__fs32	fs_dblkno;	/* offset of first data after cg */
-+	__fs32	fs_cgoffset;	/* cylinder group offset in cylinder */
-+	__fs32	fs_cgmask;	/* used to calc mod fs_ntrak */
-+	__fs32	fs_time;	/* last time written -- time_t */
-+	__fs32	fs_size;	/* number of blocks in fs */
-+	__fs32	fs_dsize;	/* number of data blocks in fs */
-+	__fs32	fs_ncg;		/* number of cylinder groups */
-+	__fs32	fs_bsize;	/* size of basic blocks in fs */
-+	__fs32	fs_fsize;	/* size of frag blocks in fs */
-+	__fs32	fs_frag;	/* number of frags in a block in fs */
-+/* these are configuration parameters */
-+	__fs32	fs_minfree;	/* minimum percentage of free blocks */
-+	__fs32	fs_rotdelay;	/* num of ms for optimal next block */
-+	__fs32	fs_rps;		/* disk revolutions per second */
-+/* these fields can be computed from the others */
-+	__fs32	fs_bmask;	/* ``blkoff'' calc of blk offsets */
-+	__fs32	fs_fmask;	/* ``fragoff'' calc of frag offsets */
-+	__fs32	fs_bshift;	/* ``lblkno'' calc of logical blkno */
-+	__fs32	fs_fshift;	/* ``numfrags'' calc number of frags */
-+/* these are configuration parameters */
-+	__fs32	fs_maxcontig;	/* max number of contiguous blks */
-+	__fs32	fs_maxbpg;	/* max number of blks per cyl group */
-+/* these fields can be computed from the others */
-+	__fs32	fs_fragshift;	/* block to frag shift */
-+	__fs32	fs_fsbtodb;	/* fsbtodb and dbtofsb shift constant */
-+	__fs32	fs_sbsize;	/* actual size of super block */
-+	__fs32	fs_csmask;	/* csum block offset */
-+	__fs32	fs_csshift;	/* csum block number */
-+	__fs32	fs_nindir;	/* value of NINDIR */
-+	__fs32	fs_inopb;	/* value of INOPB */
-+	__fs32	fs_nspf;	/* value of NSPF */
-+/* yet another configuration parameter */
-+	__fs32	fs_optim;	/* optimization preference, see below */
-+/* these fields are derived from the hardware */
-+	union {
-+		struct {
-+			__fs32	fs_npsect;	/* # sectors/track including spares */
-+		} fs_sun;
-+		struct {
-+			__fs32	fs_state;	/* file system state time stamp */
-+		} fs_sunx86;
-+	} fs_u1;
-+	__fs32	fs_interleave;	/* hardware sector interleave */
-+	__fs32	fs_trackskew;	/* sector 0 skew, per track */
-+/* a unique id for this filesystem (currently unused and unmaintained) */
-+/* In 4.3 Tahoe this space is used by fs_headswitch and fs_trkseek */
-+/* Neither of those fields is used in the Tahoe code right now but */
-+/* there could be problems if they are.                            */
-+	__fs32	fs_id[2];	/* file system id */
-+/* sizes determined by number of cylinder groups and their sizes */
-+	__fs32	fs_csaddr;	/* blk addr of cyl grp summary area */
-+	__fs32	fs_cssize;	/* size of cyl grp summary area */
-+	__fs32	fs_cgsize;	/* cylinder group size */
-+/* these fields are derived from the hardware */
-+	__fs32	fs_ntrak;	/* tracks per cylinder */
-+	__fs32	fs_nsect;	/* sectors per track */
-+	__fs32	fs_spc;		/* sectors per cylinder */
-+/* this comes from the disk driver partitioning */
-+	__fs32	fs_ncyl;	/* cylinders in file system */
-+/* these fields can be computed from the others */
-+	__fs32	fs_cpg;		/* cylinders per group */
-+	__fs32	fs_ipg;		/* inodes per cylinder group */
-+	__fs32	fs_fpg;		/* blocks per group * fs_frag */
-+/* this data must be re-computed after crashes */
-+	struct ufs_csum fs_cstotal;	/* cylinder summary information */
-+/* these fields are cleared at mount time */
-+	__s8	fs_fmod;	/* super block modified flag */
-+	__s8	fs_clean;	/* file system is clean flag */
-+	__s8	fs_ronly;	/* mounted read-only flag */
-+	__s8	fs_flags;
-+	union {
-+		struct {
-+			__s8	fs_fsmnt[UFS_MAXMNTLEN];/* name mounted on */
-+			__fs32	fs_cgrotor;	/* last cg searched */
-+			__fs32	fs_csp[UFS_MAXCSBUFS];/*list of fs_cs info buffers */
-+			__fs32	fs_maxcluster;
-+			__fs32	fs_cpc;		/* cyl per cycle in postbl */
-+			__fs16	fs_opostbl[16][8]; /* old rotation block list head */
-+		} fs_u1;
-+		struct {
-+			__s8  fs_fsmnt[UFS2_MAXMNTLEN];	/* name mounted on */
-+			__u8   fs_volname[UFS2_MAXVOLLEN]; /* volume name */
-+			__fs64  fs_swuid;		/* system-wide uid */
-+			__fs32  fs_pad;	/* due to alignment of fs_swuid */
-+			__fs32   fs_cgrotor;     /* last cg searched */
-+			__fs32   fs_ocsp[UFS2_NOCSPTRS]; /*list of fs_cs info buffers */
-+			__fs32   fs_contigdirs;/*# of contiguously allocated dirs */
-+			__fs32   fs_csp;	/* cg summary info buffer for fs_cs */
-+			__fs32   fs_maxcluster;
-+			__fs32   fs_active;/* used by snapshots to track fs */
-+			__fs32   fs_old_cpc;	/* cyl per cycle in postbl */
-+			__fs32   fs_maxbsize;/*maximum blocking factor permitted */
-+			__fs64   fs_sparecon64[17];/*old rotation block list head */
-+			__fs64   fs_sblockloc; /* byte offset of standard superblock */
-+			struct  ufs2_csum_total fs_cstotal;/*cylinder summary information*/
-+			struct  ufs_timeval    fs_time;		/* last time written */
-+			__fs64    fs_size;		/* number of blocks in fs */
-+			__fs64    fs_dsize;	/* number of data blocks in fs */
-+			__fs64   fs_csaddr;	/* blk addr of cyl grp summary area */
-+			__fs64    fs_pendingblocks;/* blocks in process of being freed */
-+			__fs32    fs_pendinginodes;/*inodes in process of being freed */
-+		} fs_u2;
-+	}  fs_u11;
-+	union {
-+		struct {
-+			__fs32	fs_sparecon[53];/* reserved for future constants */
-+			__fs32	fs_reclaim;
-+			__fs32	fs_sparecon2[1];
-+			__fs32	fs_state;	/* file system state time stamp */
-+			__fs32	fs_qbmask[2];	/* ~usb_bmask */
-+			__fs32	fs_qfmask[2];	/* ~usb_fmask */
-+		} fs_sun;
-+		struct {
-+			__fs32	fs_sparecon[53];/* reserved for future constants */
-+			__fs32	fs_reclaim;
-+			__fs32	fs_sparecon2[1];
-+			__fs32	fs_npsect;	/* # sectors/track including spares */
-+			__fs32	fs_qbmask[2];	/* ~usb_bmask */
-+			__fs32	fs_qfmask[2];	/* ~usb_fmask */
-+		} fs_sunx86;
-+		struct {
-+			__fs32	fs_sparecon[50];/* reserved for future constants */
-+			__fs32	fs_contigsumsize;/* size of cluster summary array */
-+			__fs32	fs_maxsymlinklen;/* max length of an internal symlink */
-+			__fs32	fs_inodefmt;	/* format of on-disk inodes */
-+			__fs32	fs_maxfilesize[2];	/* max representable file size */
-+			__fs32	fs_qbmask[2];	/* ~usb_bmask */
-+			__fs32	fs_qfmask[2];	/* ~usb_fmask */
-+			__fs32	fs_state;	/* file system state time stamp */
-+		} fs_44;
-+	} fs_u2;
-+	__fs32	fs_postblformat;	/* format of positional layout tables */
-+	__fs32	fs_nrpos;		/* number of rotational positions */
-+	__fs32	fs_postbloff;		/* (__s16) rotation block list head */
-+	__fs32	fs_rotbloff;		/* (__u8) blocks for each rotation */
-+	__fs32	fs_magic;		/* magic number */
-+	__u8	fs_space[1];		/* list of blocks for each rotation */
-+};
-+#endif/*struct ufs_super_block*/
-+
-+/*
-+ * Preference for optimization.
-+ */
-+#define UFS_OPTTIME	0	/* minimize allocation time */
-+#define UFS_OPTSPACE	1	/* minimize disk fragmentation */
-+
-+/*
-+ * Rotational layout table format types
-+ */
-+#define UFS_42POSTBLFMT		-1	/* 4.2BSD rotational table format */
-+#define UFS_DYNAMICPOSTBLFMT	1	/* dynamic rotational table format */
-+
-+/*
-+ * Convert cylinder group to base address of its global summary info.
-+ */
-+#define fs_cs(indx) s_csp[(indx)]
-+
-+/*
-+ * Cylinder group block for a file system.
-+ *
-+ * Writable fields in the cylinder group are protected by the associated
-+ * super block lock fs->fs_lock.
-+ */
-+#define	CG_MAGIC	0x090255
-+#define ufs_cg_chkmagic(sb, ucg) \
-+	(fs32_to_cpu((sb), (ucg)->cg_magic) == CG_MAGIC)
-+/*
-+ * Macros for access to old cylinder group array structures
-+ */
-+#define ufs_ocg_blktot(sb, ucg)      fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_btot)
-+#define ufs_ocg_blks(sb, ucg, cylno) fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_b[cylno])
-+#define ufs_ocg_inosused(sb, ucg)    fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_iused)
-+#define ufs_ocg_blksfree(sb, ucg)    fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_free)
-+#define ufs_ocg_chkmagic(sb, ucg) \
-+	(fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_magic) == CG_MAGIC)
-+
-+/*
-+ * size of this structure is 172 B
-+ */
-+struct	ufs_cylinder_group {
-+	__fs32	cg_link;		/* linked list of cyl groups */
-+	__fs32	cg_magic;		/* magic number */
-+	__fs32	cg_time;		/* time last written */
-+	__fs32	cg_cgx;			/* we are the cgx'th cylinder group */
-+	__fs16	cg_ncyl;		/* number of cyl's this cg */
-+	__fs16	cg_niblk;		/* number of inode blocks this cg */
-+	__fs32	cg_ndblk;		/* number of data blocks this cg */
-+	struct	ufs_csum cg_cs;		/* cylinder summary information */
-+	__fs32	cg_rotor;		/* position of last used block */
-+	__fs32	cg_frotor;		/* position of last used frag */
-+	__fs32	cg_irotor;		/* position of last used inode */
-+	__fs32	cg_frsum[UFS_MAXFRAG];	/* counts of available frags */
-+	__fs32	cg_btotoff;		/* (__u32) block totals per cylinder */
-+	__fs32	cg_boff;		/* (short) free block positions */
-+	__fs32	cg_iusedoff;		/* (char) used inode map */
-+	__fs32	cg_freeoff;		/* (u_char) free block map */
-+	__fs32	cg_nextfreeoff;		/* (u_char) next available space */
-+	union {
-+		struct {
-+			__fs32	cg_clustersumoff;	/* (u_int32) counts of avail clusters */
-+			__fs32	cg_clusteroff;		/* (u_int8) free cluster map */
-+			__fs32	cg_nclusterblks;	/* number of clusters this cg */
-+			__fs32	cg_sparecon[13];	/* reserved for future use */
-+		} cg_44;
-+		struct {
-+			__fs32	cg_clustersumoff;/* (u_int32) counts of avail clusters */
-+			__fs32	cg_clusteroff;	/* (u_int8) free cluster map */
-+			__fs32	cg_nclusterblks;/* number of clusters this cg */
-+			__fs32   cg_niblk; /* number of inode blocks this cg */
-+			__fs32   cg_initediblk;	/* last initialized inode */
-+			__fs32   cg_sparecon32[3];/* reserved for future use */
-+			__fs64   cg_time;	/* time last written */
-+			__fs64	cg_sparecon[3];	/* reserved for future use */
-+		} cg_u2;
-+		__fs32	cg_sparecon[16];	/* reserved for future use */
-+	} cg_u;
-+	__u8	cg_space[1];		/* space for cylinder group maps */
-+/* actually longer */
-+};
-+
-+/* Historic Cylinder group info */
-+struct ufs_old_cylinder_group {
-+	__fs32	cg_link;		/* linked list of cyl groups */
-+	__fs32	cg_rlink;		/* for incore cyl groups     */
-+	__fs32	cg_time;		/* time last written */
-+	__fs32	cg_cgx;			/* we are the cgx'th cylinder group */
-+	__fs16	cg_ncyl;		/* number of cyl's this cg */
-+	__fs16	cg_niblk;		/* number of inode blocks this cg */
-+	__fs32	cg_ndblk;		/* number of data blocks this cg */
-+	struct	ufs_csum cg_cs;		/* cylinder summary information */
-+	__fs32	cg_rotor;		/* position of last used block */
-+	__fs32	cg_frotor;		/* position of last used frag */
-+	__fs32	cg_irotor;		/* position of last used inode */
-+	__fs32	cg_frsum[8];		/* counts of available frags */
-+	__fs32	cg_btot[32];		/* block totals per cylinder */
-+	__fs16	cg_b[32][8];		/* positions of free blocks */
-+	__u8	cg_iused[256];		/* used inode map */
-+	__fs32	cg_magic;		/* magic number */
-+	__u8	cg_free[1];		/* free block map */
-+/* actually longer */
-+};
-+
-+/*
-+ * structure of an on-disk inode
-+ */
-+struct ufs_inode {
-+	__fs16	ui_mode;		/*  0x0 */
-+	__fs16	ui_nlink;		/*  0x2 */
-+	union {
-+		struct {
-+			__fs16	ui_suid;	/*  0x4 */
-+			__fs16	ui_sgid;	/*  0x6 */
-+		} oldids;
-+		__fs32	ui_inumber;		/*  0x4 lsf: inode number */
-+		__fs32	ui_author;		/*  0x4 GNU HURD: author */
-+	} ui_u1;
-+	__fs64	ui_size;		/*  0x8 */
-+	struct ufs_timeval ui_atime;	/* 0x10 access */
-+	struct ufs_timeval ui_mtime;	/* 0x18 modification */
-+	struct ufs_timeval ui_ctime;	/* 0x20 creation */
-+	union {
-+		struct {
-+			__fs32	ui_db[UFS_NDADDR];/* 0x28 data blocks */
-+			__fs32	ui_ib[UFS_NINDIR];/* 0x58 indirect blocks */
-+		} ui_addr;
-+		__u8	ui_symlink[4*(UFS_NDADDR+UFS_NINDIR)];/* 0x28 fast symlink */
-+	} ui_u2;
-+	__fs32	ui_flags;		/* 0x64 immutable, append-only... */
-+	__fs32	ui_blocks;		/* 0x68 blocks in use */
-+	__fs32	ui_gen;			/* 0x6c like ext2 i_version, for NFS support */
-+	union {
-+		struct {
-+			__fs32	ui_shadow;	/* 0x70 shadow inode with security data */
-+			__fs32	ui_uid;		/* 0x74 long EFT version of uid */
-+			__fs32	ui_gid;		/* 0x78 long EFT version of gid */
-+			__fs32	ui_oeftflag;	/* 0x7c reserved */
-+		} ui_sun;
-+		struct {
-+			__fs32	ui_uid;		/* 0x70 File owner */
-+			__fs32	ui_gid;		/* 0x74 File group */
-+			__fs32	ui_spare[2];	/* 0x78 reserved */
-+		} ui_44;
-+		struct {
-+			__fs32	ui_uid;		/* 0x70 */
-+			__fs32	ui_gid;		/* 0x74 */
-+			__fs16	ui_modeh;	/* 0x78 mode high bits */
-+			__fs16	ui_spare;	/* 0x7A unused */
-+			__fs32	ui_trans;	/* 0x7c filesystem translator */
-+		} ui_hurd;
-+	} ui_u3;
-+};
-+
-+#define UFS_NXADDR  2            /* External addresses in inode. */
-+struct ufs2_inode {
-+	__fs16     ui_mode;        /*   0: IFMT, permissions; see below. */
-+	__fs16     ui_nlink;       /*   2: File link count. */
-+	__fs32     ui_uid;         /*   4: File owner. */
-+	__fs32     ui_gid;         /*   8: File group. */
-+	__fs32     ui_blksize;     /*  12: Inode blocksize. */
-+	__fs64     ui_size;        /*  16: File byte count. */
-+	__fs64     ui_blocks;      /*  24: Bytes actually held. */
-+	__fs64   ui_atime;       /*  32: Last access time. */
-+	__fs64   ui_mtime;       /*  40: Last modified time. */
-+	__fs64   ui_ctime;       /*  48: Last inode change time. */
-+	__fs64   ui_birthtime;   /*  56: Inode creation time. */
-+	__fs32     ui_mtimensec;   /*  64: Last modified time. */
-+	__fs32     ui_atimensec;   /*  68: Last access time. */
-+	__fs32     ui_ctimensec;   /*  72: Last inode change time. */
-+	__fs32     ui_birthnsec;   /*  76: Inode creation time. */
-+	__fs32     ui_gen;         /*  80: Generation number. */
-+	__fs32     ui_kernflags;   /*  84: Kernel flags. */
-+	__fs32     ui_flags;       /*  88: Status flags (chflags). */
-+	__fs32     ui_extsize;     /*  92: External attributes block. */
-+	__fs64     ui_extb[UFS_NXADDR];/*  96: External attributes block. */
-+	union {
-+		struct {
-+			__fs64     ui_db[UFS_NDADDR]; /* 112: Direct disk blocks. */
-+			__fs64     ui_ib[UFS_NINDIR];/* 208: Indirect disk blocks.*/
-+		} ui_addr;
-+	__u8	ui_symlink[2*4*(UFS_NDADDR+UFS_NINDIR)];/* 0x28 fast symlink */
-+	} ui_u2;
-+	__fs64     ui_spare[3];    /* 232: Reserved; currently unused */
-+};
-+
-+
-+/* FreeBSD has these in sys/stat.h */
-+/* ui_flags that can be set by a file owner */
-+#define UFS_UF_SETTABLE   0x0000ffff
-+#define UFS_UF_NODUMP     0x00000001  /* do not dump */
-+#define UFS_UF_IMMUTABLE  0x00000002  /* immutable (can't "change") */
-+#define UFS_UF_APPEND     0x00000004  /* append-only */
-+#define UFS_UF_OPAQUE     0x00000008  /* directory is opaque (unionfs) */
-+#define UFS_UF_NOUNLINK   0x00000010  /* can't be removed or renamed */
-+/* ui_flags that only root can set */
-+#define UFS_SF_SETTABLE   0xffff0000
-+#define UFS_SF_ARCHIVED   0x00010000  /* archived */
-+#define UFS_SF_IMMUTABLE  0x00020000  /* immutable (can't "change") */
-+#define UFS_SF_APPEND     0x00040000  /* append-only */
-+#define UFS_SF_NOUNLINK   0x00100000  /* can't be removed or renamed */
-+
-+/*
-+ * This structure is used for reading disk structures larger
-+ * than the size of fragment.
-+ */
-+struct ufs_buffer_head {
-+	__u64 fragment;			/* first fragment */
-+	__u64 count;				/* number of fragments */
-+	struct buffer_head * bh[UFS_MAXFRAG];	/* buffers */
-+};
-+
-+struct ufs_cg_private_info {
-+	struct ufs_buffer_head c_ubh;
-+	__u32	c_cgx;		/* number of cylidner group */
-+	__u16	c_ncyl;		/* number of cyl's this cg */
-+	__u16	c_niblk;	/* number of inode blocks this cg */
-+	__u32	c_ndblk;	/* number of data blocks this cg */
-+	__u32	c_rotor;	/* position of last used block */
-+	__u32	c_frotor;	/* position of last used frag */
-+	__u32	c_irotor;	/* position of last used inode */
-+	__u32	c_btotoff;	/* (__u32) block totals per cylinder */
-+	__u32	c_boff;		/* (short) free block positions */
-+	__u32	c_iusedoff;	/* (char) used inode map */
-+	__u32	c_freeoff;	/* (u_char) free block map */
-+	__u32	c_nextfreeoff;	/* (u_char) next available space */
-+	__u32	c_clustersumoff;/* (u_int32) counts of avail clusters */
-+	__u32	c_clusteroff;	/* (u_int8) free cluster map */
-+	__u32	c_nclusterblks;	/* number of clusters this cg */
-+};	
-+
-+
-+struct ufs_sb_private_info {
-+	struct ufs_buffer_head s_ubh; /* buffer containing super block */
-+	struct ufs_csum_core cs_total;
-+	__u32	s_sblkno;	/* offset of super-blocks in filesys */
-+	__u32	s_cblkno;	/* offset of cg-block in filesys */
-+	__u32	s_iblkno;	/* offset of inode-blocks in filesys */
-+	__u32	s_dblkno;	/* offset of first data after cg */
-+	__u32	s_cgoffset;	/* cylinder group offset in cylinder */
-+	__u32	s_cgmask;	/* used to calc mod fs_ntrak */
-+	__u32	s_size;		/* number of blocks (fragments) in fs */
-+	__u32	s_dsize;	/* number of data blocks in fs */
-+	__u64	s_u2_size;	/* ufs2: number of blocks (fragments) in fs */
-+	__u64	s_u2_dsize;	/*ufs2:  number of data blocks in fs */
-+	__u32	s_ncg;		/* number of cylinder groups */
-+	__u32	s_bsize;	/* size of basic blocks */
-+	__u32	s_fsize;	/* size of fragments */
-+	__u32	s_fpb;		/* fragments per block */
-+	__u32	s_minfree;	/* minimum percentage of free blocks */
-+	__u32	s_bmask;	/* `blkoff'' calc of blk offsets */
-+	__u32	s_fmask;	/* s_fsize mask */
-+	__u32	s_bshift;	/* `lblkno'' calc of logical blkno */
-+	__u32   s_fshift;	/* s_fsize shift */
-+	__u32	s_fpbshift;	/* fragments per block shift */
-+	__u32	s_fsbtodb;	/* fsbtodb and dbtofsb shift constant */
-+	__u32	s_sbsize;	/* actual size of super block */
-+	__u32   s_csmask;	/* csum block offset */
-+	__u32	s_csshift;	/* csum block number */
-+	__u32	s_nindir;	/* value of NINDIR */
-+	__u32	s_inopb;	/* value of INOPB */
-+	__u32	s_nspf;		/* value of NSPF */
-+	__u32	s_npsect;	/* # sectors/track including spares */
-+	__u32	s_interleave;	/* hardware sector interleave */
-+	__u32	s_trackskew;	/* sector 0 skew, per track */
-+	__u64	s_csaddr;	/* blk addr of cyl grp summary area */
-+	__u32	s_cssize;	/* size of cyl grp summary area */
-+	__u32	s_cgsize;	/* cylinder group size */
-+	__u32	s_ntrak;	/* tracks per cylinder */
-+	__u32	s_nsect;	/* sectors per track */
-+	__u32	s_spc;		/* sectors per cylinder */
-+	__u32	s_ipg;		/* inodes per cylinder group */
-+	__u32	s_fpg;		/* fragments per group */
-+	__u32	s_cpc;		/* cyl per cycle in postbl */
-+	__s32	s_contigsumsize;/* size of cluster summary array, 44bsd */
-+	__s64	s_qbmask;	/* ~usb_bmask */
-+	__s64	s_qfmask;	/* ~usb_fmask */
-+	__s32	s_postblformat;	/* format of positional layout tables */
-+	__s32	s_nrpos;	/* number of rotational positions */
-+        __s32	s_postbloff;	/* (__s16) rotation block list head */
-+	__s32	s_rotbloff;	/* (__u8) blocks for each rotation */
-+
-+	__u32	s_fpbmask;	/* fragments per block mask */
-+	__u32	s_apb;		/* address per block */
-+	__u32	s_2apb;		/* address per block^2 */
-+	__u32	s_3apb;		/* address per block^3 */
-+	__u32	s_apbmask;	/* address per block mask */
-+	__u32	s_apbshift;	/* address per block shift */
-+	__u32	s_2apbshift;	/* address per block shift * 2 */
-+	__u32	s_3apbshift;	/* address per block shift * 3 */
-+	__u32	s_nspfshift;	/* number of sector per fragment shift */
-+	__u32	s_nspb;		/* number of sector per block */
-+	__u32	s_inopf;	/* inodes per fragment */
-+	__u32	s_sbbase;	/* offset of NeXTstep superblock */
-+	__u32	s_bpf;		/* bits per fragment */
-+	__u32	s_bpfshift;	/* bits per fragment shift*/
-+	__u32	s_bpfmask;	/* bits per fragment mask */
-+
-+	__u32	s_maxsymlinklen;/* upper limit on fast symlinks' size */
-+	__s32	fs_magic;       /* filesystem magic */
-+	unsigned int s_dirblksize;
-+};
-+
-+/*
-+ * Sizes of this structures are:
-+ *	ufs_super_block_first	512
-+ *	ufs_super_block_second	512
-+ *	ufs_super_block_third	356
-+ */
-+struct ufs_super_block_first {
-+	union {
-+		struct {
-+			__fs32	fs_link;	/* UNUSED */
-+		} fs_42;
-+		struct {
-+			__fs32	fs_state;	/* file system state flag */
-+		} fs_sun;
-+	} fs_u0;
-+	__fs32	fs_rlink;
-+	__fs32	fs_sblkno;
-+	__fs32	fs_cblkno;
-+	__fs32	fs_iblkno;
-+	__fs32	fs_dblkno;
-+	__fs32	fs_cgoffset;
-+	__fs32	fs_cgmask;
-+	__fs32	fs_time;
-+	__fs32	fs_size;
-+	__fs32	fs_dsize;
-+	__fs32	fs_ncg;
-+	__fs32	fs_bsize;
-+	__fs32	fs_fsize;
-+	__fs32	fs_frag;
-+	__fs32	fs_minfree;
-+	__fs32	fs_rotdelay;
-+	__fs32	fs_rps;
-+	__fs32	fs_bmask;
-+	__fs32	fs_fmask;
-+	__fs32	fs_bshift;
-+	__fs32	fs_fshift;
-+	__fs32	fs_maxcontig;
-+	__fs32	fs_maxbpg;
-+	__fs32	fs_fragshift;
-+	__fs32	fs_fsbtodb;
-+	__fs32	fs_sbsize;
-+	__fs32	fs_csmask;
-+	__fs32	fs_csshift;
-+	__fs32	fs_nindir;
-+	__fs32	fs_inopb;
-+	__fs32	fs_nspf;
-+	__fs32	fs_optim;
-+	union {
-+		struct {
-+			__fs32	fs_npsect;
-+		} fs_sun;
-+		struct {
-+			__fs32	fs_state;
-+		} fs_sunx86;
-+	} fs_u1;
-+	__fs32	fs_interleave;
-+	__fs32	fs_trackskew;
-+	__fs32	fs_id[2];
-+	__fs32	fs_csaddr;
-+	__fs32	fs_cssize;
-+	__fs32	fs_cgsize;
-+	__fs32	fs_ntrak;
-+	__fs32	fs_nsect;
-+	__fs32	fs_spc;
-+	__fs32	fs_ncyl;
-+	__fs32	fs_cpg;
-+	__fs32	fs_ipg;
-+	__fs32	fs_fpg;
-+	struct ufs_csum fs_cstotal;
-+	__s8	fs_fmod;
-+	__s8	fs_clean;
-+	__s8	fs_ronly;
-+	__s8	fs_flags;
-+	__s8	fs_fsmnt[UFS_MAXMNTLEN - 212];
-+
-+};
-+
-+struct ufs_super_block_second {
-+	union {
-+		struct {
-+			__s8	fs_fsmnt[212];
-+			__fs32	fs_cgrotor;
-+			__fs32	fs_csp[UFS_MAXCSBUFS];
-+			__fs32	fs_maxcluster;
-+			__fs32	fs_cpc;
-+			__fs16	fs_opostbl[82];
-+		} fs_u1;
-+		struct {
-+			__s8  fs_fsmnt[UFS2_MAXMNTLEN - UFS_MAXMNTLEN + 212];
-+			__u8   fs_volname[UFS2_MAXVOLLEN];
-+			__fs64  fs_swuid;
-+			__fs32  fs_pad;
-+			__fs32   fs_cgrotor;
-+			__fs32   fs_ocsp[UFS2_NOCSPTRS];
-+			__fs32   fs_contigdirs;
-+			__fs32   fs_csp;
-+			__fs32   fs_maxcluster;
-+			__fs32   fs_active;
-+			__fs32   fs_old_cpc;
-+			__fs32   fs_maxbsize;
-+			__fs64   fs_sparecon64[17];
-+			__fs64   fs_sblockloc;
-+			__fs64	cs_ndir;
-+			__fs64	cs_nbfree;
-+		} fs_u2;
-+	} fs_un;
-+};
-+
-+struct ufs_super_block_third {
-+	union {
-+		struct {
-+			__fs16	fs_opostbl[46];
-+		} fs_u1;
-+		struct {
-+			__fs64	cs_nifree;	/* number of free inodes */
-+			__fs64	cs_nffree;	/* number of free frags */
-+			__fs64   cs_numclusters;	/* number of free clusters */
-+			__fs64   cs_spare[3];	/* future expansion */
-+			struct  ufs_timeval    fs_time;		/* last time written */
-+			__fs64    fs_size;		/* number of blocks in fs */
-+			__fs64    fs_dsize;	/* number of data blocks in fs */
-+			__fs64   fs_csaddr;	/* blk addr of cyl grp summary area */
-+			__fs64    fs_pendingblocks;/* blocks in process of being freed */
-+			__fs32    fs_pendinginodes;/*inodes in process of being freed */
-+		} __attribute__ ((packed)) fs_u2;
-+	} fs_un1;
-+	union {
-+		struct {
-+			__fs32	fs_sparecon[53];/* reserved for future constants */
-+			__fs32	fs_reclaim;
-+			__fs32	fs_sparecon2[1];
-+			__fs32	fs_state;	/* file system state time stamp */
-+			__fs32	fs_qbmask[2];	/* ~usb_bmask */
-+			__fs32	fs_qfmask[2];	/* ~usb_fmask */
-+		} fs_sun;
-+		struct {
-+			__fs32	fs_sparecon[53];/* reserved for future constants */
-+			__fs32	fs_reclaim;
-+			__fs32	fs_sparecon2[1];
-+			__fs32	fs_npsect;	/* # sectors/track including spares */
-+			__fs32	fs_qbmask[2];	/* ~usb_bmask */
-+			__fs32	fs_qfmask[2];	/* ~usb_fmask */
-+		} fs_sunx86;
-+		struct {
-+			__fs32	fs_sparecon[50];/* reserved for future constants */
-+			__fs32	fs_contigsumsize;/* size of cluster summary array */
-+			__fs32	fs_maxsymlinklen;/* max length of an internal symlink */
-+			__fs32	fs_inodefmt;	/* format of on-disk inodes */
-+			__fs32	fs_maxfilesize[2];	/* max representable file size */
-+			__fs32	fs_qbmask[2];	/* ~usb_bmask */
-+			__fs32	fs_qfmask[2];	/* ~usb_fmask */
-+			__fs32	fs_state;	/* file system state time stamp */
-+		} fs_44;
-+	} fs_un2;
-+	__fs32	fs_postblformat;
-+	__fs32	fs_nrpos;
-+	__fs32	fs_postbloff;
-+	__fs32	fs_rotbloff;
-+	__fs32	fs_magic;
-+	__u8	fs_space[1];
-+};
-+
-+#endif /* __LINUX_UFS_FS_H */
-diff -Naur silo-1.4.14.orig/include/stringops.h silo-1.4.14/include/stringops.h
---- silo-1.4.14.orig/include/stringops.h	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/include/stringops.h	2011-01-10 22:12:44.851156025 -0500
-@@ -3,13 +3,7 @@
- 
- #include <silo.h>
- 
--/* common */
--#ifndef __SIZE_TYPE__
--#define __SIZE_TYPE__ long unsigned int
--#endif
--#ifndef _LINUX_TYPES_H
--typedef __SIZE_TYPE__ size_t;
--#endif
-+#include <stddef.h>
- 
- /* stringops1.c */
- char *strcpy(char *, const char *);
-diff -Naur silo-1.4.14.orig/libext2fs/ChangeLog silo-1.4.14/libext2fs/ChangeLog
---- silo-1.4.14.orig/libext2fs/ChangeLog	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/ChangeLog	2011-01-10 21:59:35.403016722 -0500
-@@ -0,0 +1,3311 @@
-+2006-06-30  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.38
-+
-+2005-06-30  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* bitops.h, bitops.c (ext2fs_set_bit, ext2fs_clear_bit,
-+		ext2fs_test_bit): Change these function prototypes to be
-+		unsigned int's.  Negative bit numbers were never allowed
-+		(and never made any sense), so this should be a safe
-+		change.  This is needed to allow safe use of block numbers
-+		greater than or equal to 2**31.
-+
-+2005-06-27  Stephen Tweedie  <sct@redhat.com>
-+
-+	* ext2fs.h (ext2fs_resize_mem): Fix C99 strict type aliasing
-+		problems.  Addresses Red Hat Bugzilla #161183.
-+
-+2005-06-19  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* getsectsize.c (BLKSSZGET): Clean up test for when to manually
-+		define the BLKSSZGET ioctl.
-+
-+2005-05-29  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ismounted.c (ext2fs_check_mount_point): Add test to see if the
-+		device appears to be busy; this only works on Linux 2.6+
-+		systems, but provides some additional bullet-proofing in
-+		those cases.
-+
-+2005-05-08  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* test_io.c (safe_getenv): Fix bug so it would fetch the right
-+		environment variable.
-+
-+2005-04-09  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* inode.c (ext2fs_write_new_inode), 
-+		ind_block.c (ext2fs_read_ind_block): Add missing return
-+		value in error return case.  (Otherwise we return garbage
-+		instead of the error code.)
-+
-+2005-03-31  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* test_io.c (test_open): If called by a setuid/setgid or an
-+		otherwise privileged program, be paranoid and ignore the
-+		TEST_IO_* environment variables.
-+
-+2005-03-21  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.37
-+
-+2005-03-21  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_ext_attr.h (EXT2_XATTR_LEN, EXT2_XATTR_SIZE): Add new
-+		convenience cpp macros.
-+
-+2005-03-20  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* mkdir.c (ext2fs_mkdir): Call ext2fs_write_new_inode() instead of
-+		ext2fs_write_inode().
-+
-+	* inode.c (ext2fs_write_new_inode): New function which should be
-+		used when the caller is writing an inode for the first
-+		time.  It makes sure that the extra portion of the large
-+		inode is initialized properly.
-+
-+2005-03-18  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Makefile.in: Fix clean target to remove tst_getsectsize.
-+
-+	* getsize.c (ext2fs_get_device_size): Check to see if the number
-+		of blocks is greater than 2**32 when we are doing a binary
-+		search to determine the device size.  Thanks to Stephen
-+		Tweedie for the patch.
-+	
-+2006-02-05  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.36
-+
-+2005-02-05  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Makefile.in: Remove ext2fs.pc on a "make distclean"
-+
-+2005-02-04  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Makefile.in (clean): Remove tst_getsize when doing a make clean
-+
-+2005-02-03  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* bitops.c: Make the generic functions more efficient.
-+
-+	* bitops.h: Drop SPARC assembly code. It's less efficient than GCC
-+		3.4 compiled code and also triggers nasty compiler
-+		warnings on sparc64.  Thanks to Matthias Andree for his
-+		analysis and suggestion.
-+	
-+2005-01-27  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* res_gdt.c (ext2fs_create_resize_inode): Create the resize inode
-+		even if s_reserved_gdt_blocks is zero.
-+
-+2005-01-26  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2fs.pc.in: Add pkg-config files.
-+
-+2005-01-25  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2fs.h: Add definition of struct ext2_inode_large
-+
-+	* ext2_fs.h: Add new function prototypes
-+
-+	* ext_attr.c (ext2fs_read_ext_attr, ext2fs_write_ext_attr): The
-+		ext2fs_swap_ext_attr() has been moved to swapfs.c, and
-+		given a new argument, has_header.
-+
-+	* swapfs.c (ext2fs_swap_ext_attr): Moved from ext_attr.c, and
-+		takes an argument which controls whether or not there is
-+		an EA header which needs to be byteswaped.
-+		(ext2fs_swap_inode_full): New function which byte-swaps
-+		the EA in inode.
-+
-+	* inode.c (ext2fs_get_next_inode_full, ext2fs_read_inode_full,
-+		ext2fs_write_inode_full): New functions, originally from
-+		Alex Tomas, but which needed to be substantially fixed so
-+		that the tests wouldn't cause major stack overwrite bugs
-+		in byte-swapping is enabled.
-+	
-+2005-01-18  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Makefile.in: Fix the kernel compile-time echo commands to be
-+		consistent and portable
-+
-+2005-01-07  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* unlink.c (ext2fs_unlink): If both the name and the inode number
-+		are unspecified, then return an error, so that we don't do
-+		something surprising such as unconditionally deleting the
-+		first directory entry.
-+		(unlink_proc): Delete directory entries by coalescing it
-+		with the previous entry, to avoid directory fragmentation.
-+
-+2005-01-06  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* version.c (ext2fs_parse_version_string): Change parsing
-+		algorithm so that version strings such as 1.36-rc1 returns
-+		a non-surprising result (i.e., 136, and not 1361).
-+
-+2005-01-05  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* block.c (block_iterate_ind, block_iterate_dind,
-+		block_iterate_tind): Move the code which byte swaps and
-+		read/writes indirect blocks to ext2fs_{read,write}_ind_block.
-+		This saves 400 bytes, and we need them for the
-+		resize_inode handling. 
-+
-+	* ind_block.c (ext2fs_read_ind_block, ext2fs_write_ind_block): New
-+		functions.
-+
-+	* res_gdt.c (ext2fs_create_resize_inode): Use 
-+		ext2fs_{read,write}_ind_block so that byte swapping is
-+		handled on big-endian systems.
-+
-+	* dupfs.c (ext2fs_dup_handle): Make sure the new filesystem handle
-+		has its own copy of the orig_super data structure.  (This
-+		is a better way of fixing a double-free problem in
-+		resize2fs which Fedora attempted to fix in 
-+		e2fsprogs-1.35-double_free.patch.   Addresses Red Hat
-+		Bugzilla #132707.)
-+	
-+2004-12-23  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* inode.c (ext2fs_flush_icache): When flushing the icache, clear
-+		the last-read block information as well.
-+
-+	* ext2fs.h (BMAP_SET), bmap.c (ext2fs_bmap): Add support for new
-+		flag, BMAP_SET, which allows the caller to set a
-+		particular logical->physical block mapping.
-+
-+	* ext2_err.et.in (EXT2_ET_SET_BMAP_NO_IND): New error code
-+
-+	* initialize.c (calc_reserved_gdt_blocks): #ifdef out all
-+		debugging printf statements.
-+	
-+	* res_gdt.c (ext2fs_create_resize_inode): Return
-+		EXT2_ET_RESIZE_INODE_CORRUPT if the resize inode is not
-+		what we expect.  #ifdef out all debugging printf
-+		statements.
-+
-+	* ext2_err.et.in (EXT2_ET_RESIZE_INODE_CORRUPT): Add new error code.
-+
-+2004-12-22  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* swapfs.c (ext2fs_swap_super): Byteswap the reserved_gdt_blocks
-+		superblocks field.
-+
-+2004-12-15  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* sparse.c (ext2fs_list_backups, ext2fs_bg_has_super),
-+		res_gdt.c (list_backups), closefs.c (ext2fs_bg_has_super),
-+		ext2fs.h: Move ext2fs_list_backups() to res_gdt.c, and
-+		ext2fs_bg_has_super() back to closefs.c.  There's no
-+		reason for the new file, since list_backups() isn't being
-+		used by any other functions, and can be made static, and
-+		all users of the ext2fs filesystem will have to call
-+		ext2fs_close() anyway.
-+
-+2004-12-15  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Applied resize inode patch from Andreas Dilger
-+
-+	* res_gdt.c (ext2fs_create_resize_inode): New function that
-+		creates the resize inode.
-+
-+	* initialize.c (ext2fs_initialize): Reserve space for the resize
-+		inode.
-+
-+	* ext2fs.h (EXT2_LIB_FEATURE_COMPAT_SUPP): Add
-+		EXT2_FEATURE_COMPAT_RESIZE_INODE to the list of supported
-+		capabilities.
-+		Add function prototypes for res_gdt.c and sparse.c.
-+
-+	* closefs.c (ext2fs_super_and_bgd_loc): Take the reserved blocks
-+		into account when calculating the number of overhead
-+		blocks.
-+
-+	* closefs.c (ext2fs_bg_has_super, test_root), sparse.c: Move these
-+		functions to the new file sparse.c
-+
-+	* alloc_sb.c (ext2fs_reserve_super_and_bgd): Reserve the blocks
-+		saved in the resize inode as being in use.
-+
-+	* ext2_err.et.in (EXT2_ET_RES_GDT_BLOCKS): Add new error code.
-+
-+	* Makefile.in (srcdir): Add res_gdt.c and sparse.c to the ext2fs
-+		library.
-+
-+2004-12-14  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Makefile.in: Use Linux-kernel-style makefile output for "make
-+		install"
-+
-+	* Makefile.in (installdirs): Use $(MKINSTALLDIRS) macro
-+		Update dependencies.
-+
-+2004-11-30  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* unix_io.c (unix_set_option): Add support for the offset option.
-+
-+	* test_io.c (test_set_option): Add support for the set_option method.
-+
-+	* ext2_io.h: Add new io_channel method, set_option(), and change
-+		io_channel_write_byte() from a macro to a library function.
-+
-+	* ext2fs.h, openfs.c(ext2fs_open2): New version of ext2fs_open
-+		which adds a new parameter, io_options.
-+		(ext2fs_open): If there is a question mark in the
-+		filename, and no io_options are specified, assumed that
-+		the text following the question mark are io_options.
-+	
-+	* io_manager.c, Makefile.in: New source file which contains
-+		high-level functions for the io_channel layer.
-+
-+	* freefs.c (ext2fs_free): Make sure we don't free the io_channel
-+		if image_io is NULL.
-+
-+	* Makefile.in: Use Linux-kernel-style makefile output to make it
-+		easier to see errors/warnings.
-+
-+2004-11-29  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_fs.h (EXT2_EXTENTS_FL, EXT3_FEATURE_INCOMPAT_EXTENTS, 
-+		EXT2_MAX_BLOCK_LOG_SIZE): Add definition for extent
-+		feature and inode flag.  Change maximum allowable block
-+		size to be 65536.
-+
-+2004-10-08  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* getsize.c (ext2fs_get_device_size): Add support for Windows
-+		9x/NT under Cygwin.  Thanks to Sam Robb
-+		(samrobb@users.sourceforge.net) for pointing this and the
-+		suggested code patch.
-+
-+2004-09-17  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* getsize.c: Clean up header #include's.
-+
-+	* llseek.c (ext2fs_llseek): On non-linux systems, use lseek64() if
-+		it is present.  (Addresses Debian bug #269044)
-+
-+2004-07-28  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* rw_bitmaps.c (read_bitmaps), block.c (block_iterate_ind,
-+		block_iterate_dind, block_iterate_tind), inode.c
-+		(ext2fs_read_inode): If EXT2_FLAG_IMAGE_FILE is set, so
-+		read the metadata from fs->image_io instead of fs->io.
-+
-+	* initialize.c (ext2fs_initialize), openfs.c (ext2fs_open):
-+		Initialize fs->image_io to be the same as fs->io.
-+	
-+	* ext2_err.et.in (EXT2_ET_NOT_IMAGE_FILE): Add new error code. 
-+
-+	* openfs.c (ext2fs_get_data_io, ext2fs_set_data_io,
-+		ext2fs_rewrite_to_io): New functions that allow
-+		applications to manipulate fs->image_io and fs->io safely.
-+
-+	* freefs.c (ext2fs_free): If fs->image_io is different fs->io,
-+		then call io_channel_close on fs->image_io.
-+
-+	* ext2fs.h: Add image_io element to the ext2_filsys data
-+		structure.  Add ext2fs_get_data_io() ext2fs_set_data_io(),
-+		and ext2fs_rewrite_to_io() prototypes.
-+
-+2004-05-26  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* closefs.c (ext2fs_flush): Make sure the master superblock is
-+		written last, and only after other I/O has been flushed to
-+		disk.  Thanks to Junfeng Yang from the Stanford
-+		Metacompilation group for pointing a potential ordering
-+		constraint problem if we don't write things out in the
-+		right order.
-+
-+	* test_io.c: Implement the ability to abort after n reads or
-+		writes to a particular block.  The block is specified by
-+		TEST_IO_BLOCK environment variable, and the read/write
-+		count by the TEST_IO_READ_ABORT and TEST_IO_WRITE_ABORT
-+		environment variables.  The block data is now only dumped
-+		if the 0x10 bit is set in TEST_IO_FLAGS.
-+
-+2004-04-03  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_types.h.in: Remove check for _UUID_TYPES since uuid_types.h
-+		is no longer used.
-+
-+2004-03-08  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* getsize.c (ext2fs_get_device_size): Only use the BLKGETSIZE64
-+		ioctl on Linux 2.6 since it is unreliable in Linux 2.4.
-+		(Addresses Debian Bug #236528).  Fix typo in the ioctl
-+		used for Mac OS X.
-+
-+2004-03-02  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* getsize.c (ext2fs_get_device_size): Update getsize functions to
-+		use Apple Darwin and Linux 64-bit ioctl's
-+
-+2004-02-29  Brian Bergstrand  <brian@bergstrand.org>
-+
-+	* Makefile.in: Use $(BSDLIB_PIC_FLAG) to determine whether to use
-+		-fpic or -fPIC
-+
-+2004-02-28  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.35
-+
-+2004-02-21  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2fs.h (ext2fs_resize_mem): Fix C++ problem.  (Addresses Red
-+		Hat Bugzilla #112448; thanks Thomas Woerner from Red Hat.)
-+
-+2004-02-14  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* namei.c (follow_link): Correctly deal with symlinks that have
-+		extended attribute information.  (Addresses Debian Bug
-+		#232328)
-+
-+2004-01-30  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_fs.h: Reserve an extra 4 bytes for the journal backup,
-+		which we're using due to a typo in the e2fsck code.  (Oops)
-+
-+	* swapfs.c (ext2fs_swap_inode): Fix byte swap bug which causes SE
-+		Linux created symlinks with mandatory attributes to fail
-+		to be properly handled on big endian systems.  (Addresses
-+		Debian Bug #228723).
-+		(ext2fs_swap_super): Byte swap some new fields in the
-+		superblock, including the journal backup fields.
-+
-+2003-12-02  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* alloc.c, bb_inode.c, bitops.c, block.c, check_desc.c, closefs.c,
-+		dir_iterate.c, dirblock.c, expanddir.c, ext2fs.h,
-+		get_pathname.c, icount.c, imager.c, initalize.c, inode.c,
-+		lookup.c, openfs.c, read_bb.c, read_bb_file.c,
-+		rw_bitmaps.c, unix_io.c, unlink.c, write_bb_file.c: Fix
-+		gcc -Wall complaints.  Mainly marking variables as being
-+		unsued, and catching signed vs. unsigned comparisons.
-+
-+2003-09-03  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* closefs.c (ext2fs_super_and_bgd_loc): New function which
-+		centralizes the calculation of the superblock and block
-+		group descriptors.
-+		(ext2fs_flush): Use ext2fs_super_and_bgd_lock to figure
-+		out where to write the superblock and block group
-+		descriptors.
-+
-+	* alloc_sb.c (ext2fs_reserve_super_and_bgd): New function which
-+		reserves space in the block bitmap using
-+		ext2fs_super_and_bgd_loc.
-+
-+	* initialize.c (ext2fs_initialize): Use
-+		ext2fs_reserve_super_and_bgd to initialize the block bitmap.
-+
-+2003-08-20  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* inode_io.c (ext2fs_inode_io_intern2), ext2fs.h: Add new function
-+		allows the caller to pass in the inode data structure.
-+
-+	* fileio.c (ext2fs_file_open2), ext2fs.h: Add new function which
-+		allows the caller to pass in the inode to be used in the
-+		file I/O.
-+
-+	* ext2_fs.h: Add a backup of the location of the journal inode
-+		blocks to the superblock.
-+
-+	* mkjournal.c (write_journal_inode): Save the location of the
-+		journal inode to the backup location in the superblock.
-+
-+2003-08-01  Philipp Thomas <pthomas@suse.de>
-+
-+	* alloc.c, badblocks.c, bb_inode.c, bitmaps.c, block.c, bmap.c,
-+		bmove.c, brel_ma.c, closefs.c, dblist.c, dblist_dir.c,
-+		dir_iterate.c, dirblock.c, dupfs.c, expanddir.c, ext2fs.h,
-+		ext_attr.c, fileio.c, freefs.c, get_pathname.c, icount.c,
-+		initialize.c, inode.c, inode_io.c, irel_ma.c, mkdir.c,
-+		mkjournal.c, namei.c, newdir.c, openfs.c, rs_bitmap.c,
-+		rw_bitmaps.c, test_io.c, unix_io.c: ext2fs_getmem(),
-+		ext2fs_free_mem(), and ext2fs_resize_mem() all now take a
-+		'void *' instead of a 'void **' in order to avoid pointer
-+		aliasing problems with GCC 3.x.
-+
-+2003-07-25  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.34
-+
-+2003-07-06  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* kernel-jbd.h, flushb.c: Fix gcc -Wall nitpicks (indented cpp
-+		directives)
-+
-+	* ext2_types.h.in, initialize.c: Fix gcc -Wall nitpicks 
-+		(don't use #elsif)
-+
-+	* ismounted.c: Fix gcc -Wall nitpicks (Don't use exit as a goto label)
-+
-+	* llseek.c: Fix gcc -Wall nitpicks (don't use #elsif)
-+
-+	* lookup.c, read_bb.c: Fix gcc -Wall nitpicks (indent
-+		non-traditional #pragma)
-+
-+	* test_io.c: Fix gcc -Wall nitpicks (const/unsigned type issues)
-+
-+2003-06-24    <tytso@snap.thunk.org>
-+
-+	* badblocks.c, ext2fs.h (ext2fs_u32_list_find,
-+		ext2fs_u32_list_test, ext2fs_u32_list_del,
-+		ext2fs_badblocks_list_del): Add functions to delete a
-+		block from the badblocks list.
-+	* tst_badblocks.c: Add test cases for ext2fs_badblocks_list_del().
-+
-+2003-05-21  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* getsectsize.c (ext2fs_get_device_sectsize): New function which
-+		returns the hardware sector size (if it is available).
-+
-+2003-05-13  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* unix_io.c: Add #ifdef NO_IO_CACHE which disables all userspace
-+		caching by the unix_io layer.  Not enabled, only for
-+		debugging. 
-+
-+2003-05-05  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* test_io.c: Pay attention to the environment variables
-+		TEST_IO_LOGFILE, TEST_IO_FLAGS, and TEST_IO_BLOCK to
-+		determine whether or not we should log io activity, and to
-+		where.
-+
-+2003-05-03  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* tst_badblocks.c (file_test): Use tmpfile() instead of mktemp().
-+
-+2003-04-29  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* getsize.c (ext2fs_get_device_size): Allow windows code to get
-+		the resize for filesystems that are in regular files.
-+
-+2003-04-21  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.33
-+
-+2003-04-21  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Makefile.in: Use DYLD_LIBRAY_PATH so that "make check" works on
-+		Darwin systems when building with shared libraries.
-+
-+2003-04-18  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* unix_io.c: Use __CYGWIN__ instead of CYGWIN.
-+
-+2003-04-17  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* getsize.c: Add Cygwin/Windows version of ext2fs_get_device_size()
-+
-+2003-04-12  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* unix_io.c (raw_read_blk): Add Cygwin support (the Windows block
-+		device only accepts sector aligned read requests.
-+
-+	* ismounted.c (check_mntent_file): Deal with OS's that don't
-+		define MNTOPT_RO.
-+
-+	* imager.c: If the OS doesn't define ssize_t, typedef it to int.
-+
-+2003-04-11  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_fs.h (EXT2_FEATURE_RO_COMPAT_BTREE_DIR): Comment out unused
-+		feature flag
-+
-+2003-03-30  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Makefile.in: Use the compile_et --build-tree option.
-+
-+2003-03-14  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* getsize.c: Add support for Apple Darwin's ioctl to get the hard
-+		disk size.
-+
-+	* badblocks.c (ext2fs_u32_list_count), ext2fs.h: Add new function
-+		which returns the number of entries in the list.
-+
-+2003-03-10  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* fileio.c (ext2fs_file_lseek): Fix bug added when adding 64-bit
-+		support; avoid null dereference when ret_pos is NULL.
-+
-+2003-03-06  Theodore Tso  <tytso@mit.edu>
-+
-+	* ext2_types.h.in: Don't redefine types if other e2fsprogs
-+		*_types.h files have been included already.
-+
-+	* kernel-jbd.h: Use C99 variadic cpp macros if not using GCC.
-+		(Older GCC's don't support the C99 variadic macros.)
-+
-+	* flushb.c (ext2fs_sync_device), 
-+	ismounted.c (ext2fs_check_mount_point): Avoid GCC extension: 
-+	#warning not supported by Solaris suncc
-+
-+	* ext2_ext_attr.h: Avoid GCC extension: 0 length arrays in
-+		structure definition.  Not needed for now in 
-+		ext2_ext_attr_entry.
-+
-+2003-01-25  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* dirhash.c: Fix gcc -Wall nits.
-+
-+2003-01-22  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* unix_io.c (unix_write_blk): Fix up GCC -Wall nits.
-+
-+2003-01-21  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* fileio.c (ext2fs_file_read, ext2_file_lseek,
-+		ext2_file_get_size): Add 64-bit support.
-+
-+	* ext2fs.h (EXT2_I_SIZE): Add macro which caluates a 64bit size
-+		from i_size and i_size_high.
-+
-+2003-01-19  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* initialize.c (ext2fs_initialize): If the user specifies a really
-+		large number of inodes, then reduce the number of blocks
-+		per group until we find a workable set of filesystem
-+		parameters.
-+
-+	* ext2_err.et.in (EXT2_ET_TOO_MANY_INODES): Add new error code.
-+
-+2002-11-09  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.32
-+
-+2002-11-09  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* unix_io.c (find_cached_block, reuse_cache, unix_read_blk, 
-+		unix_write_blk): Optimize routines so that we don't end up
-+		searching the cache twice when a block isn't in the
-+		cache.  If reads are larger than READ_DIRECT_SIZE, don't
-+		let them go through the cache.
-+
-+	* unix_io.c (find_cached_block): Fixed bug which caused some clean
-+		blocks to be erroneously marked as dirty, so they would
-+		get written back to the disk before they are evicted from
-+		the cache.  Harmless, but it slows down e2fsck
-+		significantly.
-+
-+2002-11-08  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.31
-+
-+2002-11-08    <tytso@snap.thunk.org>
-+
-+	* Makefile.in (check): Skip trying to compile test_byteswap
-+		if --disable-byteswaap had been given to configure.
-+
-+2002-11-07    <tytso@snap.thunk.org>
-+
-+	* closefs.c (write_bgdesc, ext2fs_flush): Fix bug in meta_bg
-+		support when the MASTER_SB_ONLY flag is set.  Some of
-+		the descriptor blocks that should have been written out
-+		were getting skipped.
-+
-+2002-10-31  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.30
-+
-+2002-10-31  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_fs.h: Add support for a new inode flag, which is to be used
-+		for indicating the top of directory hierarchies for the
-+		Orlov block allocator.
-+	
-+	* ismounted.c (check_mntent, check_mntent_file): Add better
-+		support for loopback-mounted filesystems.  Check /etc/mtab
-+		if /proc/mounts doesn't turn up any mount flags, since
-+		/etc/mtab has the loopback image filename, instead of
-+		/dev/loop0.  Also, check based on st_dev and st_ino, so
-+		that if a relative pathname or a pathnames using symbolic
-+		links are used, we can detect the the filesystem correctly
-+		in those cases.  (Addresses Sourceforge bug #619119)
-+
-+	* flushb.c (ext2fs_sync_device): If the BLKFLSBUF ioctl succeeds,
-+		don't try the FDFLUSH ioctl that was required for floppies
-+		with older kernels.  This avoids needless whining from the
-+		MD device driver.  (Addresses Sourceforge bug #545832).
-+
-+	* openfs.c (ext2fs_open): Fix bug which caused us to pass the
-+		wrong group_block to ext2fs_descriptor_block_loc if we're
-+		using the backup superblock/block group descriptors.
-+		(ext2fs_descriptor_block_loc): If we're using the backup
-+		superblock descriptors, use the backup descriptor block in
-+		the next block group.
-+
-+2002-10-30  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* alloc_tables.c (ext2fs_allocate_group_table): Allocate the inode
-+		table so that it buts up against the bitmap blocks, to
-+		avoid block fragmentation.
-+
-+	* closefs.c (write_bgdesc), initalize.c (ext2fs_initialize): Fix
-+		bug; only allocate group descriptor blocks up to
-+		s_first_meta_bg.
-+
-+2002-10-25  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_fs.h: Add a new superblock field, s_mkfs_time, so that we
-+		know when a filesystem was created.  (Sometimes this can
-+		be useful...)
-+
-+	* initialize.c (ext2fs_initialize): Set the s_mkfs_time field.
-+
-+2002-10-20  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* ext2_fs.h (EXT3_DEFM_JMODE): Add new default mount options for
-+		the journal data mode.
-+
-+	* closefs.c (ext2fs_flush, write_bgdesc), ext2_fs.h, ext2fs.h,
-+	openfs.c (ext2fs_descriptor_block_loc, ext2fs_open), initialize.c
-+	(ext2fs_initialize), swapfs.c (ext2fs_swap_super): Add support for
-+	the meta_blockgroup filesystem format.
-+
-+2002-10-15    <tytso@snap.thunk.org>
-+
-+	* ext2_fs.h: Add new field in superblock for default mount options.
-+
-+2002-10-13  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2fs.h: Add #include of header files necessary for ext2fs.h to
-+		compile cleanly.
-+
-+2002-10-02  Theodore Y. Ts'o  <tytso@mit.edu>
-+
-+	* rw_bitmaps.c (ext2fs_write_block_bitmap,
-+		ext2fs_read_block_bitmap): Don't set the CHANGED bit just
-+		because the bitmap is getting written to disk.  Make
-+		ext2fs_swap_bitmap be a static function, since it's not
-+		intended to be exported.
-+
-+	* swapfs.c (ext2fs_swap_super): Byte-swap the hash seed
-+
-+2001-09-24  Theodore Tso  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.29
-+
-+2001-08-31  Theodore Tso  <tytso@thunk.org>
-+
-+	* Release of E2fsprogs 1.28
-+
-+2002-08-31  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* dblist.c (ext2fs_dblist_sort): New function which allows the
-+		caller to pass in a special sort comparison function.
-+
-+2002-08-20  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* valid_blk.c (ext2fs_inode_has_valid_blocks): Fix bug which
-+		failed to accurately characterize non-standard slow
-+		symlinks.  (Which don't appear in practice on real-life
-+		systems, fortunately.)
-+
-+2002-08-17  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* Makefile.in: Remove inode_io.o from the standard object files,
-+		and only build it if debugfs is enabled (it requires
-+		fileio.o, which is only built if --disable-debugfs isn't
-+		specified to configure).
-+
-+	* dirhash.c (ext2fs_dirhash): Change the MD4 hash in a backwards
-+		incompatible way so that it is no longer
-+		endian-dependent.  Add the TEA hash.  Allow the seed
-+		parameter to be optional.
-+
-+	* ext2_fs.h: Remove the HALF_MD4_SEED and HALF_MD4_64 hashes.
-+		These features are all now in the HALF_MD4 hash.  Add
-+		definition for EXT2_HASH_TEA.
-+
-+	* ext2fs.h (ext2fs_dirhash): Change function prototype so it takes
-+		a pointer instead of an array.
-+
-+2002-08-16  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_err.et.in (EXT2_ET_BAD_EA_BLOCK_NUM): New error code
-+
-+	* ext2fs.h (ext2fs_inode_data_blocks): New function which returns
-+		the number of data blocks used by an inode exclusive of
-+		the EA block.
-+
-+	* ext_attr.c (ext2fs_adjust_ea_refcount): New function which
-+		adjusts the reference count in an extended attribute block.
-+
-+	* valid_blk.c (ext2fs_inode_has_valid_blocks): Add code to
-+		correctly deal with extended attribute blocks in symbolic
-+		links. 
-+
-+2002-08-13    <tytso@snap.thunk.org>
-+
-+	* Makefile.in: Move dupfs.o and test_io.o from the
-+		needed-by-debugfs object list to the needed-by-resizer
-+		object list.  Fixes compile problem if the system is built
-+		with only --disable-debugfs.
-+
-+2002-07-29  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* link.c (ext2fs_link): When adding a new link to a directory,
-+		clear the HTREE bit.
-+
-+2002-07-23  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* dirhash.c (ext2fs_dirhash): Fix bug which caused MD4
-+		calculations for names > 32 characters to be completely
-+		bogus.  Changed MD4 calculation to match what is currently
-+		being used in the CVS gkernel tree.
-+
-+2002-07-19  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_fs.h: Add s_hash_seed and s_def_hash_version to the
-+		superblock definition.
-+
-+	* badblocks.c, freefs.c, ext2fs.h: Use the badblocks functions to
-+		create a set of u32_list functions.
-+
-+	* dirhash.c (halfMD4Transform): Shift the hash by one bit,
-+		since that's required by the directory indexing code.
-+
-+2002-07-14  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2fs.h, read_bb_file.c: Change private to priv_data, to avoid
-+		using a C++ reserved word.
-+
-+	* unix_io.c (unix_open): Only attempt the setrlimit workaround if
-+		the kernel version is 2.4.10 -- 2.4.17, since otherwise an
-+		old version of glibc (built against 2.2 headers) will
-+		interact badly with the workaround to actually cause more
-+		problems.  I hate it when the glibc folks think they're
-+		being smarter than the kernel....
-+
-+2002-06-28  Andreas Dilger <adilger@clusterfs.com>
-+
-+	* ext2_fs.h: Add superblock field for reserved group descriptors.
-+
-+2002-06-28  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* bitops.h: Add #define's for ext2fs_{l,b}e{32,16}_to_cpu and
-+		ext2fs_cpu_to_{l,b}e{32,16}
-+
-+2002-06-27  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ismounted.c (check_mntent): In AIX 4.3, MOUNTED isn't defined.
-+		Add appropriate fallbacks in this case.
-+
-+2002-06-26  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* dirhash.c (ext2fs_dirhash): Change function signature to support
-+		a hash seed, and to return the minor hash (for 64-bit hash
-+		support).   Add support for the half MD4, half MD4 with
-+		seed, and half MD4 with seed and 64 bits.
-+
-+2002-06-15  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_fs.h (EXT2_DIRSYNC_FL): Add new file.
-+
-+2002-06-09  Andreas Dilger <adilger@clusterfs.com>
-+
-+	* ext2_fs.h: Add macros for maximum block/inode counts:
-+		EXT2_INODES_PER_BLOCK, EXT2_MAX_BLOCKS_PER_GROUP,
-+		and EXT2_MAX_INODES_PER_GROUP.
-+
-+	* openfs.c (ext2fs_open): Check that the number of blocks in a group
-+		is less than 2^16, otherwise we need an INCOMPAT flag (not
-+		in existence yet, if ever) to open such a filesystem.
-+
-+	* initialize.c (ext2fs_initialize): Limit the number of blocks and
-+		inodes in a group to less than 2^16.
-+
-+2002-06-09  Andreas Dilger <adilger@clusterfs.com>
-+
-+	* ext2_fs.h: Further minor cleanups of the header.  Consolidate
-+		some checks for __KERNEL__ into one place.
-+
-+2002-05-22  Andreas Dilger <adilger@clusterfs.com>
-+
-+	* ext2_fs.h: Remove macros accessing u.ext2_sb field and use
-+		the EXT2_SB() macro instead.  Remove kernel function
-+		prototypes also.  This matches the 2.5 kernel, and
-+		is also cleaner for other reasons.  Whitespace cleanup.
-+
-+2002-05-21  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ext2_ext_attr.h: Update to V2 version of the Bestbits format.
-+
-+2002-05-16  Andreas Dilger <adilger@clusterfs.com>
-+
-+	* ext2_fs.h: Change limits to support filesystems with 8k blocks.
-+
-+	* initialize.c (ext2fs_initialize): Remove assumption that
-+		blocksizes are always <= 4k.
-+
-+2002-05-11  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* bmap.c (ext2fs_bmap): Fix bug which caused ext2fs_bmap to fail
-+		silently if inode pointer is NULL (and ext2fs_bmap is
-+		expected to read the inode itself).
-+
-+2002-04-27  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ismounted.c (check_mntent_file, is_swap_device): Verify that the
-+		file we are checking is a block device file before looking
-+		at st_rdev, since it's not valid for normal files.
-+		(is_swap_device): Move so that it is outside the
-+		HAVE_MNTENT_H, so that it is always built.
-+
-+2002-03-11  Theodore Tso  <tytso@mit.edu>
-+
-+	* dirblock.c (ext2fs_read_dir_block2, ext2fs_write_dir_block): New
-+		functions which take an extra flags argument.  The flag
-+		EXT2_DIRBLOCK_V2_STRUCT will reverse when the name_len
-+		field is byte swampped on big-endian machines, since in
-+		the V2 structure, name_len is a char field which is
-+		doesn't need to be byte swapped --- except if an
-+		old-style kernel had byte-swapped the name_len field
-+		as part of the V1 structure.
-+
-+	* ext2_err.et.in (EXT2_ET_DIRHASH_UNSUPP): New error code
-+
-+	* dirhash.c (ext2fs_dirhash): New function which calculates the
-+		hash for a filename in an indexed directory.
-+
-+2002-03-08  Theodore Tso  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs 1.27
-+
-+2002-03-07  Theodore Tso  <tytso@mit.edu>
-+
-+	* ext2fs.h (ext2fs_inode_io_intern): Add missing function prototype.
-+
-+	* bmap.c, fileio.c, inode_io.c, tst_badblocks.c, 
-+		tst_byteswap.c: Fix gcc -Wall complaints
-+
-+	* Makefile.in (check): Use LD_LIBRARY_PATH to run test programs.
-+		(From Philipp Thomas <pthomas@suse.de>)
-+
-+2002-02-25  Theodore Tso  <tytso@mit.edu>
-+
-+	* ext2_fs.h: Add structure definitions for the directory indexing
-+		extension.
-+
-+2002-02-23  Theodore Tso  <tytso@mit.edu>
-+
-+	* unix_io.c (unix_open): Fix 2.4 resource limit workaround so that
-+		it doesn't break things on mis32, sparc32, and alpha
-+		platforms.
-+
-+2002-02-21  Theodore Tso  <tytso@mit.edu>
-+
-+	* ismounted.c (is_swap_device): Fix file descriptor/memory leak;
-+		we were missing an fclose().
-+
-+2002-02-20  Theodore Tso  <tytso@mit.edu>
-+
-+	* Makefile.in, inode_io.c, ext2fs.h, ext2_err.et.in: Add new io
-+		abstraction interface which exports an ext2 inode.
-+
-+	* ext2fs.h, fileio.c (ext2fs_file_flush): Export ext2fs_file_flush
-+		as a public interface.  Change void * to const void * in
-+		ext2fs_file_write's interface.
-+
-+	* test_io.c (test_close), unix_io.c (unix_close): Remove unneeded
-+		conditional; save a few bytes.
-+	
-+2002-02-12  Theodore Tso  <tytso@mit.edu>
-+
-+	* Makefile.in (tst_badblocks): Add some extra .o files when
-+		linking the debugging program tst_badblocks which are
-+		needed if we aren't compiling with inline functions enable.
-+
-+	* kernel-list.h (__inline__): On non-gcc and non-Watcom compilers,
-+		define away __inline__ since it may not be supported.
-+
-+	* kernel-jbd.h (jbd_debug): For systems that don't do STDC, use a
-+		stripped down jbd_debug that doesn't use variadic
-+		arguments.  This will cause warnings under AIX, but things
-+		should still build.
-+
-+2002-02-03  Theodore Tso  <tytso@thunk.org>
-+
-+	* Release of E2fsprogs 1.26
-+
-+2002-02-03  Theodore Tso  <tytso@mit.edu>
-+
-+	* mkdir.c (ext2fs_mkdir): Change to use ext2fs_inode_alloc_stats2
-+		so that the number of directories in use is adjusted
-+		appropriately.
-+
-+	* alloc_stats.c (ext2fs_inode_alloc_stats2): Add new function
-+		which optionally will modify the number of directories
-+		count.
-+
-+2002-01-03  Theodore Tso  <tytso@mit.edu>
-+
-+	* dir_iterate.c (ext2fs_dir_iterate2, ext2fs_process_dir_block):
-+		Add support for a new flag, DIRENT_FLAG_INCLUDE_REMOVED,
-+		which will return deleted directory entries.
-+		ext2fs_dir_iterate2 takes a new callback function which
-+		is identical with the one used by
-+		ext2fs_dblist_dir_iterate().  If the directory entry is
-+		deleted, the callback function will be called with the
-+		entry paraemter set to DIRENT_DELETED_FILE.
-+
-+	* Makefile.in, alloc_stats.c (ext2fs_inode_alloc_stats,
-+		ext2fs_block_alloc_stats): New functions which update
-+		block/inode allocation statistics in the bitmaps, block
-+		group descriptors, and superblock.
-+
-+	* mkjournal.c (mkjournal_proc), mkdir.c (ext2fs_mkdir),
-+		expanddir.c (expand_dir_proc), bb_inode.c
-+		(clear_bad_block_proc, set_bad_block_proc,
-+		ext2fs_update_bb_inode), alloc.c (ext2fs_alloc_block):
-+		Update to use new block/inode allocation statistics.
-+
-+2001-12-24  Theodore Tso  <tytso@mit.edu>
-+
-+	* ismounted.c (is_swap_device): New function used by
-+		ext2fs_check_if_mounted and ext2fs_check_mount_point which
-+		determines whether or not the specified device is a swap
-+		device by using /proc/swaps.  More bulletproofing for
-+		idiotic/careless system administrators!
-+
-+	* ext2fs.h, openfs.c (ext2fs_open), initialize.c
-+		(ext2fs_initialize), mkdir.c (ext2fs_mkdir): Add a new
-+		field to struct_ext2_filsys, umask.  This field is
-+		initialize to 022, and affects ext2fs_mkdir in the obvious
-+		way.  (In the future umask should also affect new file
-+		creation routines, but the fileio functions don't
-+		currently support this yes.)
-+
-+	* ismounted.c (check_mntent_file): Stat all of the entries in
-+		/etc/mtab and/or /proc/mounts in order to catch dim-witted
-+		system administrators who might have created alias
-+		devices.
-+ 
-+2001-12-23  Theodore Tso  <tytso@mit.edu>
-+
-+	* Makefile.in, jfs_user.h: Move linux/jbd.h to
-+		ext2fs/kernel-jbd.h, to avoid using the system header
-+		file version of hbd.h when using diet glibc (since it
-+		forcibly adds /usr/include to the beginning of the
-+		include search path.)
-+
-+	* kernel-jbd.h, kernel-list.h, jfs_compat.h: Move files from
-+		include/linux directory.
-+
-+2001-12-16  Theodore Tso  <tytso@mit.edu>
-+
-+	* bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap),
-+		ext_attr.c (ext2fs_read_ext_attr, ext2fs_write_ext_attr),
-+		fileio.c (ext2fs_file_write): Fix gcc -Wall nits
-+
-+	* Makefile.in, jfs_user.h: linux/jfs.h has been renamed to
-+		linux/jbd.h
-+
-+2001-12-03  Theodore Tso  <tytso@mit.edu>
-+
-+	* unix_io.c (unix_open): Make sure the ulimit workaround works
-+		regardless of the version of glibc which is used to
-+		compild e2fsprogs.
-+
-+2001-11-26  Theodore Tso  <tytso@mit.edu>
-+
-+	* unix_io.c (unix_open): Work around a bug in 2.4.10+ kernels by
-+		trying to unset the filesize limit if at all possible,
-+		if a block device is getting opened.  (The filesize limit
-+		shouldn't be applied against writes to a block device, but
-+		starting in 2.4.10, the kernel is doing this.)
-+	
-+2001-11-05  Theodore Tso  <tytso@mit.edu>
-+
-+	* mkjournal.c (ext2fs_add_journal_inode): When creating a .journal
-+		file on adding a journal to an already-mounted filesystem,
-+		try to clear the ext2 file attributes on an already
-+		existing .journal file so that we don't fail if on a
-+		partially added journal to the filesystem.
-+
-+	* ext2_fs.h: Define a new ext2 file attribute, EXT2_NOTAIL_FL,
-+		which signals that a particular inode should not have the
-+		last bits of data (the "tail") be merged with another
-+		file.  This is necessary to keep LILO happy.
-+
-+2001-09-20  Theodore Tso  <tytso@thunk.org>
-+
-+	* Release of E2fsprogs 1.25
-+
-+2001-09-16  Theodore Tso  <tytso@mit.edu>
-+
-+	* ext2_ext_attr.h: Remove unneeded #include of <linux/config.h>
-+		which was breaking the build on the Hurd.  (Addresses
-+		Debian bug #112414).
-+
-+2001-09-13  Theodore Ts'o  <tytso@mit.edu>
-+
-+	* ismounted.c (check_mntent_file): We now validate the entry in
-+		/etc/mtab to make sure the filesystem is really mounted,
-+		since some broken distributions (read: Slackware) have
-+		buggy boot scripts that don't initialize /etc/mtab before
-+		checking non-root filesystems.  (Slackware also doesn't
-+		check the root filesystem separately, and reboot if the
-+		root filesystem had changes applied to it, which is
-+		dangerous and broken.)   
-+
-+2001-09-02  Theodore Tso  <tytso@thunk.org>
-+
-+	* Release of E2fsprogs 1.24a
-+
-+2001-08-30  Theodore Tso  <tytso@thunk.org>
-+
-+	* Release of E2fsprogs 1.24
-+
-+2001-08-30  Theodore Tso  <tytso@valinux.com>
-+
-+	* getsize.c (ext2fs_get_device_size): Back out BLKGETSIZE64
-+		changes, since the ioctl number has been reused by another
-+		unofficial patch.
-+
-+2001-08-15  Theodore Tso  <tytso@valinux.com>
-+
-+	* Release of E2fsprogs 1.23
-+
-+2001-08-05  Theodore Tso  <tytso@valinux.com>
-+
-+	* alloc.c (ext2fs_new_inode, ext2fs_new_block): Use the fast
-+		version of the bitmap test routines to speed up these
-+		routines.  (At some point I may want to make these
-+		routines use the find_first_bit functions, but that will
-+		add a lot of complexity since it means that these
-+		functions will have to break the bitmap abstraction
-+		boundary.  It's not clear it's worth it.)
-+
-+	* mkjournal.c (mkjournal_proc): Remember the last block allocated
-+		to speed up ext2fs_new_block().
-+
-+2001-07-29  Theodore Tso  <tytso@valinux.com>
-+
-+	* finddev.c (scan_dir): Fix memory leak; we weren't calling
-+		closedir() when exiting the function in all cases.
-+
-+2001-07-27  Theodore Tso  <tytso@valinux.com>
-+
-+	* mkjournal.c (ext2fs_create_journal_superblock): Set the first
-+		block usable in the journal for external journals to be 2
-+		or 3, depending on the blocksize, so that the existing
-+		kernel code does the right thing.
-+
-+	* getsize.c (ext2fs_get_device_size): Add support for the
-+		BLKGETSIZE64 ioctl.  (Ioctl defined by unofficial patches
-+		from Ben LaHaise, but it's likely this interface won't
-+		change.)
-+
-+	* mkjournal.c (ext2fs_add_journal_device): Use the correct block
-+		when writing the journal superblock, too.  (Oops! Needed
-+		to make 1k filesystems with external journal to work.)
-+
-+2001-07-26  Theodore Tso  <tytso@valinux.com>
-+
-+	* mkjournal.c (ext2fs_add_journal_device): Use the correct block
-+		to find the journal superblock if the blocksize is 1024.
-+
-+2001-07-21  Theodore Tso  <tytso@valinux.com>
-+
-+	* ext2_err.et.in (EXT2_ET_LOAD_EXT_JOURNAL): Add new error code
-+
-+2001-07-20  Theodore Tso  <tytso@valinux.com>
-+
-+	* ext_attr.c (ext2fs_write_ext_attr): When writing the extended
-+		attribute block, set the filesystem changed bit.
-+
-+	* bitops.h (ext2fs_find_first_bit_set, ext2fs_find_next_bit_set):
-+		Comment out these functions since we're not using them.
-+
-+2001-07-10  Theodore Tso  <tytso@valinux.com>
-+
-+	* closefs.c (write_primary_superblock): After writing changes to
-+		the primary superblock, update the original superblock
-+		copy so we don't have to re-write those changes in the
-+		future.
-+		(ext2fs_flush): Clear the superblock dirty flag after
-+		we've flushed out changes to disk.
-+
-+2001-07-07  Theodore Tso  <tytso@valinux.com>
-+
-+	* bitops.h (ext2fs_find_first_bit_set): Use %esi instead of %ebx
-+		to avoid register conflicts when compiling in PIC mode.
-+
-+2001-07-04  Theodore Tso  <tytso@valinux.com>
-+
-+	* bitops.h (ext2fs_find_first_bit_set, ext2fs_find_next_bit_set):
-+		Add new functions (C and in i386 assembler) which quickly
-+		find bits set in a bitmask.
-+
-+2001-06-23  Theodore Tso  <tytso@valinux.com>
-+
-+	* Makefile.in, ext_attr.c, ext2_attr.c, ext2fs.h: Add new files
-+		ext2_ext_attr.h and ext_attr.c for extended attributes
-+		support.
-+
-+	* Release of E2fsprogs 1.22
-+
-+2001-06-22  Theodore Tso  <tytso@valinux.com>
-+
-+	* mkjournal.c (ext2fs_add_journal_inode): Move close of file
-+		descriptor so that adding a journal to a mounted
-+		filesystem doesn't die.  (Fixes a bug accidentally
-+		introduced in e2fsprogs 1.21.)
-+
-+	* mkjournal.c (ext2fs_add_journal_inode): Only use fchflags if
-+		HAVE_CHFLAGS and UF_NODUMP are defined, since the Hurd has
-+		fchflags without defining UF_NODUMP.  (Addresses Debian
-+		bug #101361)
-+
-+	* flushb.c: Use platform independent method of defining the
-+		BLKFLSBUF and FDFLUSH ioctl's.  Also include sys/mount.h
-+		since on newer glibc's BLKFLSBUF is defined there.
-+
-+	* bitops.h: The C language versions of ext2fs_swab16/32 need to be
-+		included if EXT2FS_ENABLE_SWAPFS is defined, since we need
-+		to support byte swapping even if we don't support the
-+		conversion functions.  (Fixes Debian bug #101686).
-+
-+	* dirblock.c (ext2fs_read_dir_block): Remove use of dir_entry_2
-+		since the byte-swapping code all assumes the
-+		ext2_dir_entry structure.  (It's a question of whether or
-+		not name_len should be byte-swapped or not, and whether
-+		it's a 16 bit or 8 bit field.)
-+
-+2001-06-15  Theodore Tso  <tytso@valinux.com>
-+
-+	* Release of E2fsprogs 1.21
-+
-+2001-06-15  Theodore Tso  <tytso@valinux.com>
-+
-+	* Makefile.in: Fix bug in installation of ext2_types.h.  It is a
-+		file which is generated and is therefore found in the
-+		build directory, not source directory.
-+
-+	* ismounted.c (check_mntent_file): Use a test file in / to check
-+		to see if the root filesystem is mounted read-only.  This
-+		protects against the case where /etc might not be on /, as
-+		well as the case where /etc/mtab doesn't exist.  (Both are
-+		should-never happen scenarios, but you never know...)
-+
-+2001-06-14  Theodore Tso  <tytso@valinux.com>
-+
-+	* ismounted.c (ext2fs_check_if_mounted): Fix grammer in comment.
-+		Remove unneeded #pragma argsused, since the arguments are
-+		always used.
-+
-+2001-06-13  Theodore Tso  <tytso@valinux.com>
-+
-+	* ext2_types.h.in: If linux/types.h has been defined, then don't
-+		try to redefine the typedefs.
-+
-+	* Makefile.in (HFILES): Add ext2_types.h to the list of files
-+		which should be installed.
-+
-+	* ismounted.c (check_mntent_file): Work around GNU hurd brain
-+		damage.  Addresses Debian bug #100304.
-+
-+	* Makefile.in: Limit some .o files from being included into the
-+		library if --disable-debugfs, --disable-swapfs,
-+		--disable-imager, or --disable-resizer are used.
-+
-+2001-06-12  Theodore Tso  <tytso@valinux.com>
-+
-+	* inode.c, tst_iscan.c: Stop using the compatibility badblocks
-+		function, and use the ext2fs_badblocks_* functions
-+		instead.
-+
-+2001-06-11  Theodore Tso  <tytso@valinux.com>
-+
-+	* Makefile.in, gen_bitmap.c, bitops.h: Move inline functions
-+		ext2fs_mark_generic_bitmap and
-+		ext2fs_unmark_generic_bitmap to gen_bitmap.c as normal
-+		functions.  (This saves space and doesn't significantly
-+		change the speed of e2fsck on a P-III.)
-+
-+	* ext2fs.h, bitops.h, block.c, bmap.c, closefs.c, dirblock.c,
-+		inode.c, native.c, openfs.c, rw_bitmaps.c, swapfs.c: Only
-+		include the byte-swapping logic if ENABLE_SWAPFS is turned
-+		on or if we're on a big-endian machine.
-+	
-+	* initialize.c (ext2fs_initialize):Use WORDS_BIGENDIAN directly to
-+		set EXT2_FLAG_SWAP_BYTES, instead of using
-+		ext2fs_native_flag.
-+	
-+	* native.c (ext2fs_native_flag): Use WORDS_BIGENDIAN provided by
-+		autoconf to determine whether or not return
-+		EXT2_FLAG_SWAP_BYTES.
-+
-+2001-06-10  Theodore Tso  <tytso@valinux.com>
-+
-+	* Makefile.in: Remove the dependence on the libe2p library.
-+
-+	* mkjournal.c (ext2fs_add_journal_inode): Replace use of fsetflags
-+		with direct usage of the ioctl/fchflags so that we don't
-+		have to depend on the libe2p library.
-+
-+2001-06-08  Theodore Tso  <tytso@valinux.com>
-+
-+	* ext2_types.h.in: Use unsigned ints in favor of unsigned longs
-+		when trying to find a 32-bit wide type.
-+
-+	* icount.c (insert_icount_el): Fix the code used to estimate the
-+		size of the new icount array to be more intelligent, to
-+		avoid reallocating the array too many times.  Thanks to
-+		Enrique Perez-Terron for pointing this out.
-+
-+2001-06-02  Theodore Tso  <tytso@valinux.com>
-+
-+	* valid_blk.c (ext2fs_inode_has_valid_blocks): Only check i_blocks
-+		for a symlink to determine whether it is a fast symlink.
-+
-+2001-06-01  Theodore Tso  <tytso@valinux.com>
-+
-+	* Makefile.in, dosio.c, ext2_fs.h, ext2_types.h.in, ext2fs.h:
-+		Move include/asm/types.h.in to lib/ext2fs/ext2_types.h.in.
-+
-+2001-05-25  Theodore Tso  <tytso@valinux.com>
-+
-+	* Release of E2fsprogs 1.20
-+
-+2001-05-25  Theodore Tso  <tytso@valinux.com>
-+
-+	* ismounted.c: More cleanups for ismounted.c, some from Andreas,
-+		some to clean up Andreas's patches.  Use strncpy instead
-+		of strcpy to save the root's mountpoint.  Clean up #ifdef
-+		structure.  Remove uneeded variable in testing/debug driver.
-+
-+2001-05-24  Andreas Dilger  <adilger@turbolinux.com>
-+
-+	* ismounted.c: Add check for root device which doesn't depend on
-+		/etc/fstab or /proc/mounts to be correct.  Don't call
-+		endmntent() before we are done with mnt struct.
-+
-+2001-05-23  Theodore Tso  <tytso@valinux.com>
-+
-+	* ext2_err.et.in (EXT2_ET_JOURNAL_UNSUPP_VERSION): Added new error
-+		code.
-+
-+2001-05-21  Theodore Tso  <tytso@valinux.com>
-+
-+	* ext2_fs.h: Change assignment of EXT2_FEATURE_COMPAT_DIR_INDEX to
-+		make room for pre-existing usage of
-+		EXT2_FEATURE_COMPAT_EXT_ATTR.  Add flag EXT2_INDEX_FL with
-+		the same codepoint as EXT2_BTREE_FL.
-+
-+2001-05-20  Theodore Tso  <tytso@valinux.com>
-+
-+	* ext2fs.h: #include <> instead of "" for ext2fs and et header
-+		files, since they will be installed in /usr/include
-+
-+2001-05-14  Theodore Tso  <tytso@valinux.com>
-+
-+	* alloc.c, alloc_tables.c, badblocks.c, bb_compat.c, bb_inode.c,
-+		bitmaps.c, bitops.c, block.c, bmap.c, bmove.c, brel_ma.c,
-+		check_desc.c, closefs.c, cmp_bitmaps.c, dblist.c,
-+		dblist_dir.c, dir_iterate.c, dirblock.c, dupfs.c,
-+		expanddir.c, ext2_fs.h, fileio.c, finddev.c, flushb.c,
-+		freefs.c, get_pathname.c, getsize.c, icount.c, imager.c,
-+		initialize.c, inline.c, inode.c, irel_ma.c, ismounted.c,
-+		link.c, lookup.c, mkdir.c, mkjournal.c, namei.c, native.c,
-+		newdir.c, nt_io.c, openfs.c, read_bb.c, read_bb_file.c,
-+		rs_bitmap.c, rw_bitmaps.c, swapfs.c, test_io.c,
-+		tst_badblocks.c, tst_byteswap.c, tst_getsize.c,
-+		tst_iscan.c, unix_io.c, unlink.c, valid_blk.c, version.c,
-+		write_bb_file.c, ext2_fs.h: Moved file from include/linux.
-+		Adjust all files in this directroy to include this file.
-+
-+	* mkjournal.c (ext2fs_create_journal_superblock): Remove redundant
-+		code.
-+
-+2001-05-05  Theodore Tso  <tytso@valinux.com>
-+
-+	* fileio.c (ext2fs_file_read): Factored out common code and
-+		cleaned up function.  Fixed a bug where if there was an
-+		error reading from the disk, the number of bytes read
-+		wasn't reliably set.  (Fixes Debian bug #79163)
-+		(ext2fs_file_write): Factored out common code and made
-+		function more efficient; if writing a full block, don't
-+		bother to do a read-modify-write cycle.
-+
-+2001-05-04  Theodore Tso  <tytso@valinux.com>
-+
-+	* dirblock.c (ext2fs_read_dir_block): Check for an directory
-+		record length which isn't a multiple four, and treat that
-+		as an invalid.  Scan the directory and return an error
-+		(EXT2_ET_DIR_CORRUPTED) if the directory records are
-+		corrupted.
-+		(ext2fs_write_dir_block): If while byte-swapping the
-+		directory block, if there's an error, abort and return
-+		EXT2_ET_DIR_CORRUPTED.
-+
-+2001-05-02  Theodore Tso  <tytso@valinux.com>
-+
-+	* ext2fs.h (EXT2_FLAG_IMAGE_FILE): Add new flag, and add
-+		image_header field in the ext2_filsys structure
-+
-+	* block.c (block_iterate_ind, block_iterate_dind, block_iterate_tind): 
-+	* inode.c (ext2fs_read_inode): 
-+	* rw_bitmaps.c (read_bitmaps): 
-+	* openfs.c (ext2fs_open): Add support for EXT2_FLAG_IMAGE_FILE
-+
-+	* imager.c (ext2fs_image_bitmap_read): Fix bug in imager to make
-+		sure the full bitmap is saved.
-+
-+2001-05-01  Theodore Tso  <tytso@valinux.com>
-+
-+	* e2image.h (struct ext2_image_hdr): Add space for the device name
-+		in the image header.
-+
-+	* dir_iterate.c (ext2fs_process_dir_block): Add a double-check to
-+		make sure the rec_len is a multiple of 4, to prevent
-+		bus-errors on architectures which care about mis-aligned
-+		pointer references.
-+
-+2001-04-25  Theodore Tso  <tytso@valinux.com>
-+
-+	* getsize.c (ext2fs_get_device_size): Use an unsigned long to
-+		query the device sizes using the BLKGETSIZE ioctl.
-+
-+2001-04-16  Theodore Tso  <tytso@valinux.com>
-+
-+	* ismounted.c (check_mntent): Check /proc/mounts on Linux systems
-+		before checking /etc/mtab.  The EXT2_MF_READONLY flag is
-+		now set from the /etc/mtab options field for all
-+		filesystems, not just the root filesystem.  Add debugging
-+		code to make it easier to test ext2fs_check_if_mounted().
-+
-+	* mkjournal.c (ext2fs_create_journal_superblock): Add safety
-+		check; return an error if there's an attempt to create a
-+		journal less than 1024 filesystem blocks.
-+
-+	* ext2_err.et.in, mkjournal.c: Change EXT2_JOURNAL_NOT_BLOCK and
-+		EXT2_NO_JOURNAL_SB to be EXT2_ET_*.
-+
-+2001-02-20  Theodore Tso  <tytso@valinux.com>
-+
-+	* bitops.h (ext2fs_swab16, ext2fs_swab32): Add i386 assembly
-+		inline functions.
-+
-+	* tst_byteswap.c: New function to test the byteswap functions.
-+		Add to regression test suite.
-+
-+2001-02-08  Theodore Tso  <tytso@valinux.com>
-+
-+	* e2image.h (struct ext2_image_hdr): Fix type for fs_hostname
-+
-+2001-02-07  Theodore Tso  <tytso@valinux.com>
-+
-+	* mkjournal.c (ext2fs_create_journal_superblock): Fix the setting
-+		of s_first for external devices to always be 1, since
-+		jsb->s_first is always relative to the start of the
-+		journal superblock.  Use htonl(1) when setting s_nr_users.
-+
-+2001-01-17  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* mkjournal.c (ext2fs_add_journal_device): Fix bug where the
-+		device number of the filesystem (instead of the journal)
-+		was being dropped into s_journal_dev.
-+
-+2001-01-15  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* initialize.c (ext2fs_initialize): Add support for initializing
-+		the ext2 superblock for external journal devices.  This
-+		basically means we don't bother to allocate any block
-+		group descriptors.
-+
-+	* openfs.c (ext2fs_open): Only open external journal devices if
-+		the new flag EXT2_FLAG_JOURNAL_DEV_OK is passed to
-+		ext2fs_open.  When opening such devices, don't try to read
-+		the block group descriptors, since they're not there.
-+
-+	* ext2_err.et.in (EXT2_NO_JOURNAL_SB): Add new error code 
-+	
-+	* mkjournal.c: Export a new function,
-+		ext2fs_create_journal_superblock(), which allocates and
-+		returns a buffer containing a journal superblock.  This is
-+		needed by mke2fs to create an external journal.  Rewrote
-+		ext2fs_add_journal_device() so that it no longer creates
-+		the external journal, but rather adds a filesystem to an
-+		existing external journal.  It handles all of the UUID
-+		manipulation.
-+
-+	* ext2fs.h: List the EXT3_FEATURE_JOURNAL_DEV as a flag supported
-+		by the library.  Define the EXT2_FLAG_JOURNAL_DEV_OK.
-+		Changed function prototype for ext2fs_add_journal_device().
-+		
-+2001-01-14  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* closefs.c (ext2fs_flush): Don't write out anything beyond the
-+		 primary superblock if EXT2_INCOMPAT_JOURNAL_DEV is
-+		 listed.
-+
-+2001-01-12  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* imager.c: Fix gcc -Wall complaints and a series of bugs where
-+		retval wasn't set correctly.  (Thanks to Andreas Dilger
-+		for pointing this out.)
-+
-+2001-01-11    <tytso@snap.thunk.org>
-+
-+	* flushb.c (ext2fs_sync_device): New function which centralizes
-+		all of the places which might try to use the BLKFLSBUF
-+		or FDFLUSH ioctls (and usually failing to define them
-+		since the system header files don't usually do this for
-+		us, and we're trying to avoid usage of kernel include
-+		files now).
-+
-+2001-01-10    <tytso@snap.thunk.org>
-+
-+	* alloc.c, bb_inode.c, bitmaps.c, bitops.h, block.c, bmap.c, 
-+		bmove.c, brel.h, cmp_bitmaps.c, dblist.c, dblist_dir.c, 
-+		dir_iterate.c, expanddir.c, ext2fs.h, ext2fsP.h, fileio.c,
-+		finddev.c, get_pathname.c, icount.c, inode.c, irel.h, 
-+		irel_ma.c, ismounted.c, link.c, lookup.c, mkdir.c, 
-+		mkjournal.c, namei.c, newdir.c, read_bb_file.c, test_io.c,
-+		tst_iscan.c, unix_io.c, unlink.c: Change use of ino_t to
-+		ext2_ino_t, to protect applications that attempt to
-+		compile -D_FILE_OFFSET_BITS=64, since this inexplicably
-+		changes ino_t(!?).  So we use ext2_ino_t  to avoid an
-+		unexpected ABI change.
-+
-+2001-01-05    <tytso@snap.thunk.org>
-+
-+	* dirblock.c (ext2fs_read_dir_block): Fix a potential case where
-+		we may overrun allocated memory in case of a corrupted
-+		filesystem (or an e2fsck test case :-) when byte-swapping
-+		the directory block.
-+
-+	* ext2fs.h: Indent the #warning to fix gcc -Wall complaint.
-+
-+	* mkjournal.c (ext2fs_add_journal_device): Fix various gcc -Wall
-+		complaints including a missing return 0 at the end of
-+		ext2fs_add_journal_device.
-+
-+2001-01-03    <tytso@snap.thunk.org>
-+
-+	* Makefile.in: Link in libe2p when creating libext2fs as a shared
-+		library, since mkjournal.c now references fsetflags().
-+
-+	* mkjournal.c (ext2fs_add_journal_inode): Folded in Andreas
-+		Dilger's changes (with fixups) to allow on-line creation
-+		of a journal file.
-+
-+	* ext2fs.h, closefs.c (ext2fs_flush): Add new flag,
-+		EXT2_FLAG_SUPER_ONLY, which the close routines to only
-+		update the superblock, and not the group descriptors.
-+
-+2000-12-30  Andreas Dilger  <adilger@turbolinux.com>
-+
-+	* ismounted.c: add ext2fs_check_mount_point() function, which will
-+		optionally return the mount point of a device if mounted
-+
-+2000-12-14  Andreas Dilger  <adilger@turbolinux.com>
-+
-+	* mkjournal.c: rename ext2fs_add_journal_fs() to the more descriptive
-+		ext2fs_add_journal_inode()
-+
-+2001-01-01    <tytso@snap.thunk.org>
-+
-+	* ext2fs.h: Remove definition of ext2fs_sb.  Note: this may break
-+		source (but not binary) compatibility of some users of the
-+		ext2 library.  They should just simply do a global search
-+		and replace of struct ext2fs_sb with struct
-+		ext2_super_block, and use their own private copy of
-+		ext2_fs.h if they aren't already.
-+
-+	* closefs.c, initialize.c, link.c, newdir.c, openfs.c, swapfs.c:
-+		Replace use of ext2fs_sb with ext2_super_block.
-+
-+2000-12-31    <tytso@snap.thunk.org>
-+
-+	* ext2fs.h: Cleaned up header file by removing definitions of
-+		feature flags that might not have been defined in older
-+		ext2 header files.  Now that we're using our own
-+		include/linux/ext2fs.h header file, this can never happen.
-+
-+	* jfs_dat.h: Removed old header file which is no longer needed.
-+
-+2000-12-13  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* closefs.c (ext2fs_update_dynamic_rev): New function suggested
-+		by Andreas Dilger to update the filesystem revision to
-+		EXT2_DYNAMIC_REV.
-+
-+	* swapfs.c (ext2fs_swap_super): Add byte swapping for the journal
-+		fields.
-+
-+2000-12-09    <tytso@snap.thunk.org>
-+
-+	* ext2fs.h, mkjournal.c (ext2fs_add_journal_inode,
-+		ext2fs_add_journal_device): Add a new argument to the APIs
-+		of these function, which is a flags word.  This is used to
-+		allow the creation of a V1 superblock for those folks who
-+		are using ext3 0.3b in production.  Note, the user-land
-+		interface for getting at this flag won't be documented, as
-+		the V1 superblock is deprecated.
-+
-+	* mkjournal.c (init_journal_superblock): Sync Stephen's changes
-+		which creates a V2 superblock instead of a V1 superblock.
-+
-+2000-11-21    <tytso@snap.thunk.org>
-+
-+	* test_io.c (test_write_blk, test_write_byte): Fix typos pointed
-+		out by Andreas Dilger.
-+
-+2000-11-05    <tytso@snap.thunk.org>
-+
-+	* imager.c (ext2fs_image_{inode,super,bitmap}_{read,write},
-+		ext2_fs.h, Makefile.in: New file that has routines that
-+		save ext2fs metadata to a file.
-+
-+	* ext2_err.et.in (EXT2_ET_MAGIC_E2IMAGE): New error code assigned.
-+
-+	* e2image.h: New file which defines the file format for the ext2
-+		image file.  (Saved copy of ext2 metadata to a file as a
-+		saving throw against worst-case damage.)
-+
-+2000-11-01    <tytso@snap.thunk.org>
-+
-+	* inode.c (ext2fs_flush_icache): Add new function
-+		ext2fs_flush_icache() which flushes the internal inode
-+		cache.  Applications which modify the inode table blocks
-+		directly must call this function.
-+
-+2000-10-26    <tytso@snap.thunk.org>
-+
-+	* mkjournal.c: Add #include of netinet/in.h, since Solaris
-+		requires it for ntohl().
-+
-+	* ext2_io.h (io_channel_write_byte): Add new interface to allow
-+		callers to write specific byte ranges.  This is an
-+		optional interface, which not all IO channels may
-+		implement.
-+
-+	* unix_io.c (unix_write_byte):
-+	* test_io.c (test_write_byte): Add implementation of the
-+		write_byte function.
-+
-+	* closefs.c (write_primary_superblock, ext2fs_flush): Add a new
-+		function which writes the primary superblock.  If the IO
-+		channel supports writing raw bytes directly, only fields
-+		which were modified are written to the disk.  This makes
-+		it safe(r) to use utilities like tune2fs on a mounted
-+		filesystem. 
-+
-+	* freefs.c (ext2fs_free): Free the original superblock if it is
-+		available. 
-+
-+	* openfs.c (ext2fs_open): Store a copy of the original superblock
-+		when opening it.
-+
-+	* ext2fs.h: Add a field to store the original superblock in the
-+		ext2 context structure.
-+
-+2000-10-24    <tytso@snap.thunk.org>
-+
-+	* llseek.c: Add #ifdef's for IA64 (it's a 64-bit platform, so we
-+		don't need to use llseek).
-+
-+2000-10-24    <tytso@valinux.com>
-+
-+	* Makefile.in, ext2fs.h, jfs_dat.h, mkjournal.c: Add functions for
-+		creating an ext3 journal on a filesystem.
-+
-+2000-08-21    <tytso@valinux.com>
-+
-+	* ext2_err.et.in (EXT2_JOURNAL_NOT_BLOCK): Add new error code.
-+
-+2000-08-22    <tytso@valinux.com>
-+
-+	* unix_io.c: Make massive changes to support a multiple block
-+		writethrough cacheing.
-+
-+	* ext2_io.h: Added flags field to the io_channel structure.
-+
-+2000-08-19    <tytso@valinux.com>
-+
-+	* finddev.c, ext2fs.h, Makefile.in: Add new file, finddev.c, which
-+		provides the function ext2fs_find_block_device().  This
-+		function returns the pathname to a block device, given its
-+		device number.
-+
-+2000-07-13    <tytso@valinux.com>
-+
-+	* Release of E2fsprogs 1.19
-+
-+2000-07-07  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* ext2fs.h (EXT2_LIB_FEATURE_INCOMPAT_SUPP): Add
-+		EXT3_FEATURE_INCOMPAT_RECOVER (aka needs_recovery) to the
-+		list of filesystem flags supported by the library.
-+
-+2000-07-04  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* ext2fs.h: Update to include latest journalling additions to the
-+		superblock.
-+
-+	* dll/jump.funcs: Add new jumptable entries for
-+		ext2fs_write_bb_FILE, ext2fs_read_bb_FILE2, and
-+		ext2fs_badblocks_equal.
-+
-+	* tst_badblocks.c: Update test program to test
-+		ext2fs_read_bb_FILE2 and ext2fs_write_FILE.
-+
-+	* write_bb_file.c (ext2fs_write_bb_FILE): New function which
-+		writes out bad blocks list to a file.
-+
-+	* read_bb_file.c (ext2fs_read_bb_FILE2): Add new function which
-+		changes the callback function to take two additional
-+		arguments; a private blind pointer supplied by the caller,
-+		and pointer to a char * containing a pointer to the
-+		invalid string.
-+
-+	* badblocks.c (ext2fs_badblocks_equal): Add new function which
-+		returns true if two badblocks list are equal.
-+
-+	* Makefile.in: Remove explicit link of -lc in the shared library.
-+		(It shouldn't be necessary, and is harmful in some cases).
-+
-+2000-06-10  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* getsize.c (main): Add debugging code under #ifdef DEBUG
-+
-+2000-05-27  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* mkdir.c (ext2fs_mkdir): Read the parent directory's inode
-+		earlier, so that if there's an error reading it, we can
-+		more cleanly back out of the operation.
-+
-+2000-05-25    <tytso@snap.thunk.org>
-+
-+	* getsize.c (ext2fs_get_device_size): Use open64() instead of
-+		open() if it exists.  Under linux, manually define the
-+		ioctl for BLKGETSIZE if it isn't already defined and it's
-+		safe to do so.
-+
-+	* unix_io.c (unix_open): Use open64() instead of open() if it
-+		exists. 
-+
-+	* llseek.c: Simplify header includes of unistd.h.  If lseek64 is
-+		available (and prototypes are defined) use it in
-+		preference to llseek.
-+
-+	* Makefile: Add hack dependency rule so that parallel makes work
-+		correctly. 
-+
-+2000-05-18  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* ext2fs.h: Add appropriate ifdef's to support C++ compilation.
-+
-+2000-04-03  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* block.c: Readibility tweak in conditionals involving
-+		ctx->fs->flags.
-+
-+	* ext2fs.h: Use AUTOCONF SIZEOF_* macros if available to determine
-+		how to define __s64 and __u64.  Turn off "compression is
-+		experimental" warning if the cpp macro
-+		I_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL is defined.
-+
-+2000-02-11    <tytso@snap.thunk.org>
-+
-+	* ext2fs.h: Define EXT2FS_COMPRESSED_BLKADDR and HOLE_BLKADDR.
-+		Conditionally include Compression as a supported type if
-+		ENABLE_COMPRESSION (via --enable-compression) is turned on.
-+
-+	* swapfs.c (ext2fs_swap_super): Swap the compression usage bitmap.
-+
-+2000-02-08    <tytso@snap.thunk.org>
-+
-+	* bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
-+		ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
-+		ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap):
-+		Change to return the previous state of the bit that is
-+		being marked or unmarked.  For speed optimization.
-+	
-+2000-02-02  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* getsize.c, ismounted.c: Remove unneeded include of linux/fs.h
-+
-+	* swapfs.c: Remove #ifdef HAVE_EXT2_INODE_VERSION since it's not
-+		needed any more; we know it will always be i_generation.
-+		Add support for swapping the high bits of the uid and gid.
-+
-+1999-11-19    <tytso@valinux.com>
-+
-+	* mkdir.c (ext2fs_mkdir): Only update the parent's inode link
-+		counts if the link was successful.  Patch suggested by
-+		jeremy@goop.org.
-+
-+	* Makefile.in (distclean): Remove TAGS and Makefile.in.old from
-+		the source directory.
-+
-+1999-11-10    <tytso@valinux.com>
-+
-+	* Release of E2fsprogs 1.18
-+
-+1999-11-08    <tytso@valinux.com>
-+
-+	* Makefile.in (tst_badblocks): Add freefs.o to the object list,
-+		since ext2fs_badblocks_list_free was moved to freefs.c.
-+
-+	* tst_badblocks.c: Use the newer badblocks API names.  Add
-+		duplicate blocks to the test inputs to test dealing with
-+		adding blocks which are already in the badblocks list.
-+
-+	* badblocks.c (ext2fs_badblocks_list_add): If appending to the end
-+		of the list, use a shortcut O(1) operations instead of an
-+		O(n) operation.  (Idea suggested by David Beattie.)
-+
-+	* freefs.c (ext2fs_free): Use ext2fs_badblocks_list_free() instead
-+		of badblocks_list_free(), to save a procedure call.
-+
-+1999-10-26    <tytso@valinux.com>
-+
-+	* Release of E2fsprogs 1.17
-+
-+1999-10-26    <tytso@valinux.com>
-+
-+	* ext2fs.h: Add kludge to deal with the fact that egcs cpp doesn't
-+		seem to handle ~0UL the same way as they used to.
-+
-+1999-10-25    <tytso@valinux.com>
-+
-+	* nt_io.c (_OpenNtName): Open the device using
-+		FILE_SYNCHRONOUS_IO_NONALERT instead of
-+		FILE_SYNCHRONOUS_IO_ALERT
-+		(nt_open): At the end of the device open routine, unlock 
-+		the drive but do not dismount it.
-+
-+	* initialize.c (CREATOR_OS): Use __GNU__ instead of __gnu__ to
-+		detect the Hurd OS.
-+
-+1999-10-22    <tytso@valinux.com>
-+
-+	* Release of E2fsprogs 1.16
-+
-+1999-10-22    <tytso@valinux.com>
-+
-+	* mkdir.c (ext2fs_mkdir): Pass EXT2_FT_DIR flag to ext2fs_link().
-+
-+	* link.c (ext2fs_link): This call now uses the low three bits of
-+		the flags parameter to pass the directory filetype
-+		information; it will set the directory entry FILETYPE
-+		information if the filesystem supports it.
-+
-+	* newdir.c (ext2fs_new_dir_block): If the FILETYPE superblock
-+		option is set, then create the '.' and '..' entries with
-+		the filetype set to EXT2_FT_DIR.
-+
-+1999-09-24    <tytso@valinux.com>
-+
-+	* nt_io.c: New file which supports I/O under Windows NT.
-+
-+1999-09-07    <tytso@valinux.com>
-+
-+	* ext2fs.h: Add new fields for journalling and define new
-+		feature bits used by newer filesystems: IMAGIC_INODES,
-+		HAS_JOURNAL, RECOVER.
-+
-+	* expanddir.c (ext2fs_expand_dir, expand_dir_proc): Change where
-+		we update the inode block count and size files so that the
-+		block count field is updated correctly when we create an
-+		indirect block.
-+
-+1999-07-18  Theodore Ts'o  <tytso@valinux.com>
-+
-+	* Release of E2fsprogs 1.15
-+
-+1999-06-23    <tytso@valinux.com>
-+
-+	* swapfs.c (ext2fs_swap_inode): Add compatibility for Linux 2.3
-+		kernels that use i_generation instead of i_version.  Patch
-+		supplied by Jon Bright <sircus@sircus.demon.co.uk>.
-+
-+1999-06-21    <tytso@valinux.com>
-+
-+	* dir_iterate.c (ext2fs_process_dir_block): Check for corrupted
-+		directory entry before calling the callback function.
-+		This should prevent some core dumps of insufficiently
-+		paranoid callback functions.
-+
-+1999-05-29    <tytso@rsts-11.mit.edu>
-+
-+	* ext2fs.h: Add feature definition for AFS IMAGIC inodes.
-+
-+	* fileio.c (ext2fs_file_open): Remove obsolete comment stating
-+		that we don't handle writing yet (we do).  Fixed bug where
-+		we weren't allocating a big enough buffer for ext2_bmap.
-+
-+1999-05-03    <tytso@rsts-11.mit.edu>
-+
-+	* openfs.c (ext2fs_open): Check to make sure that the number of
-+		blocks per group is not zero --- if so, it must be a bad
-+		superblock!
-+
-+1999-01-09  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Release of E2fsprogs 1.14
-+
-+1999-01-07  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_read_inode, ext2fs_write_inode): Check to see if
-+		the inode number is zero; if it's zero, return
-+		EXT2_ET_BAD_INODE_NUM.
-+
-+1998-12-30  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* initialize.c (ext2fs_initialize): Use EXT2_FIRST_INODE instead
-+		of EXT2_FIRST_INO to ensure compatibility with Linux 1.2
-+		header files.
-+
-+Mon Jan  4 02:32:09 1999  Theodore Y. Ts'o  <tytso@mit.edu>
-+
-+	* llseek.c (ext2fs_llseek): Change ext2fs_llseek() in the
-+ 		non-Linux case to use EINVAL by default, unless it isn't
-+ 		defined, in which case we use EXT2_ET_INVALID_ARGUMENT
-+ 		instead.
-+
-+1998-12-15  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Release of E2fsprogs 1.13
-+
-+1998-12-03  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Makefile.in: Updated dependencies.
-+
-+1998-09-22  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* initialize.c (ext2fs_initialize): Make sure that we allocate
-+		enough inodes so that we can make a valid filesystem.
-+
-+1998-09-02  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* rw_bitmaps.c: Fixed signed/unsigned warnings.
-+
-+	* fileio.c (ext2fs_file_set_size): Remove unneeded extern from the
-+		function declaration.
-+
-+	* dblist.c (make_dblist): Add safety check in case the dblist
-+		pointer passed in is null (in which case, assign it to
-+		fs->dblist).  Fixed some signed/unsigned warnings.
-+
-+	* bmap.c: Make addr_per_block be of type blk_t to avoid
-+		signed/unsigned warnings.
-+
-+	* namei.c (ext2fs_follow_link): Remove uneeded extern from the
-+		function declaration.
-+
-+	* get_pathname.c (get_pathname_proc): Use return value from
-+		ext2fs_get_mem, instead of checking if &gp->name is
-+		NULL.
-+
-+	* dir_iterate.c (ext2fs_process_dir_block): 
-+	* dblist_dir.c (ext2fs_dblist_dir_iterate): Remove uneeded extern
-+		from the function declaration.
-+
-+	* block.c (ext2fs_block_iterate2): If the read_inode call fails,
-+		return the error directly instead of jumping to the
-+		cleanup routine, since we don't need to do any cleanup.
-+
-+	* alloc_table.c (ext2fs_allocate_group_table): Make this
-+		function take a dgrp_t for its group argument.
-+
-+	* ext2fs.h: Make dgrp_t an __u32 type, and make
-+		fs->desc_group_count be of type dgrp_t.
-+
-+1998-07-27  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* badblocks.c (ext2fs_badblocks_list_add): Use a bigger increment
-+		than 10 blocks when we need to expand the size of the
-+		badblocks list.
-+
-+1998-07-09  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Release of E2fsprogs 1.12
-+
-+1998-06-30  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* closefs.c (ext2fs_flush): Update the s_block_group_nr field as
-+		appropriate for all of the block group copies, so that
-+		it's clear where the beginning of the filesystem is on the
-+		disk.  (For when the partition table gets scrod.)
-+
-+	* ext2fs.h: Change the name of the feature from
-+		EXT2_FEATURE_INCOMPAT_DIRNAME_SIZE to
-+		EXT2_FEATURE_INCOMPAT_FILESIZE (to match with the kernel).
-+
-+1998-06-18  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (get_next_blockgroup): Fix bug where if
-+		get_next_blockgroup() is called early because of a missing
-+		inode table in a block group, the current_inode counter
-+		wasn't incremented correctly.
-+
-+1998-06-16  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* read_bb.c (ext2fs_read_bb_inode): Make function more robust
-+		against a completely trashed bad block inode.
-+
-+1998-06-10  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* alloc_tables.c (ext2fs_allocate_group_table): Fix bug so that if
-+		the stride length hits a bad value, we retry the block
-+		allocation starting at the beginning of the block group.
-+
-+	* ext2fs.h, bb_inode.c, block.c, bmove.c, dir_iterate.c,
-+		expanddir.c, ext2fsP.h, read_bb.c: Change blkcnt_t to be
-+		e2_blkcnt_t to avoid collision with LFS API.
-+
-+1998-05-01  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* initialize.c (ext2fs_initialize): Initialize s_inodes_count in a
-+		way that avoids overflows on disk sizes greater than 4GB.
-+
-+1998-04-28  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* ext2fs.h: Define EXT2_QSORT_TYPE appropriately for the
-+		return type for comparison functions for qsort.
-+
-+	* dblist.c (dir_block_cmp): Use EXT2_QSORT_TYPE in function
-+		declaration.
-+
-+1998-04-26  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* ext2fs.h, bitops.h: Add support for the Watcom C compiler to do
-+		inline functions.
-+
-+	* ext2fs.h, dosio.c: Use asm/types.h instead of linux/types.h to
-+		evade a potential problem with glibc's header files trying
-+		to spike out linux/types.h.
-+
-+	* ext2fs.h (ext2fs_resize_mem): Change the function prototype to
-+		include the old size of the memory, which is needed for
-+		some braindamaged memory allocation systems that don't
-+		support realloc().
-+
-+	* badblocks.c (ext2fs_badblocks_list_add):
-+	  bb_inode.c (clear_bad_block_proc):
-+	  dblist.c (ext2fs_add_dir_block):
-+	  icount.c (insert_icount_el):
-+	  irel_ma.c (ima_put):
-+	  rs_bitmap.c (ext2fs_resize_generic_bitmap): Update functions to
-+		  pass the old size of the memory to be resized to
-+		  ext2fs_resize_mem(). 
-+
-+1998-03-30  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Makefile.in: Change to use new installation directory variables
-+		convention.  Fix uninstall rules to take $(DESTDIR) into
-+		account.
-+
-+1998-03-29  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* ext2fs.h: If __STRICT_ANSI__ is defined and we're on a platform
-+		with 32 bit longs, then we need to manually define __s64
-+		and __u64, since the current kernel header files don't
-+		define these if __STRICT_ANSI__ is defined.  This is a
-+		problem if we are compiling with full GCC warnings, since
-+		we do need 64 bit support.
-+	
-+	* Makefile.in (OBJS): Remove bmove.o from files to be built,
-+		since we're not using ext2fs_move_blocks() and there
-+		is some question as to its usefulness in its current
-+		form.
-+
-+	* bmap.c (block_bmap): Remove unused function.
-+
-+	* bmove.c (process_block): Fix -Wall warning.
-+
-+1998-03-23  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* block.c (ext2fs_block_iterate3): Make the ref_offset field
-+		contain the offset into the inode.i_blocks array when
-+		ref_block is zero.  Since we haven't done a formal
-+		release of e2fsprogs since block_iterate2 was first
-+		introduced, I removed block_iterate2, and renamed
-+		block_iterate3 to be block_iterate2.
-+
-+	* bb_inode.c, bmove.c, dblist_dir.c, dir_iterate.c,
-+		expanddir.c, ext2fs.h, ext2fsP.h, read_bb.c: Change
-+		use of block_iterate and block_iterate2 to
-+		block_iterate2 with the new prototype for the
-+		interator function.  (using blkcnt_t forr blockcount)
-+
-+1998-03-21  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* ext2fs.h: Add new superblock fields (s_algorithm_usage_bitmap, 
-+		s_prealloc_blocks, s_prealloc_dir_blocks).  Added
-+		conditional defines of new features COMPAT_DIR_PREALLOC,
-+		RO_COMPAT_LARGE_FILE RO_COMPAT_BTREE_DIR,
-+		INCOMPAT_COMPRESSION, INCOMPAT_DIRNAME_SIZE.  Changed
-+		the library to declare that we support COMPAT_DIR_PREALLOC, 
-+		INCOMPAT_DIRNAME_SIZE, RO_COMPAT_LARGE_FILE.
-+
-+	* fileio.c: Rename function ext2fs_file_llseek to be
-+		ext2fs_file_lseek, which is more accurate.
-+
-+	* block.c: Add new function ext2fs_block_iterate3 which calls
-+		the iterator function with the blockcount argument of
-+		type blkcnt_t.  This version of the function is
-+		allowed to handle large files; the other fucntions are
-+		not.
-+
-+	* ext2fs.h: Add new type blkcnt_t
-+
-+	* ext2_err.et.in: Add error code EXT2_ET_FILE_TOO_BIG
-+
-+	* block.c (ext2fs_block_iterate2): Fix bug where the block count
-+		field wasn't getting correctly incremented for sparse
-+		files when the indirect or doubly-indirect block
-+		specified in the inode was zero.
-+
-+Sun Mar  8 22:42:47 1998  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* unlink.c (unlink_proc): 
-+	* lookup.c (lookup_proc): 
-+	* link.c (link_proc): 
-+	* get_pathname.c (get_pathname_proc): 
-+	* dir_iterate.c (ext2fs_process_dir_block): Mask off high 8 bits
-+		from dirent->name_len, so it can be used for other
-+		purposes.
-+
-+	* ext2fs.h: Add definition of EXT2_FEATURE_INCOMPAT_DIRNAME_SIZE,
-+		and indicate that we have support for this incompatible
-+		option.
-+
-+Mon Feb 23 08:46:33 1998  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* ext2_err.et.in: Added new error code, EXT2_ET_CANCEL_REQUESTED.
-+
-+Fri Feb 20 23:58:01 1998  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* dblist.c (ext2fs_get_num_dirs): Improve the estimation of the
-+ 		number of directories when the block group information is
-+ 		unreliable.
-+
-+1998-02-20  Theodore Y. Ts'o  <tytso@edt.mit.edu>
-+
-+	* inode.c (ext2fs_get_next_inode): Always do the check to see if the
-+		inode table is missing so that we catch the case where the
-+		first block group is missing.
-+
-+	* getsize.c, ismounted.c, unix_io.c: #include errno.h since it's
-+		needed.
-+
-+Mon Feb 16 16:16:00 1998  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* ext2_io.h, ext2fs.h: Protect against being included multiple times.
-+
-+	* bmove.c: #include ext2fsP.h instead of "ext2fs/ext2fs.h"
-+
-+	* test_io.c (test_flush): Add a debugging printf when the flush
-+		method is called.
-+
-+	* rw_bitmaps.c (ext2fs_read_bitmaps): If the bitmaps are already
-+		read in, return right away.
-+
-+Sun Feb  1 08:20:24 1998  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* bitops.h: Don't try to do i386 inline asm functions if the
-+ 		compiler isn't GCC.
-+
-+	* ext2fs.h: If EXT2_FLAT_INCLUDES is defined, #include e2_types.h,
-+ 		instead of linux/types.h, and e2_bitops.h instead of
-+ 		ext2fs/bitops.h.
-+
-+	* icount.c, version.c: Don't #include <et/com_err.h>, as it isn't
-+		necessary. 
-+
-+Sat Jan 17 13:13:31 1998  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_open_inode_scan): Initialize the group variables
-+		so that we don't need to call get_next_blockgroup() the
-+		first time around.  Saves a bit of time, and prevents us
-+		from needing to assign -1 to current_group (which is an
-+		unsigned value).
-+
-+	* icount.c (insert_icount_el): Cast the estimated number of inodes
-+		from a float to an ino_t.
-+
-+	* alloc.c, alloc_tables.c, badlbocks.c, bb_compat.c, bb_inode.c,
-+ 		bitmaps.c, bitops.c, block.c, bmap.c, bmove.c, brel_ma.c,
-+ 		check_desc.c, closefs.c, cmp_bitmaps.c, dblist.c,
-+ 		dblist_dir.c, dir_iterate.c, dirblock.c, dupfs.c,
-+		expanddir.c, ext2fs.h, fileio.c, freefs.c,
-+		get_pathname.c, getsize.c, icount.c, initialize.c,
-+		inline.c, inode.c, irel_ma.c, ismounted.c, link.c,
-+		lookup.c, mkdir.c, namei.c, native.c, newdir.c,
-+		openfs.c, read_bb.c, read_bb_file.c, rs_bitmap.c,
-+		rw_bitmaps.c, swapfs.c, test_io.c, tst_badblocks.c,
-+		tst_getsize.c, tst_iscan.c, unix_io.c, unlink.c,
-+		valid_blk.c, version.c: If EXT2_FLAT_INCLUDES is
-+		defined, then assume all of the
-+ 		ext2-specific header files are in a flat directory.
-+
-+	* block.c, bmove.c, dirblock.c, fileio.c: Explicitly cast
-+		all assignments from void * to be compatible with C++.
-+
-+Tue Jan  6 11:28:15 1998  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* closefs.c (ext2fs_flush): Add a call to io_channel_flush() to
-+		make sure the contents of the disk are flushed to disk.
-+
-+Mon Dec 29 14:39:13 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* dblist.c (ext2fs_add_dir_block): Change new to be new_entry to
-+		avoid C++ namespace clash.
-+
-+	* bitmaps.c (ext2fs_copy_bitmap): Change new to be new_map to
-+		avoid C++ namespace clash.
-+
-+	* ext2fs.h, bb_inode.c, block.c, bmove.c, brel.h, brel_ma.c,
-+ 	 	irel.h, irel_ma.c, dblist.c, dblist_dir.c, dir_iterate.c,
-+ 	 	ext2fsP.h, expanddir.c, get_pathname.c, inode.c, link.c,
-+ 	 	unlink.c: Change private to be priv_data (to avoid C++
-+ 	 	namespace clash)
-+
-+Fri Nov 28 09:26:31 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* dblist.c (ext2fs_get_num_dirs): Make ext2fs_get_num_dirs more
-+		paranoid about validating the directory counts from the
-+		block group information.
-+
-+	* all files: Don't include stdlib.h anymore; include it in
-+		ext2_fs.h, since that file requires stdlib.h
-+
-+Thu Nov 20 16:07:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* expanddir.c (ext2fs_expand_dir): Check to make sure the block
-+		bitmap is loaded, and return an error if it is not.
-+		(expand_dir_proc): Only use ext2fs_write_dir_block when
-+		writing a directory block, not when writing out a fresh
-+		indirect block.
-+
-+Tue Nov 11 22:46:45 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Makefile.in, tst_getsize.c: Added new file which is used to test
-+		the ext2fs_get_device_size function.
-+
-+	* ext2_err.et.in (EXT2_ET_UNIMPLEMENTED): Added new error code.
-+
-+Sun Nov  2 20:36:13 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* ext2fs.h: Make ext2fs_get_mem take an unsigned argument.
-+
-+	* fileio.c (ext2fs_file_get_size, ext2fs_file_set_size,
-+		ext2fs_file_get_fs): New functions added.
-+
-+
-+Fri Oct 31 12:16:52 1997    <tytso@EDT.MIT.EDU>
-+
-+	* bitops.c (ext2fs_warn_bitmap, ext2fs_warn_bitmap2): Don't call
-+	 	com_err if OMIT_COM_ERR is defined.
-+
-+Thu Oct 30 11:33:57 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Rename new error codes to _ET_ in them for consistency.
-+
-+Sat Oct 25 00:06:58 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* [all files, basically]: Added definition of ext2fs_get_mem, 
-+		ext2fs_free_mem, and ext2fs_resize_mem in ext2fs.h, and
-+		changed all library routines to use these wrapper functions.
-+
-+	* dblist.c, mkdir.c: use EXT2_DIR_EXISTS and EXT2_DB_NOT_FOUND
-+		instead of the system error messages.
-+	
-+	* ext2_err.et.in: Added new error messages EXT2_DIR_EXISTS and
-+	 	EXT2_DB_NOT_FOUND
-+
-+	* ext2fs.h: Added function declarations and constants for bmap.c
-+	 	and fileio.c.
-+
-+	* ext2_err.et.in: Added new error messages EXT2_FILE_RO and
-+	 	EXT2_ET_MAGIC_EXT2_FILE
-+
-+	* Makefile.in: Added files bmap.c and fileio.c, and temporarily
-+		commented out brel_ma.c and irel_ma.c
-+
-+	* bmap.c: New file which maps a file's logical block number to its
-+		physical block number.
-+
-+	* fileio.c: New file which implements simple file reading and
-+		writing primitives.
-+
-+	* alloc.c (ext2fs_alloc_block): New function which allocates a
-+ 		block, zeros it, and updates the filesystem accounting
-+ 		records appropriately.
-+
-+Wed Oct 22 16:47:27 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* ext2_err.et.in: Added new error codes: EXT2_NO_MEMORY,
-+		EXT2_INVALID_ARGUMENT, EXT2_BLOCK_ALLOC_FAIL,
-+		EXT2_INODE_ALLOC_FAIL, EXT2_NOT_DIRECTORY
-+
-+	* Change various library files to use these functions instead of
-+		EINVAL, ENOENT, etc.
-+
-+Mon Oct 20 19:32:40 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* llseek.c: Check HAVE_LLSEEK_PROTOTYPE to see whether or not we
-+		need to declare llseek().
-+
-+Sun Oct 19 18:56:22 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Rename io.h to be ext2_io.h (avoid namespace collisions)
-+
-+	* Add #ifdef's for HAVE_SYS_STAT_H and HAVE_SYS_TYPES_H
-+
-+Fri Oct  3 13:35:59 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* llseek.c (ext2fs_llseek): Fix type error for ext2fs_llseek()
-+
-+	* icount.c (ext2fs_icount_validate): 
-+	* bmove.c (process_block): Fix lint error in type for fprintf().
-+
-+Mon Sep 15 11:45:09 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_check_directory): Add support for the callback
-+		to return the error code EXT2_ET_CALLBACK_NOTHANDLED.
-+
-+Thu Sep  4 12:28:22 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* bitmaps.c (ext2fs_set_bitmap_padding): New function which sets the
-+		padding of the bitmap to be all one's.
-+
-+Wed Sep  3 14:27:30 1997  Theodore Y. Ts'o  <tytso@edt.mit.edu>
-+
-+	* llseek.c: Added missing semicolon to glibc fixup declaration of
-+ 	llseek().
-+
-+	* bmove.c: Add #include of errno.h
-+
-+Sat Aug 23 22:47:46 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Makefile.in (ELF_SO_VERSION): Bump version to be 2.4 since we've
-+		added a new field to the io_channel (app_data).
-+
-+	* io.h: Add a new element to the io_channel structure, app_data.
-+
-+	* initialize.c, openfs.c: Set io->app_data to point at the
-+	 	filesystem handle.
-+
-+Thu Aug 14 08:14:17 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* io.h: Change the prototype of ext2fs_llseek() to use int's
-+		instead of unsigned int's.
-+
-+	* llseek.c: Change to allow PIC and !HAVE_LLSEEK.  Add a prototype
-+		to make life easer for GNU Libc 2.
-+
-+	* rw_bitmaps.c: On the PowerPC, the big-endian variant of the ext2
-+ 		filesystem has its bitmaps stored as 32-bit words with bit
-+ 		0 as the LSB of each word.  Thus a bitmap with only bit 0
-+ 		set would be, as a string of bytes, 00 00 00 01 00 ...  To
-+ 		cope with this, we byte-reverse each word of a bitmap if
-+ 		we have a big-endian filesystem, that is, if we are *not*
-+ 		byte-swapping other word-sized numbers.
-+
-+Mon Aug 11 03:30:48 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* dosio.c: New file to do DOS/BIOS disk accesses.
-+
-+	* namei.c (open_namei): Make pathlen be of type size_t.
-+
-+	* llseek.c: Always #include stdlib.h since it's need to define
-+		size_t.  
-+
-+	* io.h: Use errcode_t for magic numbers.
-+
-+	* icount.c (get_icount_el): Use size_t where appropriate
-+	
-+	* dupfs.c (ext2fs_dup_handle): 
-+	* dblist.c (dir_block_cmp): Use size_t where appropriate.
-+
-+	* read_bb.c (ext2fs_read_bb_inode): 
-+	* cmp_bitmaps.c (ext2fs_compare_inode_bitmap): Use blk_t, ino_t
-+		and size_t where appropriate.
-+
-+	* closefs.c (ext2fs_flush): Use dgrp_t instead of int where
-+		appropriate.
-+
-+	* openfs.c (ext2fs_open): 
-+	* check_desc.c (ext2fs_check_desc): Use blk_t instead of int where
-+		appropriate.
-+
-+	* rw_bitmaps.c (read_bitmaps): 
-+	* irel_ma.c: 
-+	* inode.c (ext2fs_write_inode): 
-+	* initialize.c (ext2fs_initialize):
-+	* brel_ma.c: Fix to make be 16-bit safe.
-+
-+	* link.c (ext2fs_link): 
-+	* unlink.c (ext2fs_unlink):
-+	* lookup.c (lookup_proc): 
-+	* ismounted.c (ext2fs_check_if_mounted): 
-+	* block.c (xlate_func): Add #pragma argsused for Turbo C.
-+
-+Sun Aug 10 10:05:22 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* block.c (ext2fs_block_iterate2): Use retval which is a errcode_t
-+		type.
-+
-+	* bitmaps.c (make_bitmap): Use size_t instead of int where
-+		appropriate.
-+
-+	* bb_inode.c (set_bad_block_proc): Add #pragma argsused for Turbo C.
-+
-+	* alloc.c (ext2fs_new_inode): Use ino_t instead of int for the
-+		group number.
-+
-+	* get_pathname.c: Use ino_t instead of int where appropriate.
-+
-+	* ext2fs.h: Make the magic structure element be errcode_t instead
-+		of int.
-+
-+	* alloc.c alloc_tables.c badblocks.c bb_compat.c bb_inode.c
-+ 	 	bitmaps.c block.c bmove.c brel_ma.c check_desc.c closefs.c
-+ 	 	cmp_bitmaps.c dblist.c dblist_dir.c dir_iterate.c
-+ 	 	dirblock.c dupfs.c expanddir.c freefs.c get_pathname.c
-+ 	 	icount.c initialize.c inline.c inode.c irel_ma.c link.c
-+ 	 	llseek.c lookup.c mkdir.c namei.c newdir.c read_bb.c
-+ 	 	read_bb_file.c rs_bitmap.c rw_bitmaps.c swapfs.c 
-+ 	 	test_io.c tst_badblocks.c tst_iscan.c unix_io.c unlink.c
-+ 	 	valid_blk.c version.c: Add an #ifdef for HAVE_UNISTD_H
-+
-+Tue Jun 17 01:33:20 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* unix_io.c (unix_read_blk): If ext2fs_llseek() fails, but errno
-+		is zero, then return EXT2_IO_LLSEEK_FAILED.
-+
-+	* ext2_err.et.in: Add a new error code, EXT2_IO_LLSEEK_FAILED.
-+
-+	* Release of E2fsprogs 1.11
-+
-+Mon Jun 16 23:53:06 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* dblist.c (ext2fs_dblist_count): Added new function which returns
-+		the number of directory blocks in dblist.
-+
-+Sat Jun 14 01:39:13 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* unix_io.c (unix_flush): Make the io_channel flush function do a
-+		fsync to flush the kernel buffers to disk.
-+
-+Wed Jun 11 18:25:31 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_inode_scan_goto_blockgroup): Fix bug; the
-+		current inode number wasn't being set by the
-+		goto_blockgroup function.
-+
-+Mon Jun  9 10:45:48 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* bmove.c (ext2fs_move_blocks): New function which takes a bitmap
-+		of blocks which need to be moved, and moves those blocks
-+		to another location in the filesystem.
-+
-+	* rs_bitmap.c (ext2fs_resize_generic_bitmap): When expanding a
-+		bitmap, make sure all of the new parts of the bitmap are
-+		zero. 
-+
-+Sun Jun  8 16:24:39 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* bitmaps.c (ext2fs_copy_bitmap): Fix bug; the destination bitmap
-+		wasn't being returned to the caller.
-+
-+	* alloc_tables.c (ext2fs_allocate_group_table): Add new function
-+		ext2fs_allocate_group_table() which sets the group tables
-+		for a particular block group.  The relevant code was
-+		factored out of ext2fs_allocate_tables().
-+
-+	* dblist.c (make_dblist): Adjust the initial size of the directory
-+ 		block list to be a bit more realistic (ten plus twice the
-+ 		number of directories in the filesystem).
-+
-+Thu May  8 22:19:09 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* badblocks.c (ext2fs_badblocks_list_test): Fix bug where
-+ 		ext2fs_badblocks_list_test would test the list (and exceed
-+ 		array boundaries) if there were no bad blocks on the bad
-+ 		blocks list.  (Showed up when user tried: mke2fs -c -b 4096).
-+
-+Thu Apr 24 12:16:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
-+
-+	* Release of E2fsprogs version 1.10
-+
-+Thu Apr 24 10:13:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
-+
-+	* alloc_tables.c (ext2fs_allocate_tables): Correctly place the
-+		inode and block bitmaps based on the RAID 0 stride
-+		parameter (which is passed by mke2fs).
-+
-+	* ext2fs.h: Add "stride" parameter to ext2_filsys, to be used by
-+ 		mke2fs to communicate the stride length to
-+ 		ext2fs_allocate_tables()
-+
-+Wed Apr 23 21:50:42 1997  Theodre Ts'o  <tytso@localhost.mit.edu>
-+
-+	* initialize.c (ext2fs_initialize): Fix to compile under Linux 1.2
-+		systems.  (We can't assume that the new filesystem types
-+		are supported.)
-+
-+Wed Apr 23 18:40:53 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* alloc_tables.c (ext2fs_allocate_tables): Make sure that we
-+		allocate the inode and block bitmaps inside block group at
-+		all times.
-+
-+Mon Apr 21 00:06:28 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* alloc.c (ext2fs_new_block): Fix bug where if goal==0 and the
-+		filesystem has no free blocks, ext2fs_new_block would loop
-+		forever.
-+
-+	* dupfs.c (ext2fs_dup_handle): Duplicate an ext2 filesystem handle
-+
-+	* freefs.c (ext2fs_free_inode_cache): Decrement refcount and only
-+		free if refcount goes to zero.
-+
-+	* inode.c (create_icache): Initialize refcount to 1.
-+
-+	* ext2fsP.h: Added refcount to ext2_inode_cache
-+
-+	* dblist.c (ext2fs_copy_dblist): New function to copy a directory
-+		block list.
-+
-+	* badblocks.c (ext2fs_badblocks_copy): New function to copy a
-+		badblocks structure.
-+
-+Sun Apr 20 23:19:51 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* bitmaps.c (ext2fs_copy_bitmap): New function to copy a bitmap.
-+
-+	* unix_io.c, test_io.c (unix_open, test_open): Initialize the
-+ 	 	refcount to 1.
-+		(unix_close, test_close): Decrement the refcount and only
-+ 		close the io_channel if the refcount goes to 0.
-+
-+	* io.h: Add refcount to the io_channel structure.  Add new macro
-+		interface io_channel_bumpcount() to bump the refcount.
-+
-+Thu Apr 17 20:25:03 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_read_inode, ext2fs_write_inode): Use the inode
-+		cache in the filesystem handle, instead of the inode cache
-+		in a static variable.
-+
-+	* freefs.c: Added static function to free the inode cache (called by
-+		ext2fs_free). 
-+
-+	* ext2fsP.h: Added definition of the ext2_inode_cache structures.
-+
-+	* ext2fs.h: Added pointer to the inode_cache structure.
-+
-+	* block.c (block_iterate_ind, block_iterate_dind, 
-+		block_iterate_tind): If there are holes in the indirect,
-+		doubly indirect, or triply indirect blocks, increment the
-+		block count field automatically.
-+
-+Thu Apr 17 12:23:38 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Release of E2fsprogs version 1.09
-+
-+Mon Apr 14 20:38:56 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* version.c (ext2fs_parse_version_string): Check the passed in
-+		version string (instead of the hard-coded one).
-+
-+	* alloc_tables.c (ext2fs_allocate_tables): If the last block is
-+		greater filesystem size, clamp it to prevent allocating a
-+		block or inode bitmap beyond the filesystem.
-+
-+	* initialize.c (ext2fs_initialize): Fix bug where the metatdata
-+	 	overhead calculation was accidentally removed.
-+
-+Fri Apr 11 18:56:26 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Release of E2fsprogs version 1.08
-+
-+Thu Apr 10 13:15:15 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* dblist.c (ext2fs_set_dir_block): New function which sets the
-+ 		block of a dblist entry, given the directory inode and
-+ 		blockcnt.
-+
-+Sat Apr  5 12:42:42 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* alloc_tables.c (ext2fs_allocate_tables): Allocate the bitmap and
-+		inode bitmaps at staggered locations across the block
-+		groups, to avoid concentrating the bitmaps on a small
-+		number of disks when using striped RAID arrays.
-+
-+	* initialize.c (ext2fs_initialize): By default, choose the maximum
-+		possible number of blocks per group (based on the size of
-+		the bitmaps in the blocksize).
-+
-+Fri Apr  4 11:28:16 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* initialize.c (ext2fs_initialize): Add support for
-+		EXT2_COMPAT_SPARSE_SUPER feature.
-+
-+	* closefs.c (ext2fs_bg_has_super): New function to determine
-+		whether or a particular block group should have a
-+		superblock and block group descriptor.  Used for the
-+		EXT2_COMPAT_SPARSE_SUPER feature is turned on.
-+		(ext2fs_flush):  Check ext2fs_bg_has_super to see whether
-+		or not the superblock should be written out for the block
-+		group. 
-+
-+	* ext2fs.h (EXT2_COMPAT_SPARSE_SUPER): Define compatibility flag
-+		for sparse duplicate superblocks.
-+
-+	* version.c (ext2fs_get_library_version): New function which
-+		returns the library version.
-+
-+	* version.c (ext2fs_parse_version_string): New function which
-+		parses a version string and returns a version number,
-+		so application programs can compare version numbers as
-+		integers.
-+
-+Wed Mar 26 00:43:52 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* icount.c (ext2fs_create_icount): Change function so that it also
-+		takes a new argument which contains a "hint" icount
-+		structure.  This "hint" icount allows the create function
-+		to set up the sorted list in advance.  This reduces
-+		significantly the amount of data moving needed to insert
-+		these inodes into the list later.
-+	
-+	* icount.c (ext2fs_icount_validate): New function which validates
-+		that the icount structure's rep invariant.
-+
-+	* icount.c (get_icount_el): Completely revamped implementation
-+		to subsume put_icount_el().  Put_icount_el() used to
-+		use an O(N) implementation to insert in the middle
-+		of the icount list.  It now uses a O(ln N) to search
-+		for where the icount should be inserted, and then uses
-+		a memcpy to move the list down (instead of a for loop).
-+	
-+	* icount.c (ext2fs_icount_fetch, ext2fs_icount_store,
-+ 		ext2fs_icount_increment, ext2fs_icount_decrement): Check
-+ 		to see if the inode is within bounds; if it isn't, return
-+ 		EINVAL.
-+
-+	* bitops.h (ext2fs_test_generic_bitmap): Fix error message given
-+ 		when a bad inode number is passed to test_generic_bitmap
-+ 		to be EXT2FS_TEST_ERROR instead of the wrong
-+ 		EXT2FS_UNMARK_ERROR.
-+
-+Wed Mar 12 13:32:05 1997  Theodore Y. Ts'o  <tytso@mit.edu>
-+
-+	* Release of E2fsprogs version 1.07
-+
-+Sun Mar  2 16:46:18 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Makefile.in (ELF_VERSION): Change version to be 2.2
-+
-+Tue Feb 11 14:54:02 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* alloc.c (ext2fs_get_free_blocks): Change routine to use
-+	 	ext2fs_fast_test_block_bitmap_range().
-+
-+	* bitops.h (ext2fs_fast_test_block_bitmap_range,
-+ 		ext2fs_test_block_bitmap_range: New inline functions which
-+ 		test to see whether a contiguous range of blocks is
-+ 		available.
-+
-+Thu Feb  6 10:00:13 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* badblocks.c (ext2fs_badblocks_list_create): Rename sybmols to use
-+ 		use ext2fs_badblocks_* instead of badblocks_*
-+
-+	* bb_compat.c: New file which translates between old badblocks_*()
-+		names to ext2fs_badblocks_*()
-+
-+	* unlink.c (ext2fs_unlink): New file, moved ext2fs_unlink() from
-+	 	link.c (since e2fsck doesn't use ext2fs_unlink()).
-+
-+	* rs_bitmap.c (ext2fs_resize_generic_bitmap): New file, contains
-+ 		bitmap resizing routine moved from bitmaps.c, since e2fsck
-+ 		doesn't need to use this function.
-+
-+	* lookup.c (ext2fs_lookup): Moved ext2fs_lookup to its own file,
-+		since e2fsck only needs ext2fs_lookup.
-+
-+Mon Feb  3 10:11:40 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_open_inode_scan): Set fs->badblocks if it is not
-+		already set; this is needed so that programs like dump
-+		which use the inode scan functions will deal with
-+		filesystems that have bad blocks in the inode table.
-+
-+Sun Feb  2 00:17:36 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* ext2fs.h (struct_badblocks_list, struct_badblocks_iterate): 
-+		Moved to ext2fsP.h, since it doesn't need to be part of
-+		the public interface.
-+
-+	* dir_iterate.c: Move ext2_dir_iterate out of namei.c.
-+
-+Sat Feb  1 10:14:55 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* dblist.c (ext2fs_get_num_dirs): New file, which implements a
-+ 		directory block list abstraction.  (Code moved from
-+ 		e2fsck).
-+
-+	* ext2fs.h, inode.c: Moved definition of ext2_struct_inode_scan to
-+		to inode.c (since no one else should be peeking inside it!)
-+
-+	* valid_blk.c (ext2_inode_has_valid_blocks): New function.
-+
-+	* openfs.c (ext2fs_open): Check the feature set in the ext2
-+		superblock, and refuse to open filesystems if they contain
-+		incompatible features.  (Can be overriden with the
-+		EXT2_FLAG_FORCE 
-+
-+Sun Jan 12 11:31:46 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* block.c (ext2fs_block_iterate2): Added new function
-+	 	ext2fs_block_iterate2 which changes the function
-+	 	signature of the callback function to include the
-+	 	referencing block and offset.
-+
-+	* inode.c (ext2fs_inode_scan_goto_blockgroup): Added new function
-+	 	ext2fs_inode_scan_goto_blockgroup which allows an
-+	 	application to jump to a particular block group while
-+	 	doing an inode scan.
-+
-+Wed Jan  1 23:50:12 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* dirblock.c: Include string.h, since we use memcpy().
-+
-+Tue Dec  3 12:27:29 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* getsize.c (ext2fs_get_device_size): The ioctl BLKGETSIZE returns
-+		a long not an int; this doesn't matter on i386 machines,
-+		but it does on Alpha's.
-+	
-+Fri Nov 29 20:57:37 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_write_inode, ext2fs_read_inode): If the inode
-+ 		table pointer is NULL, then return an error indicating
-+ 		that the inode table is missing.
-+		(get_next_blockgroup, get_next_blocks,
-+ 		ext2fs_get_next_inode): Don't treat a missing inode table
-+ 		as permanent error.  Return MISSING_INODE_TABLE, but as an
-+ 		advisory error code, much like BAD_BLOCK_IN_INODE_TABLE.
-+
-+	* rw_bitmaps.c (ext2fs_write_block_bitmap,
-+ 	 	ext2fs_write_inode_bitmap): If the inode or block bitmap
-+ 	 	block is zero, then don't write out the inode or block
-+ 	 	bitmap.  The idea here is to avoid stomping on the
-+ 	 	superblock.
-+		(read_bitmaps): If the inode or block bitmap block is
-+	 	zero, then fill in that portion of the inode or block
-+	 	bitmap with all zeros.
-+
-+	* inode.c (ext2fs_get_next_inode): Fix bug in handling of bad
-+ 		blocks in inode table when the inode table size is
-+ 		non-standard (and can therefore span blocks).
-+
-+Tue Oct 29 20:13:14 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* alloc.c (ext2fs_new_block): Fix fencepost error in
-+		ext2fs_new_block; make sure we don't try to allocate the
-+		first block beyond the end of the filesystem.
-+
-+Mon Oct 14 11:00:48 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (check_for_inode_bad_blocks): New function called by
-+		get_next_blocks() to avoid reading in bad blocks marked in
-+		fs->badblocks.  Inodes located in bad blocks are returned
-+		by ext2fs_get_next_inode() returns the error code 
-+		EXT2_ET_BAD_BLOCK_IN_INODE_TABLE.
-+	
-+	* alloc_tables.c (ext2fs_allocate_tables): New function which
-+		performs the part of mke2fs's job of allocating the 
-+		filesystem tables.
-+
-+	* test_io.c (test_close): IO manager which is used for testing
-+	 	purposes.
-+
-+Sun Oct 13 04:31:57 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_get_next_inode): Separate out the function of
-+ 		setting up for a new block group to get_next_blockgroup().
-+		Separate out the function of reading in blocks of the
-+		inode table to get_next_blocks().
-+
-+	* ext2fs.h: Add the badblocks list to the ext2_filsys entry
-+
-+	* badblocks.c (badblocks_list_add, badblocks_list_test): Add
-+ 		blocks to the badblock list in sorted order.  This allows
-+ 		badblocks_list_test to be coded using a binary search for
-+ 		speed.
-+
-+Tue Oct  8 02:02:03 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Release of E2fsprogs version 1.06
-+
-+Mon Oct  7 00:44:17 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* ext2fs.h, block.c, closefs.c, dirblock.c, inode.c, native.c,
-+	 	open.c: Change EXT2_SWAP to EXT2_FLAG_SWAP for
-+	 	consistency's sake.
-+	
-+	* closefs.c (ext2fs_flush): If the flag EXT2_MASTER_SB_ONLY is
-+		set, then only write out the master superblock.
-+
-+Sun Oct  6 21:45:26 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* block.c (ext2fs_block_iterate): Fixed bug which caused
-+ 		block_iterate to fail to handle HURD created filesystems;
-+ 		it tested the inode translator field before the inode was
-+ 		loaded.
-+
-+Tue Sep 17 14:08:24 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* initialize.c (ext2fs_initialize): Make sure the description for
-+		the inode bitmap is set correctly.
-+
-+	* bitmaps.c (ext2fs_allocate_generic_bitmap): Fix minor type typo.
-+
-+Thu Sep 12 15:23:07 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
-+
-+	* Release of E2fsprogs version 1.05
-+
-+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
-+
-+Wed Mar 27 00:33:40 1996    <tytso@rsts-11.mit.edu>
-+
-+	* Release of E2fsprogs version 1.03
-+
-+Tue Mar 26 12:06:32 1996    <tytso@rsts-11.mit.edu>
-+
-+	* bitops.h (ext2fs_set_bit, ext2fs_clear_bit, ext2fs_test_bit):
-+		Change the m68k bit numbering for bitmasks to match with
-+		the bit numbering used by all other ext2 implementations.
-+
-+Thu Mar  7 03:37:00 1996    <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_get_next_inode, ext2fs_close_inode_scan, 
-+	ext2fs_open_inode_scan): Support dynamically-sized inodes.
-+
-+Wed Mar  6 12:26:29 1996    <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_read_inode, ext2fs_write_inode): Support
-+		dynamically-sized inodes.
-+
-+	* openfs.c (ext2fs_open): Allow dynamic revision filesystem to be
-+	        loaded.
-+
-+Tue Mar  5 03:49:37 1996    <tytso@rsts-11.mit.edu>
-+
-+	* initialize.c (ext2fs_initialize): Catch an error condition where
-+		the passed in size is *really* too small.
-+
-+	* alloc.c (ext2fs_new_inode): 
-+	* ext2fs.h (EXT2_FIRST_INODE): Add support for dynamic revision to
-+		get first inode.
-+
-+Wed Feb 21 15:56:17 1996    <tytso@rsts-11.mit.edu>
-+
-+	* getsize.c (ext2fs_get_device_size): Open the device read-only
-+		when trying to determine its size.
-+
-+Wed Jan 31 11:06:08 1996    <tytso@rsts-11.mit.edu>
-+
-+	* Release of E2fsprogs version 1.02
-+
-+Sat Dec  9 09:57:50 1995    <tytso@rsts-11.mit.edu>
-+
-+	* rw_bitops.c (ext2fs_write_block_bitmap):
-+	* bitops.c (ext2fs_test_bit, ext2fs_clear_bit, ext2fs_set_bit):
-+	* bitops.h (ext2fs_test_bit, ext2fs_clear_bit, ext2fs_set_bit):
-+		Rename {test,set,clear}_bit to ext2fs_{test,set,clear}_bit, 
-+		to avoid conflicts with with kernel include files.  Also
-+		rename ADDR and CONST_ADDR to EXT2FS_ADDR and
-+		EXT2FS_CONST_ADDR. 
-+
-+Thu Oct 26 12:09:16 1995    <tytso@rsts-11.mit.edu>
-+
-+	* ext2_err.et: Updated message in EXT2_ET_BASE to say version 0.5c
-+
-+	* swapfs.c (ext2fs_swap_super): Put an #ifdef check around
-+		s_def_resuid and s_def_resgid for backwards compatibility.
-+
-+Fri Oct 20 23:33:31 1995    <tytso@rsts-11.mit.edu>
-+
-+	* bitops.h: Added #ifdef's for Sparc.
-+
-+Wed Sep  6 22:14:46 1995    <tytso@rsts-11.mit.edu>
-+
-+	* getsize.c: #include <sys/ioctl.h> under Linux to pick up ioctl()
-+	        declaration
-+
-+	* closefs.c: #include <string.h> to pick up memset() declaration
-+
-+Mon Sep  4 21:45:29 1995  Remy Card  <card@bbj>
-+
-+	* Makefile.in: Added support for BSD shared libraries.
-+
-+	* initialize.c (ext2fs_initialize): Correctly set the s_creator_os
-+		flag.
-+
-+Mon Sep  4 09:55:30 1995    <tytso@rsts-11.mit.edu>
-+
-+	* unix_io.c (unix_open): Add a double check; if the passed in name
-+		is NULL, return EXT2_ET_BAD_DEVICE_NAME.
-+
-+	* ext2_err.et (EXT2_ET_BAD_DEVICE_NAME): Added new error code
-+
-+Wed Aug 16 15:44:10 1995    <tytso@rsts-11.mit.edu>
-+
-+	* inode.c (ext2fs_check_directory): Use LINUX_S_ISDIR instead of
-+		S_ISDIR.
-+
-+Tue Aug 15 13:08:36 1995    <tytso@rsts-11.mit.edu>
-+
-+	* getsize.c (ext2fs_get_device_size): Add support for reading the
-+		partition size from a BSD disk label.
-+
-+Thu Aug 10 09:33:26 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
-+
-+	* getsize.c (ext2fs_get_device_size): New function that determins
-+		the size of a device.  Used by mke2fs and e2fsck.
-+
-+Sat Aug 12 03:09:54 1995  Remy Card  <card@bbj>
-+
-+	* Makefile.in (install): Install static libraries in $(ulibdir)
-+		(/usr/lib on Linux) instead of $(libdir) (/lib on Linux).
-+
-+Wed Aug  9 17:04:23 1995  Theodore Y. Ts'o  <tytso@dcl>
-+
-+	* bitmaps.c (ext2fs_free_inode_bitmap, ext2fs_free_block_bitmap):
-+		Move these functions to freefs.c.
-+
-+	* closefs.c (ext2fs_flush): If swapping blocks, clear the group
-+		descriptors shadow memory to keep purify quiet.  (This
-+		also has the nice benefit that the unused portion of the
-+		shadow descriptors are zeroed out.)
-+
-+	* dirblock.c (ext2fs_write_dir_block): We need to use
-+		dirent->rec_len *before* it's byteswapped to find the
-+		location of the next directory structure!
-+
-+	* alloc.c (ext2fs_new_inode): Fix bug which could potentially
-+		cause ext2fs_new_inode to loop infinitely if we're trying
-+		to allocate an inode in group #0 and there are no free
-+		inodes at all in the system.
-+
-+	* closefs.c: #include <errno.h> if it exists.
-+
-+Sun Aug  6 13:27:50 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
-+
-+	* ext2fs.h (BLOCK_FLAG_HOLE): Added new definition for
-+		BLOCK_FLAG_APPEND.  Added documentation for the block
-+		interator flags.
-+
-+Sat Aug  5 11:44:05 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
-+
-+	* Makefile.in (DLL_INSTALL_DIR, ELF_INSTALL_DIR): Set the
-+		installation directories correctly.
-+
-+Tue Jul 18 09:27:38 1995    <tytso@rsx-11.mit.edu>
-+
-+	* namei.c (process_dir_block): 
-+	* mkdir.c (ext2fs_mkdir): 
-+	* expanddir.c (expand_dir_proc): Use ext2fs_{read,write}_dir_block
-+		to read/write the directory block.
-+
-+	* dirblock.c (ext2fs_read_dir_block), ext2fs_write_dir_block): New
-+		file containing functions for reading and writing
-+		directory blocks (byte swapping if necesssary)
-+
-+	* block.c (block_iterate_ind, block_iterate_dind, 
-+		block_iterate_tind): Byte swap the block addresses if
-+		EXT2_SWAP_BYTES is set (and swap them back before writing
-+		them out.)
-+
-+	* inode.c (inocpy_with_swap): New function.
-+	(ext2fs_get_next_inode, ext2fs_read_inode, ext2fs_write_inode):
-+		Call inocpy_with_swap if EXT2_SWAP_BYTES if set.
-+
-+	* closefs.c (ext2fs_flush): If EXT2_SWAP_BYTES is set, then swap
-+		the superblock and group descriptors before writing it out.
-+
-+	* openfs.c (ext2fs_open): If the magic number is byte-swapped,
-+		then set the EXT2_SWAP_BYTES and byte-swap the superblock
-+		and group descriptors.
-+
-+	* swapfs.c (ext2fs_swap_super, ext2fs_swap_group_desc): New functions
-+		to desp ext2 filesystem structures.
-+
-+	* bitops.c (set_bit, clear_bit, test_bit): Use modifications
-+		supplied by Pete A. Zaitcev so that the C language
-+		versions of these functions are more portable.  They will
-+		now work on both little and big endian systems, and the
-+		assumption that 32-bit integers are used is gone.
-+
-+	* bitops.h (ext2_swab16, ext2_swab32): Added new functions for
-+		doing byte swapping.
-+
-+	* ext2fs.h (EXT2_SWAP_BYTES): Add new flag which indicates that
-+		byte swapping should take place.
-+
-+Sun Jul 16 06:21:43 1995    <tytso@rsx-11.mit.edu>
-+
-+	* Makefile.in, cmp_bitmaps.c (ext2fs_compare_block_bitmap_end,
-+	        ext2fs_compare_inode_bitmap_end): Added new file
-+		containing routines to compare bitmaps.
-+
-+	* ext2_err.et (EXT2_ET_NEQ_BLOCK_BITMAP, EXT2_ET_NEQ_INODE_BITMAP): 
-+		Added new error codes.
-+
-+Sat Jul 15 04:23:37 1995    <tytso@rsx-11.mit.edu>
-+
-+	* inode.c (ext2fs_get_next_inode): Don't check scan->inode_buffer;
-+		if the magic number is correct, it will be allocated.
-+
-+Fri Jul 14 19:02:59 1995    <tytso@rsx-11.mit.edu>
-+
-+	* block.c (block_iterate_ind, block_iterate_dind, 
-+		block_iterate_tind): Don't recompute block_nr each loop;
-+		just increment it!  Factor check of BLOCK_FLAG_APPEND out
-+		of the loop.  Factor mask of BLOCK_CHANGED into changed
-+		variable out of the loop.  (block_iterate_ind, in
-+		particular, gets called a lot, so every little
-+		optimization helps.)
-+
-+Thu Jul 13 08:02:45 1995    <tytso@rsx-11.mit.edu>
-+
-+	* block.c (block_iterate_ind, block_iterate_dind, 
-+		block_iterate_tind): Precompute limit of loop to speed up
-+		block_iterate_ind and company.
-+
-+	* bitops.h (ext2fs_fast_mark_block_bitmap, 
-+		ext2fs_fast_unmark_block_bitmap, ext2fs_fast_test_block_bitmap,
-+		ext2fs_fast_mark_inode_bitmap, ext2fs_fast_unmark_inode_bitmap,
-+		ext2fs_fast_test_inode_bitmap): Add fast version of these
-+		functions, which don't do range checking.
-+
-+	* bitops.h (ext2fs_get_block_bitmap_start, 
-+		ext2fs_get_inode_bitmap_start, ext2fs_get_block_bitmap_end,
-+		ext2fs_get_inode_bitmap_end): Add new accessor functions
-+		which return the start and end points of the bitmaps.
-+
-+Tue Jul 11 18:59:41 1995    <tytso@rsx-11.mit.edu>
-+
-+	* llseek.c (ext2_llseek): If the offset is small enough, use lseek
-+		instead of llseek.  The errno if the offset is too large
-+		and lseek is not supported should be EINVAL, not -EINVAL.
-+
-+Thu Jun 15 23:43:02 1995  Remy Card  <card@bbj>
-+
-+	* Makefile.in: Added support for ELF shared libraries.
-+		Fixed typos in the compilation rules.
-+		(distclean): Added Makefile.
-+
-+	* llseek.c (llseek): New function, if llseek() does not exist in the
-+	C library.
-+	(ext2_llseek): Changed to call llseek().
-+
-+Mon Jun 12 08:29:07 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
-+
-+	* ext2fs.h: Use __u32 to define blk_t, instead of unsigned long.
-+
-+Sun Jun 11 15:02:54 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
-+
-+	* mkdir.c (ext2fs_mkdir): Use LINUX_S_IFDIR instead of S_IFDIR.
-+
-+	* ext2fs.h (LINUX_S_IFDIR): Define a linux specific versions of
-+		the S_*, which are normally defined in <sys/stat.h>.  This
-+		allows us to compile e2fsprogs on a non-Linux system,
-+		which may have a different value for S_IFDIR.
-+
-+Sat Jun 10 23:47:05 1995  Theodore Y. Ts'o  <tytso@lurch.mit.edu>
-+
-+	* bitops.c (clear_bit, set_bit): Remove calls to cli() and sti();
-+		this is a user-mode application!
-+
-+Thu Jun  8 13:13:22 1995  Miles Bader  <miles@churchy.gnu.ai.mit.edu>
-+
-+	* llseek.c: Put the include of <linux/unistd.h> inside the #ifdef
-+	__linux__ so that non-linux systems won't see it.
-+
-+	* alloc.c: Include <errno.h> if possible.
-+	* badblocks.c: Ditto.
-+	* bb_inode.c: Ditto.
-+	* bitmaps.c: Ditto.
-+	* block.c: Ditto.
-+	* expanddir.c: Ditto.
-+	* get_pathname.c: Ditto.
-+	* initialize.c: Ditto.
-+	* inode.c: Ditto.
-+	* llseek.c: Ditto.
-+	* mkdir.c: Ditto.
-+	* namei.c: Ditto.
-+	* newdir.c: Ditto.
-+	* openfs.c: Ditto.
-+	* rw_bitmaps.c: Ditto.
-+	* unix_io.c: Ditto.
-+
-+	* Makefile.in: Rewritten to conform to GNU coding standards and
-+	support separate compilation directories.
-+
-+Thu May 11 04:13:12 1995    <tytso@rsx-11.mit.edu>
-+
-+	* initialize.c (ext2fs_initialize): Don't allow more than one
-+		bitmaps's worth of inodes in a group.
-+
-+Sat Mar 11 14:07:11 1995  Theodore Y. Ts'o  <tytso@localhost>
-+
-+	* llseek.c (ext2_llseek): Added error checking to the llseek()
-+		compat code to protect against overflow.  This only
-+		applies to 1.0 and early 1.1 kernels, which don't support
-+		the llseek() system call.
-+
-+Thu Nov 24 16:29:00 1994  Theodore Y. Ts'o  (tytso@rt-11)
-+
-+	* unix_io.c (unix_open): Initialize the read_error and write_error
-+		io_channel pointers to be null.
-+
-+	* bb_inode.c (clear_bad_block_proc): If an illegal block number is
-+		found, clear it but don't try to update the filesystem
-+		accounting information, since that's hopeless anyway.
-+
-+	* block.c (bloblock_iterate_ind, bloblock_iterate_dind,
-+	bloblock_iterate_tind): Check to see if the indirect blocks are
-+		valid before trying to read them.
-+
-+	* ext2_err.et (EXT2_ET_BAD_IND_BLOCK, EX2_ET_BAD_DIND_BLOCK,
-+	EXT2_ET_BAD_TIND_BLOCK): Add new error codes.
-+
-+	* bitops.h (ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
-+	ext2fs_test_block_bitmap, ext2fs_mark_inode_bitmap,
-+	ext2fs_unmark_inode_bitmap, ext2fs_test_inode_bitmap):  If an
-+		illegal block or inode number is passed in, return instead
-+		of trying to test, set, or clear the bit.
-+
-+Mon Nov  7 21:32:33 1994  Remy Card  <card@bbj>
-+
-+	* Makefile: Added a dummy install target in case shared libraries
-+		are not built.
-+
-+Mon Oct 24 14:11:44 1994    (tytso@rsx-11)
-+
-+	* bitmaps.c (ext2fs_allocate_block_bitmap): Fix calculation of how
-+		the real last block of the bitmap should be calculated.
-+
-+Wed Sep  7 10:05:36 1994    (tytso@rsx-11)
-+
-+	* bitmaps.c (ext2fs_fudge_inode_bitmap_end, 
-+		ext2fs_fudge_block_bitmap_end, ext2fs_clear_inode_bitmap,
-+		ext2fs_clear_block_bitmap, ext2fs_free_inode_bitmap,
-+		ext2fs_free_block_bitmap): Add magic number checking for
-+		the inode and block bitmaps.
-+
-+	* bitmaps.c (ext2fs_allocate_block_bitmap): Fix to set the correct
-+		magic number for a block bitmap instead of an inode bitmap.
-+
-+	* inode.c (ext2fs_close_inode_scan, ext2fs_get_next_inode):  Add
-+		magic number checking for the inode_scan structure.
-+
-+	* badblocks.c (badblocks_list_free, badblocks_list_add, 
-+		badblocks_list_test, badblocks_list_iterate_begin,
-+		badblocks_list_iterate, badblocks_list_iterate_end): Add
-+		magic number checking for the badblocks_list and
-+		badblocks_iterate structures.
-+
-+	* ext2_err.et (EXT2_ET_MAGIC_UNIX_IO_CHANNEL): 
-+	* unix_io.c (unix_open, unix_close, unix_set_blksize, unix_read_blk,
-+		unix_write_blk, unix_flush): Add magic number checking
-+		both for io_channel structure and unix_private_data
-+		structure.
-+
-+	* openfs.c (ext2fs_open): Add check for io_manager structure's
-+		magic number.
-+
-+	* rw_bitmaps.c (ext2fs_write_inode_bitmap, ext2fs_write_block_bitmap,
-+		ext2fs_read_inode_bitmap, ext2fs_read_block_bitmap,
-+		ext2fs_read_bitmaps, ext2fs_write_bitmaps): 
-+	* read_bb.c (ext2fs_read_bb_inode): 
-+	* read_bb_file.c (ext2fs_read_bb_FILE): 
-+	* newdir.c (ext2fs_new_dir_block): 
-+	* namei.c (ext2fs_dir_iterate, ext2fs_lookup, ext2fs_namei): 
-+	* link.c (ext2fs_link, ext2fs_unlink): 
-+	* inode.c (ext2fs_open_inode_scan, ext2fs_read_inode,
-+		ext2fs_write_inode, ext2fs_get_blocks, 
-+		ext2fs_check_directory): 
-+	* get_pathname.c (ext2fs_get_pathname): 
-+	* expanddir.c (ext2fs_expand_dir): 
-+	* block.c (ext2fs_block_iterate): 
-+	* bitmaps.c (ext2fs_allocate_inode_bitmap, 
-+		ext2fs_allocate_block_bitmap): 
-+	* bb_inode.c (ext2fs_update_bb_inode): 
-+	* alloc.c (ext2fs_new_inode,ext2fs_new_block,ext2fs_get_free_blocks): 
-+	* check_desc.c (ext2fs_check_desc): 
-+	* closefs.c (ext2fs_close, ext2fs_flush): 
-+	* freefs.c (ext2fs_free): Add check for ext2_filsys magic number.
-+
-+	* Makefile:
-+	* ext2fs.h:
-+	* openfs.c:
-+	* check_desc.c (ext2fs_check_desc): Move ext2fs_check_desc from
-+	openfs.c into its own file.
-+
-+	* ext2fs.h (EXT2_CHECK_MAGIC): Added macro for checking for
-+	structure magic numbers.
-+
-+	* closefs.c (ext2fs_flush): Folded in Remy Card's changes to clear
-+	the EXT2_VALID_FS flag in the backup superblock blocks, so that if
-+	someone uses the -b option to specify the use of the backup
-+	superblock --- this usually means that the main superblock is
-+	toast.  :-)
-+
-+	* ext2fs.h: 
-+	* ext2_err.et (EXT2_ET_REV_TOO_HIGH): 
-+	* openfs.c (ext2fs_open): Folded in Remy Card's changes to add a
-+	revision level to the superblock.
-+
-+Sun Aug 21 00:50:08 1994  Theodore Y. Ts'o  (tytso@rt-11)
-+
-+	* ext2fs.h:
-+	* bitmaps.c:
-+	* bitops.c
-+	* bitops.h:
-+	* openfs.c:
-+	* initialize.c: Completely revamped the inode and block bitmap
-+	structures, so that they can be better chance of being extensible
-+	in a shared library.  They are now their own type, instead of
-+	being a char *.  Also, the function signatures of
-+	ext2fs_test_block_bitmap, ext2fs_mark_block_bitmap,
-+	ext2fs_unmark_block_bitmap, ext2fs_test_inode_bitmap,
-+	ext2fs_mark_inode_bitmap, and ext2fs_unmark_inode_bitmap were
-+	changed to eliminate the ext2_filsys argument, since it is no
-+	longer necessary.
-+
-+Wed Aug 17 21:46:44 1994  Remy Card  (card@bbj)
-+
-+	* unix_io.c (unix_read_blk and unix_write_blk): use the llseek
-+	system call if available.
-+
-+	* llseek.c: new file.  This is the stub calling the llseek system
-+	call which allows supports for 2GB+ file systems.
-+
-+	* initialize.c (ext2fs_initialize): Ext2fs_initialize now stores
-+	the creator operating system.
-+
-+Wed Aug 17 10:03:24 1994  Theodore Y. Ts'o  (tytso@rt-11)
-+
-+	* initialize.c (ext2fs_initialize): Ext2fs_initialize now sets up
-+	the group descriptor statistics in addition to everything else.
-+	This relieves mke2fs of the responsibility of doing it.
-+
-+	* bitops.c, bitops.h: Add assembly inline functions for the 68000.
-+	Added a new #define, _EXT2_HAVE_ASM_BITOPS_ to control whether or
-+	not the generic C function equivalents should be included or not.
-+
-+	* openfs.c (ext2fs_open): If a superblock is specified, then use
-+	the backup group descriptors that go along with this superblock,
-+	instead of using the primary group descriptors.  This allows
-+	e2fsck to recover filesystems where the primary group descriptors
-+	have been trashed.
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/Makefile silo-1.4.14/libext2fs/Makefile
---- silo-1.4.14.orig/libext2fs/Makefile	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/Makefile	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,21 @@
-+
-+include ../Rules.make
-+
-+DEFS = -DLOCALEDIR=\"$(localedir)\" -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DENABLE_HTREE=1 -DENABLE_SWAPFS=1 -DPACKAGE=\"e2fsprogs\" -DVERSION=\"0.14.1\" -DHAVE_LONG_LONG=1 -DHAVE_LONG_DOUBLE=1 -DHAVE_WCHAR_T=1 -DHAVE_WINT_T=1 -DHAVE_INTTYPES_H_WITH_UINTMAX=1 -DHAVE_STDINT_H_WITH_UINTMAX=1 -DHAVE_INTMAX_T=1 -DHAVE_POSIX_PRINTF=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DINTDIV0_RAISES_SIGFPE=1 -DHAVE_UNSIGNED_LONG_LONG=1 -DHAVE_UINTMAX_T=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_STDINT_H=1 -DHAVE_ARGZ_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1 -DHAVE_NL_TYPES_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STDDEF_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_ASPRINTF=1 -DHAVE_FWPRINTF=1 -DHAVE_GETCWD=1 -DHAVE_GETEGID=1 -DHAVE_GETEUID=1 -DHAVE_GETGID=1 -DHAVE_GETUID=1 -DHAVE_MEMPCPY=1 -DHAVE_MUNMAP=1 -DHAVE_PUTENV=1 -DHAVE_SETENV=1 -DHAVE_SETLOCALE=1 -DHAVE_SNPRINTF=1 -DHAVE_STPCPY=1 -DHAVE_STRCASECMP=1 -DHAVE_STRDUP=1 -DHAVE_STRTOUL=1 -DHAVE_TSEARCH=1 -DHAVE_WCSLEN=1 -DHAVE___ARGZ_COUNT=1 -DHAVE___ARGZ_STRINGIFY=1 -DHAVE___ARGZ_NEXT=1 -DHAVE___FSETLOCKING=1 -DHAVE_DECL__SNPRINTF=0 -DHAVE_DECL__SNWPRINTF=0 -DHAVE_DECL_FEOF_UNLOCKED=1 -DHAVE_DECL_FGETS_UNLOCKED=0 -DHAVE_DECL_GETC_UNLOCKED=1 -DHAVE_ICONV=1 -DICONV_CONST= -DHAVE_LANGINFO_CODESET=1 -DHAVE_LC_MESSAGES=1 -DENABLE_NLS=1 -DHAVE_GETTEXT=1 -DHAVE_DCGETTEXT=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1 -DHAVE_STDINT_H=1 -DHAVE_ERRNO_H=1 -DHAVE_MALLOC_H=1 -DHAVE_MNTENT_H=1 -DHAVE_PATHS_H=1 -DHAVE_DIRENT_H=1 -DHAVE_GETOPT_H=1 -DHAVE_SETJMP_H=1 -DHAVE_SIGNAL_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_LINUX_FD_H=1 -DHAVE_LINUX_MAJOR_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_PRCTL_H=1 -DHAVE_SYS_QUEUE_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_SYS_RESOURCE_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_SYS_MOUNT_H=1 -DHAVE_NET_IF_H=1 -DHAVE_VPRINTF=1 -DHAVE_RECLEN_DIRENT=1 -DHAVE_TYPE_SSIZE_T=1 -DHAVE_LSEEK64_PROTOTYPE=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DHAVE_INTTYPES_H=1 -DHAVE_INTPTR_T=1 -DHAVE_GETRUSAGE=1 -DHAVE_LLSEEK=1 -DHAVE_LSEEK64=1 -DHAVE_OPEN64=1 -DHAVE_STRTOULL=1 -DHAVE_STRCASECMP=1 -DHAVE_SRANDOM=1 -DHAVE_FCHOWN=1 -DHAVE_MALLINFO=1 -DHAVE_FDATASYNC=1 -DHAVE_STRNLEN=1 -DHAVE_STRPTIME=1 -DHAVE_SYSCONF=1 -DHAVE_PATHCONF=1 -DHAVE_POSIX_MEMALIGN=1 -DHAVE_MEMALIGN=1 -DHAVE_VALLOC=1 -DHAVE___SECURE_GETENV=1 -DHAVE_PRCTL=1 -DHAVE_DLOPEN=1 -DHAVE_EXT2_IOCTLS=1
-+
-+DEBUGFS_LIB_OBJS = inode_io.o namei.o write_bb_file.o 
-+RESIZE_LIB_OBJS = rs_bitmap.o dupfs.o test_io.o 
-+E2IMAGE_LIB_OBJS = imager.o
-+OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) ext2_err.o alloc.o alloc_sb.o alloc_stats.o alloc_tables.o badblocks.o bb_inode.o bitmaps.o bitops.o block.o bmap.o check_desc.o closefs.o dblist.o dblist_dir.o dirblock.o dirhash.o dir_iterate.o expanddir.o ext_attr.o finddev.o flushb.o freefs.o gen_bitmap.o get_pathname.o getsize.o getsectsize.o icount.o ind_block.o initialize.o inline.o inode.o io_manager.o ismounted.o link.o llseek.o lookup.o mkdir.o mkjournal.o native.o newdir.o openfs.o read_bb.o read_bb_file.o res_gdt.o rw_bitmaps.o swapfs.o unix_io.o unlink.o valid_blk.o version.o
-+
-+all: libext2fs.a
-+
-+libext2fs.a: $(OBJS)
-+	$(RM) libext2fs.a
-+	$(AR) rc libext2fs.a $(OBJS)
-+
-+clean:
-+	$(RM) -f libext2fs.a $(OBJS)
-+
-+.c.o:
-+	$(CC-SILO) $(CFLAGS) $(DEFS) -c $< -o $@
-diff -Naur silo-1.4.14.orig/libext2fs/alloc.c silo-1.4.14/libext2fs/alloc.c
---- silo-1.4.14.orig/libext2fs/alloc.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/alloc.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,173 @@
-+/*
-+ * alloc.c --- allocate new inodes, blocks for ext2fs
-+ *
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <time.h>
-+#include <string.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * Right now, just search forward from the parent directory's block
-+ * group to find the next free inode.
-+ *
-+ * Should have a special policy for directories.
-+ */
-+errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, 
-+			   int mode EXT2FS_ATTR((unused)),
-+			   ext2fs_inode_bitmap map, ext2_ino_t *ret)
-+{
-+	ext2_ino_t	dir_group = 0;
-+	ext2_ino_t	i;
-+	ext2_ino_t	start_inode;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+	
-+	if (!map)
-+		map = fs->inode_map;
-+	if (!map)
-+		return EXT2_ET_NO_INODE_BITMAP;
-+	
-+	if (dir > 0) 
-+		dir_group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super);
-+
-+	start_inode = (dir_group * EXT2_INODES_PER_GROUP(fs->super)) + 1;
-+	if (start_inode < EXT2_FIRST_INODE(fs->super))
-+		start_inode = EXT2_FIRST_INODE(fs->super);
-+	i = start_inode;
-+
-+	do {
-+		if (!ext2fs_fast_test_inode_bitmap(map, i))
-+			break;
-+		i++;
-+		if (i > fs->super->s_inodes_count)
-+			i = EXT2_FIRST_INODE(fs->super);
-+	} while (i != start_inode);
-+	
-+	if (ext2fs_test_inode_bitmap(map, i))
-+		return EXT2_ET_INODE_ALLOC_FAIL;
-+	*ret = i;
-+	return 0;
-+}
-+
-+/*
-+ * Stupid algorithm --- we now just search forward starting from the
-+ * goal.  Should put in a smarter one someday....
-+ */
-+errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
-+			   ext2fs_block_bitmap map, blk_t *ret)
-+{
-+	blk_t	i;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (!map)
-+		map = fs->block_map;
-+	if (!map)
-+		return EXT2_ET_NO_BLOCK_BITMAP;
-+	if (!goal || (goal >= fs->super->s_blocks_count))
-+		goal = fs->super->s_first_data_block;
-+	i = goal;
-+	do {
-+		if (!ext2fs_fast_test_block_bitmap(map, i)) {
-+			*ret = i;
-+			return 0;
-+		}
-+		i++;
-+		if (i >= fs->super->s_blocks_count)
-+			i = fs->super->s_first_data_block;
-+	} while (i != goal);
-+	return EXT2_ET_BLOCK_ALLOC_FAIL;
-+}
-+
-+/*
-+ * This function zeros out the allocated block, and updates all of the
-+ * appropriate filesystem records.
-+ */
-+errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
-+			     char *block_buf, blk_t *ret)
-+{
-+	errcode_t	retval;
-+	blk_t		block;
-+	char		*buf = 0;
-+
-+	if (!block_buf) {
-+		retval = ext2fs_get_mem(fs->blocksize, &buf);
-+		if (retval)
-+			return retval;
-+		block_buf = buf;
-+	}
-+	memset(block_buf, 0, fs->blocksize);
-+
-+	if (!fs->block_map) {
-+		retval = ext2fs_read_block_bitmap(fs);
-+		if (retval)
-+			goto fail;
-+	}
-+
-+	retval = ext2fs_new_block(fs, goal, 0, &block);
-+	if (retval)
-+		goto fail;
-+
-+	retval = io_channel_write_blk(fs->io, block, 1, block_buf);
-+	if (retval)
-+		goto fail;
-+	
-+	ext2fs_block_alloc_stats(fs, block, +1);
-+	*ret = block;
-+	return 0;
-+
-+fail:
-+	if (buf)
-+		ext2fs_free_mem(&buf);
-+	return retval;
-+}
-+
-+errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
-+				 int num, ext2fs_block_bitmap map, blk_t *ret)
-+{
-+	blk_t	b = start;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (!map)
-+		map = fs->block_map;
-+	if (!map)
-+		return EXT2_ET_NO_BLOCK_BITMAP;
-+	if (!b)
-+		b = fs->super->s_first_data_block;
-+	if (!finish)
-+		finish = start;
-+	if (!num)
-+		num = 1;
-+	do {
-+		if (b+num-1 > fs->super->s_blocks_count)
-+			b = fs->super->s_first_data_block;
-+		if (ext2fs_fast_test_block_bitmap_range(map, b, num)) {
-+			*ret = b;
-+			return 0;
-+		}
-+		b++;
-+	} while (b != finish);
-+	return EXT2_ET_BLOCK_ALLOC_FAIL;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/alloc_sb.c silo-1.4.14/libext2fs/alloc_sb.c
---- silo-1.4.14.orig/libext2fs/alloc_sb.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/alloc_sb.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,57 @@
-+/*
-+ * alloc_sb.c --- Allocate the superblock and block group descriptors for a 
-+ * newly initialized filesystem.  Used by mke2fs when initializing a filesystem
-+ *
-+ * Copyright (C) 1994, 1995, 1996, 2003 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+int ext2fs_reserve_super_and_bgd(ext2_filsys fs, 
-+				 dgrp_t group,
-+				 ext2fs_block_bitmap bmap)
-+{
-+	blk_t	super_blk, old_desc_blk, new_desc_blk;
-+	int	j, old_desc_blocks, num_blocks;
-+
-+	num_blocks = ext2fs_super_and_bgd_loc(fs, group, &super_blk, 
-+					      &old_desc_blk, &new_desc_blk, 0);
-+
-+	if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
-+		old_desc_blocks = fs->super->s_first_meta_bg;
-+	else
-+		old_desc_blocks = 
-+			fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
-+
-+	if (super_blk || (group == 0))
-+		ext2fs_mark_block_bitmap(bmap, super_blk);
-+
-+	if (old_desc_blk) {
-+		for (j=0; j < old_desc_blocks; j++)
-+			ext2fs_mark_block_bitmap(bmap, old_desc_blk + j);
-+	}
-+	if (new_desc_blk)
-+		ext2fs_mark_block_bitmap(bmap, new_desc_blk);
-+
-+	return num_blocks;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/alloc_stats.c silo-1.4.14/libext2fs/alloc_stats.c
---- silo-1.4.14.orig/libext2fs/alloc_stats.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/alloc_stats.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,52 @@
-+/*
-+ * alloc_stats.c --- Update allocation statistics for ext2fs
-+ *
-+ * Copyright (C) 2001 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ */
-+
-+#include <stdio.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
-+			       int inuse, int isdir)
-+{
-+	int	group = ext2fs_group_of_ino(fs, ino);
-+
-+	if (inuse > 0)
-+		ext2fs_mark_inode_bitmap(fs->inode_map, ino);
-+	else
-+		ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
-+	fs->group_desc[group].bg_free_inodes_count -= inuse;
-+	if (isdir)
-+		fs->group_desc[group].bg_used_dirs_count += inuse;
-+	fs->super->s_free_inodes_count -= inuse;
-+	ext2fs_mark_super_dirty(fs);
-+	ext2fs_mark_ib_dirty(fs);
-+}
-+
-+void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse)
-+{
-+	ext2fs_inode_alloc_stats2(fs, ino, inuse, 0);
-+}
-+
-+void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse)
-+{
-+	int	group = ext2fs_group_of_blk(fs, blk);
-+
-+	if (inuse > 0)
-+		ext2fs_mark_block_bitmap(fs->block_map, blk);
-+	else
-+		ext2fs_unmark_block_bitmap(fs->block_map, blk);
-+	fs->group_desc[group].bg_free_blocks_count -= inuse;
-+	fs->super->s_free_blocks_count -= inuse;
-+	ext2fs_mark_super_dirty(fs);
-+	ext2fs_mark_bb_dirty(fs);
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/alloc_tables.c silo-1.4.14/libext2fs/alloc_tables.c
---- silo-1.4.14.orig/libext2fs/alloc_tables.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/alloc_tables.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,117 @@
-+/*
-+ * alloc_tables.c --- Allocate tables for a newly initialized
-+ * filesystem.  Used by mke2fs when initializing a filesystem
-+ *
-+ * Copyright (C) 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
-+				      ext2fs_block_bitmap bmap)
-+{
-+	errcode_t	retval;
-+	blk_t		group_blk, start_blk, last_blk, new_blk, blk;
-+	int		j;
-+
-+	group_blk = fs->super->s_first_data_block +
-+		(group * fs->super->s_blocks_per_group);
-+	
-+	last_blk = group_blk + fs->super->s_blocks_per_group;
-+	if (last_blk >= fs->super->s_blocks_count)
-+		last_blk = fs->super->s_blocks_count - 1;
-+
-+	if (!bmap)
-+		bmap = fs->block_map;
-+	
-+	/*
-+	 * Allocate the block and inode bitmaps, if necessary
-+	 */
-+	if (fs->stride) {
-+		start_blk = group_blk + fs->inode_blocks_per_group;
-+		start_blk += ((fs->stride * group) %
-+			      (last_blk - start_blk));
-+		if (start_blk > last_blk)
-+			start_blk = group_blk;
-+	} else
-+		start_blk = group_blk;
-+
-+	if (!fs->group_desc[group].bg_block_bitmap) {
-+		retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-+						1, bmap, &new_blk);
-+		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) 
-+			retval = ext2fs_get_free_blocks(fs, group_blk,
-+					last_blk, 1, bmap, &new_blk);
-+		if (retval)
-+			return retval;
-+		ext2fs_mark_block_bitmap(bmap, new_blk);
-+		fs->group_desc[group].bg_block_bitmap = new_blk;
-+	}
-+
-+	if (!fs->group_desc[group].bg_inode_bitmap) {
-+		retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-+						1, bmap, &new_blk);
-+		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) 
-+			retval = ext2fs_get_free_blocks(fs, group_blk,
-+					last_blk, 1, bmap, &new_blk);
-+		if (retval)
-+			return retval;
-+		ext2fs_mark_block_bitmap(bmap, new_blk);
-+		fs->group_desc[group].bg_inode_bitmap = new_blk;
-+	}
-+
-+	/*
-+	 * Allocate the inode table
-+	 */
-+	if (!fs->group_desc[group].bg_inode_table) {
-+		retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
-+						fs->inode_blocks_per_group,
-+						bmap, &new_blk);
-+		if (retval)
-+			return retval;
-+		for (j=0, blk = new_blk;
-+		     j < fs->inode_blocks_per_group;
-+		     j++, blk++)
-+			ext2fs_mark_block_bitmap(bmap, blk);
-+		fs->group_desc[group].bg_inode_table = new_blk;
-+	}
-+
-+	
-+	return 0;
-+}
-+
-+	
-+
-+errcode_t ext2fs_allocate_tables(ext2_filsys fs)
-+{
-+	errcode_t	retval;
-+	dgrp_t		i;
-+
-+	for (i = 0; i < fs->group_desc_count; i++) {
-+		retval = ext2fs_allocate_group_table(fs, i, fs->block_map);
-+		if (retval)
-+			return retval;
-+	}
-+	return 0;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/badblocks.c silo-1.4.14/libext2fs/badblocks.c
---- silo-1.4.14.orig/libext2fs/badblocks.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/badblocks.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,327 @@
-+/*
-+ * badblocks.c --- routines to manipulate the bad block structure
-+ * 
-+ * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+/*
-+ * Helper function for making a badblocks list
-+ */
-+static errcode_t make_u32_list(int size, int num, __u32 *list,
-+			       ext2_u32_list *ret)
-+{
-+	ext2_u32_list	bb;
-+	errcode_t	retval;
-+	
-+	retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_list), &bb);
-+	if (retval)
-+		return retval;
-+	memset(bb, 0, sizeof(struct ext2_struct_u32_list));
-+	bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
-+	bb->size = size ? size : 10;
-+	bb->num = num;
-+	retval = ext2fs_get_mem(bb->size * sizeof(blk_t), &bb->list);
-+	if (!bb->list) {
-+		ext2fs_free_mem(&bb);
-+		return retval;
-+	}
-+	if (list)
-+		memcpy(bb->list, list, bb->size * sizeof(blk_t));
-+	else
-+		memset(bb->list, 0, bb->size * sizeof(blk_t));
-+	*ret = bb;
-+	return 0;
-+}
-+	
-+
-+/*
-+ * This procedure creates an empty u32 list.
-+ */
-+errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size)
-+{
-+	return make_u32_list(size, 0, 0, ret);
-+}
-+
-+/*
-+ * This procedure creates an empty badblocks list.
-+ */
-+errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
-+{
-+	return make_u32_list(size, 0, 0, (ext2_badblocks_list *) ret);
-+}
-+
-+
-+/*
-+ * This procedure copies a badblocks list
-+ */
-+errcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest)
-+{
-+	errcode_t	retval;
-+	
-+	retval = make_u32_list(src->size, src->num, src->list, dest);
-+	if (retval)
-+		return retval;
-+	(*dest)->badblocks_flags = src->badblocks_flags;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
-+				ext2_badblocks_list *dest)
-+{
-+	return ext2fs_u32_copy((ext2_u32_list) src,
-+			       (ext2_u32_list *) dest);
-+}
-+
-+/*
-+ * This procedure frees a badblocks list.
-+ *
-+ * (note: moved to closefs.c)
-+ */
-+
-+
-+/*
-+ * This procedure adds a block to a badblocks list.
-+ */
-+errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk)
-+{
-+	errcode_t	retval;
-+	int		i, j;
-+	unsigned long	old_size;
-+
-+	EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
-+
-+	if (bb->num >= bb->size) {
-+		old_size = bb->size * sizeof(__u32);
-+		bb->size += 100;
-+		retval = ext2fs_resize_mem(old_size, bb->size * sizeof(__u32),
-+					   &bb->list);
-+		if (retval) {
-+			bb->size -= 100;
-+			return retval;
-+		}
-+	}
-+
-+	/*
-+	 * Add special case code for appending to the end of the list
-+	 */
-+	i = bb->num-1;
-+	if ((bb->num != 0) && (bb->list[i] == blk))
-+		return 0;
-+	if ((bb->num == 0) || (bb->list[i] < blk)) {
-+		bb->list[bb->num++] = blk;
-+		return 0;
-+	}
-+
-+	j = bb->num;
-+	for (i=0; i < bb->num; i++) {
-+		if (bb->list[i] == blk)
-+			return 0;
-+		if (bb->list[i] > blk) {
-+			j = i;
-+			break;
-+		}
-+	}
-+	for (i=bb->num; i > j; i--)
-+		bb->list[i] = bb->list[i-1];
-+	bb->list[j] = blk;
-+	bb->num++;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
-+{
-+	return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk);
-+}
-+
-+/*
-+ * This procedure finds a particular block is on a badblocks
-+ * list.
-+ */
-+int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk)
-+{
-+	int	low, high, mid;
-+
-+	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
-+		return -1;
-+
-+	if (bb->num == 0)
-+		return -1;
-+
-+	low = 0;
-+	high = bb->num-1;
-+	if (blk == bb->list[low])
-+		return low;
-+	if (blk == bb->list[high])
-+		return high;
-+
-+	while (low < high) {
-+		mid = (low+high)/2;
-+		if (mid == low || mid == high)
-+			break;
-+		if (blk == bb->list[mid])
-+			return mid;
-+		if (blk < bb->list[mid])
-+			high = mid;
-+		else
-+			low = mid;
-+	}
-+	return -1;
-+}
-+
-+/*
-+ * This procedure tests to see if a particular block is on a badblocks
-+ * list.
-+ */
-+int ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk)
-+{
-+	if (ext2fs_u32_list_find(bb, blk) < 0)
-+		return 0;
-+	else
-+		return 1;
-+}
-+
-+int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
-+{
-+	return ext2fs_u32_list_test((ext2_u32_list) bb, (__u32) blk);
-+}
-+
-+
-+/*
-+ * Remove a block from the badblock list
-+ */
-+int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk)
-+{
-+	int	remloc, i;
-+
-+	if (bb->num == 0)
-+		return -1;
-+
-+	remloc = ext2fs_u32_list_find(bb, blk);
-+	if (remloc < 0)
-+		return -1;
-+
-+	for (i = remloc ; i < bb->num-1; i++)
-+		bb->list[i] = bb->list[i+1];
-+	bb->num--;
-+	return 0;
-+}
-+
-+void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk)
-+{
-+	ext2fs_u32_list_del(bb, blk);
-+}
-+
-+errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
-+					ext2_u32_iterate *ret)
-+{
-+	ext2_u32_iterate iter;
-+	errcode_t		retval;
-+
-+	EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
-+
-+	retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_iterate), &iter);
-+	if (retval)
-+		return retval;
-+
-+	iter->magic = EXT2_ET_MAGIC_BADBLOCKS_ITERATE;
-+	iter->bb = bb;
-+	iter->ptr = 0;
-+	*ret = iter;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
-+					      ext2_badblocks_iterate *ret)
-+{
-+	return ext2fs_u32_list_iterate_begin((ext2_u32_list) bb,
-+					      (ext2_u32_iterate *) ret);
-+}
-+
-+
-+int ext2fs_u32_list_iterate(ext2_u32_iterate iter, __u32 *blk)
-+{
-+	ext2_u32_list	bb;
-+
-+	if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE)
-+		return 0;
-+
-+	bb = iter->bb;
-+
-+	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
-+		return 0;
-+	
-+	if (iter->ptr < bb->num) {
-+		*blk = bb->list[iter->ptr++];
-+		return 1;
-+	} 
-+	*blk = 0;
-+	return 0;
-+}
-+
-+int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk)
-+{
-+	return ext2fs_u32_list_iterate((ext2_u32_iterate) iter,
-+				       (__u32 *) blk);
-+}
-+
-+
-+void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter)
-+{
-+	if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE))
-+		return;
-+
-+	iter->bb = 0;
-+	ext2fs_free_mem(&iter);
-+}
-+
-+void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter)
-+{
-+	ext2fs_u32_list_iterate_end((ext2_u32_iterate) iter);
-+}
-+
-+
-+int ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2)
-+{
-+	EXT2_CHECK_MAGIC(bb1, EXT2_ET_MAGIC_BADBLOCKS_LIST);
-+	EXT2_CHECK_MAGIC(bb2, EXT2_ET_MAGIC_BADBLOCKS_LIST);
-+
-+	if (bb1->num != bb2->num)
-+		return 0;
-+
-+	if (memcmp(bb1->list, bb2->list, bb1->num * sizeof(blk_t)) != 0)
-+		return 0;
-+	return 1;
-+}
-+
-+int ext2fs_badblocks_equal(ext2_badblocks_list bb1, ext2_badblocks_list bb2)
-+{
-+	return ext2fs_u32_list_equal((ext2_u32_list) bb1,
-+				     (ext2_u32_list) bb2);
-+}
-+
-+int ext2fs_u32_list_count(ext2_u32_list bb)
-+{
-+	return bb->num;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/bb_compat.c silo-1.4.14/libext2fs/bb_compat.c
---- silo-1.4.14.orig/libext2fs/bb_compat.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/bb_compat.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,63 @@
-+/*
-+ * bb_compat.c --- compatibility badblocks routines
-+ * 
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+errcode_t badblocks_list_create(badblocks_list *ret, int size)
-+{
-+	return ext2fs_badblocks_list_create(ret, size);
-+}
-+
-+void badblocks_list_free(badblocks_list bb)
-+{
-+	ext2fs_badblocks_list_free(bb);
-+}
-+
-+errcode_t badblocks_list_add(badblocks_list bb, blk_t blk)
-+{
-+	return ext2fs_badblocks_list_add(bb, blk);
-+}
-+
-+int badblocks_list_test(badblocks_list bb, blk_t blk)
-+{
-+	return ext2fs_badblocks_list_test(bb, blk);
-+}
-+
-+errcode_t badblocks_list_iterate_begin(badblocks_list bb,
-+				       badblocks_iterate *ret)
-+{
-+	return ext2fs_badblocks_list_iterate_begin(bb, ret);
-+}
-+
-+int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk)
-+{
-+	return ext2fs_badblocks_list_iterate(iter, blk);
-+}
-+
-+void badblocks_list_iterate_end(badblocks_iterate iter)
-+{
-+	ext2fs_badblocks_list_iterate_end(iter);
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/bb_inode.c silo-1.4.14/libext2fs/bb_inode.c
---- silo-1.4.14.orig/libext2fs/bb_inode.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/bb_inode.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,267 @@
-+/*
-+ * bb_inode.c --- routines to update the bad block inode.
-+ * 
-+ * WARNING: This routine modifies a lot of state in the filesystem; if
-+ * this routine returns an error, the bad block inode may be in an
-+ * inconsistent state.
-+ * 
-+ * Copyright (C) 1994, 1995 Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct set_badblock_record {
-+	ext2_badblocks_iterate	bb_iter;
-+	int		bad_block_count;
-+	blk_t		*ind_blocks;
-+	int		max_ind_blocks;
-+	int		ind_blocks_size;
-+	int		ind_blocks_ptr;
-+	char		*block_buf;
-+	errcode_t	err;
-+};
-+
-+static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
-+			      e2_blkcnt_t blockcnt,
-+			      blk_t ref_block, int ref_offset,
-+			      void *priv_data);
-+static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
-+				e2_blkcnt_t blockcnt,
-+				blk_t ref_block, int ref_offset,
-+				void *priv_data);
-+	
-+/*
-+ * Given a bad blocks bitmap, update the bad blocks inode to reflect
-+ * the map.
-+ */
-+errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
-+{
-+	errcode_t			retval;
-+	struct set_badblock_record 	rec;
-+	struct ext2_inode		inode;
-+	
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (!fs->block_map)
-+		return EXT2_ET_NO_BLOCK_BITMAP;
-+	
-+	rec.bad_block_count = 0;
-+	rec.ind_blocks_size = rec.ind_blocks_ptr = 0;
-+	rec.max_ind_blocks = 10;
-+	retval = ext2fs_get_mem(rec.max_ind_blocks * sizeof(blk_t),
-+				&rec.ind_blocks);
-+	if (retval)
-+		return retval;
-+	memset(rec.ind_blocks, 0, rec.max_ind_blocks * sizeof(blk_t));
-+	retval = ext2fs_get_mem(fs->blocksize, &rec.block_buf);
-+	if (retval)
-+		goto cleanup;
-+	memset(rec.block_buf, 0, fs->blocksize);
-+	rec.err = 0;
-+	
-+	/*
-+	 * First clear the old bad blocks (while saving the indirect blocks) 
-+	 */
-+	retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO,
-+				       BLOCK_FLAG_DEPTH_TRAVERSE, 0,
-+				       clear_bad_block_proc, &rec);
-+	if (retval)
-+		goto cleanup;
-+	if (rec.err) {
-+		retval = rec.err;
-+		goto cleanup;
-+	}
-+	
-+	/*
-+	 * Now set the bad blocks!
-+	 *
-+	 * First, mark the bad blocks as used.  This prevents a bad
-+	 * block from being used as an indirecto block for the bad
-+	 * block inode (!).
-+	 */
-+	if (bb_list) {
-+		retval = ext2fs_badblocks_list_iterate_begin(bb_list,
-+							     &rec.bb_iter);
-+		if (retval)
-+			goto cleanup;
-+		retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO,
-+					       BLOCK_FLAG_APPEND, 0,
-+					       set_bad_block_proc, &rec);
-+		ext2fs_badblocks_list_iterate_end(rec.bb_iter);
-+		if (retval) 
-+			goto cleanup;
-+		if (rec.err) {
-+			retval = rec.err;
-+			goto cleanup;
-+		}
-+	}
-+	
-+	/*
-+	 * Update the bad block inode's mod time and block count
-+	 * field.  
-+	 */
-+	retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
-+	if (retval)
-+		goto cleanup;
-+	
-+	inode.i_atime = inode.i_mtime = time(0);
-+	if (!inode.i_ctime)
-+		inode.i_ctime = time(0);
-+	inode.i_blocks = rec.bad_block_count * (fs->blocksize / 512);
-+	inode.i_size = rec.bad_block_count * fs->blocksize;
-+
-+	retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
-+	if (retval)
-+		goto cleanup;
-+	
-+cleanup:
-+	ext2fs_free_mem(&rec.ind_blocks);
-+	ext2fs_free_mem(&rec.block_buf);
-+	return retval;
-+}
-+
-+/*
-+ * Helper function for update_bb_inode()
-+ *
-+ * Clear the bad blocks in the bad block inode, while saving the
-+ * indirect blocks.
-+ */
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
-+				e2_blkcnt_t blockcnt,
-+				blk_t ref_block EXT2FS_ATTR((unused)),
-+				int ref_offset EXT2FS_ATTR((unused)),
-+				void *priv_data)
-+{
-+	struct set_badblock_record *rec = (struct set_badblock_record *)
-+		priv_data;
-+	errcode_t	retval;
-+	unsigned long 	old_size;
-+
-+	if (!*block_nr)
-+		return 0;
-+
-+	/*
-+	 * If the block number is outrageous, clear it and ignore it.
-+	 */
-+	if (*block_nr >= fs->super->s_blocks_count ||
-+	    *block_nr < fs->super->s_first_data_block) {
-+		*block_nr = 0;
-+		return BLOCK_CHANGED;
-+	}
-+
-+	if (blockcnt < 0) {
-+		if (rec->ind_blocks_size >= rec->max_ind_blocks) {
-+			old_size = rec->max_ind_blocks * sizeof(blk_t);
-+			rec->max_ind_blocks += 10;
-+			retval = ext2fs_resize_mem(old_size, 
-+				   rec->max_ind_blocks * sizeof(blk_t),
-+				   &rec->ind_blocks);
-+			if (retval) {
-+				rec->max_ind_blocks -= 10;
-+				rec->err = retval;
-+				return BLOCK_ABORT;
-+			}
-+		}
-+		rec->ind_blocks[rec->ind_blocks_size++] = *block_nr;
-+	}
-+
-+	/*
-+	 * Mark the block as unused, and update accounting information
-+	 */
-+	ext2fs_block_alloc_stats(fs, *block_nr, -1);
-+	
-+	*block_nr = 0;
-+	return BLOCK_CHANGED;
-+}
-+
-+	
-+/*
-+ * Helper function for update_bb_inode()
-+ *
-+ * Set the block list in the bad block inode, using the supplied bitmap.
-+ */
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
-+			      e2_blkcnt_t blockcnt,
-+			      blk_t ref_block EXT2FS_ATTR((unused)),
-+			      int ref_offset EXT2FS_ATTR((unused)),
-+			      void *priv_data)
-+{
-+	struct set_badblock_record *rec = (struct set_badblock_record *)
-+		priv_data;
-+	errcode_t	retval;
-+	blk_t		blk;
-+
-+	if (blockcnt >= 0) {
-+		/*
-+		 * Get the next bad block.
-+		 */
-+		if (!ext2fs_badblocks_list_iterate(rec->bb_iter, &blk))
-+			return BLOCK_ABORT;
-+		rec->bad_block_count++;
-+	} else {
-+		/*
-+		 * An indirect block; fetch a block from the
-+		 * previously used indirect block list.  The block
-+		 * most be not marked as used; if so, get another one.
-+		 * If we run out of reserved indirect blocks, allocate
-+		 * a new one.
-+		 */
-+	retry:
-+		if (rec->ind_blocks_ptr < rec->ind_blocks_size) {
-+			blk = rec->ind_blocks[rec->ind_blocks_ptr++];
-+			if (ext2fs_test_block_bitmap(fs->block_map, blk))
-+				goto retry;
-+		} else {
-+			retval = ext2fs_new_block(fs, 0, 0, &blk);
-+			if (retval) {
-+				rec->err = retval;
-+				return BLOCK_ABORT;
-+			}
-+		}
-+		retval = io_channel_write_blk(fs->io, blk, 1, rec->block_buf);
-+		if (retval) {
-+			rec->err = retval;
-+			return BLOCK_ABORT;
-+		}
-+	}
-+	
-+	/*
-+	 * Update block counts
-+	 */
-+	ext2fs_block_alloc_stats(fs, blk, +1);
-+	
-+	*block_nr = blk;
-+	return BLOCK_CHANGED;
-+}
-+
-+
-+
-+
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/bitmaps.c silo-1.4.14/libext2fs/bitmaps.c
---- silo-1.4.14.orig/libext2fs/bitmaps.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/bitmaps.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,212 @@
-+/*
-+ * bitmaps.c --- routines to read, write, and manipulate the inode and
-+ * block bitmaps.
-+ *
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+static errcode_t make_bitmap(__u32 start, __u32 end, __u32 real_end,
-+			     const char *descr, char *init_map,
-+			     ext2fs_generic_bitmap *ret)
-+{
-+	ext2fs_generic_bitmap	bitmap;
-+	errcode_t		retval;
-+	size_t			size;
-+
-+	retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap), 
-+				&bitmap);
-+	if (retval)
-+		return retval;
-+
-+	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) {
-+		retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description);
-+		if (retval) {
-+			ext2fs_free_mem(&bitmap);
-+			return retval;
-+		}
-+		strcpy(bitmap->description, descr);
-+	} else
-+		bitmap->description = 0;
-+
-+	size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
-+	retval = ext2fs_get_mem(size, &bitmap->bitmap);
-+	if (retval) {
-+		ext2fs_free_mem(&bitmap->description);
-+		ext2fs_free_mem(&bitmap);
-+		return retval;
-+	}
-+
-+	if (init_map)
-+		memcpy(bitmap->bitmap, init_map, size);
-+	else
-+		memset(bitmap->bitmap, 0, size);
-+	*ret = bitmap;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
-+					 __u32 end,
-+					 __u32 real_end,
-+					 const char *descr,
-+					 ext2fs_generic_bitmap *ret)
-+{
-+	return make_bitmap(start, end, real_end, descr, 0, ret);
-+}
-+
-+errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
-+			     ext2fs_generic_bitmap *dest)
-+{
-+	errcode_t		retval;
-+	ext2fs_generic_bitmap	new_map;
-+
-+	retval = make_bitmap(src->start, src->end, src->real_end,
-+			     src->description, src->bitmap, &new_map);
-+	if (retval)
-+		return retval;
-+	new_map->magic = src->magic;
-+	new_map->fs = src->fs;
-+	new_map->base_error_code = src->base_error_code;
-+	*dest = new_map;
-+	return 0;
-+}
-+
-+void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map)
-+{
-+	__u32	i, j;
-+
-+	for (i=map->end+1, j = i - map->start; i <= map->real_end; i++, j++)
-+		ext2fs_set_bit(j, map->bitmap);
-+
-+	return;
-+}	
-+
-+errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
-+				       const char *descr,
-+				       ext2fs_inode_bitmap *ret)
-+{
-+	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;
-+
-+	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->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
-+	
-+	*ret = bitmap;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
-+					ext2_ino_t end, ext2_ino_t *oend)
-+{
-+	EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
-+	
-+	if (end > bitmap->real_end)
-+		return EXT2_ET_FUDGE_INODE_BITMAP_END;
-+	if (oend)
-+		*oend = bitmap->end;
-+	bitmap->end = end;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
-+					blk_t end, blk_t *oend)
-+{
-+	EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
-+	
-+	if (end > bitmap->real_end)
-+		return EXT2_ET_FUDGE_BLOCK_BITMAP_END;
-+	if (oend)
-+		*oend = bitmap->end;
-+	bitmap->end = end;
-+	return 0;
-+}
-+
-+void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap)
-+{
-+	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
-+		return;
-+
-+	memset(bitmap->bitmap, 0,
-+	       (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
-+}
-+
-+void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap)
-+{
-+	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
-+		return;
-+
-+	memset(bitmap->bitmap, 0,
-+	       (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/bitops.c silo-1.4.14/libext2fs/bitops.c
---- silo-1.4.14.orig/libext2fs/bitops.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/bitops.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,91 @@
-+/*
-+ * bitops.c --- Bitmap frobbing code.  See bitops.h for the inlined
-+ * 	routines.
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#ifndef _EXT2_HAVE_ASM_BITOPS_
-+
-+/*
-+ * For the benefit of those who are trying to port Linux to another
-+ * architecture, here are some C-language equivalents.  You should
-+ * recode these in the native assmebly language, if at all possible.
-+ *
-+ * C language equivalents written by Theodore Ts'o, 9/26/92.
-+ * Modified by Pete A. Zaitcev 7/14/95 to be portable to big endian
-+ * systems, as well as non-32 bit systems.
-+ */
-+
-+int ext2fs_set_bit(unsigned int nr,void * addr)
-+{
-+	int		mask, retval;
-+	unsigned char	*ADDR = (unsigned char *) addr;
-+
-+	ADDR += nr >> 3;
-+	mask = 1 << (nr & 0x07);
-+	retval = mask & *ADDR;
-+	*ADDR |= mask;
-+	return retval;
-+}
-+
-+int ext2fs_clear_bit(unsigned int nr, void * addr)
-+{
-+	int		mask, retval;
-+	unsigned char	*ADDR = (unsigned char *) addr;
-+
-+	ADDR += nr >> 3;
-+	mask = 1 << (nr & 0x07);
-+	retval = mask & *ADDR;
-+	*ADDR &= ~mask;
-+	return retval;
-+}
-+
-+int ext2fs_test_bit(unsigned 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);
-+}
-+
-+#endif	/* !_EXT2_HAVE_ASM_BITOPS_ */
-+
-+void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
-+			const char *description)
-+{
-+#ifndef OMIT_COM_ERR
-+	if (description)
-+		com_err(0, errcode, "#%lu for %s", arg, description);
-+	else
-+		com_err(0, errcode, "#%lu", arg);
-+#endif
-+}
-+
-+void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
-+			    int code, unsigned long arg)
-+{
-+#ifndef OMIT_COM_ERR
-+	if (bitmap->description)
-+		com_err(0, bitmap->base_error_code+code,
-+			"#%lu for %s", arg, bitmap->description);
-+	else
-+		com_err(0, bitmap->base_error_code + code, "#%lu", arg);
-+#endif
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/bitops.h silo-1.4.14/libext2fs/bitops.h
---- silo-1.4.14.orig/libext2fs/bitops.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/bitops.h	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,617 @@
-+/*
-+ * bitops.h --- Bitmap frobbing code.  The byte swapping routines are
-+ * 	also included here.
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
-+ * Linus Torvalds.
-+ */
-+
-+
-+extern int ext2fs_set_bit(unsigned int nr,void * addr);
-+extern int ext2fs_clear_bit(unsigned int nr, void * addr);
-+extern int ext2fs_test_bit(unsigned int nr, const void * addr);
-+extern __u16 ext2fs_swab16(__u16 val);
-+extern __u32 ext2fs_swab32(__u32 val);
-+
-+#ifdef WORDS_BIGENDIAN
-+#define ext2fs_cpu_to_le32(x) ext2fs_swab32((x))
-+#define ext2fs_le32_to_cpu(x) ext2fs_swab32((x))
-+#define ext2fs_cpu_to_le16(x) ext2fs_swab16((x))
-+#define ext2fs_le16_to_cpu(x) ext2fs_swab16((x))
-+#define ext2fs_cpu_to_be32(x) ((__u32)(x))
-+#define ext2fs_be32_to_cpu(x) ((__u32)(x))
-+#define ext2fs_cpu_to_be16(x) ((__u16)(x))
-+#define ext2fs_be16_to_cpu(x) ((__u16)(x))
-+#else
-+#define ext2fs_cpu_to_le32(x) ((__u32)(x))
-+#define ext2fs_le32_to_cpu(x) ((__u32)(x))
-+#define ext2fs_cpu_to_le16(x) ((__u16)(x))
-+#define ext2fs_le16_to_cpu(x) ((__u16)(x))
-+#define ext2fs_cpu_to_be32(x) ext2fs_swab32((x))
-+#define ext2fs_be32_to_cpu(x) ext2fs_swab32((x))
-+#define ext2fs_cpu_to_be16(x) ext2fs_swab16((x))
-+#define ext2fs_be16_to_cpu(x) ext2fs_swab16((x))
-+#endif
-+
-+/*
-+ * EXT2FS bitmap manipulation routines.
-+ */
-+
-+/* Support for sending warning messages from the inline subroutines */
-+extern const char *ext2fs_block_string;
-+extern const char *ext2fs_inode_string;
-+extern const char *ext2fs_mark_string;
-+extern const char *ext2fs_unmark_string;
-+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 int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
-+extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
-+				       blk_t block);
-+extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
-+
-+extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
-+extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+				       ext2_ino_t inode);
-+extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
-+
-+extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
-+					  blk_t block);
-+extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
-+					    blk_t block);
-+extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
-+					 blk_t block);
-+
-+extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+					  ext2_ino_t inode);
-+extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+					    ext2_ino_t inode);
-+extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+					 ext2_ino_t inode);
-+extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
-+extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
-+extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
-+extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
-+
-+extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+					   blk_t block, int num);
-+extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+					     blk_t block, int num);
-+extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+					  blk_t block, int num);
-+extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+						blk_t block, int num);
-+extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+						  blk_t block, int num);
-+extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+					       blk_t block, int num);
-+extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
-+
-+/* These two routines moved to gen_bitmap.c */
-+extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
-+					 __u32 bitno);
-+extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
-+					   blk_t bitno);
-+/*
-+ * The inline routines themselves...
-+ * 
-+ * If NO_INLINE_FUNCS is defined, then we won't try to do inline
-+ * functions at all; they will be included as normal functions in
-+ * inline.c
-+ */
-+#ifdef NO_INLINE_FUNCS
-+#if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
-+			   defined(__i586__) || defined(__mc68000__) || \
-+			   defined(__sparc__)))
-+	/* This prevents bitops.c from trying to include the C */
-+	/* function version of these functions */
-+#define _EXT2_HAVE_ASM_BITOPS_
-+#endif
-+#endif /* NO_INLINE_FUNCS */
-+
-+#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
-+#ifdef INCLUDE_INLINE_FUNCS
-+#define _INLINE_ extern
-+#else
-+#ifdef __GNUC__
-+#define _INLINE_ extern __inline__
-+#else				/* For Watcom C */
-+#define _INLINE_ extern inline
-+#endif
-+#endif
-+
-+#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
-+     (defined(__i386__) || defined(__i486__) || defined(__i586__)))
-+
-+#define _EXT2_HAVE_ASM_BITOPS_
-+#define _EXT2_HAVE_ASM_SWAB_
-+#define _EXT2_HAVE_ASM_FINDBIT_
-+
-+/*
-+ * These are done by inline assembly for speed reasons.....
-+ *
-+ * All bitoperations return 0 if the bit was cleared before the
-+ * operation and != 0 if it was not.  Bit 0 is the LSB of addr; bit 32
-+ * is the LSB of (addr+1).
-+ */
-+
-+/*
-+ * Some hacks to defeat gcc over-optimizations..
-+ */
-+struct __dummy_h { unsigned long a[100]; };
-+#define EXT2FS_ADDR (*(struct __dummy_h *) addr)
-+#define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)	
-+
-+_INLINE_ int ext2fs_set_bit(unsigned int nr, void * addr)
-+{
-+	int oldbit;
-+
-+	__asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
-+		:"=r" (oldbit),"=m" (EXT2FS_ADDR)
-+		:"r" (nr));
-+	return oldbit;
-+}
-+
-+_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
-+{
-+	int oldbit;
-+
-+	__asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
-+		:"=r" (oldbit),"=m" (EXT2FS_ADDR)
-+		:"r" (nr));
-+	return oldbit;
-+}
-+
-+_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
-+{
-+	int oldbit;
-+
-+	__asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
-+		:"=r" (oldbit)
-+		:"m" (EXT2FS_CONST_ADDR),"r" (nr));
-+	return oldbit;
-+}
-+
-+#if 0
-+_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
-+{
-+	int d0, d1, d2;
-+	int res;
-+
-+	if (!size)
-+		return 0;
-+	/* This looks at memory. Mark it volatile to tell gcc not to move it around */
-+	__asm__ __volatile__(
-+		"cld\n\t"			     
-+		"xorl %%eax,%%eax\n\t"
-+		"xorl %%edx,%%edx\n\t"
-+		"repe; scasl\n\t"
-+		"je 1f\n\t"
-+		"movl -4(%%edi),%%eax\n\t"
-+		"subl $4,%%edi\n\t"
-+		"bsfl %%eax,%%edx\n"
-+		"1:\tsubl %%esi,%%edi\n\t"
-+		"shll $3,%%edi\n\t"
-+		"addl %%edi,%%edx"
-+		:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
-+		:"1" ((size + 31) >> 5), "2" (addr), "S" (addr));
-+	return res;
-+}
-+
-+_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
-+{
-+	unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
-+	int set = 0, bit = offset & 31, res;
-+	
-+	if (bit) {
-+		/*
-+		 * Look for zero in first byte
-+		 */
-+		__asm__("bsfl %1,%0\n\t"
-+			"jne 1f\n\t"
-+			"movl $32, %0\n"
-+			"1:"
-+			: "=r" (set)
-+			: "r" (*p >> bit));
-+		if (set < (32 - bit))
-+			return set + offset;
-+		set = 32 - bit;
-+		p++;
-+	}
-+	/*
-+	 * No bit found yet, search remaining full bytes for a bit
-+	 */
-+	res = ext2fs_find_first_bit_set(p, size - 32 * (p - (unsigned long *) addr));
-+	return (offset + set + res);
-+}
-+#endif
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+_INLINE_ __u32 ext2fs_swab32(__u32 val)
-+{
-+#ifdef EXT2FS_REQUIRE_486
-+	__asm__("bswap %0" : "=r" (val) : "0" (val));
-+#else
-+	__asm__("xchgb %b0,%h0\n\t"	/* swap lower bytes	*/
-+		"rorl $16,%0\n\t"	/* swap words		*/
-+		"xchgb %b0,%h0"		/* swap higher bytes	*/
-+		:"=q" (val)
-+		: "0" (val));
-+#endif
-+	return val;
-+}
-+
-+_INLINE_ __u16 ext2fs_swab16(__u16 val)
-+{
-+	__asm__("xchgb %b0,%h0"		/* swap bytes		*/ \
-+		: "=q" (val) \
-+		:  "0" (val)); \
-+		return val;
-+}
-+#endif
-+
-+#undef EXT2FS_ADDR
-+
-+#endif	/* i386 */
-+
-+#ifdef __mc68000__
-+
-+#define _EXT2_HAVE_ASM_BITOPS_
-+
-+_INLINE_ int ext2fs_set_bit(unsigned int nr,void * addr)
-+{
-+	char retval;
-+
-+	__asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
-+	     : "=d" (retval) : "d" (nr^7), "a" (addr));
-+
-+	return retval;
-+}
-+
-+_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
-+{
-+	char retval;
-+
-+	__asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
-+	     : "=d" (retval) : "d" (nr^7), "a" (addr));
-+
-+	return retval;
-+}
-+
-+_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
-+{
-+	char retval;
-+
-+	__asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
-+	     : "=d" (retval) : "d" (nr^7), "a" (addr));
-+
-+	return retval;
-+}
-+
-+#endif /* __mc68000__ */
-+
-+
-+#if !defined(_EXT2_HAVE_ASM_SWAB_) && defined(EXT2FS_ENABLE_SWAPFS)
-+
-+_INLINE_ __u16 ext2fs_swab16(__u16 val)
-+{
-+	return (val >> 8) | (val << 8);
-+}
-+
-+_INLINE_ __u32 ext2fs_swab32(__u32 val)
-+{
-+	return ((val>>24) | ((val>>8)&0xFF00) |
-+		((val<<8)&0xFF0000) | (val<<24));
-+}
-+
-+#endif /* !_EXT2_HAVE_ASM_SWAB */
-+
-+#if !defined(_EXT2_HAVE_ASM_FINDBIT_)
-+_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
-+{
-+	char	*cp = (unsigned char *) addr;
-+	int 	res = 0, d0;
-+
-+	if (!size)
-+		return 0;
-+
-+	while ((size > res) && (*cp == 0)) {
-+		cp++;
-+		res += 8;
-+	}
-+	d0 = ffs(*cp);
-+	if (d0 == 0)
-+		return size;
-+	
-+	return res + d0 - 1;
-+}
-+
-+_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
-+{
-+	unsigned char * p;
-+	int set = 0, bit = offset & 7, res = 0, d0;
-+	
-+	res = offset >> 3;
-+	p = ((unsigned char *) addr) + res;
-+	
-+	if (bit) {
-+		set = ffs(*p & ~((1 << bit) - 1));
-+		if (set)
-+			return (offset & ~7) + set - 1;
-+		p++;
-+		res += 8;
-+	}
-+	while ((size > res) && (*p == 0)) {
-+		p++;
-+		res += 8;
-+	}
-+	d0 = ffs(*p);
-+	if (d0 == 0)
-+		return size;
-+
-+	return (res + d0 - 1);
-+}
-+#endif	
-+
-+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
-+					blk_t bitno);
-+
-+_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_TEST_ERROR, bitno);
-+		return 0;
-+	}
-+	return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
-+				       blk_t block)
-+{
-+	return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
-+				       bitmap,
-+					  block);
-+}
-+
-+_INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
-+					 blk_t block)
-+{
-+	return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
-+					    block);
-+}
-+
-+_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
-+				       blk_t block)
-+{
-+	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
-+					  block);
-+}
-+
-+_INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+				       ext2_ino_t inode)
-+{
-+	return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
-+					  inode);
-+}
-+
-+_INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+					 ext2_ino_t inode)
-+{
-+	return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
-+				     inode);
-+}
-+
-+_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+				       ext2_ino_t inode)
-+{
-+	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
-+					  inode);
-+}
-+
-+_INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
-+					    blk_t block)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+	if ((block < bitmap->start) || (block > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
-+				   bitmap->description);
-+		return;
-+	}
-+#endif	
-+	ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
-+					      blk_t block)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+	if ((block < bitmap->start) || (block > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
-+				   block, bitmap->description);
-+		return;
-+	}
-+#endif
-+	ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
-+					    blk_t block)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+	if ((block < bitmap->start) || (block > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
-+				   block, bitmap->description);
-+		return 0;
-+	}
-+#endif
-+	return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+					    ext2_ino_t inode)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+	if ((inode < bitmap->start) || (inode > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
-+				   inode, bitmap->description);
-+		return;
-+	}
-+#endif
-+	ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+					      ext2_ino_t inode)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+	if ((inode < bitmap->start) || (inode > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
-+				   inode, bitmap->description);
-+		return;
-+	}
-+#endif
-+	ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+					   ext2_ino_t inode)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+	if ((inode < bitmap->start) || (inode > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
-+				   inode, bitmap->description);
-+		return 0;
-+	}
-+#endif
-+	return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
-+{
-+	return bitmap->start;
-+}
-+
-+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
-+{
-+	return bitmap->start;
-+}
-+
-+_INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
-+{
-+	return bitmap->end;
-+}
-+
-+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
-+{
-+	return bitmap->end;
-+}
-+
-+_INLINE_ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+					    blk_t block, int num)
-+{
-+	int	i;
-+
-+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
-+				   block, bitmap->description);
-+		return 0;
-+	}
-+	for (i=0; i < num; i++) {
-+		if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
-+			return 0;
-+	}
-+	return 1;
-+}
-+
-+_INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+						 blk_t block, int num)
-+{
-+	int	i;
-+
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
-+				   block, bitmap->description);
-+		return 0;
-+	}
-+#endif
-+	for (i=0; i < num; i++) {
-+		if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
-+			return 0;
-+	}
-+	return 1;
-+}
-+
-+_INLINE_ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+					     blk_t block, int num)
-+{
-+	int	i;
-+	
-+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
-+				   bitmap->description);
-+		return;
-+	}
-+	for (i=0; i < num; i++)
-+		ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+						  blk_t block, int num)
-+{
-+	int	i;
-+	
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
-+				   bitmap->description);
-+		return;
-+	}
-+#endif	
-+	for (i=0; i < num; i++)
-+		ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+					       blk_t block, int num)
-+{
-+	int	i;
-+	
-+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
-+				   bitmap->description);
-+		return;
-+	}
-+	for (i=0; i < num; i++)
-+		ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+						    blk_t block, int num)
-+{
-+	int	i;
-+	
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
-+				   bitmap->description);
-+		return;
-+	}
-+#endif	
-+	for (i=0; i < num; i++)
-+		ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
-+}
-+#undef _INLINE_
-+#endif
-+
-diff -Naur silo-1.4.14.orig/libext2fs/block.c silo-1.4.14/libext2fs/block.c
---- silo-1.4.14.orig/libext2fs/block.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/block.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,437 @@
-+/*
-+ * block.c --- iterate over all blocks in an inode
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct block_context {
-+	ext2_filsys	fs;
-+	int (*func)(ext2_filsys	fs,
-+		    blk_t	*blocknr,
-+		    e2_blkcnt_t	bcount,
-+		    blk_t	ref_blk,
-+		    int		ref_offset,
-+		    void	*priv_data);
-+	e2_blkcnt_t	bcount;
-+	int		bsize;
-+	int		flags;
-+	errcode_t	errcode;
-+	char	*ind_buf;
-+	char	*dind_buf;
-+	char	*tind_buf;
-+	void	*priv_data;
-+};
-+
-+static int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
-+			     int ref_offset, struct block_context *ctx)
-+{
-+	int	ret = 0, changed = 0;
-+	int	i, flags, limit, offset;
-+	blk_t	*block_nr;
-+
-+	limit = ctx->fs->blocksize >> 2;
-+	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
-+	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
-+		ret = (*ctx->func)(ctx->fs, ind_block,
-+				   BLOCK_COUNT_IND, ref_block,
-+				   ref_offset, ctx->priv_data);
-+	if (!*ind_block || (ret & BLOCK_ABORT)) {
-+		ctx->bcount += limit;
-+		return ret;
-+	}
-+	if (*ind_block >= ctx->fs->super->s_blocks_count ||
-+	    *ind_block < ctx->fs->super->s_first_data_block) {
-+		ctx->errcode = EXT2_ET_BAD_IND_BLOCK;
-+		ret |= BLOCK_ERROR;
-+		return ret;
-+	}
-+	ctx->errcode = ext2fs_read_ind_block(ctx->fs, *ind_block, 
-+					     ctx->ind_buf);
-+	if (ctx->errcode) {
-+		ret |= BLOCK_ERROR;
-+		return ret;
-+	}
-+
-+	block_nr = (blk_t *) ctx->ind_buf;
-+	offset = 0;
-+	if (ctx->flags & BLOCK_FLAG_APPEND) {
-+		for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) {
-+			flags = (*ctx->func)(ctx->fs, block_nr, ctx->bcount,
-+					     *ind_block, offset, 
-+					     ctx->priv_data);
-+			changed	|= flags;
-+			if (flags & BLOCK_ABORT) {
-+				ret |= BLOCK_ABORT;
-+				break;
-+			}
-+			offset += sizeof(blk_t);
-+		}
-+	} else {
-+		for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) {
-+			if (*block_nr == 0)
-+				continue;
-+			flags = (*ctx->func)(ctx->fs, block_nr, ctx->bcount,
-+					     *ind_block, offset, 
-+					     ctx->priv_data);
-+			changed	|= flags;
-+			if (flags & BLOCK_ABORT) {
-+				ret |= BLOCK_ABORT;
-+				break;
-+			}
-+			offset += sizeof(blk_t);
-+		}
-+	}
-+	if (changed & BLOCK_CHANGED) {
-+		ctx->errcode = ext2fs_write_ind_block(ctx->fs, *ind_block,
-+						      ctx->ind_buf);
-+		if (ctx->errcode)
-+			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,
-+				    BLOCK_COUNT_IND, ref_block,
-+				    ref_offset, ctx->priv_data);
-+	return ret;
-+}
-+	
-+static int block_iterate_dind(blk_t *dind_block, blk_t ref_block,
-+			      int ref_offset, struct block_context *ctx)
-+{
-+	int	ret = 0, changed = 0;
-+	int	i, flags, limit, offset;
-+	blk_t	*block_nr;
-+
-+	limit = ctx->fs->blocksize >> 2;
-+	if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
-+			    BLOCK_FLAG_DATA_ONLY)))
-+		ret = (*ctx->func)(ctx->fs, dind_block,
-+				   BLOCK_COUNT_DIND, ref_block,
-+				   ref_offset, ctx->priv_data);
-+	if (!*dind_block || (ret & BLOCK_ABORT)) {
-+		ctx->bcount += limit*limit;
-+		return ret;
-+	}
-+	if (*dind_block >= ctx->fs->super->s_blocks_count ||
-+	    *dind_block < ctx->fs->super->s_first_data_block) {
-+		ctx->errcode = EXT2_ET_BAD_DIND_BLOCK;
-+		ret |= BLOCK_ERROR;
-+		return ret;
-+	}
-+	ctx->errcode = ext2fs_read_ind_block(ctx->fs, *dind_block, 
-+					     ctx->dind_buf);
-+	if (ctx->errcode) {
-+		ret |= BLOCK_ERROR;
-+		return ret;
-+	}
-+
-+	block_nr = (blk_t *) ctx->dind_buf;
-+	offset = 0;
-+	if (ctx->flags & BLOCK_FLAG_APPEND) {
-+		for (i = 0; i < limit; i++, block_nr++) {
-+			flags = block_iterate_ind(block_nr,
-+						  *dind_block, offset,
-+						  ctx);
-+			changed |= flags;
-+			if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+				ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
-+				break;
-+			}
-+			offset += sizeof(blk_t);
-+		}
-+	} else {
-+		for (i = 0; i < limit; i++, block_nr++) {
-+			if (*block_nr == 0) {
-+				ctx->bcount += limit;
-+				continue;
-+			}
-+			flags = block_iterate_ind(block_nr,
-+						  *dind_block, offset,
-+						  ctx);
-+			changed |= flags;
-+			if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+				ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
-+				break;
-+			}
-+			offset += sizeof(blk_t);
-+		}
-+	}
-+	if (changed & BLOCK_CHANGED) {
-+		ctx->errcode = ext2fs_write_ind_block(ctx->fs, *dind_block,
-+						      ctx->dind_buf);
-+		if (ctx->errcode)
-+			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,
-+				    BLOCK_COUNT_DIND, ref_block,
-+				    ref_offset, ctx->priv_data);
-+	return ret;
-+}
-+	
-+static int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
-+			      int ref_offset, struct block_context *ctx)
-+{
-+	int	ret = 0, changed = 0;
-+	int	i, flags, limit, offset;
-+	blk_t	*block_nr;
-+
-+	limit = ctx->fs->blocksize >> 2;
-+	if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
-+			    BLOCK_FLAG_DATA_ONLY)))
-+		ret = (*ctx->func)(ctx->fs, tind_block,
-+				   BLOCK_COUNT_TIND, ref_block,
-+				   ref_offset, ctx->priv_data);
-+	if (!*tind_block || (ret & BLOCK_ABORT)) {
-+		ctx->bcount += limit*limit*limit;
-+		return ret;
-+	}
-+	if (*tind_block >= ctx->fs->super->s_blocks_count ||
-+	    *tind_block < ctx->fs->super->s_first_data_block) {
-+		ctx->errcode = EXT2_ET_BAD_TIND_BLOCK;
-+		ret |= BLOCK_ERROR;
-+		return ret;
-+	}
-+	ctx->errcode = ext2fs_read_ind_block(ctx->fs, *tind_block, 
-+					     ctx->tind_buf);
-+	if (ctx->errcode) {
-+		ret |= BLOCK_ERROR;
-+		return ret;
-+	}
-+
-+	block_nr = (blk_t *) ctx->tind_buf;
-+	offset = 0;
-+	if (ctx->flags & BLOCK_FLAG_APPEND) {
-+		for (i = 0; i < limit; i++, block_nr++) {
-+			flags = block_iterate_dind(block_nr,
-+						   *tind_block,
-+						   offset, ctx);
-+			changed |= flags;
-+			if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+				ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
-+				break;
-+			}
-+			offset += sizeof(blk_t);
-+		}
-+	} else {
-+		for (i = 0; i < limit; i++, block_nr++) {
-+			if (*block_nr == 0) {
-+				ctx->bcount += limit*limit;
-+				continue;
-+			}
-+			flags = block_iterate_dind(block_nr,
-+						   *tind_block,
-+						   offset, ctx);
-+			changed |= flags;
-+			if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+				ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
-+				break;
-+			}
-+			offset += sizeof(blk_t);
-+		}
-+	}
-+	if (changed & BLOCK_CHANGED) {
-+		ctx->errcode = ext2fs_write_ind_block(ctx->fs, *tind_block,
-+						      ctx->tind_buf);
-+		if (ctx->errcode)
-+			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,
-+				    BLOCK_COUNT_TIND, ref_block,
-+				    ref_offset, ctx->priv_data);
-+	
-+	return ret;
-+}
-+	
-+errcode_t ext2fs_block_iterate2(ext2_filsys fs,
-+				ext2_ino_t ino,
-+				int	flags,
-+				char *block_buf,
-+				int (*func)(ext2_filsys fs,
-+					    blk_t	*blocknr,
-+					    e2_blkcnt_t	blockcnt,
-+					    blk_t	ref_blk,
-+					    int		ref_offset,
-+					    void	*priv_data),
-+				void *priv_data)
-+{
-+	int	i;
-+	int	got_inode = 0;
-+	int	ret = 0;
-+	blk_t	blocks[EXT2_N_BLOCKS];	/* directory data blocks */
-+	struct ext2_inode inode;
-+	errcode_t	retval;
-+	struct block_context ctx;
-+	int	limit;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	/*
-+	 * Check to see if we need to limit large files
-+	 */
-+	if (flags & BLOCK_FLAG_NO_LARGE) {
-+		ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
-+		if (ctx.errcode)
-+			return ctx.errcode;
-+		got_inode = 1;
-+		if (!LINUX_S_ISDIR(inode.i_mode) &&
-+		    (inode.i_size_high != 0))
-+			return EXT2_ET_FILE_TOO_BIG;
-+	}
-+
-+	retval = ext2fs_get_blocks(fs, ino, blocks);
-+	if (retval)
-+		return retval;
-+
-+	limit = fs->blocksize >> 2;
-+
-+	ctx.fs = fs;
-+	ctx.func = func;
-+	ctx.priv_data = priv_data;
-+	ctx.flags = flags;
-+	ctx.bcount = 0;
-+	if (block_buf) {
-+		ctx.ind_buf = block_buf;
-+	} else {
-+		retval = ext2fs_get_mem(fs->blocksize * 3, &ctx.ind_buf);
-+		if (retval)
-+			return retval;
-+	}
-+	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)) {
-+		ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
-+		if (ctx.errcode)
-+			goto abort_exit;
-+		got_inode = 1;
-+		if (inode.osd1.hurd1.h_i_translator) {
-+			ret |= (*ctx.func)(fs,
-+					   &inode.osd1.hurd1.h_i_translator,
-+					   BLOCK_COUNT_TRANSLATOR,
-+					   0, 0, priv_data);
-+			if (ret & BLOCK_ABORT)
-+				goto abort_exit;
-+		}
-+	}
-+	
-+	/*
-+	 * Iterate over normal data blocks
-+	 */
-+	for (i = 0; i < EXT2_NDIR_BLOCKS ; i++, ctx.bcount++) {
-+		if (blocks[i] || (flags & BLOCK_FLAG_APPEND)) {
-+			ret |= (*ctx.func)(fs, &blocks[i],
-+					    ctx.bcount, 0, i, priv_data);
-+			if (ret & BLOCK_ABORT)
-+				goto abort_exit;
-+		}
-+	}
-+	if (*(blocks + EXT2_IND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
-+		ret |= block_iterate_ind(blocks + EXT2_IND_BLOCK,
-+					 0, EXT2_IND_BLOCK, &ctx);
-+		if (ret & BLOCK_ABORT)
-+			goto abort_exit;
-+	} else
-+		ctx.bcount += limit;
-+	if (*(blocks + EXT2_DIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
-+		ret |= block_iterate_dind(blocks + EXT2_DIND_BLOCK,
-+					  0, EXT2_DIND_BLOCK, &ctx);
-+		if (ret & BLOCK_ABORT)
-+			goto abort_exit;
-+	} else
-+		ctx.bcount += limit * limit;
-+	if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
-+		ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK,
-+					  0, EXT2_TIND_BLOCK, &ctx);
-+		if (ret & BLOCK_ABORT)
-+			goto abort_exit;
-+	}
-+
-+abort_exit:
-+	if (ret & BLOCK_CHANGED) {
-+		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);
-+		if (retval)
-+			return retval;
-+	}
-+
-+	if (!block_buf)
-+		ext2fs_free_mem(&ctx.ind_buf);
-+
-+	return (ret & BLOCK_ERROR) ? ctx.errcode : 0;
-+}
-+
-+/*
-+ * Emulate the old ext2fs_block_iterate function!
-+ */
-+
-+struct xlate {
-+	int (*func)(ext2_filsys	fs,
-+		    blk_t	*blocknr,
-+		    int		bcount,
-+		    void	*priv_data);
-+	void *real_private;
-+};
-+
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int xlate_func(ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t blockcnt,
-+		      blk_t ref_block EXT2FS_ATTR((unused)),
-+		      int ref_offset EXT2FS_ATTR((unused)),
-+		      void *priv_data)
-+{
-+	struct xlate *xl = (struct xlate *) priv_data;
-+
-+	return (*xl->func)(fs, blocknr, (int) blockcnt, xl->real_private);
-+}
-+
-+errcode_t ext2fs_block_iterate(ext2_filsys fs,
-+			       ext2_ino_t ino,
-+			       int	flags,
-+			       char *block_buf,
-+			       int (*func)(ext2_filsys fs,
-+					   blk_t	*blocknr,
-+					   int	blockcnt,
-+					   void	*priv_data),
-+			       void *priv_data)
-+{
-+	struct xlate xl;
-+	
-+	xl.real_private = priv_data;
-+	xl.func = func;
-+
-+	return ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_NO_LARGE | flags,
-+				     block_buf, xlate_func, &xl);
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/bmap.c silo-1.4.14/libext2fs/bmap.c
---- silo-1.4.14.orig/libext2fs/bmap.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/bmap.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,270 @@
-+/*
-+ * bmap.c --- logical to physical block mapping
-+ *
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#if defined(__GNUC__) && !defined(NO_INLINE_FUNCS)
-+#define _BMAP_INLINE_	__inline__
-+#else
-+#define _BMAP_INLINE_
-+#endif
-+
-+extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
-+			     struct ext2_inode *inode, 
-+			     char *block_buf, int bmap_flags,
-+			     blk_t block, blk_t *phys_blk);
-+
-+#define inode_bmap(inode, nr) ((inode)->i_block[(nr)])
-+
-+static _BMAP_INLINE_ errcode_t block_ind_bmap(ext2_filsys fs, int flags, 
-+					      blk_t ind, char *block_buf, 
-+					      int *blocks_alloc,
-+					      blk_t nr, blk_t *ret_blk)
-+{
-+	errcode_t	retval;
-+	blk_t		b;
-+
-+	if (!ind) {
-+		if (flags & BMAP_SET)
-+			return EXT2_ET_SET_BMAP_NO_IND;
-+		*ret_blk = 0;
-+		return 0;
-+	}
-+	retval = io_channel_read_blk(fs->io, ind, 1, block_buf);
-+	if (retval)
-+		return retval;
-+
-+	if (flags & BMAP_SET) {
-+		b = *ret_blk;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+		if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+		    (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
-+			b = ext2fs_swab32(b);
-+#endif
-+		((blk_t *) block_buf)[nr] = b;
-+		return io_channel_write_blk(fs->io, ind, 1, block_buf);
-+	}
-+
-+	b = ((blk_t *) block_buf)[nr];
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+	    (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
-+		b = ext2fs_swab32(b);
-+#endif
-+
-+	if (!b && (flags & BMAP_ALLOC)) {
-+		b = nr ? ((blk_t *) block_buf)[nr-1] : 0;
-+		retval = ext2fs_alloc_block(fs, b,
-+					    block_buf + fs->blocksize, &b);
-+		if (retval)
-+			return retval;
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+		if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+		    (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
-+			((blk_t *) block_buf)[nr] = ext2fs_swab32(b);
-+		else
-+#endif
-+			((blk_t *) block_buf)[nr] = b;
-+
-+		retval = io_channel_write_blk(fs->io, ind, 1, block_buf);
-+		if (retval)
-+			return retval;
-+
-+		(*blocks_alloc)++;
-+	}
-+
-+	*ret_blk = b;
-+	return 0;
-+}
-+
-+static _BMAP_INLINE_ errcode_t block_dind_bmap(ext2_filsys fs, int flags,
-+					       blk_t dind, char *block_buf, 
-+					       int *blocks_alloc,
-+					       blk_t nr, blk_t *ret_blk)
-+{
-+	blk_t		b;
-+	errcode_t	retval;
-+	blk_t		addr_per_block;
-+	
-+	addr_per_block = (blk_t) fs->blocksize >> 2;
-+
-+	retval = block_ind_bmap(fs, flags & ~BMAP_SET, dind, block_buf, 
-+				blocks_alloc, nr / addr_per_block, &b);
-+	if (retval)
-+		return retval;
-+	retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc,
-+				nr % addr_per_block, ret_blk);
-+	return retval;
-+}
-+
-+static _BMAP_INLINE_ errcode_t block_tind_bmap(ext2_filsys fs, int flags,
-+					       blk_t tind, char *block_buf, 
-+					       int *blocks_alloc,
-+					       blk_t nr, blk_t *ret_blk)
-+{
-+	blk_t		b;
-+	errcode_t	retval;
-+	blk_t		addr_per_block;
-+	
-+	addr_per_block = (blk_t) fs->blocksize >> 2;
-+
-+	retval = block_dind_bmap(fs, flags & ~BMAP_SET, tind, block_buf, 
-+				 blocks_alloc, nr / addr_per_block, &b);
-+	if (retval)
-+		return retval;
-+	retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc,
-+				nr % addr_per_block, ret_blk);
-+	return retval;
-+}
-+
-+errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
-+		      char *block_buf, int bmap_flags, blk_t block,
-+		      blk_t *phys_blk)
-+{
-+	struct ext2_inode inode_buf;
-+	blk_t addr_per_block;
-+	blk_t	b;
-+	char	*buf = 0;
-+	errcode_t	retval = 0;
-+	int		blocks_alloc = 0, inode_dirty = 0;
-+
-+	if (!(bmap_flags & BMAP_SET))
-+		*phys_blk = 0;
-+
-+	/* Read inode structure if necessary */
-+	if (!inode) {
-+		retval = ext2fs_read_inode(fs, ino, &inode_buf);
-+		if (retval)
-+			return retval;
-+		inode = &inode_buf;
-+	}
-+	addr_per_block = (blk_t) fs->blocksize >> 2;
-+
-+	if (!block_buf) {
-+		retval = ext2fs_get_mem(fs->blocksize * 2, &buf);
-+		if (retval)
-+			return retval;
-+		block_buf = buf;
-+	}
-+
-+	if (block < EXT2_NDIR_BLOCKS) {
-+		if (bmap_flags & BMAP_SET) {
-+			b = *phys_blk;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+			if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+			    (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
-+				b = ext2fs_swab32(b);
-+#endif
-+			inode_bmap(inode, block) = b;
-+			inode_dirty++;
-+			goto done;
-+		}
-+
-+		*phys_blk = inode_bmap(inode, block);
-+		b = block ? inode_bmap(inode, block-1) : 0;
-+		
-+		if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) {
-+			retval = ext2fs_alloc_block(fs, b, block_buf, &b);
-+			if (retval)
-+				goto done;
-+			inode_bmap(inode, block) = b;
-+			blocks_alloc++;
-+			*phys_blk = b;
-+		}
-+		goto done;
-+	}
-+	
-+	/* Indirect block */
-+	block -= EXT2_NDIR_BLOCKS;
-+	if (block < addr_per_block) {
-+		b = inode_bmap(inode, EXT2_IND_BLOCK);
-+		if (!b) {
-+			if (!(bmap_flags & BMAP_ALLOC)) {
-+				if (bmap_flags & BMAP_SET)
-+					retval = EXT2_ET_SET_BMAP_NO_IND;
-+				goto done;
-+			}
-+
-+			b = inode_bmap(inode, EXT2_IND_BLOCK-1);
-+ 			retval = ext2fs_alloc_block(fs, b, block_buf, &b);
-+			if (retval)
-+				goto done;
-+			inode_bmap(inode, EXT2_IND_BLOCK) = b;
-+			blocks_alloc++;
-+		}
-+		retval = block_ind_bmap(fs, bmap_flags, b, block_buf, 
-+					&blocks_alloc, block, phys_blk);
-+		goto done;
-+	}
-+	
-+	/* Doubly indirect block  */
-+	block -= addr_per_block;
-+	if (block < addr_per_block * addr_per_block) {
-+		b = inode_bmap(inode, EXT2_DIND_BLOCK);
-+		if (!b) {
-+			if (!(bmap_flags & BMAP_ALLOC)) {
-+				if (bmap_flags & BMAP_SET)
-+					retval = EXT2_ET_SET_BMAP_NO_IND;
-+				goto done;
-+			}
-+
-+			b = inode_bmap(inode, EXT2_IND_BLOCK);
-+ 			retval = ext2fs_alloc_block(fs, b, block_buf, &b);
-+			if (retval)
-+				goto done;
-+			inode_bmap(inode, EXT2_DIND_BLOCK) = b;
-+			blocks_alloc++;
-+		}
-+		retval = block_dind_bmap(fs, bmap_flags, b, block_buf, 
-+					 &blocks_alloc, block, phys_blk);
-+		goto done;
-+	}
-+
-+	/* Triply indirect block */
-+	block -= addr_per_block * addr_per_block;
-+	b = inode_bmap(inode, EXT2_TIND_BLOCK);
-+	if (!b) {
-+		if (!(bmap_flags & BMAP_ALLOC)) {
-+			if (bmap_flags & BMAP_SET)
-+				retval = EXT2_ET_SET_BMAP_NO_IND;
-+			goto done;
-+		}
-+
-+		b = inode_bmap(inode, EXT2_DIND_BLOCK);
-+		retval = ext2fs_alloc_block(fs, b, block_buf, &b);
-+		if (retval)
-+			goto done;
-+		inode_bmap(inode, EXT2_TIND_BLOCK) = b;
-+		blocks_alloc++;
-+	}
-+	retval = block_tind_bmap(fs, bmap_flags, b, block_buf, 
-+				 &blocks_alloc, block, phys_blk);
-+done:
-+	if (buf)
-+		ext2fs_free_mem(&buf);
-+	if ((retval == 0) && (blocks_alloc || inode_dirty)) {
-+		inode->i_blocks += (blocks_alloc * fs->blocksize) / 512;
-+		retval = ext2fs_write_inode(fs, ino, inode);
-+	}
-+	return retval;
-+}
-+
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/bmove.c silo-1.4.14/libext2fs/bmove.c
---- silo-1.4.14.orig/libext2fs/bmove.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/bmove.c	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,160 @@
-+/*
-+ * bmove.c --- Move blocks around to make way for a particular
-+ * 	filesystem structure.
-+ *
-+ * Copyright (C) 1997 Theodore Ts'o.  This file may be redistributed
-+ * under the terms of the GNU Public License.
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#if HAVE_SYS_TIME_H
-+#include <sys/time.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+struct process_block_struct {
-+	ext2_ino_t		ino;
-+	struct ext2_inode *	inode;
-+	ext2fs_block_bitmap	reserve;
-+	ext2fs_block_bitmap	alloc_map;
-+	errcode_t		error;
-+	char			*buf;
-+	int			add_dir;
-+	int			flags;
-+};
-+
-+static int process_block(ext2_filsys fs, blk_t	*block_nr,
-+			 e2_blkcnt_t blockcnt, blk_t ref_block,
-+			 int ref_offset, void *priv_data)
-+{
-+	struct process_block_struct *pb;
-+	errcode_t	retval;
-+	int		ret;
-+	blk_t		block, orig;
-+
-+	pb = (struct process_block_struct *) priv_data;
-+	block = orig = *block_nr;
-+	ret = 0;
-+	
-+	/*
-+	 * Let's see if this is one which we need to relocate
-+	 */
-+	if (ext2fs_test_block_bitmap(pb->reserve, block)) {
-+		do {
-+			if (++block >= fs->super->s_blocks_count)
-+				block = fs->super->s_first_data_block;
-+			if (block == orig) {
-+				pb->error = EXT2_ET_BLOCK_ALLOC_FAIL;
-+				return BLOCK_ABORT;
-+			}
-+		} while (ext2fs_test_block_bitmap(pb->reserve, block) ||
-+			 ext2fs_test_block_bitmap(pb->alloc_map, block));
-+
-+		retval = io_channel_read_blk(fs->io, orig, 1, pb->buf);
-+		if (retval) {
-+			pb->error = retval;
-+			return BLOCK_ABORT;
-+		}
-+		retval = io_channel_write_blk(fs->io, block, 1, pb->buf);
-+		if (retval) {
-+			pb->error = retval;
-+			return BLOCK_ABORT;
-+		}
-+		*block_nr = block;
-+		ext2fs_mark_block_bitmap(pb->alloc_map, block);
-+		ret = BLOCK_CHANGED;
-+		if (pb->flags & EXT2_BMOVE_DEBUG)
-+			printf("ino=%ld, blockcnt=%lld, %d->%d\n", pb->ino,
-+			       blockcnt, orig, block);
-+	}
-+	if (pb->add_dir) {
-+		retval = ext2fs_add_dir_block(fs->dblist, pb->ino,
-+					      block, (int) blockcnt);
-+		if (retval) {
-+			pb->error = retval;
-+			ret |= BLOCK_ABORT;
-+		}
-+	}
-+	return ret;
-+}
-+
-+errcode_t ext2fs_move_blocks(ext2_filsys fs,
-+			     ext2fs_block_bitmap reserve,
-+			     ext2fs_block_bitmap alloc_map,
-+			     int flags)
-+{
-+	ext2_ino_t	ino;
-+	struct ext2_inode inode;
-+	errcode_t	retval;
-+	struct process_block_struct pb;
-+	ext2_inode_scan	scan;
-+	char		*block_buf;
-+	
-+	retval = ext2fs_open_inode_scan(fs, 0, &scan);
-+	if (retval)
-+		return retval;
-+
-+	pb.reserve = reserve;
-+	pb.error = 0;
-+	pb.alloc_map = alloc_map ? alloc_map : fs->block_map;
-+	pb.flags = flags;
-+	
-+	retval = ext2fs_get_mem(fs->blocksize * 4, &block_buf);
-+	if (retval)
-+		return retval;
-+	pb.buf = block_buf + fs->blocksize * 3;
-+
-+	/*
-+	 * If GET_DBLIST is set in the flags field, then we should
-+	 * gather directory block information while we're doing the
-+	 * block move.
-+	 */
-+	if (flags & EXT2_BMOVE_GET_DBLIST) {
-+		if (fs->dblist) {
-+			ext2fs_free_dblist(fs->dblist);
-+			fs->dblist = NULL;
-+		}
-+		retval = ext2fs_init_dblist(fs, 0);
-+		if (retval)
-+			return retval;
-+	}
-+
-+	retval = ext2fs_get_next_inode(scan, &ino, &inode);
-+	if (retval)
-+		return retval;
-+	
-+	while (ino) {
-+		if ((inode.i_links_count == 0) ||
-+		    !ext2fs_inode_has_valid_blocks(&inode))
-+			goto next;
-+		
-+		pb.ino = ino;
-+		pb.inode = &inode;
-+
-+		pb.add_dir = (LINUX_S_ISDIR(inode.i_mode) &&
-+			      flags & EXT2_BMOVE_GET_DBLIST);
-+
-+		retval = ext2fs_block_iterate2(fs, ino, 0, block_buf,
-+					      process_block, &pb);
-+		if (retval)
-+			return retval;
-+		if (pb.error)
-+			return pb.error;
-+
-+	next:
-+		retval = ext2fs_get_next_inode(scan, &ino, &inode);
-+		if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
-+			goto next;
-+	}
-+	return 0;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/brel.h silo-1.4.14/libext2fs/brel.h
---- silo-1.4.14.orig/libext2fs/brel.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/brel.h	2011-01-10 21:59:35.407120276 -0500
-@@ -0,0 +1,86 @@
-+/*
-+ * brel.h
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+struct ext2_block_relocate_entry {
-+	blk_t	new;
-+	__s16	offset;
-+	__u16	flags;
-+	union {
-+		blk_t		block_ref;
-+		ext2_ino_t	inode_ref;
-+	} owner;
-+};
-+
-+#define RELOCATE_TYPE_REF  0x0007
-+#define RELOCATE_BLOCK_REF 0x0001
-+#define RELOCATE_INODE_REF 0x0002
-+
-+typedef struct ext2_block_relocation_table *ext2_brel;
-+
-+struct ext2_block_relocation_table {
-+	__u32	magic;
-+	char	*name;
-+	blk_t	current;
-+	void	*priv_data;
-+
-+	/*
-+	 * Add a block relocation entry.
-+	 */
-+	errcode_t (*put)(ext2_brel brel, blk_t old,
-+			      struct ext2_block_relocate_entry *ent);
-+
-+	/*
-+	 * Get a block relocation entry.
-+	 */
-+	errcode_t (*get)(ext2_brel brel, blk_t old,
-+			      struct ext2_block_relocate_entry *ent);
-+
-+	/*
-+	 * Initialize for iterating over the block relocation entries.
-+	 */
-+	errcode_t (*start_iter)(ext2_brel brel);
-+	
-+	/*
-+	 * The iterator function for the inode relocation entries.
-+	 * Returns an inode number of 0 when out of entries.
-+	 */
-+	errcode_t (*next)(ext2_brel brel, blk_t *old,
-+			  struct ext2_block_relocate_entry *ent);
-+
-+	/*
-+	 * Move the inode relocation table from one block number to
-+	 * another.
-+	 */
-+	errcode_t (*move)(ext2_brel brel, blk_t old, blk_t new);
-+
-+	/*
-+	 * Remove a block relocation entry.
-+	 */
-+	errcode_t (*delete)(ext2_brel brel, blk_t old);
-+
-+
-+	/*
-+	 * Free the block relocation table.
-+	 */
-+	errcode_t (*free)(ext2_brel brel);
-+};
-+
-+errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block,
-+				    ext2_brel *brel);
-+
-+#define ext2fs_brel_put(brel, old, ent) ((brel)->put((brel), old, ent))
-+#define ext2fs_brel_get(brel, old, ent) ((brel)->get((brel), old, ent))
-+#define ext2fs_brel_start_iter(brel) ((brel)->start_iter((brel)))
-+#define ext2fs_brel_next(brel, old, ent) ((brel)->next((brel), old, ent))
-+#define ext2fs_brel_move(brel, old, new) ((brel)->move((brel), old, new))
-+#define ext2fs_brel_delete(brel, old) ((brel)->delete((brel), old))
-+#define ext2fs_brel_free(brel) ((brel)->free((brel)))
-+
-diff -Naur silo-1.4.14.orig/libext2fs/brel_ma.c silo-1.4.14/libext2fs/brel_ma.c
---- silo-1.4.14.orig/libext2fs/brel_ma.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/brel_ma.c	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,197 @@
-+/*
-+ * brel_ma.c
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * TODO: rewrite to not use a direct array!!!  (Fortunately this
-+ * module isn't really used yet.)
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <fcntl.h>
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+#include "brel.h"
-+
-+static errcode_t bma_put(ext2_brel brel, blk_t old,
-+			struct ext2_block_relocate_entry *ent);
-+static errcode_t bma_get(ext2_brel brel, blk_t old,
-+			struct ext2_block_relocate_entry *ent);
-+static errcode_t bma_start_iter(ext2_brel brel);
-+static errcode_t bma_next(ext2_brel brel, blk_t *old,
-+			 struct ext2_block_relocate_entry *ent);
-+static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new);
-+static errcode_t bma_delete(ext2_brel brel, blk_t old);
-+static errcode_t bma_free(ext2_brel brel);
-+
-+struct brel_ma {
-+	__u32 magic;
-+	blk_t max_block;
-+	struct ext2_block_relocate_entry *entries;
-+};
-+
-+errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block,
-+				      ext2_brel *new_brel)
-+{
-+	ext2_brel		brel = 0;
-+	errcode_t	retval;
-+	struct brel_ma 	*ma = 0;
-+	size_t		size;
-+
-+	*new_brel = 0;
-+
-+	/*
-+	 * Allocate memory structures
-+	 */
-+	retval = ext2fs_get_mem(sizeof(struct ext2_block_relocation_table),
-+				&brel);
-+	if (retval)
-+		goto errout;
-+	memset(brel, 0, sizeof(struct ext2_block_relocation_table));
-+	
-+	retval = ext2fs_get_mem(strlen(name)+1, &brel->name);
-+	if (retval)
-+		goto errout;
-+	strcpy(brel->name, name);
-+	
-+	retval = ext2fs_get_mem(sizeof(struct brel_ma), &ma);
-+	if (retval)
-+		goto errout;
-+	memset(ma, 0, sizeof(struct brel_ma));
-+	brel->priv_data = ma;
-+	
-+	size = (size_t) (sizeof(struct ext2_block_relocate_entry) *
-+			 (max_block+1));
-+	retval = ext2fs_get_mem(size, &ma->entries);
-+	if (retval)
-+		goto errout;
-+	memset(ma->entries, 0, size);
-+	ma->max_block = max_block;
-+
-+	/*
-+	 * Fill in the brel data structure
-+	 */
-+	brel->put = bma_put;
-+	brel->get = bma_get;
-+	brel->start_iter = bma_start_iter;
-+	brel->next = bma_next;
-+	brel->move = bma_move;
-+	brel->delete = bma_delete;
-+	brel->free = bma_free;
-+	
-+	*new_brel = brel;
-+	return 0;
-+
-+errout:
-+	bma_free(brel);
-+	return retval;
-+}
-+
-+static errcode_t bma_put(ext2_brel brel, blk_t old,
-+			struct ext2_block_relocate_entry *ent)
-+{
-+	struct brel_ma 	*ma;
-+
-+	ma = brel->priv_data;
-+	if (old > ma->max_block)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	ma->entries[(unsigned)old] = *ent;
-+	return 0;
-+}
-+
-+static errcode_t bma_get(ext2_brel brel, blk_t old,
-+			struct ext2_block_relocate_entry *ent)
-+{
-+	struct brel_ma 	*ma;
-+
-+	ma = brel->priv_data;
-+	if (old > ma->max_block)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	if (ma->entries[(unsigned)old].new == 0)
-+		return ENOENT;
-+	*ent = ma->entries[old];
-+	return 0;
-+}
-+
-+static errcode_t bma_start_iter(ext2_brel brel)
-+{
-+	brel->current = 0;
-+	return 0;
-+}
-+
-+static errcode_t bma_next(ext2_brel brel, blk_t *old,
-+			  struct ext2_block_relocate_entry *ent)
-+{
-+	struct brel_ma 	*ma;
-+
-+	ma = brel->priv_data;
-+	while (++brel->current < ma->max_block) {
-+		if (ma->entries[(unsigned)brel->current].new == 0)
-+			continue;
-+		*old = brel->current;
-+		*ent = ma->entries[(unsigned)brel->current];
-+		return 0;
-+	}
-+	*old = 0;
-+	return 0;
-+}
-+
-+static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new)
-+{
-+	struct brel_ma 	*ma;
-+
-+	ma = brel->priv_data;
-+	if ((old > ma->max_block) || (new > ma->max_block))
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	if (ma->entries[(unsigned)old].new == 0)
-+		return ENOENT;
-+	ma->entries[(unsigned)new] = ma->entries[old];
-+	ma->entries[(unsigned)old].new = 0;
-+	return 0;
-+}
-+
-+static errcode_t bma_delete(ext2_brel brel, blk_t old)
-+{
-+	struct brel_ma 	*ma;
-+
-+	ma = brel->priv_data;
-+	if (old > ma->max_block)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	if (ma->entries[(unsigned)old].new == 0)
-+		return ENOENT;
-+	ma->entries[(unsigned)old].new = 0;
-+	return 0;
-+}
-+
-+static errcode_t bma_free(ext2_brel brel)
-+{
-+	struct brel_ma 	*ma;
-+
-+	if (!brel)
-+		return 0;
-+
-+	ma = brel->priv_data;
-+
-+	if (ma) {
-+		if (ma->entries)
-+			ext2fs_free_mem(&ma->entries);
-+		ext2fs_free_mem(&ma);
-+	}
-+	if (brel->name)
-+		ext2fs_free_mem(&brel->name);
-+	ext2fs_free_mem(&brel);
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/check_desc.c silo-1.4.14/libext2fs/check_desc.c
---- silo-1.4.14.orig/libext2fs/check_desc.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/check_desc.c	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,68 @@
-+/*
-+ * check_desc.c --- Check the group descriptors of an ext2 filesystem
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * This routine sanity checks the group descriptors
-+ */
-+errcode_t ext2fs_check_desc(ext2_filsys fs)
-+{
-+	dgrp_t i;
-+	blk_t block = fs->super->s_first_data_block;
-+	blk_t next;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	for (i = 0; i < fs->group_desc_count; i++) {
-+		next = block + fs->super->s_blocks_per_group;
-+		/*
-+		 * Check to make sure block bitmap for group is
-+		 * located within the group.
-+		 */
-+		if (fs->group_desc[i].bg_block_bitmap < block ||
-+		    fs->group_desc[i].bg_block_bitmap >= next)
-+			return EXT2_ET_GDESC_BAD_BLOCK_MAP;
-+		/*
-+		 * Check to make sure inode bitmap for group is
-+		 * located within the group
-+		 */
-+		if (fs->group_desc[i].bg_inode_bitmap < block ||
-+		    fs->group_desc[i].bg_inode_bitmap >= next)
-+			return EXT2_ET_GDESC_BAD_INODE_MAP;
-+		/*
-+		 * Check to make sure inode table for group is located
-+		 * within the group
-+		 */
-+		if (fs->group_desc[i].bg_inode_table < block ||
-+		    ((fs->group_desc[i].bg_inode_table +
-+		      fs->inode_blocks_per_group) >= next))
-+			return EXT2_ET_GDESC_BAD_INODE_TABLE;
-+		
-+		block = next;
-+	}
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/closefs.c silo-1.4.14/libext2fs/closefs.c
---- silo-1.4.14.orig/libext2fs/closefs.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/closefs.c	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,381 @@
-+/*
-+ * closefs.c --- close an ext2 filesystem
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <time.h>
-+#include <string.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+static int test_root(int a, int b)
-+{
-+	if (a == 0)
-+		return 1;
-+	while (1) {
-+		if (a == 1)
-+			return 1;
-+		if (a % b)
-+			return 0;
-+		a = a / b;
-+	}
-+}
-+
-+int ext2fs_bg_has_super(ext2_filsys fs, int group_block)
-+{
-+	if (!(fs->super->s_feature_ro_compat &
-+	      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
-+		return 1;
-+
-+	if (test_root(group_block, 3) || (test_root(group_block, 5)) ||
-+	    test_root(group_block, 7))
-+		return 1;
-+
-+	return 0;
-+}
-+
-+int ext2fs_super_and_bgd_loc(ext2_filsys fs, 
-+			     dgrp_t group,
-+			     blk_t *ret_super_blk,
-+			     blk_t *ret_old_desc_blk,
-+			     blk_t *ret_new_desc_blk,
-+			     int *ret_meta_bg)
-+{
-+	blk_t	group_block, super_blk = 0, old_desc_blk = 0, new_desc_blk = 0;
-+	unsigned int meta_bg, meta_bg_size;
-+	int	numblocks, has_super;
-+	int	old_desc_blocks;
-+
-+	group_block = fs->super->s_first_data_block +
-+		(group * fs->super->s_blocks_per_group);
-+
-+	if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
-+		old_desc_blocks = fs->super->s_first_meta_bg;
-+	else
-+		old_desc_blocks = 
-+			fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
-+
-+	if (group == fs->group_desc_count-1) {
-+		numblocks = (fs->super->s_blocks_count -
-+			     fs->super->s_first_data_block) %
-+			fs->super->s_blocks_per_group;
-+		if (!numblocks)
-+			numblocks = fs->super->s_blocks_per_group;
-+	} else
-+		numblocks = fs->super->s_blocks_per_group;
-+
-+	has_super = ext2fs_bg_has_super(fs, group);
-+
-+	if (has_super) {
-+		super_blk = group_block;
-+		numblocks--;
-+	}
-+	meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc));
-+	meta_bg = group / meta_bg_size;
-+
-+	if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
-+	    (meta_bg < fs->super->s_first_meta_bg)) {
-+		if (has_super) {
-+			old_desc_blk = group_block + 1;
-+			numblocks -= old_desc_blocks;
-+		}
-+	} else {
-+		if (((group % meta_bg_size) == 0) ||
-+		    ((group % meta_bg_size) == 1) ||
-+		    ((group % meta_bg_size) == (meta_bg_size-1))) {
-+			if (has_super)
-+				has_super = 1;
-+			new_desc_blk = group_block + has_super;
-+			numblocks--;
-+		}
-+	}
-+		
-+	numblocks -= 2 + fs->inode_blocks_per_group;
-+
-+	if (ret_super_blk)
-+		*ret_super_blk = super_blk;
-+	if (ret_old_desc_blk)
-+		*ret_old_desc_blk = old_desc_blk;
-+	if (ret_new_desc_blk)
-+		*ret_new_desc_blk = new_desc_blk;
-+	if (ret_meta_bg)
-+		*ret_meta_bg = meta_bg;
-+	return (numblocks);
-+}
-+
-+
-+/*
-+ * This function forces out the primary superblock.  We need to only
-+ * write out those fields which we have changed, since if the
-+ * filesystem is mounted, it may have changed some of the other
-+ * fields.
-+ *
-+ * It takes as input a superblock which has already been byte swapped
-+ * (if necessary).
-+ *
-+ */
-+static errcode_t write_primary_superblock(ext2_filsys fs,
-+					  struct ext2_super_block *super)
-+{
-+	__u16		*old_super, *new_super;
-+	int		check_idx, write_idx, size;
-+	errcode_t	retval;
-+
-+	if (!fs->io->manager->write_byte || !fs->orig_super) {
-+		io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET);
-+		retval = io_channel_write_blk(fs->io, 1, -SUPERBLOCK_SIZE,
-+					      super);
-+		io_channel_set_blksize(fs->io, fs->blocksize);
-+		return retval;
-+	}
-+
-+	old_super = (__u16 *) fs->orig_super;
-+	new_super = (__u16 *) super;
-+
-+	for (check_idx = 0; check_idx < SUPERBLOCK_SIZE/2; check_idx++) {
-+		if (old_super[check_idx] == new_super[check_idx])
-+			continue;
-+		write_idx = check_idx;
-+		for (check_idx++; check_idx < SUPERBLOCK_SIZE/2; check_idx++)
-+			if (old_super[check_idx] == new_super[check_idx])
-+				break;
-+		size = 2 * (check_idx - write_idx);
-+#if 0
-+		printf("Writing %d bytes starting at %d\n",
-+		       size, write_idx*2);
-+#endif
-+		retval = io_channel_write_byte(fs->io,
-+			       SUPERBLOCK_OFFSET + (2 * write_idx), size,
-+					       new_super + write_idx);
-+		if (retval)
-+			return retval;
-+	}
-+	memcpy(fs->orig_super, super, SUPERBLOCK_SIZE);
-+	return 0;
-+}
-+
-+
-+/*
-+ * Updates the revision to EXT2_DYNAMIC_REV
-+ */
-+void ext2fs_update_dynamic_rev(ext2_filsys fs)
-+{
-+	struct ext2_super_block *sb = fs->super;
-+
-+	if (sb->s_rev_level > EXT2_GOOD_OLD_REV)
-+		return;
-+
-+	sb->s_rev_level = EXT2_DYNAMIC_REV;
-+	sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
-+	sb->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
-+	/* s_uuid is handled by e2fsck already */
-+	/* other fields should be left alone */
-+}
-+
-+static errcode_t write_backup_super(ext2_filsys fs, dgrp_t group,
-+				    blk_t group_block,
-+				    struct ext2_super_block *super_shadow)
-+{
-+	dgrp_t	sgrp = group;
-+	
-+	if (sgrp > ((1 << 16) - 1))
-+		sgrp = (1 << 16) - 1;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if (fs->flags & EXT2_FLAG_SWAP_BYTES)
-+		super_shadow->s_block_group_nr = ext2fs_swab16(sgrp);
-+	else
-+#endif
-+		fs->super->s_block_group_nr = sgrp;
-+
-+	return io_channel_write_blk(fs->io, group_block, -SUPERBLOCK_SIZE, 
-+				    super_shadow);
-+}
-+
-+
-+errcode_t ext2fs_flush(ext2_filsys fs)
-+{
-+	dgrp_t		i,j;
-+	blk_t		group_block;
-+	errcode_t	retval;
-+	unsigned long	fs_state;
-+	struct ext2_super_block *super_shadow = 0;
-+	struct ext2_group_desc *group_shadow = 0;
-+	struct ext2_group_desc *s, *t;
-+	char	*group_ptr;
-+	int	old_desc_blocks;
-+	
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	fs_state = fs->super->s_state;
-+
-+	fs->super->s_wtime = time(NULL);
-+	fs->super->s_block_group_nr = 0;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-+		retval = EXT2_ET_NO_MEMORY;
-+		retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super_shadow);
-+		if (retval)
-+			goto errout;
-+		retval = ext2fs_get_mem((size_t)(fs->blocksize *
-+						 fs->desc_blocks),
-+					&group_shadow);
-+		if (retval)
-+			goto errout;
-+		memset(group_shadow, 0, (size_t) fs->blocksize *
-+		       fs->desc_blocks);
-+
-+		/* swap the group descriptors */
-+		for (j=0, s=fs->group_desc, t=group_shadow;
-+		     j < fs->group_desc_count; j++, t++, s++) {
-+			*t = *s;
-+			ext2fs_swap_group_desc(t);
-+		}
-+	} else {
-+		super_shadow = fs->super;
-+		group_shadow = fs->group_desc;
-+	}
-+#else
-+	super_shadow = fs->super;
-+	group_shadow = fs->group_desc;
-+#endif
-+	
-+	/*
-+	 * If this is an external journal device, don't write out the
-+	 * block group descriptors or any of the backup superblocks
-+	 */
-+	if (fs->super->s_feature_incompat &
-+	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
-+		goto write_primary_superblock_only;
-+
-+	/*
-+	 * Set the state of the FS to be non-valid.  (The state has
-+	 * already been backed up earlier, and will be restored after
-+	 * we write out the backup superblocks.)
-+	 */
-+	fs->super->s_state &= ~EXT2_VALID_FS;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-+		*super_shadow = *fs->super;
-+		ext2fs_swap_super(super_shadow);
-+	}
-+#endif
-+
-+	/*
-+	 * Write out the master group descriptors, and the backup
-+	 * superblocks and group descriptors.
-+	 */
-+	group_block = fs->super->s_first_data_block;
-+	group_ptr = (char *) group_shadow;
-+	if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
-+		old_desc_blocks = fs->super->s_first_meta_bg;
-+	else
-+		old_desc_blocks = fs->desc_blocks;
-+
-+	for (i = 0; i < fs->group_desc_count; i++) {
-+		blk_t	super_blk, old_desc_blk, new_desc_blk;
-+		int	meta_bg;
-+
-+		ext2fs_super_and_bgd_loc(fs, i, &super_blk, &old_desc_blk, 
-+					 &new_desc_blk, &meta_bg);
-+
-+		if (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) &&i && super_blk) {
-+			retval = write_backup_super(fs, i, super_blk,
-+						    super_shadow);
-+			if (retval)
-+				goto errout;
-+		}
-+		if (fs->flags & EXT2_FLAG_SUPER_ONLY)
-+			continue;
-+		if ((old_desc_blk) && 
-+		    (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) || (i == 0))) {
-+			retval = io_channel_write_blk(fs->io,
-+			      old_desc_blk, old_desc_blocks, group_ptr);
-+			if (retval)
-+				goto errout;
-+		}
-+		if (new_desc_blk) {
-+			retval = io_channel_write_blk(fs->io, new_desc_blk,
-+				1, group_ptr + (meta_bg*fs->blocksize));
-+			if (retval)
-+				goto errout;
-+		}
-+	}
-+	fs->super->s_block_group_nr = 0;
-+	fs->super->s_state = fs_state;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-+		*super_shadow = *fs->super;
-+		ext2fs_swap_super(super_shadow);
-+	}
-+#endif
-+
-+	/*
-+	 * If the write_bitmaps() function is present, call it to
-+	 * flush the bitmaps.  This is done this way so that a simple
-+	 * program that doesn't mess with the bitmaps doesn't need to
-+	 * drag in the bitmaps.c code.
-+	 */
-+	if (fs->write_bitmaps) {
-+		retval = fs->write_bitmaps(fs);
-+		if (retval)
-+			goto errout;
-+	}
-+
-+write_primary_superblock_only:
-+	/*
-+	 * Write out master superblock.  This has to be done
-+	 * separately, since it is located at a fixed location
-+	 * (SUPERBLOCK_OFFSET).  We flush all other pending changes
-+	 * out to disk first, just to avoid a race condition with an
-+	 * insy-tinsy window....
-+	 */
-+	retval = io_channel_flush(fs->io);
-+	retval = write_primary_superblock(fs, super_shadow);
-+	if (retval)
-+		goto errout;
-+
-+	fs->flags &= ~EXT2_FLAG_DIRTY;
-+
-+	retval = io_channel_flush(fs->io);
-+errout:
-+	fs->super->s_state = fs_state;
-+	if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-+		if (super_shadow)
-+			ext2fs_free_mem(&super_shadow);
-+		if (group_shadow)
-+			ext2fs_free_mem(&group_shadow);
-+	}
-+	return retval;
-+}
-+
-+errcode_t ext2fs_close(ext2_filsys fs)
-+{
-+	errcode_t	retval;
-+	
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (fs->flags & EXT2_FLAG_DIRTY) {
-+		retval = ext2fs_flush(fs);
-+		if (retval)
-+			return retval;
-+	}
-+	if (fs->write_bitmaps) {
-+		retval = fs->write_bitmaps(fs);
-+		if (retval)
-+			return retval;
-+	}
-+	ext2fs_free(fs);
-+	return 0;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/cmp_bitmaps.c silo-1.4.14/libext2fs/cmp_bitmaps.c
---- silo-1.4.14.orig/libext2fs/cmp_bitmaps.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/cmp_bitmaps.c	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,72 @@
-+/*
-+ * cmp_bitmaps.c --- routines to compare inode and block bitmaps.
-+ *
-+ * Copyright (C) 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
-+				      ext2fs_block_bitmap bm2)
-+{
-+	blk_t	i;
-+	
-+	EXT2_CHECK_MAGIC(bm1, EXT2_ET_MAGIC_BLOCK_BITMAP);
-+	EXT2_CHECK_MAGIC(bm2, EXT2_ET_MAGIC_BLOCK_BITMAP);
-+
-+	if ((bm1->start != bm2->start) ||
-+	    (bm1->end != bm2->end) ||
-+	    (memcmp(bm1->bitmap, bm2->bitmap,
-+		    (size_t) (bm1->end - bm1->start)/8)))
-+		return EXT2_ET_NEQ_BLOCK_BITMAP;
-+
-+	for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
-+		if (ext2fs_fast_test_block_bitmap(bm1, i) !=
-+		    ext2fs_fast_test_block_bitmap(bm2, i))
-+			return EXT2_ET_NEQ_BLOCK_BITMAP;
-+
-+	return 0;
-+}
-+
-+errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
-+				      ext2fs_inode_bitmap bm2)
-+{
-+	ext2_ino_t	i;
-+	
-+	EXT2_CHECK_MAGIC(bm1, EXT2_ET_MAGIC_INODE_BITMAP);
-+	EXT2_CHECK_MAGIC(bm2, EXT2_ET_MAGIC_INODE_BITMAP);
-+
-+	if ((bm1->start != bm2->start) ||
-+	    (bm1->end != bm2->end) ||
-+	    (memcmp(bm1->bitmap, bm2->bitmap,
-+		    (size_t) (bm1->end - bm1->start)/8)))
-+		return EXT2_ET_NEQ_INODE_BITMAP;
-+
-+	for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
-+		if (ext2fs_fast_test_inode_bitmap(bm1, i) !=
-+		    ext2fs_fast_test_inode_bitmap(bm2, i))
-+			return EXT2_ET_NEQ_INODE_BITMAP;
-+
-+	return 0;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/dblist.c silo-1.4.14/libext2fs/dblist.c
---- silo-1.4.14.orig/libext2fs/dblist.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/dblist.c	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,260 @@
-+/*
-+ * dblist.c -- directory block list functions
-+ * 
-+ * Copyright 1997 by Theodore Ts'o
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b);
-+
-+/*
-+ * Returns the number of directories in the filesystem as reported by
-+ * the group descriptors.  Of course, the group descriptors could be
-+ * wrong!
-+ */
-+errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs)
-+{
-+	dgrp_t	i;
-+	ext2_ino_t	num_dirs, max_dirs;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+	
-+	num_dirs = 0;
-+	max_dirs = fs->super->s_inodes_per_group;
-+	for (i = 0; i < fs->group_desc_count; i++) {
-+		if (fs->group_desc[i].bg_used_dirs_count > max_dirs)
-+			num_dirs += max_dirs / 8;
-+		else
-+			num_dirs += fs->group_desc[i].bg_used_dirs_count;
-+	}
-+	if (num_dirs > fs->super->s_inodes_count)
-+		num_dirs = fs->super->s_inodes_count;
-+
-+	*ret_num_dirs = num_dirs;
-+
-+	return 0;
-+}
-+
-+/*
-+ * helper function for making a new directory block list (for
-+ * initialize and copy).
-+ */
-+static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, ext2_ino_t count,
-+			     struct ext2_db_entry *list,
-+			     ext2_dblist *ret_dblist)
-+{
-+	ext2_dblist	dblist;
-+	errcode_t	retval;
-+	size_t		len;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if ((ret_dblist == 0) && fs->dblist &&
-+	    (fs->dblist->magic == EXT2_ET_MAGIC_DBLIST))
-+		return 0;
-+
-+	retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist), &dblist);
-+	if (retval)
-+		return retval;
-+	memset(dblist, 0, sizeof(struct ext2_struct_dblist));
-+
-+	dblist->magic = EXT2_ET_MAGIC_DBLIST;
-+	dblist->fs = fs;
-+	if (size)
-+		dblist->size = size;
-+	else {
-+		retval = ext2fs_get_num_dirs(fs, &dblist->size);
-+		if (retval)
-+			goto cleanup;
-+		dblist->size = (dblist->size * 2) + 12;
-+	}
-+	len = (size_t) sizeof(struct ext2_db_entry) * dblist->size;
-+	dblist->count = count;
-+	retval = ext2fs_get_mem(len, &dblist->list);
-+	if (retval)
-+		goto cleanup;
-+	
-+	if (list)
-+		memcpy(dblist->list, list, len);
-+	else
-+		memset(dblist->list, 0, len);
-+	if (ret_dblist)
-+		*ret_dblist = dblist;
-+	else
-+		fs->dblist = dblist;
-+	return 0;
-+cleanup:
-+	if (dblist)
-+		ext2fs_free_mem(&dblist);
-+	return retval;
-+}
-+
-+/*
-+ * Initialize a directory block list
-+ */
-+errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist)
-+{
-+	ext2_dblist	dblist;
-+	errcode_t	retval;
-+
-+	retval = make_dblist(fs, 0, 0, 0, &dblist);
-+	if (retval)
-+		return retval;
-+
-+	dblist->sorted = 1;
-+	if (ret_dblist)
-+		*ret_dblist = dblist;
-+	else
-+		fs->dblist = dblist;
-+
-+	return 0;
-+}
-+
-+/*
-+ * Copy a directory block list
-+ */
-+errcode_t ext2fs_copy_dblist(ext2_dblist src, ext2_dblist *dest)
-+{
-+	ext2_dblist	dblist;
-+	errcode_t	retval;
-+
-+	retval = make_dblist(src->fs, src->size, src->count, src->list,
-+			     &dblist);
-+	if (retval)
-+		return retval;
-+	dblist->sorted = src->sorted;
-+	*dest = dblist;
-+	return 0;
-+}
-+
-+/*
-+ * Close a directory block list
-+ *
-+ * (moved to closefs.c)
-+ */
-+
-+
-+/*
-+ * Add a directory block to the directory block list
-+ */
-+errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk,
-+			       int blockcnt)
-+{
-+	struct ext2_db_entry 	*new_entry;
-+	errcode_t		retval;
-+	unsigned long		old_size;
-+	
-+	EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
-+
-+	if (dblist->count >= dblist->size) {
-+		old_size = dblist->size * sizeof(struct ext2_db_entry);
-+		dblist->size += 100;
-+		retval = ext2fs_resize_mem(old_size, (size_t) dblist->size *
-+					   sizeof(struct ext2_db_entry),
-+					   &dblist->list);
-+		if (retval) {
-+			dblist->size -= 100;
-+			return retval;
-+		}
-+	}
-+	new_entry = dblist->list + ( (int) dblist->count++);
-+	new_entry->blk = blk;
-+	new_entry->ino = ino;
-+	new_entry->blockcnt = blockcnt;
-+
-+	dblist->sorted = 0;
-+
-+	return 0;
-+}
-+
-+/*
-+ * Change the directory block to the directory block list
-+ */
-+errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk,
-+			       int blockcnt)
-+{
-+	dgrp_t			i;
-+	
-+	EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
-+
-+	for (i=0; i < dblist->count; i++) {
-+		if ((dblist->list[i].ino != ino) ||
-+		    (dblist->list[i].blockcnt != blockcnt))
-+			continue;
-+		dblist->list[i].blk = blk;
-+		dblist->sorted = 0;
-+		return 0;
-+	}
-+	return EXT2_ET_DB_NOT_FOUND;
-+}
-+
-+void ext2fs_dblist_sort(ext2_dblist dblist,
-+			EXT2_QSORT_TYPE (*sortfunc)(const void *,
-+						    const void *))
-+{
-+	if (!sortfunc)
-+		sortfunc = dir_block_cmp;
-+	qsort(dblist->list, (size_t) dblist->count,
-+	      sizeof(struct ext2_db_entry), sortfunc);
-+	dblist->sorted = 1;
-+}
-+
-+/*
-+ * This function iterates over the directory block list
-+ */
-+errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
-+				int (*func)(ext2_filsys fs,
-+					    struct ext2_db_entry *db_info,
-+					    void	*priv_data),
-+				void *priv_data)
-+{
-+	ext2_ino_t	i;
-+	int		ret;
-+	
-+	EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
-+
-+	if (!dblist->sorted)
-+		ext2fs_dblist_sort(dblist, 0);
-+	for (i=0; i < dblist->count; i++) {
-+		ret = (*func)(dblist->fs, &dblist->list[(int)i], priv_data);
-+		if (ret & DBLIST_ABORT)
-+			return 0;
-+	}
-+	return 0;
-+}
-+
-+static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b)
-+{
-+	const struct ext2_db_entry *db_a =
-+		(const struct ext2_db_entry *) a;
-+	const struct ext2_db_entry *db_b =
-+		(const struct ext2_db_entry *) b;
-+
-+	if (db_a->blk != db_b->blk)
-+		return (int) (db_a->blk - db_b->blk);
-+	
-+	if (db_a->ino != db_b->ino)
-+		return (int) (db_a->ino - db_b->ino);
-+
-+	return (int) (db_a->blockcnt - db_b->blockcnt);
-+}
-+
-+int ext2fs_dblist_count(ext2_dblist dblist)
-+{
-+	return (int) dblist->count;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/dblist_dir.c silo-1.4.14/libext2fs/dblist_dir.c
---- silo-1.4.14.orig/libext2fs/dblist_dir.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/dblist_dir.c	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,75 @@
-+/*
-+ * dblist_dir.c --- iterate by directory entry
-+ *
-+ * Copyright 1997 by Theodore Ts'o
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info,
-+		       void *priv_data);
-+
-+errcode_t ext2fs_dblist_dir_iterate(ext2_dblist dblist,
-+				    int	flags,
-+				    char	*block_buf,
-+				    int (*func)(ext2_ino_t dir,
-+						int	entry,
-+						struct ext2_dir_entry *dirent,
-+						int	offset,
-+						int	blocksize,
-+						char	*buf,
-+						void	*priv_data),
-+				    void *priv_data)
-+{
-+	errcode_t		retval;
-+	struct dir_context	ctx;
-+
-+	EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
-+
-+	ctx.dir = 0;
-+	ctx.flags = flags;
-+	if (block_buf)
-+		ctx.buf = block_buf;
-+	else {
-+		retval = ext2fs_get_mem(dblist->fs->blocksize, &ctx.buf);
-+		if (retval)
-+			return retval;
-+	}
-+	ctx.func = func;
-+	ctx.priv_data = priv_data;
-+	ctx.errcode = 0;
-+
-+	retval = ext2fs_dblist_iterate(dblist, db_dir_proc, &ctx);
-+	
-+	if (!block_buf)
-+		ext2fs_free_mem(&ctx.buf);
-+	if (retval)
-+		return retval;
-+	return ctx.errcode;
-+}
-+
-+static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info,
-+		       void *priv_data)
-+{
-+	struct dir_context	*ctx;
-+
-+	ctx = (struct dir_context *) priv_data;
-+	ctx->dir = db_info->ino;
-+	
-+	return ext2fs_process_dir_block(fs, &db_info->blk,
-+					db_info->blockcnt, 0, 0, priv_data);
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/dir_iterate.c silo-1.4.14/libext2fs/dir_iterate.c
---- silo-1.4.14.orig/libext2fs/dir_iterate.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/dir_iterate.c	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,219 @@
-+/*
-+ * dir_iterate.c --- ext2fs directory iteration operations
-+ * 
-+ * Copyright (C) 1993, 1994, 1994, 1995, 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+/*
-+ * This function checks to see whether or not a potential deleted
-+ * directory entry looks valid.  What we do is check the deleted entry
-+ * and each successive entry to make sure that they all look valid and
-+ * that the last deleted entry ends at the beginning of the next
-+ * undeleted entry.  Returns 1 if the deleted entry looks valid, zero
-+ * if not valid.
-+ */
-+static int ext2fs_validate_entry(char *buf, int offset, int final_offset)
-+{
-+	struct ext2_dir_entry *dirent;
-+	
-+	while (offset < final_offset) {
-+		dirent = (struct ext2_dir_entry *)(buf + offset);
-+		offset += dirent->rec_len;
-+		if ((dirent->rec_len < 8) ||
-+		    ((dirent->rec_len % 4) != 0) ||
-+		    (((dirent->name_len & 0xFF)+8) > dirent->rec_len))
-+			return 0;
-+	}
-+	return (offset == final_offset);
-+}
-+
-+errcode_t ext2fs_dir_iterate2(ext2_filsys fs,
-+			      ext2_ino_t dir,
-+			      int flags,
-+			      char *block_buf,
-+			      int (*func)(ext2_ino_t	dir,
-+					  int		entry,
-+					  struct ext2_dir_entry *dirent,
-+					  int	offset,
-+					  int	blocksize,
-+					  char	*buf,
-+					  void	*priv_data),
-+			      void *priv_data)
-+{
-+	struct		dir_context	ctx;
-+	errcode_t	retval;
-+	
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	retval = ext2fs_check_directory(fs, dir);
-+	if (retval)
-+		return retval;
-+	
-+	ctx.dir = dir;
-+	ctx.flags = flags;
-+	if (block_buf)
-+		ctx.buf = block_buf;
-+	else {
-+		retval = ext2fs_get_mem(fs->blocksize, &ctx.buf);
-+		if (retval)
-+			return retval;
-+	}
-+	ctx.func = func;
-+	ctx.priv_data = priv_data;
-+	ctx.errcode = 0;
-+	retval = ext2fs_block_iterate2(fs, dir, 0, 0,
-+				       ext2fs_process_dir_block, &ctx);
-+	if (!block_buf)
-+		ext2fs_free_mem(&ctx.buf);
-+	if (retval)
-+		return retval;
-+	return ctx.errcode;
-+}
-+
-+struct xlate {
-+	int (*func)(struct ext2_dir_entry *dirent,
-+		    int		offset,
-+		    int		blocksize,
-+		    char	*buf,
-+		    void	*priv_data);
-+	void *real_private;
-+};
-+
-+static int xlate_func(ext2_ino_t dir EXT2FS_ATTR((unused)),
-+		      int entry EXT2FS_ATTR((unused)),
-+		      struct ext2_dir_entry *dirent, int offset,
-+		      int blocksize, char *buf, void *priv_data)
-+{
-+	struct xlate *xl = (struct xlate *) priv_data;
-+
-+	return (*xl->func)(dirent, offset, blocksize, buf, xl->real_private);
-+}
-+
-+extern errcode_t ext2fs_dir_iterate(ext2_filsys fs, 
-+			      ext2_ino_t dir,
-+			      int flags,
-+			      char *block_buf,
-+			      int (*func)(struct ext2_dir_entry *dirent,
-+					  int	offset,
-+					  int	blocksize,
-+					  char	*buf,
-+					  void	*priv_data),
-+			      void *priv_data)
-+{
-+	struct xlate xl;
-+	
-+	xl.real_private = priv_data;
-+	xl.func = func;
-+
-+	return ext2fs_dir_iterate2(fs, dir, flags, block_buf,
-+				   xlate_func, &xl);
-+}
-+
-+
-+/*
-+ * Helper function which is private to this module.  Used by
-+ * ext2fs_dir_iterate() and ext2fs_dblist_dir_iterate()
-+ */
-+int ext2fs_process_dir_block(ext2_filsys fs,
-+			     blk_t	*blocknr,
-+			     e2_blkcnt_t blockcnt,
-+			     blk_t	ref_block EXT2FS_ATTR((unused)),
-+			     int	ref_offset EXT2FS_ATTR((unused)),
-+			     void	*priv_data)
-+{
-+	struct dir_context *ctx = (struct dir_context *) priv_data;
-+	unsigned int	offset = 0;
-+	unsigned int	next_real_entry = 0;
-+	int		ret = 0;
-+	int		changed = 0;
-+	int		do_abort = 0;
-+	int		entry, size;
-+	struct ext2_dir_entry *dirent;
-+
-+	if (blockcnt < 0)
-+		return 0;
-+
-+	entry = blockcnt ? DIRENT_OTHER_FILE : DIRENT_DOT_FILE;
-+	
-+	ctx->errcode = ext2fs_read_dir_block(fs, *blocknr, ctx->buf);
-+	if (ctx->errcode)
-+		return BLOCK_ABORT;
-+
-+	while (offset < fs->blocksize) {
-+		dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
-+		if (((offset + dirent->rec_len) > fs->blocksize) ||
-+		    (dirent->rec_len < 8) ||
-+		    ((dirent->rec_len % 4) != 0) ||
-+		    (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
-+			ctx->errcode = EXT2_ET_DIR_CORRUPTED;
-+			return BLOCK_ABORT;
-+		}
-+		if (!dirent->inode &&
-+		    !(ctx->flags & DIRENT_FLAG_INCLUDE_EMPTY))
-+			goto next;
-+
-+		ret = (ctx->func)(ctx->dir,
-+				  (next_real_entry > offset) ?
-+				  DIRENT_DELETED_FILE : entry,
-+				  dirent, offset,
-+				  fs->blocksize, ctx->buf,
-+				  ctx->priv_data);
-+		if (entry < DIRENT_OTHER_FILE)
-+			entry++;
-+			
-+		if (ret & DIRENT_CHANGED)
-+			changed++;
-+		if (ret & DIRENT_ABORT) {
-+			do_abort++;
-+			break;
-+		}
-+next:		
-+ 		if (next_real_entry == offset)
-+			next_real_entry += dirent->rec_len;
-+ 
-+ 		if (ctx->flags & DIRENT_FLAG_INCLUDE_REMOVED) {
-+			size = ((dirent->name_len & 0xFF) + 11) & ~3;
-+
-+			if (dirent->rec_len != size)  {
-+				unsigned int final_offset;
-+
-+				final_offset = offset + dirent->rec_len;
-+				offset += size;
-+				while (offset < final_offset &&
-+				       !ext2fs_validate_entry(ctx->buf,
-+							      offset,
-+							      final_offset))
-+					offset += 4;
-+				continue;
-+			}
-+		}
-+		offset += dirent->rec_len;
-+	}
-+
-+	if (changed) {
-+		ctx->errcode = ext2fs_write_dir_block(fs, *blocknr, ctx->buf);
-+		if (ctx->errcode)
-+			return BLOCK_ABORT;
-+	}
-+	if (do_abort)
-+		return BLOCK_ABORT;
-+	return 0;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/dirblock.c silo-1.4.14/libext2fs/dirblock.c
---- silo-1.4.14.orig/libext2fs/dirblock.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/dirblock.c	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,130 @@
-+/*
-+ * dirblock.c --- directory block routines.
-+ * 
-+ * Copyright (C) 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
-+				 void *buf, int flags EXT2FS_ATTR((unused)))
-+{
-+	errcode_t	retval;
-+	char		*p, *end;
-+	struct ext2_dir_entry *dirent;
-+	unsigned int	name_len, rec_len, do_swap;
-+	
-+
-+ 	retval = io_channel_read_blk(fs->io, block, 1, buf);
-+	if (retval)
-+		return retval;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	do_swap = (fs->flags & (EXT2_FLAG_SWAP_BYTES|
-+				EXT2_FLAG_SWAP_BYTES_READ)) != 0;
-+#endif
-+	p = (char *) buf;
-+	end = (char *) buf + fs->blocksize;
-+	while (p < end-8) {
-+		dirent = (struct ext2_dir_entry *) p;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+		if (do_swap) {
-+			dirent->inode = ext2fs_swab32(dirent->inode);
-+			dirent->rec_len = ext2fs_swab16(dirent->rec_len);
-+			dirent->name_len = ext2fs_swab16(dirent->name_len);
-+		}
-+#endif
-+		name_len = dirent->name_len;
-+#ifdef WORDS_BIGENDIAN
-+		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
-+			dirent->name_len = ext2fs_swab16(dirent->name_len);
-+#endif
-+		rec_len = dirent->rec_len;
-+		if ((rec_len < 8) || (rec_len % 4)) {
-+			rec_len = 8;
-+			retval = EXT2_ET_DIR_CORRUPTED;
-+		}
-+		if (((name_len & 0xFF) + 8) > dirent->rec_len)
-+			retval = EXT2_ET_DIR_CORRUPTED;
-+		p += rec_len;
-+	}
-+	return retval;
-+}
-+
-+errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
-+				 void *buf)
-+{
-+	return ext2fs_read_dir_block2(fs, block, buf, 0);
-+}
-+
-+
-+errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
-+				  void *inbuf, int flags EXT2FS_ATTR((unused)))
-+{
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	int		do_swap = 0;
-+	errcode_t	retval;
-+	char		*p, *end;
-+	char		*buf = 0;
-+	struct ext2_dir_entry *dirent;
-+
-+	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+	    (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
-+		do_swap = 1;
-+
-+#ifndef WORDS_BIGENDIAN
-+	if (!do_swap)
-+		return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
-+#endif
-+
-+	retval = ext2fs_get_mem(fs->blocksize, &buf);
-+	if (retval)
-+		return retval;
-+	memcpy(buf, inbuf, fs->blocksize);
-+	p = buf;
-+	end = buf + fs->blocksize;
-+	while (p < end) {
-+		dirent = (struct ext2_dir_entry *) p;
-+		if ((dirent->rec_len < 8) ||
-+		    (dirent->rec_len % 4)) {
-+			ext2fs_free_mem(&buf);
-+			return (EXT2_ET_DIR_CORRUPTED);
-+		}
-+		p += dirent->rec_len;
-+		if (do_swap) {
-+			dirent->inode = ext2fs_swab32(dirent->inode);
-+			dirent->rec_len = ext2fs_swab16(dirent->rec_len);
-+			dirent->name_len = ext2fs_swab16(dirent->name_len);
-+		}
-+#ifdef WORDS_BIGENDIAN 
-+		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
-+			dirent->name_len = ext2fs_swab16(dirent->name_len);
-+#endif
-+	}
-+ 	retval = io_channel_write_blk(fs->io, block, 1, buf);
-+	ext2fs_free_mem(&buf);
-+	return retval;
-+#else
-+ 	return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
-+#endif
-+}
-+
-+
-+errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
-+				 void *inbuf)
-+{
-+	return ext2fs_write_dir_block2(fs, block, inbuf, 0);
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/dirhash.c silo-1.4.14/libext2fs/dirhash.c
---- silo-1.4.14.orig/libext2fs/dirhash.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/dirhash.c	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,233 @@
-+/*
-+ * dirhash.c -- Calculate the hash of a directory entry
-+ *
-+ * Copyright (c) 2001  Daniel Phillips
-+ * 
-+ * Copyright (c) 2002 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * Keyed 32-bit hash function using TEA in a Davis-Meyer function
-+ *   H0 = Key
-+ *   Hi = E Mi(Hi-1) + Hi-1
-+ *
-+ * (see Applied Cryptography, 2nd edition, p448).
-+ *
-+ * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
-+ * 
-+ * This code is made available under the terms of the GPL
-+ */
-+#define DELTA 0x9E3779B9
-+
-+static void TEA_transform(__u32 buf[4], __u32 const in[])
-+{
-+	__u32	sum = 0;
-+	__u32	b0 = buf[0], b1 = buf[1];
-+	__u32	a = in[0], b = in[1], c = in[2], d = in[3];
-+	int	n = 16;
-+
-+	do {							
-+		sum += DELTA;					
-+		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);	
-+		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);	
-+	} while(--n);
-+
-+	buf[0] += b0;
-+	buf[1] += b1;
-+}
-+
-+/* F, G and H are basic MD4 functions: selection, majority, parity */
-+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-+#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
-+#define H(x, y, z) ((x) ^ (y) ^ (z))
-+
-+/*
-+ * The generic round function.  The application is so specific that
-+ * we don't bother protecting all the arguments with parens, as is generally
-+ * good macro practice, in favor of extra legibility.
-+ * Rotation is separate from addition to prevent recomputation
-+ */
-+#define ROUND(f, a, b, c, d, x, s)	\
-+	(a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
-+#define K1 0
-+#define K2 013240474631UL
-+#define K3 015666365641UL
-+
-+/*
-+ * Basic cut-down MD4 transform.  Returns only 32 bits of result.
-+ */
-+static void halfMD4Transform (__u32 buf[4], __u32 const in[])
-+{
-+	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-+
-+	/* Round 1 */
-+	ROUND(F, a, b, c, d, in[0] + K1,  3);
-+	ROUND(F, d, a, b, c, in[1] + K1,  7);
-+	ROUND(F, c, d, a, b, in[2] + K1, 11);
-+	ROUND(F, b, c, d, a, in[3] + K1, 19);
-+	ROUND(F, a, b, c, d, in[4] + K1,  3);
-+	ROUND(F, d, a, b, c, in[5] + K1,  7);
-+	ROUND(F, c, d, a, b, in[6] + K1, 11);
-+	ROUND(F, b, c, d, a, in[7] + K1, 19);
-+
-+	/* Round 2 */
-+	ROUND(G, a, b, c, d, in[1] + K2,  3);
-+	ROUND(G, d, a, b, c, in[3] + K2,  5);
-+	ROUND(G, c, d, a, b, in[5] + K2,  9);
-+	ROUND(G, b, c, d, a, in[7] + K2, 13);
-+	ROUND(G, a, b, c, d, in[0] + K2,  3);
-+	ROUND(G, d, a, b, c, in[2] + K2,  5);
-+	ROUND(G, c, d, a, b, in[4] + K2,  9);
-+	ROUND(G, b, c, d, a, in[6] + K2, 13);
-+
-+	/* Round 3 */
-+	ROUND(H, a, b, c, d, in[3] + K3,  3);
-+	ROUND(H, d, a, b, c, in[7] + K3,  9);
-+	ROUND(H, c, d, a, b, in[2] + K3, 11);
-+	ROUND(H, b, c, d, a, in[6] + K3, 15);
-+	ROUND(H, a, b, c, d, in[1] + K3,  3);
-+	ROUND(H, d, a, b, c, in[5] + K3,  9);
-+	ROUND(H, c, d, a, b, in[0] + K3, 11);
-+	ROUND(H, b, c, d, a, in[4] + K3, 15);
-+
-+	buf[0] += a;
-+	buf[1] += b;
-+	buf[2] += c;
-+	buf[3] += d;
-+}
-+
-+#undef ROUND
-+#undef F
-+#undef G
-+#undef H
-+#undef K1
-+#undef K2
-+#undef K3
-+
-+/* The old legacy hash */
-+static ext2_dirhash_t dx_hack_hash (const char *name, int len)
-+{
-+	__u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
-+	while (len--) {
-+		__u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
-+		
-+		if (hash & 0x80000000) hash -= 0x7fffffff;
-+		hash1 = hash0;
-+		hash0 = hash;
-+	}
-+	return (hash0 << 1);
-+}
-+
-+static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
-+{
-+	__u32	pad, val;
-+	int	i;
-+
-+	pad = (__u32)len | ((__u32)len << 8);
-+	pad |= pad << 16;
-+
-+	val = pad;
-+	if (len > num*4)
-+		len = num * 4;
-+	for (i=0; i < len; i++) {
-+		if ((i % 4) == 0)
-+			val = pad;
-+		val = msg[i] + (val << 8);
-+		if ((i % 4) == 3) {
-+			*buf++ = val;
-+			val = pad;
-+			num--;
-+		}
-+	}
-+	if (--num >= 0)
-+		*buf++ = val;
-+	while (--num >= 0)
-+		*buf++ = pad;
-+}
-+
-+/*
-+ * Returns the hash of a filename.  If len is 0 and name is NULL, then
-+ * this function can be used to test whether or not a hash version is
-+ * supported.
-+ * 
-+ * The seed is an 4 longword (32 bits) "secret" which can be used to
-+ * uniquify a hash.  If the seed is all zero's, then some default seed
-+ * may be used.
-+ * 
-+ * A particular hash version specifies whether or not the seed is
-+ * represented, and whether or not the returned hash is 32 bits or 64
-+ * bits.  32 bit hashes will return 0 for the minor hash.
-+ */
-+errcode_t ext2fs_dirhash(int version, const char *name, int len,
-+			 const __u32 *seed,
-+			 ext2_dirhash_t *ret_hash,
-+			 ext2_dirhash_t *ret_minor_hash)
-+{
-+	__u32	hash;
-+	__u32	minor_hash = 0;
-+	const char	*p;
-+	int		i;
-+	__u32 		in[8], buf[4];
-+
-+	/* Initialize the default seed for the hash checksum functions */
-+	buf[0] = 0x67452301;
-+	buf[1] = 0xefcdab89;
-+	buf[2] = 0x98badcfe;
-+	buf[3] = 0x10325476;
-+
-+	/* Check to see if the seed is all zero's */
-+	if (seed) {
-+		for (i=0; i < 4; i++) {
-+			if (seed[i])
-+				break;
-+		}
-+		if (i < 4)
-+			memcpy(buf, seed, sizeof(buf));
-+	}
-+		
-+	switch (version) {
-+	case EXT2_HASH_LEGACY:
-+		hash = dx_hack_hash(name, len);
-+		break;
-+	case EXT2_HASH_HALF_MD4:
-+		p = name;
-+		while (len > 0) {
-+			str2hashbuf(p, len, in, 8);
-+			halfMD4Transform(buf, in);
-+			len -= 32;
-+			p += 32;
-+		}
-+		minor_hash = buf[2];
-+		hash = buf[1];
-+		break;
-+	case EXT2_HASH_TEA:
-+		p = name;
-+		while (len > 0) {
-+			str2hashbuf(p, len, in, 4);
-+			TEA_transform(buf, in);
-+			len -= 16;
-+			p += 16;
-+		}
-+		hash = buf[0];
-+		minor_hash = buf[1];
-+		break;
-+	default:
-+		*ret_hash = 0;
-+		return EXT2_ET_DIRHASH_UNSUPP;
-+	}
-+	*ret_hash = hash & ~1;
-+	if (ret_minor_hash)
-+		*ret_minor_hash = minor_hash;
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/dosio.c silo-1.4.14/libext2fs/dosio.c
---- silo-1.4.14.orig/libext2fs/dosio.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/dosio.c	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,456 @@
-+/*
-+ * dosio.c -- Disk I/O module for the ext2fs/DOS library.
-+ *
-+ * Copyright (c) 1997 by Theodore Ts'o.
-+ * 
-+ * Copyright (c) 1997 Mark Habersack
-+ * This file may be distributed under the terms of the GNU Public License.
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <bios.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <io.h>
-+#ifdef HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include <ext2fs/ext2_types.h>
-+#include "utils.h"
-+#include "dosio.h"
-+#include "et/com_err.h"
-+#include "ext2_err.h"
-+#include "ext2fs/io.h"
-+
-+/*
-+ * Some helper macros
-+ */
-+#define LINUX_EXT2FS       0x83
-+#define LINUX_SWAP         0x82
-+#define WRITE_ERR(_msg_) write(2, _msg_, strlen(_msg_))
-+#define WRITE_ERR_S(_msg_) write(2, _msg_, sizeof(_msg_))
-+
-+/*
-+ * Exported variables
-+ */
-+unsigned long        _dio_error;
-+unsigned long        _dio_hw_error;
-+
-+/*
-+ * Array of all opened partitions
-+ */
-+static PARTITION        **partitions = NULL;
-+static unsigned short   npart = 0; /* Number of mapped partitions */
-+static PARTITION        *active = NULL;
-+
-+/*
-+ * I/O Manager routine prototypes
-+ */
-+static errcode_t dos_open(const char *dev, int flags, io_channel *channel);
-+static errcode_t dos_close(io_channel channel);
-+static errcode_t dos_set_blksize(io_channel channel, int blksize);
-+static errcode_t dos_read_blk(io_channel channel, unsigned long block,
-+                                             int count, void *buf);
-+static errcode_t dos_write_blk(io_channel channel, unsigned long block,
-+                               int count, const void *buf);
-+static errcode_t dos_flush(io_channel channel);
-+
-+static struct struct_io_manager struct_dos_manager = {
-+        EXT2_ET_MAGIC_IO_MANAGER,
-+        "DOS I/O Manager",
-+        dos_open,
-+        dos_close,
-+        dos_set_blksize,
-+        dos_read_blk,
-+        dos_write_blk,
-+        dos_flush
-+};
-+io_manager dos_io_manager = &struct_dos_manager;
-+
-+/*
-+ * Macro taken from unix_io.c
-+ */
-+/*
-+ * For checking structure magic numbers...
-+ */
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+          if ((struct)->magic != (code)) return (code)
-+
-+/*
-+ * Calculates a CHS address of a sector from its LBA
-+ * offset for the given partition.
-+ */
-+static void lba2chs(unsigned long lba_addr, CHS *chs, PARTITION *part)
-+{
-+  unsigned long      abss;
-+
-+  chs->offset = lba_addr & 0x000001FF;
-+  abss = (lba_addr >> 9) + part->start;
-+  chs->cyl    = abss / (part->sects * part->heads);
-+  chs->head   = (abss / part->sects) % part->heads;
-+  chs->sector = (abss % part->sects) + 1;
-+}
-+
-+#ifdef __TURBOC__
-+#pragma argsused
-+#endif
-+/*
-+ * Scans the passed partition table looking for *pno partition
-+ * that has LINUX_EXT2FS type.
-+ *
-+ * TODO:
-+ * For partition numbers >5 Linux uses DOS extended partitions -
-+ * dive into them an return an appropriate entry. Also dive into
-+ * extended partitions when scanning for a first Linux/ext2fs.
-+ */
-+static PTABLE_ENTRY *scan_partition_table(PTABLE_ENTRY *pentry,
-+                                          unsigned short phys,
-+                                          unsigned char *pno)
-+{
-+  unsigned        i;
-+
-+  if(*pno != 0xFF && *pno >= 5)
-+     return NULL; /* We don't support extended partitions for now */
-+
-+  if(*pno != 0xFF)
-+  {
-+    if(pentry[*pno].type == LINUX_EXT2FS)
-+      return &pentry[*pno];
-+    else
-+    {
-+      if(!pentry[*pno].type)
-+        *pno = 0xFE;
-+      else if(pentry[*pno].type == LINUX_SWAP)
-+        *pno = 0xFD;
-+      return NULL;
-+    }
-+  }
-+
-+  for(i = 0; i < 4; i++)
-+    if(pentry[i].type == LINUX_EXT2FS)
-+    {
-+      *pno = i;
-+      return &pentry[i];
-+    }
-+
-+  return NULL;
-+}
-+
-+/*
-+ * Allocate libext2fs structures associated with I/O manager
-+ */
-+static io_channel alloc_io_channel(PARTITION *part)
-+{
-+  io_channel     ioch;
-+
-+  ioch = (io_channel)malloc(sizeof(struct struct_io_channel));
-+  if (!ioch)
-+	  return NULL;
-+  memset(ioch, 0, sizeof(struct struct_io_channel));
-+  ioch->magic = EXT2_ET_MAGIC_IO_CHANNEL;
-+  ioch->manager = dos_io_manager;
-+  ioch->name = (char *)malloc(strlen(part->dev)+1);
-+  if (!ioch->name) {
-+	  free(ioch);
-+	  return NULL;
-+  }
-+  strcpy(ioch->name, part->dev);
-+  ioch->private_data = part;
-+  ioch->block_size = 1024; /* The smallest ext2fs block size */
-+  ioch->read_error = 0;
-+  ioch->write_error = 0;
-+
-+  return ioch;
-+}
-+
-+#ifdef __TURBOC__
-+#pragma argsused
-+#endif
-+/*
-+ * Open the 'name' partition, initialize all information structures
-+ * we need to keep and create libext2fs I/O manager.
-+ */
-+static errcode_t dos_open(const char *dev, int flags, io_channel *channel)
-+{
-+  unsigned char  *tmp, sec[512];
-+  PARTITION      *part;
-+  PTABLE_ENTRY   *pent;
-+  PARTITION        **newparts;
-+  
-+  if(!dev)
-+  {
-+    _dio_error = ERR_BADDEV;
-+    return EXT2_ET_BAD_DEVICE_NAME;
-+  }
-+
-+  /*
-+   * First check whether the dev name is OK
-+   */
-+  tmp = (unsigned char*)strrchr(dev, '/');
-+  if(!tmp)
-+  {
-+    _dio_error = ERR_BADDEV;
-+    return EXT2_ET_BAD_DEVICE_NAME;
-+  }
-+  *tmp = 0;
-+  if(strcmp(dev, "/dev"))
-+  {
-+    _dio_error = ERR_BADDEV;
-+    return EXT2_ET_BAD_DEVICE_NAME;
-+  }
-+  *tmp++ = '/';
-+
-+  /*
-+   * Check whether the partition data is already in cache
-+   */
-+
-+  part = (PARTITION*)malloc(sizeof(PARTITION));
-+  if (!part)
-+	  return ENOMEM;
-+  {
-+    int   i = 0;
-+
-+    for(;i < npart; i++)
-+      if(!strcmp(partitions[i]->dev, dev))
-+      {
-+        /* Found it! Make it the active one */
-+        active = partitions[i];
-+        *channel = alloc_io_channel(active);
-+	if (!*channel)
-+		return ENOMEM;
-+        return 0;
-+      }
-+  }
-+
-+  /*
-+   * Drive number & optionally partn number
-+   */
-+  switch(tmp[0])
-+  {
-+    case 'h':
-+    case 's':
-+      part->phys = 0x80;
-+      part->phys += toupper(tmp[2]) - 'A';
-+      /*
-+       * Do we have the partition number?
-+       */
-+      if(tmp[3])
-+        part->pno = isdigit((int)tmp[3]) ? tmp[3] - '0' - 1: 0;
-+      else
-+        part->pno = 0xFF;
-+      break;
-+
-+    case 'f':
-+      if(tmp[2])
-+        part->phys = isdigit((int)tmp[2]) ? tmp[2] - '0' : 0;
-+      else
-+        part->phys = 0x00; /* We'll assume /dev/fd0 */
-+      break;
-+
-+    default:
-+      _dio_error = ERR_BADDEV;
-+      return ENODEV;
-+  }
-+
-+  if(part->phys < 0x80)
-+  {
-+     /* We don't support floppies for now */
-+     _dio_error = ERR_NOTSUPP;
-+     return EINVAL;
-+  }
-+
-+  part->dev = strdup(dev);
-+
-+  /*
-+   * Get drive's geometry
-+   */
-+  _dio_hw_error = biosdisk(DISK_GET_GEOMETRY,
-+                           part->phys,
-+                           0, /* head */
-+                           0, /* cylinder */
-+                           1, /* sector */
-+                           1, /* just one sector */
-+                           sec);
-+
-+  if(!HW_OK())
-+  {
-+    _dio_error = ERR_HARDWARE;
-+    if (part)
-+	    free(part);
-+    return EFAULT;
-+  }
-+
-+  /*
-+   * Calculate the geometry
-+   */
-+  part->cyls  = (unsigned short)(((sec[0] >> 6) << 8) + sec[1] + 1);
-+  part->heads = sec[3] + 1;
-+  part->sects = sec[0] & 0x3F;
-+
-+  /*
-+   * Now that we know all we need, let's look for the partition
-+   */
-+  _dio_hw_error = biosdisk(DISK_READ, part->phys, 0, 0, 1, 1, sec);
-+
-+  if(!HW_OK())
-+  {
-+    _dio_error = ERR_HARDWARE;
-+    if (part)
-+	    free(part);
-+    return EFAULT;
-+  }
-+
-+  pent = (PTABLE_ENTRY*)&sec[0x1BE];
-+  pent = scan_partition_table(pent, part->phys, &part->pno);
-+
-+  if(!pent)
-+  {
-+    _dio_error = part->pno == 0xFE ? ERR_EMPTYPART :
-+                 part->pno == 0xFD ? ERR_LINUXSWAP : ERR_NOTEXT2FS;
-+    if (part)
-+	    free(part);
-+    return ENODEV;
-+  }
-+
-+  /*
-+   * Calculate the remaining figures
-+   */
-+  {
-+    unsigned long    fsec, fhead, fcyl;
-+
-+    fsec = (unsigned long)(pent->start_sec & 0x3F);
-+    fhead = (unsigned long)pent->start_head;
-+    fcyl = ((pent->start_sec >> 6) << 8) + pent->start_cyl;
-+    part->start = fsec + fhead * part->sects + fcyl *
-+                  (part->heads * part->sects) - 1;
-+    part->len = pent->size;
-+  }
-+
-+  /*
-+   * Add the partition to the table
-+   */
-+  newparts = (PARTITION**)realloc(partitions, sizeof(PARTITION) * npart);
-+  if (!newparts) {
-+	  free(part);
-+	  return ENOMEM;
-+  }
-+  partitions = newparts;
-+  partitions[npart++] = active = part;
-+
-+  /*
-+   * Now alloc all libe2fs structures
-+   */
-+  *channel = alloc_io_channel(active);
-+  if (!*channel)
-+	  return ENOMEM;
-+
-+  return 0;
-+}
-+
-+static errcode_t dos_close(io_channel channel)
-+{
-+	if (channel->name)
-+		free(channel->name);
-+	if (channel)
-+		free(channel);
-+
-+	return 0;
-+}
-+
-+static errcode_t dos_set_blksize(io_channel channel, int blksize)
-+{
-+  channel->block_size = blksize;
-+
-+  return 0;
-+}
-+
-+static errcode_t dos_read_blk(io_channel channel, unsigned long block,
-+                                             int count, void *buf)
-+{
-+  PARTITION     *part;
-+  size_t        size;
-+  ext2_loff_t   loc;
-+  CHS           chs;
-+
-+  EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+  part = (PARTITION*)channel->private_data;
-+
-+  size = (size_t)((count < 0) ? -count : count * channel->block_size);
-+  loc = (ext2_loff_t) block * channel->block_size;
-+
-+  lba2chs(loc, &chs, part);
-+  /*
-+   * Potential bug here:
-+   *   If DJGPP is used then reads of >18 sectors will fail!
-+   *   Have to rewrite biosdisk.
-+   */
-+  _dio_hw_error = biosdisk(DISK_READ,
-+                           part->phys,
-+                           chs.head,
-+                           chs.cyl,
-+                           chs.sector,
-+                           size < 512 ? 1 : size/512,
-+                           buf);
-+
-+  if(!HW_OK())
-+  {
-+    _dio_error = ERR_HARDWARE;
-+    return EFAULT;
-+  }
-+
-+  return 0;
-+}
-+
-+static errcode_t dos_write_blk(io_channel channel, unsigned long block,
-+                               int count, const void *buf)
-+{
-+  PARTITION     *part;
-+  size_t        size;
-+  ext2_loff_t   loc;
-+  CHS           chs;
-+
-+  EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+  part = (PARTITION*)channel->private_data;
-+
-+  if(count == 1)
-+    size = (size_t)channel->block_size;
-+  else
-+  {
-+    if (count < 0)
-+      size = (size_t)-count;
-+    else
-+      size = (size_t)(count * channel->block_size);
-+  }
-+
-+  loc = (ext2_loff_t)block * channel->block_size;
-+  lba2chs(loc, &chs, part);
-+  _dio_hw_error = biosdisk(DISK_WRITE,
-+                           part->phys,
-+                           chs.head,
-+                           chs.cyl,
-+                           chs.sector,
-+                           size < 512 ? 1 : size/512,
-+                           (void*)buf);
-+
-+  if(!HW_OK())
-+  {
-+    _dio_error = ERR_HARDWARE;
-+    return EFAULT;
-+  }
-+
-+  return 0;
-+}
-+
-+#ifdef __TURBOC__
-+#pragma argsused
-+#endif
-+static errcode_t dos_flush(io_channel channel)
-+{
-+  /*
-+   * No buffers, no flush...
-+   */
-+  return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/dosio.h silo-1.4.14/libext2fs/dosio.h
---- silo-1.4.14.orig/libext2fs/dosio.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/dosio.h	2011-01-10 21:59:35.410976098 -0500
-@@ -0,0 +1,153 @@
-+/*
-+ * v1.0
-+ *
-+ * Disk I/O include file for the ext2fs/DOS library.
-+ *
-+ * Copyright (c) 1997 Mark Habersack
-+ * This file may be distributed under the terms of the GNU Public License.
-+ *
-+ */
-+#ifndef __diskio_h
-+#define __diskio_h
-+#ifdef __TURBOC__
-+#ifndef __LARGE__
-+# error "ext2fs/DOS library requires LARGE model!"
-+#endif
-+#endif
-+
-+#ifdef __TURBOC__
-+#include "msdos.h"
-+#endif
-+
-+/*
-+ * A helper structure used in LBA => CHS conversion
-+ */
-+typedef struct
-+{
-+  unsigned short       cyl;     /* Cylinder (or track) */
-+  unsigned short       head;
-+  unsigned short       sector;
-+  unsigned short       offset;  /* Offset of byte within the sector */
-+} CHS;
-+
-+/*
-+ * All partition data we need is here
-+ */
-+typedef struct
-+{
-+  char                 *dev;  /* _Linux_ device name (like "/dev/hda1") */
-+  unsigned char        phys;  /* Physical DOS drive number */
-+  unsigned long        start; /* LBA address of partition start */
-+  unsigned long        len;   /* length of partition in sectors */
-+  unsigned char        pno;   /* Partition number (read from *dev) */
-+
-+  /* This partition's drive geometry */
-+  unsigned short       cyls;
-+  unsigned short       heads;
-+  unsigned short       sects;
-+} PARTITION;
-+
-+/*
-+ * PC partition table entry format
-+ */
-+#ifdef __DJGPP__
-+#pragma pack(1)
-+#endif
-+typedef struct
-+{
-+  unsigned char        active;
-+  unsigned char        start_head;
-+  unsigned char        start_sec;
-+  unsigned char        start_cyl;
-+  unsigned char        type;
-+  unsigned char        end_head;
-+  unsigned char        end_sec;
-+  unsigned char        end_cyl;
-+  unsigned long        first_sec_rel;
-+  unsigned long        size;
-+} PTABLE_ENTRY;
-+#ifdef __DJGPP__
-+#pragma pack()
-+#endif
-+
-+/*
-+ * INT 0x13 operation codes
-+ */
-+#define DISK_READ          0x02
-+#define DISK_WRITE         0x03
-+#define DISK_GET_GEOMETRY  0x08
-+#define DISK_READY         0x10
-+
-+/*
-+ * Errors to put in _dio_error
-+ */
-+#define ERR_BADDEV         0x00000001L
-+#define ERR_HARDWARE       0x00000002L
-+#define ERR_NOTSUPP        0x00000003L
-+#define ERR_NOTEXT2FS      0x00000004L
-+#define ERR_EMPTYPART      0x00000005L
-+#define ERR_LINUXSWAP      0x00000006L
-+
-+/*
-+ * Functions in diskio.c
-+ */
-+
-+/*
-+ * Variable contains last module's error
-+ */
-+extern unsigned long        _dio_error;
-+
-+/*
-+ * This one contains last hardware error (if _dio_error == ERR_HARDWARE)
-+ */
-+extern unsigned long        _dio_hw_error;
-+
-+/*
-+ * Macros to check for disk hardware errors
-+ */
-+#define HW_OK()             ((unsigned char)_dio_hw_error == 0x00)
-+#define HW_BAD_CMD()        ((unsigned char)_dio_hw_error == 0x01)
-+#define HW_NO_ADDR_MARK()   ((unsigned char)_dio_hw_error == 0x02)
-+#define HW_WRITE_PROT()     ((unsigned char)_dio_hw_error == 0x03)
-+#define HW_NO_SECTOR()      ((unsigned char)_dio_hw_error == 0x04)
-+#define HW_RESET_FAIL()     ((unsigned char)_dio_hw_error == 0x05)
-+#define HW_DISK_CHANGED()   ((unsigned char)_dio_hw_error == 0x06)
-+#define HW_DRIVE_FAIL()     ((unsigned char)_dio_hw_error == 0x07)
-+#define HW_DMA_OVERRUN()    ((unsigned char)_dio_hw_error == 0x08)
-+#define HW_DMA_BOUNDARY()   ((unsigned char)_dio_hw_error == 0x09)
-+#define HW_BAD_SECTOR()     ((unsigned char)_dio_hw_error == 0x0A)
-+#define HW_BAD_TRACK()      ((unsigned char)_dio_hw_error == 0x0B)
-+#define HW_UNSUPP_TRACK()   ((unsigned char)_dio_hw_error == 0x0C)
-+#define HW_BAD_CRC_ECC()    ((unsigned char)_dio_hw_error == 0x10)
-+#define HW_CRC_ECC_CORR()   ((unsigned char)_dio_hw_error == 0x11)
-+#define HW_CONTR_FAIL()     ((unsigned char)_dio_hw_error == 0x20)
-+#define HW_SEEK_FAIL()      ((unsigned char)_dio_hw_error == 0x40)
-+#define HW_ATTACH_FAIL()    ((unsigned char)_dio_hw_error == 0x80)
-+#define HW_DRIVE_NREADY()   ((unsigned char)_dio_hw_error == 0xAA)
-+#define HW_UNDEF_ERROR()    ((unsigned char)_dio_hw_error == 0xBB)
-+#define HW_WRITE_FAULT()    ((unsigned char)_dio_hw_error == 0xCC)
-+#define HW_STATUS_ERROR()   ((unsigned char)_dio_hw_error == 0xE0)
-+#define HW_SENSE_FAIL()     ((unsigned char)_dio_hw_error == 0xFF)
-+
-+
-+/*
-+ * Open the specified partition.
-+ * String 'dev' must have a format:
-+ *
-+ *  /dev/{sd|hd|fd}[X]
-+ *
-+ * where,
-+ *
-+ *  only one of the option in curly braces can be used and X is an optional
-+ *  partition number for the given device. If X is not specified, function
-+ *  scans the drive's partition table in search for the first Linux ext2fs
-+ *  partition (signature 0x83). Along the way it dives into every extended
-+ *  partition encountered.
-+ *  Scan ends if either (a) there are no more used partition entries, or
-+ *  (b) there is no Xth partition.
-+ *
-+ * Routine returns 0 on success and !=0 otherwise.
-+ */
-+int open_partition(char *dev);
-+
-+#endif /* __diskio_h */
-diff -Naur silo-1.4.14.orig/libext2fs/dupfs.c silo-1.4.14/libext2fs/dupfs.c
---- silo-1.4.14.orig/libext2fs/dupfs.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/dupfs.c	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,96 @@
-+/*
-+ * dupfs.c --- duplicate a ext2 filesystem handle
-+ * 
-+ * Copyright (C) 1997, 1998, 2001, 2003, 2005 by Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <time.h>
-+#include <string.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest)
-+{
-+	ext2_filsys	fs;
-+	errcode_t	retval;
-+
-+	EXT2_CHECK_MAGIC(src, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+	
-+	retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
-+	if (retval)
-+		return retval;
-+
-+	*fs = *src;
-+	fs->device_name = 0;
-+	fs->super = 0;
-+	fs->orig_super = 0;
-+	fs->group_desc = 0;
-+	fs->inode_map = 0;
-+	fs->block_map = 0;
-+	fs->badblocks = 0;
-+	fs->dblist = 0;
-+
-+	io_channel_bumpcount(fs->io);
-+	if (fs->icache)
-+		fs->icache->refcount++;
-+
-+	retval = ext2fs_get_mem(strlen(src->device_name)+1, &fs->device_name);
-+	if (retval)
-+		goto errout;
-+	strcpy(fs->device_name, src->device_name);
-+
-+	retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->super);
-+	if (retval)
-+		goto errout;
-+	memcpy(fs->super, src->super, SUPERBLOCK_SIZE);
-+
-+	retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->orig_super);
-+	if (retval)
-+		goto errout;
-+	memcpy(fs->orig_super, src->orig_super, SUPERBLOCK_SIZE);
-+
-+	retval = ext2fs_get_mem((size_t) fs->desc_blocks * fs->blocksize,
-+				&fs->group_desc);
-+	if (retval)
-+		goto errout;
-+	memcpy(fs->group_desc, src->group_desc,
-+	       (size_t) fs->desc_blocks * fs->blocksize);
-+
-+	if (src->inode_map) {
-+		retval = ext2fs_copy_bitmap(src->inode_map, &fs->inode_map);
-+		if (retval)
-+			goto errout;
-+	}
-+	if (src->block_map) {
-+		retval = ext2fs_copy_bitmap(src->block_map, &fs->block_map);
-+		if (retval)
-+			goto errout;
-+	}
-+	if (src->badblocks) {
-+		retval = ext2fs_badblocks_copy(src->badblocks, &fs->badblocks);
-+		if (retval)
-+			goto errout;
-+	}
-+	if (src->dblist) {
-+		retval = ext2fs_copy_dblist(src->dblist, &fs->dblist);
-+		if (retval)
-+			goto errout;
-+	}
-+	*dest = fs;
-+	return 0;
-+errout:
-+	ext2fs_free(fs);
-+	return retval;
-+	
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/e2image.h silo-1.4.14/libext2fs/e2image.h
---- silo-1.4.14.orig/libext2fs/e2image.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/e2image.h	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,51 @@
-+/*
-+ * e2image.h --- header file describing the ext2 image format
-+ * 
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ *
-+ * Note: this uses the POSIX IO interfaces, unlike most of the other
-+ * functions in this library.  So sue me.  
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+
-+struct ext2_image_hdr {
-+	__u32	magic_number;	/* This must be EXT2_ET_MAGIC_E2IMAGE */
-+	char	magic_descriptor[16]; /* "Ext2 Image 1.0", w/ null padding */
-+	char	fs_hostname[64];/* Hostname of machine of image */
-+	char	fs_netaddr[32];	/* Network address */
-+	__u32	fs_netaddr_type;/* 0 = IPV4, 1 = IPV6, etc. */
-+	__u32	fs_device;	/* Device number of image */
-+	char	fs_device_name[64]; /* Device name */
-+	char	fs_uuid[16];	/* UUID of filesystem */
-+	__u32	fs_blocksize;	/* Block size of the filesystem */
-+	__u32	fs_reserved[8];
-+	
-+	__u32	image_device;	/* Device number of image file */
-+	__u32	image_inode;	/* Inode number of image file */
-+	__u32	image_time;	/* Time of image creation */
-+	__u32	image_reserved[8];
-+
-+	__u32	offset_super;	/* Byte offset of the sb and descriptors */
-+	__u32	offset_inode;	/* Byte offset of the inode table  */
-+	__u32	offset_inodemap; /* Byte offset of the inode bitmaps */
-+	__u32	offset_blockmap; /* Byte offset of the inode bitmaps */
-+	__u32	offset_reserved[8];
-+};
-+
-+	
-+	
-+	
-+	
-+	
-+	
-+	
-+	
-+	
-+	
-+	
-+	
-diff -Naur silo-1.4.14.orig/libext2fs/expanddir.c silo-1.4.14/libext2fs/expanddir.c
---- silo-1.4.14.orig/libext2fs/expanddir.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/expanddir.c	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,126 @@
-+/*
-+ * expand.c --- expand an ext2fs directory
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999  Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct expand_dir_struct {
-+	int		done;
-+	int		newblocks;
-+	errcode_t	err;
-+};
-+
-+static int expand_dir_proc(ext2_filsys	fs,
-+			   blk_t	*blocknr,
-+			   e2_blkcnt_t	blockcnt,
-+			   blk_t	ref_block EXT2FS_ATTR((unused)),
-+			   int		ref_offset EXT2FS_ATTR((unused)),
-+			   void		*priv_data)
-+{
-+	struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
-+	blk_t	new_blk;
-+	static blk_t	last_blk = 0;
-+	char		*block;
-+	errcode_t	retval;
-+	
-+	if (*blocknr) {
-+		last_blk = *blocknr;
-+		return 0;
-+	}
-+	retval = ext2fs_new_block(fs, last_blk, 0, &new_blk);
-+	if (retval) {
-+		es->err = retval;
-+		return BLOCK_ABORT;
-+	}
-+	if (blockcnt > 0) {
-+		retval = ext2fs_new_dir_block(fs, 0, 0, &block);
-+		if (retval) {
-+			es->err = retval;
-+			return BLOCK_ABORT;
-+		}
-+		es->done = 1;
-+		retval = ext2fs_write_dir_block(fs, new_blk, block);
-+	} else {
-+		retval = ext2fs_get_mem(fs->blocksize, &block);
-+		if (retval) {
-+			es->err = retval;
-+			return BLOCK_ABORT;
-+		}
-+		memset(block, 0, fs->blocksize);
-+		retval = io_channel_write_blk(fs->io, new_blk, 1, block);
-+	}	
-+	if (retval) {
-+		es->err = retval;
-+		return BLOCK_ABORT;
-+	}
-+	ext2fs_free_mem(&block);
-+	*blocknr = new_blk;
-+	ext2fs_block_alloc_stats(fs, new_blk, +1);
-+	es->newblocks++;
-+
-+	if (es->done)
-+		return (BLOCK_CHANGED | BLOCK_ABORT);
-+	else
-+		return BLOCK_CHANGED;
-+}
-+
-+errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir)
-+{
-+	errcode_t	retval;
-+	struct expand_dir_struct es;
-+	struct ext2_inode	inode;
-+	
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (!(fs->flags & EXT2_FLAG_RW))
-+		return EXT2_ET_RO_FILSYS;
-+
-+	if (!fs->block_map)
-+		return EXT2_ET_NO_BLOCK_BITMAP;
-+
-+	retval = ext2fs_check_directory(fs, dir);
-+	if (retval)
-+		return retval;
-+	
-+	es.done = 0;
-+	es.err = 0;
-+	es.newblocks = 0;
-+	
-+	retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
-+				       0, expand_dir_proc, &es);
-+
-+	if (es.err)
-+		return es.err;
-+	if (!es.done)
-+		return EXT2_ET_EXPAND_DIR_ERR;
-+
-+	/*
-+	 * Update the size and block count fields in the inode.
-+	 */
-+	retval = ext2fs_read_inode(fs, dir, &inode);
-+	if (retval)
-+		return retval;
-+	
-+	inode.i_size += fs->blocksize;
-+	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
-+
-+	retval = ext2fs_write_inode(fs, dir, &inode);
-+	if (retval)
-+		return retval;
-+
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/ext2_err.c silo-1.4.14/libext2fs/ext2_err.c
---- silo-1.4.14.orig/libext2fs/ext2_err.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/ext2_err.c	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,148 @@
-+/*
-+ * ext2_err.c:
-+ * This file is automatically generated; please do not edit it.
-+ */
-+
-+#include <stdlib.h>
-+
-+static const char * const text[] = {
-+		"EXT2FS Library version 1.38",
-+		"Wrong magic number for ext2_filsys structure",
-+		"Wrong magic number for badblocks_list structure",
-+		"Wrong magic number for badblocks_iterate structure",
-+		"Wrong magic number for inode_scan structure",
-+		"Wrong magic number for io_channel structure",
-+		"Wrong magic number for unix io_channel structure",
-+		"Wrong magic number for io_manager structure",
-+		"Wrong magic number for block_bitmap structure",
-+		"Wrong magic number for inode_bitmap structure",
-+		"Wrong magic number for generic_bitmap structure",
-+		"Wrong magic number for test io_channel structure",
-+		"Wrong magic number for directory block list structure",
-+		"Wrong magic number for icount structure",
-+		"Wrong magic number for Powerquest io_channel structure",
-+		"Wrong magic number for ext2 file structure",
-+		"Wrong magic number for Ext2 Image Header",
-+		"Wrong magic number for inode io_channel structure",
-+		"Wrong magic number --- RESERVED_9",
-+		"Bad magic number in super-block",
-+		"Filesystem revision too high",
-+		"Attempt to write to filesystem opened read-only",
-+		"Can't read group descriptors",
-+		"Can't write group descriptors",
-+		"Corrupt group descriptor: bad block for block bitmap",
-+		"Corrupt group descriptor: bad block for inode bitmap",
-+		"Corrupt group descriptor: bad block for inode table",
-+		"Can't write an inode bitmap",
-+		"Can't read an inode bitmap",
-+		"Can't write an block bitmap",
-+		"Can't read an block bitmap",
-+		"Can't write an inode table",
-+		"Can't read an inode table",
-+		"Can't read next inode",
-+		"Filesystem has unexpected block size",
-+		"EXT2 directory corrupted",
-+		"Attempt to read block from filesystem resulted in short read",
-+		"Attempt to write block from filesystem resulted in short write",
-+		"No free space in the directory",
-+		"Inode bitmap not loaded",
-+		"Block bitmap not loaded",
-+		"Illegal inode number",
-+		"Illegal block number",
-+		"Internal error in ext2fs_expand_dir",
-+		"Not enough space to build proposed filesystem",
-+		"Illegal block number passed to ext2fs_mark_block_bitmap",
-+		"Illegal block number passed to ext2fs_unmark_block_bitmap",
-+		"Illegal block number passed to ext2fs_test_block_bitmap",
-+		"Illegal inode number passed to ext2fs_mark_inode_bitmap",
-+		"Illegal inode number passed to ext2fs_unmark_inode_bitmap",
-+		"Illegal inode number passed to ext2fs_test_inode_bitmap",
-+		"Attempt to fudge end of block bitmap past the real end",
-+		"Attempt to fudge end of inode bitmap past the real end",
-+		"Illegal indirect block found" ,
-+		"Illegal doubly indirect block found" ,
-+		"Illegal triply indirect block found" ,
-+		"Block bitmaps are not the same",
-+		"Inode bitmaps are not the same",
-+		"Illegal or malformed device name",
-+		"A block group is missing an inode table",
-+		"The ext2 superblock is corrupt",
-+		"Illegal generic bit number passed to ext2fs_mark_generic_bitmap",
-+		"Illegal generic bit number passed to ext2fs_unmark_generic_bitmap",
-+		"Illegal generic bit number passed to ext2fs_test_generic_bitmap",
-+		"Too many symbolic links encountered.",
-+		"The callback function will not handle this case",
-+		"The inode is from a bad block in the inode table",
-+		"Filesystem has unsupported feature(s)",
-+		"Filesystem has unsupported read-only feature(s)",
-+		"IO Channel failed to seek on read or write",
-+		"Memory allocation failed",
-+		"Invalid argument passed to ext2 library",
-+		"Could not allocate block in ext2 filesystem",
-+		"Could not allocate inode in ext2 filesystem",
-+		"Ext2 inode is not a directory",
-+		"Too many references in table",
-+		"File not found by ext2_lookup",
-+		"File open read-only",
-+		"Ext2 directory block not found",
-+		"Ext2 directory already exists",
-+		"Unimplemented ext2 library function",
-+		"User cancel requested",
-+		"Ext2 file too big",
-+		"Supplied journal device not a block device",
-+		"Journal superblock not found",
-+		"Journal must be at least 1024 blocks",
-+		"Unsupported journal version",
-+		"Error loading external journal",
-+		"Journal not found",
-+		"Directory hash unsupported",
-+		"Illegal extended attribute block number",
-+		"Cannot create filesystem with requested number of inodes",
-+		"E2image snapshot not in use",
-+		"Too many reserved group descriptor blocks",
-+		"Resize inode is corrupt",
-+		"Missing indirect block not present",
-+    0
-+};
-+
-+struct error_table {
-+    char const * const * msgs;
-+    long base;
-+    int n_msgs;
-+};
-+struct et_list {
-+    struct et_list *next;
-+    const struct error_table * table;
-+};
-+extern struct et_list *_et_list;
-+
-+const struct error_table et_ext2_error_table = { text, 2133571328L, 96 };
-+
-+static struct et_list link = { 0, 0 };
-+
-+void initialize_ext2_error_table_r(struct et_list **list);
-+void initialize_ext2_error_table(void);
-+
-+void initialize_ext2_error_table(void) {
-+    initialize_ext2_error_table_r(&_et_list);
-+}
-+
-+/* For Heimdal compatibility */
-+void initialize_ext2_error_table_r(struct et_list **list)
-+{
-+    struct et_list *et, **end;
-+
-+    for (end = list, et = *list; et; end = &et->next, et = et->next)
-+        if (et->table->msgs == text)
-+            return;
-+    et = malloc(sizeof(struct et_list));
-+    if (et == 0) {
-+        if (!link.table)
-+            et = &link;
-+        else
-+            return;
-+    }
-+    et->table = &et_ext2_error_table;
-+    et->next = 0;
-+    *end = et;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/ext2_ext_attr.h silo-1.4.14/libext2fs/ext2_ext_attr.h
---- silo-1.4.14.orig/libext2fs/ext2_ext_attr.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/ext2_ext_attr.h	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,69 @@
-+/*
-+  File: linux/ext2_ext_attr.h
-+
-+  On-disk format of extended attributes for the ext2 filesystem.
-+
-+  (C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+/* Magic value in attribute blocks */
-+#define EXT2_EXT_ATTR_MAGIC_v1		0xEA010000
-+#define EXT2_EXT_ATTR_MAGIC		0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT2_EXT_ATTR_REFCOUNT_MAX	1024
-+
-+struct ext2_ext_attr_header {
-+	__u32	h_magic;	/* magic number for identification */
-+	__u32	h_refcount;	/* reference count */
-+	__u32	h_blocks;	/* number of disk blocks used */
-+	__u32	h_hash;		/* hash value of all attributes */
-+	__u32	h_reserved[4];	/* zero right now */
-+};
-+
-+struct ext2_ext_attr_entry {
-+	__u8	e_name_len;	/* length of name */
-+	__u8	e_name_index;	/* attribute name index */
-+	__u16	e_value_offs;	/* offset in disk block of value */
-+	__u32	e_value_block;	/* disk block attribute is stored on (n/i) */
-+	__u32	e_value_size;	/* size of attribute value */
-+	__u32	e_hash;		/* hash value of name and value */
-+#if 0
-+	char	e_name[0];	/* attribute name */
-+#endif
-+};
-+
-+#define EXT2_EXT_ATTR_PAD_BITS		2
-+#define EXT2_EXT_ATTR_PAD		(1<<EXT2_EXT_ATTR_PAD_BITS)
-+#define EXT2_EXT_ATTR_ROUND		(EXT2_EXT_ATTR_PAD-1)
-+#define EXT2_EXT_ATTR_LEN(name_len) \
-+	(((name_len) + EXT2_EXT_ATTR_ROUND + \
-+	sizeof(struct ext2_ext_attr_entry)) & ~EXT2_EXT_ATTR_ROUND)
-+#define EXT2_EXT_ATTR_NEXT(entry) \
-+	( (struct ext2_ext_attr_entry *)( \
-+	  (char *)(entry) + EXT2_EXT_ATTR_LEN((entry)->e_name_len)) )
-+#define EXT2_EXT_ATTR_SIZE(size) \
-+	(((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND)
-+#define EXT2_EXT_IS_LAST_ENTRY(entry) (*((__u32 *)(entry)) == 0UL)
-+#define EXT2_EXT_ATTR_NAME(entry) \
-+	(((char *) (entry)) + sizeof(struct ext2_ext_attr_entry))
-+#define EXT2_XATTR_LEN(name_len) \
-+	(((name_len) + EXT2_EXT_ATTR_ROUND + \
-+	sizeof(struct ext2_xattr_entry)) & ~EXT2_EXT_ATTR_ROUND)
-+#define EXT2_XATTR_SIZE(size) \
-+	(((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+# ifdef CONFIG_EXT2_FS_EXT_ATTR
-+extern int ext2_get_ext_attr(struct inode *, const char *, char *, size_t, int);
-+extern int ext2_set_ext_attr(struct inode *, const char *, char *, size_t, int);
-+extern void ext2_ext_attr_free_inode(struct inode *inode);
-+extern void ext2_ext_attr_put_super(struct super_block *sb);
-+extern int ext2_ext_attr_init(void);
-+extern void ext2_ext_attr_done(void);
-+# else
-+#  define ext2_get_ext_attr NULL
-+#  define ext2_set_ext_attr NULL
-+# endif
-+#endif  /* __KERNEL__ */
-+
-diff -Naur silo-1.4.14.orig/libext2fs/ext2_fs.h silo-1.4.14/libext2fs/ext2_fs.h
---- silo-1.4.14.orig/libext2fs/ext2_fs.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/ext2_fs.h	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,644 @@
-+/*
-+ *  linux/include/linux/ext2_fs.h
-+ *
-+ * Copyright (C) 1992, 1993, 1994, 1995
-+ * Remy Card (card@masi.ibp.fr)
-+ * Laboratoire MASI - Institut Blaise Pascal
-+ * Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ *  from
-+ *
-+ *  linux/include/linux/minix_fs.h
-+ *
-+ *  Copyright (C) 1991, 1992  Linus Torvalds
-+ */
-+
-+#ifndef _LINUX_EXT2_FS_H
-+#define _LINUX_EXT2_FS_H
-+
-+#include <ext2fs/ext2_types.h>		/* Changed from linux/types.h */
-+
-+/*
-+ * The second extended filesystem constants/structures
-+ */
-+
-+/*
-+ * Define EXT2FS_DEBUG to produce debug messages
-+ */
-+#undef EXT2FS_DEBUG
-+
-+/*
-+ * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
-+ */
-+#define EXT2_PREALLOCATE
-+#define EXT2_DEFAULT_PREALLOC_BLOCKS	8
-+
-+/*
-+ * The second extended file system version
-+ */
-+#define EXT2FS_DATE		"95/08/09"
-+#define EXT2FS_VERSION		"0.5b"
-+
-+/*
-+ * Special inode numbers
-+ */
-+#define EXT2_BAD_INO		 1	/* Bad blocks inode */
-+#define EXT2_ROOT_INO		 2	/* Root inode */
-+#define EXT2_ACL_IDX_INO	 3	/* ACL inode */
-+#define EXT2_ACL_DATA_INO	 4	/* ACL inode */
-+#define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
-+#define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
-+#define EXT2_RESIZE_INO		 7	/* Reserved group descriptors inode */
-+#define EXT2_JOURNAL_INO	 8	/* Journal inode */
-+
-+/* First non-reserved inode for old ext2 filesystems */
-+#define EXT2_GOOD_OLD_FIRST_INO	11
-+
-+/*
-+ * The second extended file system magic number
-+ */
-+#define EXT2_SUPER_MAGIC	0xEF53
-+
-+#ifdef __KERNEL__
-+#define EXT2_SB(sb)	(&((sb)->u.ext2_sb))
-+#else
-+/* Assume that user mode programs are passing in an ext2fs superblock, not
-+ * a kernel struct super_block.  This will allow us to call the feature-test
-+ * macros from user land. */
-+#define EXT2_SB(sb)	(sb)
-+#endif
-+
-+/*
-+ * Maximal count of links to a file
-+ */
-+#define EXT2_LINK_MAX		32000
-+
-+/*
-+ * Macro-instructions used to manage several block sizes
-+ */
-+#define EXT2_MIN_BLOCK_LOG_SIZE		10	/* 1024 */
-+#define EXT2_MAX_BLOCK_LOG_SIZE		16	/* 65536 */
-+#define EXT2_MIN_BLOCK_SIZE	(1 << EXT2_MIN_BLOCK_LOG_SIZE)
-+#define EXT2_MAX_BLOCK_SIZE	(1 << EXT2_MAX_BLOCK_LOG_SIZE)
-+#ifdef __KERNEL__
-+#define EXT2_BLOCK_SIZE(s)	((s)->s_blocksize)
-+#define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
-+#define EXT2_ADDR_PER_BLOCK_BITS(s)	(EXT2_SB(s)->addr_per_block_bits)
-+#define EXT2_INODE_SIZE(s)	(EXT2_SB(s)->s_inode_size)
-+#define EXT2_FIRST_INO(s)	(EXT2_SB(s)->s_first_ino)
-+#else
-+#define EXT2_BLOCK_SIZE(s)	(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
-+#define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_log_block_size + 10)
-+#define EXT2_INODE_SIZE(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
-+				 EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size)
-+#define EXT2_FIRST_INO(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
-+				 EXT2_GOOD_OLD_FIRST_INO : (s)->s_first_ino)
-+#endif
-+#define EXT2_ADDR_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s) / sizeof(__u32))
-+
-+/*
-+ * Macro-instructions used to manage fragments
-+ */
-+#define EXT2_MIN_FRAG_SIZE		EXT2_MIN_BLOCK_SIZE
-+#define EXT2_MAX_FRAG_SIZE		EXT2_MAX_BLOCK_SIZE
-+#define EXT2_MIN_FRAG_LOG_SIZE		EXT2_MIN_BLOCK_LOG_SIZE
-+#ifdef __KERNEL__
-+# define EXT2_FRAG_SIZE(s)		(EXT2_SB(s)->s_frag_size)
-+# define EXT2_FRAGS_PER_BLOCK(s)	(EXT2_SB(s)->s_frags_per_block)
-+#else
-+# define EXT2_FRAG_SIZE(s)		(EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
-+# define EXT2_FRAGS_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
-+#endif
-+
-+/*
-+ * ACL structures
-+ */
-+struct ext2_acl_header	/* Header of Access Control Lists */
-+{
-+	__u32	aclh_size;
-+	__u32	aclh_file_count;
-+	__u32	aclh_acle_count;
-+	__u32	aclh_first_acle;
-+};
-+
-+struct ext2_acl_entry	/* Access Control List Entry */
-+{
-+	__u32	acle_size;
-+	__u16	acle_perms;	/* Access permissions */
-+	__u16	acle_type;	/* Type of entry */
-+	__u16	acle_tag;	/* User or group identity */
-+	__u16	acle_pad1;
-+	__u32	acle_next;	/* Pointer on next entry for the */
-+					/* same inode or on next free entry */
-+};
-+
-+/*
-+ * Structure of a blocks group descriptor
-+ */
-+struct ext2_group_desc
-+{
-+	__u32	bg_block_bitmap;		/* Blocks bitmap block */
-+	__u32	bg_inode_bitmap;		/* Inodes bitmap block */
-+	__u32	bg_inode_table;		/* Inodes table block */
-+	__u16	bg_free_blocks_count;	/* Free blocks count */
-+	__u16	bg_free_inodes_count;	/* Free inodes count */
-+	__u16	bg_used_dirs_count;	/* Directories count */
-+	__u16	bg_pad;
-+	__u32	bg_reserved[3];
-+};
-+
-+/*
-+ * Data structures used by the directory indexing feature
-+ *
-+ * Note: all of the multibyte integer fields are little endian.
-+ */
-+
-+/*
-+ * Note: dx_root_info is laid out so that if it should somehow get
-+ * overlaid by a dirent the two low bits of the hash version will be
-+ * zero.  Therefore, the hash version mod 4 should never be 0.
-+ * Sincerely, the paranoia department.
-+ */
-+struct ext2_dx_root_info {
-+	__u32 reserved_zero;
-+	__u8 hash_version; /* 0 now, 1 at release */
-+	__u8 info_length; /* 8 */
-+	__u8 indirect_levels;
-+	__u8 unused_flags;
-+};
-+
-+#define EXT2_HASH_LEGACY	0
-+#define EXT2_HASH_HALF_MD4	1
-+#define EXT2_HASH_TEA		2
-+
-+#define EXT2_HASH_FLAG_INCOMPAT	0x1
-+
-+struct ext2_dx_entry {
-+	__u32 hash;
-+	__u32 block;
-+};
-+
-+struct ext2_dx_countlimit {
-+	__u16 limit;
-+	__u16 count;
-+};
-+
-+
-+/*
-+ * Macro-instructions used to manage group descriptors
-+ */
-+#define EXT2_BLOCKS_PER_GROUP(s)	(EXT2_SB(s)->s_blocks_per_group)
-+#define EXT2_INODES_PER_GROUP(s)	(EXT2_SB(s)->s_inodes_per_group)
-+#define EXT2_INODES_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
-+/* limits imposed by 16-bit value gd_free_{blocks,inode}_count */
-+#define EXT2_MAX_BLOCKS_PER_GROUP(s)	((1 << 16) - 8)
-+#define EXT2_MAX_INODES_PER_GROUP(s)	((1 << 16) - EXT2_INODES_PER_BLOCK(s))
-+#ifdef __KERNEL__
-+#define EXT2_DESC_PER_BLOCK(s)		(EXT2_SB(s)->s_desc_per_block)
-+#define EXT2_DESC_PER_BLOCK_BITS(s)	(EXT2_SB(s)->s_desc_per_block_bits)
-+#else
-+#define EXT2_DESC_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
-+#endif
-+
-+/*
-+ * Constants relative to the data blocks
-+ */
-+#define EXT2_NDIR_BLOCKS		12
-+#define EXT2_IND_BLOCK			EXT2_NDIR_BLOCKS
-+#define EXT2_DIND_BLOCK			(EXT2_IND_BLOCK + 1)
-+#define EXT2_TIND_BLOCK			(EXT2_DIND_BLOCK + 1)
-+#define EXT2_N_BLOCKS			(EXT2_TIND_BLOCK + 1)
-+
-+/*
-+ * Inode flags
-+ */
-+#define EXT2_SECRM_FL			0x00000001 /* Secure deletion */
-+#define EXT2_UNRM_FL			0x00000002 /* Undelete */
-+#define EXT2_COMPR_FL			0x00000004 /* Compress file */
-+#define EXT2_SYNC_FL			0x00000008 /* Synchronous updates */
-+#define EXT2_IMMUTABLE_FL		0x00000010 /* Immutable file */
-+#define EXT2_APPEND_FL			0x00000020 /* writes to file may only append */
-+#define EXT2_NODUMP_FL			0x00000040 /* do not dump file */
-+#define EXT2_NOATIME_FL			0x00000080 /* do not update atime */
-+/* Reserved for compression usage... */
-+#define EXT2_DIRTY_FL			0x00000100
-+#define EXT2_COMPRBLK_FL		0x00000200 /* One or more compressed clusters */
-+#define EXT2_NOCOMPR_FL			0x00000400 /* Access raw compressed data */
-+#define EXT2_ECOMPR_FL			0x00000800 /* Compression error */
-+/* End compression flags --- maybe not all used */
-+#define EXT2_BTREE_FL			0x00001000 /* btree format dir */
-+#define EXT2_INDEX_FL			0x00001000 /* hash-indexed directory */
-+#define EXT2_IMAGIC_FL			0x00002000
-+#define EXT3_JOURNAL_DATA_FL		0x00004000 /* file data should be journaled */
-+#define EXT2_NOTAIL_FL			0x00008000 /* file tail should not be merged */
-+#define EXT2_DIRSYNC_FL 		0x00010000 /* Synchronous directory modifications */
-+#define EXT2_TOPDIR_FL			0x00020000 /* Top of directory hierarchies*/
-+#define EXT3_EXTENTS_FL 		0x00080000 /* Inode uses extents */
-+#define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
-+
-+#define EXT2_FL_USER_VISIBLE		0x0003DFFF /* User visible flags */
-+#define EXT2_FL_USER_MODIFIABLE		0x000080FF /* User modifiable flags */
-+
-+/*
-+ * ioctl commands
-+ */
-+#define EXT2_IOC_GETFLAGS		_IOR('f', 1, long)
-+#define EXT2_IOC_SETFLAGS		_IOW('f', 2, long)
-+#define EXT2_IOC_GETVERSION		_IOR('v', 1, long)
-+#define EXT2_IOC_SETVERSION		_IOW('v', 2, long)
-+
-+/*
-+ * Structure of an inode on the disk
-+ */
-+struct ext2_inode {
-+	__u16	i_mode;		/* File mode */
-+	__u16	i_uid;		/* Low 16 bits of Owner Uid */
-+	__u32	i_size;		/* Size in bytes */
-+	__u32	i_atime;	/* Access time */
-+	__u32	i_ctime;	/* Creation time */
-+	__u32	i_mtime;	/* Modification time */
-+	__u32	i_dtime;	/* Deletion Time */
-+	__u16	i_gid;		/* Low 16 bits of Group Id */
-+	__u16	i_links_count;	/* Links count */
-+	__u32	i_blocks;	/* Blocks count */
-+	__u32	i_flags;	/* File flags */
-+	union {
-+		struct {
-+			__u32  l_i_reserved1;
-+		} linux1;
-+		struct {
-+			__u32  h_i_translator;
-+		} hurd1;
-+		struct {
-+			__u32  m_i_reserved1;
-+		} masix1;
-+	} osd1;				/* OS dependent 1 */
-+	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
-+	__u32	i_generation;	/* File version (for NFS) */
-+	__u32	i_file_acl;	/* File ACL */
-+	__u32	i_dir_acl;	/* Directory ACL */
-+	__u32	i_faddr;	/* Fragment address */
-+	union {
-+		struct {
-+			__u8	l_i_frag;	/* Fragment number */
-+			__u8	l_i_fsize;	/* Fragment size */
-+			__u16	i_pad1;
-+			__u16	l_i_uid_high;	/* these 2 fields    */
-+			__u16	l_i_gid_high;	/* were reserved2[0] */
-+			__u32	l_i_reserved2;
-+		} linux2;
-+		struct {
-+			__u8	h_i_frag;	/* Fragment number */
-+			__u8	h_i_fsize;	/* Fragment size */
-+			__u16	h_i_mode_high;
-+			__u16	h_i_uid_high;
-+			__u16	h_i_gid_high;
-+			__u32	h_i_author;
-+		} hurd2;
-+		struct {
-+			__u8	m_i_frag;	/* Fragment number */
-+			__u8	m_i_fsize;	/* Fragment size */
-+			__u16	m_pad1;
-+			__u32	m_i_reserved2[2];
-+		} masix2;
-+	} osd2;				/* OS dependent 2 */
-+};
-+
-+/*
-+ * Permanent part of an large inode on the disk
-+ */
-+struct ext2_inode_large {
-+	__u16	i_mode;		/* File mode */
-+	__u16	i_uid;		/* Low 16 bits of Owner Uid */
-+	__u32	i_size;		/* Size in bytes */
-+	__u32	i_atime;	/* Access time */
-+	__u32	i_ctime;	/* Creation time */
-+	__u32	i_mtime;	/* Modification time */
-+	__u32	i_dtime;	/* Deletion Time */
-+	__u16	i_gid;		/* Low 16 bits of Group Id */
-+	__u16	i_links_count;	/* Links count */
-+	__u32	i_blocks;	/* Blocks count */
-+	__u32	i_flags;	/* File flags */
-+	union {
-+		struct {
-+			__u32  l_i_reserved1;
-+		} linux1;
-+		struct {
-+			__u32  h_i_translator;
-+		} hurd1;
-+		struct {
-+			__u32  m_i_reserved1;
-+		} masix1;
-+	} osd1;				/* OS dependent 1 */
-+	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
-+	__u32	i_generation;	/* File version (for NFS) */
-+	__u32	i_file_acl;	/* File ACL */
-+	__u32	i_dir_acl;	/* Directory ACL */
-+	__u32	i_faddr;	/* Fragment address */
-+	union {
-+		struct {
-+			__u8	l_i_frag;	/* Fragment number */
-+			__u8	l_i_fsize;	/* Fragment size */
-+			__u16	i_pad1;
-+			__u16	l_i_uid_high;	/* these 2 fields    */
-+			__u16	l_i_gid_high;	/* were reserved2[0] */
-+			__u32	l_i_reserved2;
-+		} linux2;
-+		struct {
-+			__u8	h_i_frag;	/* Fragment number */
-+			__u8	h_i_fsize;	/* Fragment size */
-+			__u16	h_i_mode_high;
-+			__u16	h_i_uid_high;
-+			__u16	h_i_gid_high;
-+			__u32	h_i_author;
-+		} hurd2;
-+		struct {
-+			__u8	m_i_frag;	/* Fragment number */
-+			__u8	m_i_fsize;	/* Fragment size */
-+			__u16	m_pad1;
-+			__u32	m_i_reserved2[2];
-+		} masix2;
-+	} osd2;				/* OS dependent 2 */
-+	__u16	i_extra_isize;
-+	__u16	i_pad1;
-+};
-+
-+#define i_size_high	i_dir_acl
-+
-+#if defined(__KERNEL__) || defined(__linux__)
-+#define i_reserved1	osd1.linux1.l_i_reserved1
-+#define i_frag		osd2.linux2.l_i_frag
-+#define i_fsize		osd2.linux2.l_i_fsize
-+#define i_uid_low	i_uid
-+#define i_gid_low	i_gid
-+#define i_uid_high	osd2.linux2.l_i_uid_high
-+#define i_gid_high	osd2.linux2.l_i_gid_high
-+#define i_reserved2	osd2.linux2.l_i_reserved2
-+
-+#else
-+#if defined(__GNU__)
-+
-+#define i_translator	osd1.hurd1.h_i_translator
-+#define i_frag		osd2.hurd2.h_i_frag;
-+#define i_fsize		osd2.hurd2.h_i_fsize;
-+#define i_uid_high	osd2.hurd2.h_i_uid_high
-+#define i_gid_high	osd2.hurd2.h_i_gid_high
-+#define i_author	osd2.hurd2.h_i_author
-+
-+#else
-+#if defined(__masix__)
-+
-+#define i_reserved1	osd1.masix1.m_i_reserved1
-+#define i_frag		osd2.masix2.m_i_frag
-+#define i_fsize		osd2.masix2.m_i_fsize
-+#define i_reserved2	osd2.masix2.m_i_reserved2
-+
-+#endif  /* __masix__ */
-+#endif  /* __GNU__ */
-+#endif	/* defined(__KERNEL__) || defined(__linux__) */
-+
-+/*
-+ * File system states
-+ */
-+#define EXT2_VALID_FS			0x0001	/* Unmounted cleanly */
-+#define EXT2_ERROR_FS			0x0002	/* Errors detected */
-+
-+/*
-+ * Mount flags
-+ */
-+#define EXT2_MOUNT_CHECK		0x0001	/* Do mount-time checks */
-+#define EXT2_MOUNT_GRPID		0x0004	/* Create files with directory's group */
-+#define EXT2_MOUNT_DEBUG		0x0008	/* Some debugging messages */
-+#define EXT2_MOUNT_ERRORS_CONT		0x0010	/* Continue on errors */
-+#define EXT2_MOUNT_ERRORS_RO		0x0020	/* Remount fs ro on errors */
-+#define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
-+#define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
-+#define EXT2_MOUNT_NO_UID32		0x0200  /* Disable 32-bit UIDs */
-+
-+#define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
-+#define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
-+#define test_opt(sb, opt)		(EXT2_SB(sb)->s_mount_opt & \
-+					 EXT2_MOUNT_##opt)
-+/*
-+ * Maximal mount counts between two filesystem checks
-+ */
-+#define EXT2_DFL_MAX_MNT_COUNT		20	/* Allow 20 mounts */
-+#define EXT2_DFL_CHECKINTERVAL		0	/* Don't use interval check */
-+
-+/*
-+ * Behaviour when detecting errors
-+ */
-+#define EXT2_ERRORS_CONTINUE		1	/* Continue execution */
-+#define EXT2_ERRORS_RO			2	/* Remount fs read-only */
-+#define EXT2_ERRORS_PANIC		3	/* Panic */
-+#define EXT2_ERRORS_DEFAULT		EXT2_ERRORS_CONTINUE
-+
-+/*
-+ * Structure of the super block
-+ */
-+struct ext2_super_block {
-+	__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_algorithm_usage_bitmap; /* For compression */
-+	/*
-+	 * Performance hints.  Directory preallocation should only
-+	 * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
-+	 */
-+	__u8	s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
-+	__u8	s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
-+	__u16	s_reserved_gdt_blocks;	/* Per group table for online growth */
-+	/*
-+	 * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
-+	 */
-+	__u8	s_journal_uuid[16];	/* uuid of journal superblock */
-+	__u32	s_journal_inum;		/* inode number of journal file */
-+	__u32	s_journal_dev;		/* device number of journal file */
-+	__u32	s_last_orphan;		/* start of list of inodes to delete */
-+	__u32	s_hash_seed[4];		/* HTREE hash seed */
-+	__u8	s_def_hash_version;	/* Default hash version to use */
-+	__u8	s_jnl_backup_type; 	/* Default type of journal backup */
-+	__u16	s_reserved_word_pad;
-+	__u32	s_default_mount_opts;
-+	__u32	s_first_meta_bg;	/* First metablock group */
-+	__u32	s_mkfs_time;		/* When the filesystem was created */
-+	__u32	s_jnl_blocks[17]; 	/* Backup of the journal inode */
-+	__u32	s_reserved[172];	/* Padding to the end of the block */
-+};
-+
-+/*
-+ * Codes for operating systems
-+ */
-+#define EXT2_OS_LINUX		0
-+#define EXT2_OS_HURD		1
-+#define EXT2_OS_MASIX		2
-+#define EXT2_OS_FREEBSD		3
-+#define EXT2_OS_LITES		4
-+
-+/*
-+ * Revision levels
-+ */
-+#define EXT2_GOOD_OLD_REV	0	/* The good old (original) format */
-+#define EXT2_DYNAMIC_REV	1	/* V2 format w/ dynamic inode sizes */
-+
-+#define EXT2_CURRENT_REV	EXT2_GOOD_OLD_REV
-+#define EXT2_MAX_SUPP_REV	EXT2_DYNAMIC_REV
-+
-+#define EXT2_GOOD_OLD_INODE_SIZE 128
-+
-+/*
-+ * Journal inode backup types
-+ */
-+#define EXT3_JNL_BACKUP_BLOCKS	1
-+
-+/*
-+ * Feature set definitions
-+ */
-+
-+#define EXT2_HAS_COMPAT_FEATURE(sb,mask)			\
-+	( EXT2_SB(sb)->s_feature_compat & (mask) )
-+#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)			\
-+	( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
-+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)			\
-+	( EXT2_SB(sb)->s_feature_incompat & (mask) )
-+
-+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC	0x0001
-+#define EXT2_FEATURE_COMPAT_IMAGIC_INODES	0x0002
-+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL		0x0004
-+#define EXT2_FEATURE_COMPAT_EXT_ATTR		0x0008
-+#define EXT2_FEATURE_COMPAT_RESIZE_INODE	0x0010
-+#define EXT2_FEATURE_COMPAT_DIR_INDEX		0x0020
-+
-+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
-+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE	0x0002
-+/* #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR	0x0004 not used */
-+
-+#define EXT2_FEATURE_INCOMPAT_COMPRESSION	0x0001
-+#define EXT2_FEATURE_INCOMPAT_FILETYPE		0x0002
-+#define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
-+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Journal device */
-+#define EXT2_FEATURE_INCOMPAT_META_BG		0x0010
-+#define EXT3_FEATURE_INCOMPAT_EXTENTS		0x0040
-+
-+
-+#define EXT2_FEATURE_COMPAT_SUPP	0
-+#define EXT2_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE)
-+#define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
-+					 EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
-+
-+/*
-+ * Default values for user and/or group using reserved blocks
-+ */
-+#define EXT2_DEF_RESUID		0
-+#define EXT2_DEF_RESGID		0
-+
-+/*
-+ * Default mount options
-+ */
-+#define EXT2_DEFM_DEBUG		0x0001
-+#define EXT2_DEFM_BSDGROUPS	0x0002
-+#define EXT2_DEFM_XATTR_USER	0x0004
-+#define EXT2_DEFM_ACL		0x0008
-+#define EXT2_DEFM_UID16		0x0010
-+#define EXT3_DEFM_JMODE		0x0060 
-+#define EXT3_DEFM_JMODE_DATA	0x0020
-+#define EXT3_DEFM_JMODE_ORDERED	0x0040
-+#define EXT3_DEFM_JMODE_WBACK	0x0060
-+
-+/*
-+ * Structure of a directory entry
-+ */
-+#define EXT2_NAME_LEN 255
-+
-+struct ext2_dir_entry {
-+	__u32	inode;			/* Inode number */
-+	__u16	rec_len;		/* Directory entry length */
-+	__u16	name_len;		/* Name length */
-+	char	name[EXT2_NAME_LEN];	/* File name */
-+};
-+
-+/*
-+ * The new version of the directory entry.  Since EXT2 structures are
-+ * stored in intel byte order, and the name_len field could never be
-+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
-+ * file_type field.
-+ */
-+struct ext2_dir_entry_2 {
-+	__u32	inode;			/* Inode number */
-+	__u16	rec_len;		/* Directory entry length */
-+	__u8	name_len;		/* Name length */
-+	__u8	file_type;
-+	char	name[EXT2_NAME_LEN];	/* File name */
-+};
-+
-+/*
-+ * Ext2 directory file types.  Only the low 3 bits are used.  The
-+ * other bits are reserved for now.
-+ */
-+#define EXT2_FT_UNKNOWN		0
-+#define EXT2_FT_REG_FILE	1
-+#define EXT2_FT_DIR		2
-+#define EXT2_FT_CHRDEV		3
-+#define EXT2_FT_BLKDEV		4
-+#define EXT2_FT_FIFO		5
-+#define EXT2_FT_SOCK		6
-+#define EXT2_FT_SYMLINK		7
-+
-+#define EXT2_FT_MAX		8
-+
-+/*
-+ * EXT2_DIR_PAD defines the directory entries boundaries
-+ *
-+ * NOTE: It must be a multiple of 4
-+ */
-+#define EXT2_DIR_PAD			4
-+#define EXT2_DIR_ROUND			(EXT2_DIR_PAD - 1)
-+#define EXT2_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT2_DIR_ROUND) & \
-+					 ~EXT2_DIR_ROUND)
-+
-+#endif	/* _LINUX_EXT2_FS_H */
-diff -Naur silo-1.4.14.orig/libext2fs/ext2_io.h silo-1.4.14/libext2fs/ext2_io.h
---- silo-1.4.14.orig/libext2fs/ext2_io.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/ext2_io.h	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,108 @@
-+/*
-+ * io.h --- the I/O manager abstraction
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#ifndef _EXT2FS_EXT2_IO_H
-+#define _EXT2FS_EXT2_IO_H
-+
-+/*
-+ * ext2_loff_t is defined here since unix_io.c needs it.
-+ */
-+#if defined(__GNUC__) || defined(HAS_LONG_LONG)
-+typedef long long	ext2_loff_t;
-+#else
-+typedef long		ext2_loff_t;
-+#endif
-+
-+/* llseek.c */
-+ext2_loff_t ext2fs_llseek (int, ext2_loff_t, int);
-+
-+typedef struct struct_io_manager *io_manager;
-+typedef struct struct_io_channel *io_channel;
-+
-+#define CHANNEL_FLAGS_WRITETHROUGH	0x01
-+
-+struct struct_io_channel {
-+	errcode_t	magic;
-+	io_manager	manager;
-+	char		*name;
-+	int		block_size;
-+	errcode_t	(*read_error)(io_channel channel,
-+				      unsigned long block,
-+				      int count,
-+				      void *data,
-+				      size_t size,
-+				      int actual_bytes_read,
-+				      errcode_t	error);
-+	errcode_t	(*write_error)(io_channel channel,
-+				       unsigned long block,
-+				       int count,
-+				       const void *data,
-+				       size_t size,
-+				       int actual_bytes_written,
-+				       errcode_t error);
-+	int		refcount;
-+	int		flags;
-+	int		reserved[14];
-+	void		*private_data;
-+	void		*app_data;
-+};
-+
-+struct struct_io_manager {
-+	errcode_t magic;
-+	const char *name;
-+	errcode_t (*open)(const char *name, int flags, io_channel *channel);
-+	errcode_t (*close)(io_channel channel);
-+	errcode_t (*set_blksize)(io_channel channel, int blksize);
-+	errcode_t (*read_blk)(io_channel channel, unsigned long block,
-+			      int count, void *data);
-+	errcode_t (*write_blk)(io_channel channel, unsigned long block,
-+			       int count, const void *data);
-+	errcode_t (*flush)(io_channel channel);
-+	errcode_t (*write_byte)(io_channel channel, unsigned long offset,
-+				int count, const void *data);
-+	errcode_t (*set_option)(io_channel channel, const char *option, 
-+				const char *arg);
-+	int		reserved[14];
-+};
-+
-+#define IO_FLAG_RW	1
-+
-+/*
-+ * Convenience functions....
-+ */
-+#define io_channel_close(c) 		((c)->manager->close((c)))
-+#define io_channel_set_blksize(c,s)	((c)->manager->set_blksize((c),s))
-+#define io_channel_read_blk(c,b,n,d)	((c)->manager->read_blk((c),b,n,d))
-+#define io_channel_write_blk(c,b,n,d)	((c)->manager->write_blk((c),b,n,d))
-+#define io_channel_flush(c) 		((c)->manager->flush((c)))
-+#define io_channel_bumpcount(c)		((c)->refcount++)
-+	
-+/* io_manager.c */
-+extern errcode_t io_channel_set_options(io_channel channel, 
-+					const char *options);
-+extern errcode_t io_channel_write_byte(io_channel channel, 
-+				       unsigned long offset,
-+				       int count, const void *data);
-+
-+/* unix_io.c */
-+extern io_manager unix_io_manager;
-+
-+/* test_io.c */
-+extern io_manager test_io_manager, test_io_backing_manager;
-+extern void (*test_io_cb_read_blk)
-+	(unsigned long block, int count, errcode_t err);
-+extern void (*test_io_cb_write_blk)
-+	(unsigned long block, int count, errcode_t err);
-+extern void (*test_io_cb_set_blksize)
-+	(int blksize, errcode_t err);
-+
-+#endif /* _EXT2FS_EXT2_IO_H */
-+	
-diff -Naur silo-1.4.14.orig/libext2fs/ext2fs.h silo-1.4.14/libext2fs/ext2fs.h
---- silo-1.4.14.orig/libext2fs/ext2fs.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/ext2fs.h	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,1140 @@
-+/*
-+ * ext2fs.h --- ext2fs
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#ifndef _EXT2FS_EXT2FS_H
-+#define _EXT2FS_EXT2FS_H
-+
-+#ifdef __GNUC__
-+#define EXT2FS_ATTR(x) __attribute__(x)
-+#else
-+#define EXT2FS_ATTR(x)
-+#endif
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * Non-GNU C compilers won't necessarily understand inline
-+ */
-+#if (!defined(__GNUC__) && !defined(__WATCOMC__))
-+#define NO_INLINE_FUNCS
-+#endif
-+
-+/*
-+ * Build in support for byte-swapping filesystems if we the feature
-+ * has been configured or if we're being built on a CPU architecture
-+ * with a non-native byte order.
-+ */
-+#if defined(ENABLE_SWAPFS) || defined(WORDS_BIGENDIAN)
-+#define EXT2FS_ENABLE_SWAPFS
-+#endif
-+
-+/*
-+ * Where the master copy of the superblock is located, and how big
-+ * superblocks are supposed to be.  We define SUPERBLOCK_SIZE because
-+ * the size of the superblock structure is not necessarily trustworthy
-+ * (some versions have the padding set up so that the superblock is
-+ * 1032 bytes long).
-+ */
-+#define SUPERBLOCK_OFFSET	1024
-+#define SUPERBLOCK_SIZE 	1024
-+
-+/*
-+ * The last ext2fs revision level that this version of the library is
-+ * able to support.
-+ */
-+#define EXT2_LIB_CURRENT_REV	EXT2_DYNAMIC_REV
-+
-+#ifdef HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+
-+#if EXT2_FLAT_INCLUDES
-+#include "e2_types.h"
-+#include "ext2_fs.h"
-+#else
-+#include <ext2fs/ext2_types.h>
-+#include <ext2fs/ext2_fs.h>
-+#endif /* EXT2_FLAT_INCLUDES */
-+
-+typedef __u32		ext2_ino_t;
-+typedef __u32		blk_t;
-+typedef __u32		dgrp_t;
-+typedef __u32		ext2_off_t;
-+typedef __s64		e2_blkcnt_t;
-+typedef __u32		ext2_dirhash_t;
-+
-+#if EXT2_FLAT_INCLUDES
-+#include "com_err.h"
-+#include "ext2_io.h"
-+#include "ext2_err.h"
-+#else
-+#include <et/com_err.h>
-+#include <ext2fs/ext2_io.h>
-+#include <ext2fs/ext2_err.h>
-+#endif
-+
-+/*
-+ * Portability help for Microsoft Visual C++
-+ */
-+#ifdef _MSC_VER
-+#define EXT2_QSORT_TYPE int __cdecl
-+#else
-+#define EXT2_QSORT_TYPE int
-+#endif
-+
-+typedef struct struct_ext2_filsys *ext2_filsys;
-+
-+struct ext2fs_struct_generic_bitmap {
-+	errcode_t	magic;
-+	ext2_filsys 	fs;
-+	__u32		start, end;
-+	__u32		real_end;
-+	char	*	description;
-+	char	*	bitmap;
-+	errcode_t	base_error_code;
-+	__u32		reserved[7];
-+};
-+
-+#define EXT2FS_MARK_ERROR 	0
-+#define EXT2FS_UNMARK_ERROR 	1
-+#define EXT2FS_TEST_ERROR	2
-+
-+typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_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)
-+#else
-+#define EXT2_FIRST_INODE(s)	EXT2_FIRST_INO
-+#define EXT2_INODE_SIZE(s)	sizeof(struct ext2_inode)
-+#endif
-+
-+/*
-+ * badblocks list definitions
-+ */
-+
-+typedef struct ext2_struct_u32_list *ext2_badblocks_list;
-+typedef struct ext2_struct_u32_iterate *ext2_badblocks_iterate;
-+
-+typedef struct ext2_struct_u32_list *ext2_u32_list;
-+typedef struct ext2_struct_u32_iterate *ext2_u32_iterate;
-+
-+/* old */
-+typedef struct ext2_struct_u32_list *badblocks_list;
-+typedef struct ext2_struct_u32_iterate *badblocks_iterate;
-+
-+#define BADBLOCKS_FLAG_DIRTY	1
-+
-+/*
-+ * ext2_dblist structure and abstractions (see dblist.c)
-+ */
-+struct ext2_db_entry {
-+	ext2_ino_t	ino;
-+	blk_t	blk;
-+	int	blockcnt;
-+};
-+
-+typedef struct ext2_struct_dblist *ext2_dblist;
-+
-+#define DBLIST_ABORT	1
-+
-+/*
-+ * ext2_fileio definitions
-+ */
-+
-+#define EXT2_FILE_WRITE		0x0001
-+#define EXT2_FILE_CREATE	0x0002
-+
-+#define EXT2_FILE_MASK		0x00FF
-+
-+#define EXT2_FILE_BUF_DIRTY	0x4000
-+#define EXT2_FILE_BUF_VALID	0x2000
-+
-+typedef struct ext2_file *ext2_file_t;
-+
-+#define EXT2_SEEK_SET	0
-+#define EXT2_SEEK_CUR	1
-+#define EXT2_SEEK_END	2
-+
-+/*
-+ * Flags for the ext2_filsys structure and for ext2fs_open()
-+ */
-+#define EXT2_FLAG_RW			0x01
-+#define EXT2_FLAG_CHANGED		0x02
-+#define EXT2_FLAG_DIRTY			0x04
-+#define EXT2_FLAG_VALID			0x08
-+#define EXT2_FLAG_IB_DIRTY		0x10
-+#define EXT2_FLAG_BB_DIRTY		0x20
-+#define EXT2_FLAG_SWAP_BYTES		0x40
-+#define EXT2_FLAG_SWAP_BYTES_READ	0x80
-+#define EXT2_FLAG_SWAP_BYTES_WRITE	0x100
-+#define EXT2_FLAG_MASTER_SB_ONLY	0x200
-+#define EXT2_FLAG_FORCE			0x400
-+#define EXT2_FLAG_SUPER_ONLY		0x800
-+#define EXT2_FLAG_JOURNAL_DEV_OK	0x1000
-+#define EXT2_FLAG_IMAGE_FILE		0x2000
-+
-+/*
-+ * Special flag in the ext2 inode i_flag field that means that this is
-+ * a new inode.  (So that ext2_write_inode() can clear extra fields.)
-+ */
-+#define EXT2_NEW_INODE_FL	0x80000000
-+
-+/*
-+ * Flags for mkjournal
-+ *
-+ * EXT2_MKJOURNAL_V1_SUPER	Make a (deprecated) V1 journal superblock
-+ */
-+#define EXT2_MKJOURNAL_V1_SUPER	0x0000001
-+
-+struct struct_ext2_filsys {
-+	errcode_t			magic;
-+	io_channel			io;
-+	int				flags;
-+	char *				device_name;
-+	struct ext2_super_block	* 	super;
-+	unsigned int			blocksize;
-+	int				fragsize;
-+	dgrp_t				group_desc_count;
-+	unsigned long			desc_blocks;
-+	struct ext2_group_desc *	group_desc;
-+	int				inode_blocks_per_group;
-+	ext2fs_inode_bitmap		inode_map;
-+	ext2fs_block_bitmap		block_map;
-+	errcode_t (*get_blocks)(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
-+	errcode_t (*check_directory)(ext2_filsys fs, ext2_ino_t ino);
-+	errcode_t (*write_bitmaps)(ext2_filsys fs);
-+	errcode_t (*read_inode)(ext2_filsys fs, ext2_ino_t ino,
-+				struct ext2_inode *inode);
-+	errcode_t (*write_inode)(ext2_filsys fs, ext2_ino_t ino,
-+				struct ext2_inode *inode);
-+	ext2_badblocks_list		badblocks;
-+	ext2_dblist			dblist;
-+	__u32				stride;	/* for mke2fs */
-+	struct ext2_super_block *	orig_super;
-+	struct ext2_image_hdr *		image_header;
-+	__u32				umask;
-+	/*
-+	 * Reserved for future expansion
-+	 */
-+	__u32				reserved[8];
-+
-+	/*
-+	 * Reserved for the use of the calling application.
-+	 */
-+	void *				priv_data;
-+
-+	/*
-+	 * Inode cache
-+	 */
-+	struct ext2_inode_cache		*icache;
-+	io_channel			image_io;
-+};
-+
-+#if EXT2_FLAT_INCLUDES
-+#include "e2_bitops.h"
-+#else
-+#include <ext2fs/bitops.h>
-+#endif
-+
-+/*
-+ * Return flags for the block iterator functions
-+ */
-+#define BLOCK_CHANGED	1
-+#define BLOCK_ABORT	2
-+#define BLOCK_ERROR	4
-+
-+/*
-+ * Block interate flags
-+ *
-+ * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
-+ * function should be called on blocks where the block number is zero.
-+ * This is used by ext2fs_expand_dir() to be able to add a new block
-+ * to an inode.  It can also be used for programs that want to be able
-+ * to deal with files that contain "holes".
-+ * 
-+ * BLOCK_FLAG_TRAVERSE indicates that the iterator function for the
-+ * indirect, doubly indirect, etc. blocks should be called after all
-+ * 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.
-+ *
-+ * BLOCK_FLAG_NO_LARGE is for internal use only.  It informs
-+ * ext2fs_block_iterate2 that large files won't be accepted.
-+ */
-+#define BLOCK_FLAG_APPEND	1
-+#define BLOCK_FLAG_HOLE		1
-+#define BLOCK_FLAG_DEPTH_TRAVERSE	2
-+#define BLOCK_FLAG_DATA_ONLY	4
-+
-+#define BLOCK_FLAG_NO_LARGE	0x1000
-+
-+/*
-+ * 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)
-+
-+#if 0
-+/*
-+ * Flags for ext2fs_move_blocks
-+ */
-+#define EXT2_BMOVE_GET_DBLIST	0x0001	
-+#define EXT2_BMOVE_DEBUG	0x0002
-+#endif
-+
-+/*
-+ * Flags for directory block reading and writing functions
-+ */
-+#define EXT2_DIRBLOCK_V2_STRUCT	0x0001
-+
-+/*
-+ * Return flags for the directory iterator functions
-+ */
-+#define DIRENT_CHANGED	1
-+#define DIRENT_ABORT	2
-+#define DIRENT_ERROR	3
-+
-+/*
-+ * Directory iterator flags
-+ */
-+
-+#define DIRENT_FLAG_INCLUDE_EMPTY	1
-+#define DIRENT_FLAG_INCLUDE_REMOVED	2
-+
-+#define DIRENT_DOT_FILE		1
-+#define DIRENT_DOT_DOT_FILE	2
-+#define DIRENT_OTHER_FILE	3
-+#define DIRENT_DELETED_FILE	4
-+
-+/*
-+ * Inode scan definitions
-+ */
-+typedef struct ext2_struct_inode_scan *ext2_inode_scan;
-+
-+/*
-+ * ext2fs_scan flags
-+ */
-+#define EXT2_SF_CHK_BADBLOCKS	0x0001
-+#define EXT2_SF_BAD_INODE_BLK	0x0002
-+#define EXT2_SF_BAD_EXTRA_BYTES	0x0004
-+#define EXT2_SF_SKIP_MISSING_ITABLE	0x0008
-+
-+/*
-+ * ext2fs_check_if_mounted flags
-+ */
-+#define EXT2_MF_MOUNTED		1
-+#define EXT2_MF_ISROOT		2
-+#define EXT2_MF_READONLY	4
-+#define EXT2_MF_SWAP		8
-+#define EXT2_MF_BUSY		16
-+
-+/*
-+ * Ext2/linux mode flags.  We define them here so that we don't need
-+ * to depend on the OS's sys/stat.h, since we may be compiling on a
-+ * non-Linux system.
-+ */
-+#define LINUX_S_IFMT  00170000
-+#define LINUX_S_IFSOCK 0140000
-+#define LINUX_S_IFLNK	 0120000
-+#define LINUX_S_IFREG  0100000
-+#define LINUX_S_IFBLK  0060000
-+#define LINUX_S_IFDIR  0040000
-+#define LINUX_S_IFCHR  0020000
-+#define LINUX_S_IFIFO  0010000
-+#define LINUX_S_ISUID  0004000
-+#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)
-+#define LINUX_S_ISCHR(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFCHR)
-+#define LINUX_S_ISBLK(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFBLK)
-+#define LINUX_S_ISFIFO(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFIFO)
-+#define LINUX_S_ISSOCK(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
-+
-+/*
-+ * ext2 size of an inode
-+ */
-+#define EXT2_I_SIZE(i)	((i)->i_size | ((__u64) (i)->i_size_high << 32))
-+
-+/*
-+ * ext2_icount_t abstraction
-+ */
-+#define EXT2_ICOUNT_OPT_INCREMENT	0x01
-+
-+typedef struct ext2_icount *ext2_icount_t;
-+
-+/*
-+ * Flags for ext2fs_bmap
-+ */
-+#define BMAP_ALLOC	0x0001
-+#define BMAP_SET	0x0002
-+
-+/*
-+ * Flags for imager.c functions
-+ */
-+#define IMAGER_FLAG_INODEMAP	1
-+#define IMAGER_FLAG_SPARSEWRITE	2
-+
-+/*
-+ * For checking structure magic numbers...
-+ */
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+	  if ((struct)->magic != (code)) return (code)
-+
-+
-+/*
-+ * For ext2 compression support
-+ */
-+#define EXT2FS_COMPRESSED_BLKADDR ((blk_t) 0xffffffff)
-+#define HOLE_BLKADDR(_b) ((_b) == 0 || (_b) == EXT2FS_COMPRESSED_BLKADDR)
-+
-+/*
-+ * Features supported by this version of the library
-+ */
-+#define EXT2_LIB_FEATURE_COMPAT_SUPP	(EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
-+					 EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
-+					 EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
-+					 EXT2_FEATURE_COMPAT_RESIZE_INODE|\
-+					 EXT2_FEATURE_COMPAT_DIR_INDEX|\
-+					 EXT2_FEATURE_COMPAT_EXT_ATTR)
-+
-+/* This #ifdef is temporary until compression is fully supported */
-+#ifdef ENABLE_COMPRESSION
-+#ifndef I_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL
-+/* If the below warning bugs you, then have
-+   `CPPFLAGS=-DI_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL' in your
-+   environment at configure time. */
-+ #warning "Compression support is experimental"
-+#endif
-+#define EXT2_LIB_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE|\
-+					 EXT2_FEATURE_INCOMPAT_COMPRESSION|\
-+					 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
-+					 EXT2_FEATURE_INCOMPAT_META_BG|\
-+					 EXT3_FEATURE_INCOMPAT_RECOVER)
-+#else
-+#define EXT2_LIB_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE|\
-+					 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
-+					 EXT2_FEATURE_INCOMPAT_META_BG|\
-+					 EXT3_FEATURE_INCOMPAT_RECOVER)
-+#endif
-+#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
-+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
-+/*
-+ * function prototypes
-+ */
-+
-+/* alloc.c */
-+extern errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, int mode,
-+				  ext2fs_inode_bitmap map, ext2_ino_t *ret);
-+extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
-+				  ext2fs_block_bitmap map, blk_t *ret);
-+extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
-+					blk_t finish, int num,
-+					ext2fs_block_bitmap map,
-+					blk_t *ret);
-+extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
-+				    char *block_buf, blk_t *ret);
-+
-+/* alloc_sb.c */
-+extern int ext2fs_reserve_super_and_bgd(ext2_filsys fs, 
-+					dgrp_t group,
-+					ext2fs_block_bitmap bmap);
-+
-+/* alloc_stats.c */
-+void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse);
-+void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
-+			       int inuse, int isdir);
-+void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse);
-+
-+/* alloc_tables.c */
-+extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
-+extern errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
-+					     ext2fs_block_bitmap bmap);
-+
-+/* badblocks.c */
-+extern errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size);
-+extern errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk);
-+extern int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk);
-+extern int ext2fs_u32_list_test(ext2_u32_list bb, blk_t blk);
-+extern errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
-+					       ext2_u32_iterate *ret);
-+extern int ext2fs_u32_list_iterate(ext2_u32_iterate iter, blk_t *blk);
-+extern void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter);
-+extern errcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest);
-+extern int ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2);
-+
-+extern errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret,
-+					    int size);
-+extern errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb,
-+					   blk_t blk);
-+extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
-+				    blk_t blk);
-+extern int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk);
-+extern void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk);
-+extern errcode_t
-+	ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
-+					    ext2_badblocks_iterate *ret);
-+extern int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter,
-+					 blk_t *blk);
-+extern void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter);
-+extern errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
-+				       ext2_badblocks_list *dest);
-+extern int ext2fs_badblocks_equal(ext2_badblocks_list bb1,
-+				  ext2_badblocks_list bb2);
-+extern int ext2fs_u32_list_count(ext2_u32_list bb);
-+
-+/* bb_compat */
-+extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
-+extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
-+extern int badblocks_list_test(badblocks_list bb, blk_t blk);
-+extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
-+					      badblocks_iterate *ret);
-+extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
-+extern void badblocks_list_iterate_end(badblocks_iterate iter);
-+extern void badblocks_list_free(badblocks_list bb);
-+
-+/* bb_inode.c */
-+extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
-+					ext2_badblocks_list bb_list);
-+
-+/* bitmaps.c */
-+extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
-+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);
-+extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
-+					      const char *descr,
-+					      ext2fs_inode_bitmap *ret);
-+extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
-+					       ext2_ino_t end, ext2_ino_t *oend);
-+extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
-+					       blk_t end, blk_t *oend);
-+extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
-+extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
-+extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
-+extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
-+
-+/* block.c */
-+extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
-+				      ext2_ino_t	ino,
-+				      int	flags,
-+				      char *block_buf,
-+				      int (*func)(ext2_filsys fs,
-+						  blk_t	*blocknr,
-+						  int	blockcnt,
-+						  void	*priv_data),
-+				      void *priv_data);
-+errcode_t ext2fs_block_iterate2(ext2_filsys fs,
-+				ext2_ino_t	ino,
-+				int	flags,
-+				char *block_buf,
-+				int (*func)(ext2_filsys fs,
-+					    blk_t	*blocknr,
-+					    e2_blkcnt_t	blockcnt,
-+					    blk_t	ref_blk,
-+					    int		ref_offset,
-+					    void	*priv_data),
-+				void *priv_data);
-+
-+/* bmap.c */
-+extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
-+			     struct ext2_inode *inode, 
-+			     char *block_buf, int bmap_flags,
-+			     blk_t block, blk_t *phys_blk);
-+
-+
-+#if 0
-+/* bmove.c */
-+extern errcode_t ext2fs_move_blocks(ext2_filsys fs,
-+				    ext2fs_block_bitmap reserve,
-+				    ext2fs_block_bitmap alloc_map,
-+				    int flags);
-+#endif
-+
-+/* check_desc.c */
-+extern errcode_t ext2fs_check_desc(ext2_filsys fs);
-+
-+/* closefs.c */
-+extern errcode_t ext2fs_close(ext2_filsys fs);
-+extern errcode_t ext2fs_flush(ext2_filsys fs);
-+extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block);
-+extern int ext2fs_super_and_bgd_loc(ext2_filsys fs, 
-+				    dgrp_t group,
-+				    blk_t *ret_super_blk,
-+				    blk_t *ret_old_desc_blk,
-+				    blk_t *ret_new_desc_blk,
-+				    int *ret_meta_bg);
-+extern void ext2fs_update_dynamic_rev(ext2_filsys fs);
-+
-+/* cmp_bitmaps.c */
-+extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
-+					     ext2fs_block_bitmap bm2);
-+extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
-+					     ext2fs_inode_bitmap bm2);
-+
-+/* dblist.c */
-+
-+extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
-+extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
-+extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino,
-+				      blk_t blk, int blockcnt);
-+extern void ext2fs_dblist_sort(ext2_dblist dblist,
-+			       EXT2_QSORT_TYPE (*sortfunc)(const void *,
-+							   const void *));
-+extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
-+	int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info,
-+		    void	*priv_data),
-+       void *priv_data);
-+extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino,
-+				      blk_t blk, int blockcnt);
-+extern errcode_t ext2fs_copy_dblist(ext2_dblist src,
-+				    ext2_dblist *dest);
-+extern int ext2fs_dblist_count(ext2_dblist dblist);
-+
-+/* dblist_dir.c */
-+extern errcode_t
-+	ext2fs_dblist_dir_iterate(ext2_dblist dblist,
-+				  int	flags,
-+				  char	*block_buf,
-+				  int (*func)(ext2_ino_t	dir,
-+					      int		entry,
-+					      struct ext2_dir_entry *dirent,
-+					      int	offset,
-+					      int	blocksize,
-+					      char	*buf,
-+					      void	*priv_data),
-+				  void *priv_data);
-+
-+/* dirblock.c */
-+extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
-+				       void *buf);
-+extern errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
-+					void *buf, int flags);
-+extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
-+					void *buf);
-+extern errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
-+					 void *buf, int flags);
-+
-+/* dirhash.c */
-+extern errcode_t ext2fs_dirhash(int version, const char *name, int len,
-+				const __u32 *seed,
-+				ext2_dirhash_t *ret_hash,
-+				ext2_dirhash_t *ret_minor_hash);
-+
-+
-+/* dir_iterate.c */
-+extern errcode_t ext2fs_dir_iterate(ext2_filsys fs, 
-+			      ext2_ino_t dir,
-+			      int flags,
-+			      char *block_buf,
-+			      int (*func)(struct ext2_dir_entry *dirent,
-+					  int	offset,
-+					  int	blocksize,
-+					  char	*buf,
-+					  void	*priv_data),
-+			      void *priv_data);
-+extern errcode_t ext2fs_dir_iterate2(ext2_filsys fs, 
-+			      ext2_ino_t dir,
-+			      int flags,
-+			      char *block_buf,
-+			      int (*func)(ext2_ino_t	dir,
-+					  int	entry,
-+					  struct ext2_dir_entry *dirent,
-+					  int	offset,
-+					  int	blocksize,
-+					  char	*buf,
-+					  void	*priv_data),
-+			      void *priv_data);
-+
-+/* dupfs.c */
-+extern errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest);
-+
-+/* expanddir.c */
-+extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir);
-+
-+/* ext_attr.c */
-+extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
-+extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block,
-+				       void *buf);
-+extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
-+					   char *block_buf,
-+					   int adjust, __u32 *newcount);
-+
-+/* fileio.c */
-+extern errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
-+				   struct ext2_inode *inode,
-+				   int flags, ext2_file_t *ret);
-+extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
-+				  int flags, ext2_file_t *ret);
-+extern ext2_filsys ext2fs_file_get_fs(ext2_file_t file);
-+extern errcode_t ext2fs_file_close(ext2_file_t file);
-+extern errcode_t ext2fs_file_flush(ext2_file_t file);
-+extern errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
-+				  unsigned int wanted, unsigned int *got);
-+extern errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
-+				   unsigned int nbytes, unsigned int *written);
-+extern errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset,
-+				   int whence, __u64 *ret_pos);
-+extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
-+				   int whence, ext2_off_t *ret_pos);
-+errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size);
-+extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
-+extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
-+
-+/* finddev.c */
-+extern char *ext2fs_find_block_device(dev_t device);
-+
-+/* flushb.c */
-+extern errcode_t ext2fs_sync_device(int fd, int flushb);
-+
-+/* 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);
-+extern void ext2fs_free_dblist(ext2_dblist dblist);
-+extern void ext2fs_badblocks_list_free(ext2_badblocks_list bb);
-+extern void ext2fs_u32_list_free(ext2_u32_list bb);
-+
-+/* getsize.c */
-+extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
-+					blk_t *retblocks);
-+
-+/* getsectsize.c */
-+errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize);
-+
-+/* imager.c */
-+extern errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags);
-+extern errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, int flags);
-+extern errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, int flags);
-+extern errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, int flags);
-+extern errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags);
-+extern errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags);
-+
-+/* ind_block.c */
-+errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf);
-+errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf);
-+
-+/* initialize.c */
-+extern errcode_t ext2fs_initialize(const char *name, int flags,
-+				   struct ext2_super_block *param,
-+				   io_manager manager, ext2_filsys *ret_fs);
-+
-+/* icount.c */
-+extern void ext2fs_free_icount(ext2_icount_t icount);
-+extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, 
-+				       unsigned int size,
-+				       ext2_icount_t hint, ext2_icount_t *ret);
-+extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, 
-+				      unsigned int size,
-+				      ext2_icount_t *ret);
-+extern errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino,
-+				     __u16 *ret);
-+extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
-+					 __u16 *ret);
-+extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
-+					 __u16 *ret);
-+extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
-+				     __u16 count);
-+extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
-+errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
-+
-+/* inode.c */
-+extern errcode_t ext2fs_flush_icache(ext2_filsys fs);
-+extern errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan, 
-+					    ext2_ino_t *ino,
-+					    struct ext2_inode *inode, 
-+					    int bufsize);
-+extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
-+				  ext2_inode_scan *ret_scan);
-+extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
-+extern errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
-+			       struct ext2_inode *inode);
-+extern errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
-+						   int	group);
-+extern void ext2fs_set_inode_callback
-+	(ext2_inode_scan scan,
-+	 errcode_t (*done_group)(ext2_filsys fs,
-+				 ext2_inode_scan scan,
-+				 dgrp_t group,
-+				 void * priv_data),
-+	 void *done_group_data);
-+extern int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
-+				   int clear_flags);
-+extern errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
-+					struct ext2_inode * inode, 
-+					int bufsize);
-+extern errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
-+			    struct ext2_inode * inode);
-+extern errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
-+					 struct ext2_inode * inode, 
-+					 int bufsize);
-+extern errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
-+			    struct ext2_inode * inode);
-+extern errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
-+			    struct ext2_inode * inode);
-+extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
-+extern errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino);
-+
-+/* inode_io.c */
-+extern io_manager inode_io_manager;
-+extern errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino, 
-+					char **name);
-+extern errcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
-+					 struct ext2_inode *inode,
-+					 char **name);
-+	
-+/* ismounted.c */
-+extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
-+extern errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
-+					  char *mtpt, int mtlen);
-+
-+/* namei.c */
-+extern errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
-+			 int namelen, char *buf, ext2_ino_t *inode);
-+extern errcode_t ext2fs_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+			const char *name, ext2_ino_t *inode);
-+errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+			      const char *name, ext2_ino_t *inode);
-+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+			ext2_ino_t inode, ext2_ino_t *res_inode);
-+
-+/* native.c */
-+int ext2fs_native_flag(void);
-+
-+/* newdir.c */
-+extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
-+				ext2_ino_t parent_ino, char **block);
-+
-+/* mkdir.c */
-+extern errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
-+			      const char *name);
-+
-+/* mkjournal.c */
-+extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
-+						  __u32 size, int flags,
-+						  char  **ret_jsb);
-+extern errcode_t ext2fs_add_journal_device(ext2_filsys fs,
-+					   ext2_filsys journal_dev);
-+extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size,
-+					  int flags);
-+
-+/* openfs.c */
-+extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
-+			     unsigned int block_size, io_manager manager,
-+			     ext2_filsys *ret_fs);
-+extern errcode_t ext2fs_open2(const char *name, const char *io_options, 
-+			      int flags, int superblock, 
-+			      unsigned int block_size, io_manager manager,
-+			      ext2_filsys *ret_fs);
-+extern blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, 
-+					 dgrp_t i);
-+errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io);
-+errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
-+errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
-+
-+/* get_pathname.c */
-+extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
-+			       char **name);
-+
-+/* link.c */
-+errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
-+		      ext2_ino_t ino, int flags);
-+errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
-+			ext2_ino_t ino, int flags);
-+
-+/* read_bb.c */
-+extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
-+				      ext2_badblocks_list *bb_list);
-+
-+/* read_bb_file.c */
-+extern errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f, 
-+				      ext2_badblocks_list *bb_list,
-+				      void *priv_data,
-+				      void (*invalid)(ext2_filsys fs,
-+						      blk_t blk,
-+						      char *badstr,
-+						      void *priv_data));
-+extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f, 
-+				     ext2_badblocks_list *bb_list,
-+				     void (*invalid)(ext2_filsys fs,
-+						     blk_t blk));
-+
-+/* res_gdt.c */
-+extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs);
-+
-+/* rs_bitmap.c */
-+extern errcode_t ext2fs_resize_generic_bitmap(__u32 new_end,
-+					      __u32 new_real_end,
-+					      ext2fs_generic_bitmap bmap);
-+extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
-+					    ext2fs_inode_bitmap bmap);
-+extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
-+					    ext2fs_block_bitmap bmap);
-+extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
-+				    ext2fs_generic_bitmap *dest);
-+
-+/* swapfs.c */
-+extern void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, 
-+				 int has_header);
-+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_full(ext2_filsys fs, struct ext2_inode_large *t,
-+				   struct ext2_inode_large *f, int hostorder,
-+				   int bufsize);
-+extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
-+			      struct ext2_inode *f, int hostorder);
-+
-+/* valid_blk.c */
-+extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
-+
-+/* version.c */
-+extern int ext2fs_parse_version_string(const char *ver_string);
-+extern int ext2fs_get_library_version(const char **ver_string,
-+				      const char **date_string);
-+
-+/* write_bb_file.c */
-+extern errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
-+				      unsigned int flags,
-+				      FILE *f);
-+
-+
-+/* inline functions */
-+extern errcode_t ext2fs_get_mem(unsigned long size, void *ptr);
-+extern errcode_t ext2fs_free_mem(void *ptr);
-+extern errcode_t ext2fs_resize_mem(unsigned long old_size,
-+				   unsigned long size, void *ptr);
-+extern void ext2fs_mark_super_dirty(ext2_filsys fs);
-+extern void ext2fs_mark_changed(ext2_filsys fs);
-+extern int ext2fs_test_changed(ext2_filsys fs);
-+extern void ext2fs_mark_valid(ext2_filsys fs);
-+extern void ext2fs_unmark_valid(ext2_filsys fs);
-+extern int ext2fs_test_valid(ext2_filsys fs);
-+extern void ext2fs_mark_ib_dirty(ext2_filsys fs);
-+extern void ext2fs_mark_bb_dirty(ext2_filsys fs);
-+extern int ext2fs_test_ib_dirty(ext2_filsys fs);
-+extern int ext2fs_test_bb_dirty(ext2_filsys fs);
-+extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
-+extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino);
-+extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
-+				      struct ext2_inode *inode);
-+
-+/*
-+ * The actual inlined functions definitions themselves...
-+ *
-+ * If NO_INLINE_FUNCS is defined, then we won't try to do inline
-+ * functions at all!
-+ */
-+#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
-+#ifdef INCLUDE_INLINE_FUNCS
-+#define _INLINE_ extern
-+#else
-+#ifdef __GNUC__
-+#define _INLINE_ extern __inline__
-+#else				/* For Watcom C */
-+#define _INLINE_ extern inline
-+#endif
-+#endif
-+
-+#ifndef EXT2_CUSTOM_MEMORY_ROUTINES
-+/*
-+ *  Allocate memory
-+ */
-+_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
-+{
-+	void **pp = (void **)ptr;
-+
-+	*pp = malloc(size);
-+	if (!*pp)
-+		return EXT2_ET_NO_MEMORY;
-+	return 0;
-+}
-+
-+/*
-+ * Free memory
-+ */
-+_INLINE_ errcode_t ext2fs_free_mem(void *ptr)
-+{
-+	void **pp = (void **)ptr;
-+
-+	free(*pp);
-+	*pp = 0;
-+	return 0;
-+}
-+	
-+/*
-+ *  Resize memory
-+ */
-+_INLINE_ errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_size,
-+				     unsigned long size, void *ptr)
-+{
-+	void *p;
-+
-+	/* Use "memcpy" for pointer assignments here to avoid problems
-+	 * with C99 strict type aliasing rules. */
-+	memcpy(&p, ptr, sizeof (p));
-+	p = realloc(p, size);
-+	if (!p)
-+		return EXT2_ET_NO_MEMORY;
-+	memcpy(ptr, &p, sizeof (p));
-+	return 0;
-+}
-+#endif	/* Custom memory routines */
-+
-+/*
-+ * Mark a filesystem superblock as dirty
-+ */
-+_INLINE_ void ext2fs_mark_super_dirty(ext2_filsys fs)
-+{
-+	fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
-+}
-+
-+/*
-+ * Mark a filesystem as changed
-+ */
-+_INLINE_ void ext2fs_mark_changed(ext2_filsys fs)
-+{
-+	fs->flags |= EXT2_FLAG_CHANGED;
-+}
-+
-+/*
-+ * Check to see if a filesystem has changed
-+ */
-+_INLINE_ int ext2fs_test_changed(ext2_filsys fs)
-+{
-+	return (fs->flags & EXT2_FLAG_CHANGED);
-+}
-+
-+/*
-+ * Mark a filesystem as valid
-+ */
-+_INLINE_ void ext2fs_mark_valid(ext2_filsys fs)
-+{
-+	fs->flags |= EXT2_FLAG_VALID;
-+}
-+
-+/*
-+ * Mark a filesystem as NOT valid
-+ */
-+_INLINE_ void ext2fs_unmark_valid(ext2_filsys fs)
-+{
-+	fs->flags &= ~EXT2_FLAG_VALID;
-+}
-+
-+/*
-+ * Check to see if a filesystem is valid
-+ */
-+_INLINE_ int ext2fs_test_valid(ext2_filsys fs)
-+{
-+	return (fs->flags & EXT2_FLAG_VALID);
-+}
-+
-+/*
-+ * Mark the inode bitmap as dirty
-+ */
-+_INLINE_ void ext2fs_mark_ib_dirty(ext2_filsys fs)
-+{
-+	fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
-+}
-+
-+/*
-+ * Mark the block bitmap as dirty
-+ */
-+_INLINE_ void ext2fs_mark_bb_dirty(ext2_filsys fs)
-+{
-+	fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
-+}
-+
-+/*
-+ * Check to see if a filesystem's inode bitmap is dirty
-+ */
-+_INLINE_ int ext2fs_test_ib_dirty(ext2_filsys fs)
-+{
-+	return (fs->flags & EXT2_FLAG_IB_DIRTY);
-+}
-+
-+/*
-+ * Check to see if a filesystem's block bitmap is dirty
-+ */
-+_INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs)
-+{
-+	return (fs->flags & EXT2_FLAG_BB_DIRTY);
-+}
-+
-+/*
-+ * Return the group # of a block
-+ */
-+_INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
-+{
-+	return (blk - fs->super->s_first_data_block) /
-+		fs->super->s_blocks_per_group;
-+}
-+
-+/*
-+ * Return the group # of an inode number
-+ */
-+_INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
-+{
-+	return (ino - 1) / fs->super->s_inodes_per_group;
-+}
-+
-+_INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
-+					struct ext2_inode *inode)
-+{
-+       return inode->i_blocks -
-+              (inode->i_file_acl ? fs->blocksize >> 9 : 0);
-+}
-+#undef _INLINE_
-+#endif
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _EXT2FS_EXT2FS_H */
-diff -Naur silo-1.4.14.orig/libext2fs/ext2fsP.h silo-1.4.14/libext2fs/ext2fsP.h
---- silo-1.4.14.orig/libext2fs/ext2fsP.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/ext2fsP.h	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,88 @@
-+/*
-+ * ext2fsP.h --- private header file for ext2 library
-+ * 
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include "ext2fs.h"
-+
-+/*
-+ * Badblocks list
-+ */
-+struct ext2_struct_u32_list {
-+	int	magic;
-+	int	num;
-+	int	size;
-+	__u32	*list;
-+	int	badblocks_flags;
-+};
-+
-+struct ext2_struct_u32_iterate {
-+	int			magic;
-+	ext2_u32_list		bb;
-+	int			ptr;
-+};
-+
-+
-+/*
-+ * Directory block iterator definition
-+ */
-+struct ext2_struct_dblist {
-+	int			magic;
-+	ext2_filsys		fs;
-+	ext2_ino_t		size;
-+	ext2_ino_t		count;
-+	int			sorted;
-+	struct ext2_db_entry *	list;
-+};
-+
-+/*
-+ * For directory iterators
-+ */
-+struct dir_context {
-+	ext2_ino_t		dir;
-+	int		flags;
-+	char		*buf;
-+	int (*func)(ext2_ino_t	dir,
-+		    int	entry,
-+		    struct ext2_dir_entry *dirent,
-+		    int	offset,
-+		    int	blocksize,
-+		    char	*buf,
-+		    void	*priv_data);
-+	void		*priv_data;
-+	errcode_t	errcode;
-+};
-+
-+/*
-+ * Inode cache structure
-+ */
-+struct ext2_inode_cache {
-+	void *				buffer;
-+	blk_t				buffer_blk;
-+	int				cache_last;
-+	int				cache_size;
-+	int				refcount;
-+	struct ext2_inode_cache_ent	*cache;
-+};
-+
-+struct ext2_inode_cache_ent {
-+	ext2_ino_t		ino;
-+	struct ext2_inode	inode;
-+};
-+
-+/* Function prototypes */
-+
-+extern int ext2fs_process_dir_block(ext2_filsys  	fs,
-+				    blk_t		*blocknr,
-+				    e2_blkcnt_t		blockcnt,
-+				    blk_t		ref_block,
-+				    int			ref_offset,
-+				    void		*priv_data);
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/ext_attr.c silo-1.4.14/libext2fs/ext_attr.c
---- silo-1.4.14.orig/libext2fs/ext_attr.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/ext_attr.c	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,105 @@
-+/*
-+ * ext_attr.c --- extended attribute blocks
-+ * 
-+ * Copyright (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Copyright (C) 2002 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2_ext_attr.h"
-+
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf)
-+{
-+	errcode_t	retval;
-+
-+ 	retval = io_channel_read_blk(fs->io, block, 1, buf);
-+	if (retval)
-+		return retval;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if ((fs->flags & (EXT2_FLAG_SWAP_BYTES|
-+			  EXT2_FLAG_SWAP_BYTES_READ)) != 0)
-+		ext2fs_swap_ext_attr(buf, buf, fs->blocksize, 1);
-+#endif
-+	return 0;
-+}
-+
-+errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *inbuf)
-+{
-+	errcode_t	retval;
-+	char		*write_buf;
-+	char		*buf = NULL;
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+	    (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) {
-+		retval = ext2fs_get_mem(fs->blocksize, &buf);
-+		if (retval)
-+			return retval;
-+		write_buf = buf;
-+		ext2fs_swap_ext_attr(buf, inbuf, fs->blocksize, 1);
-+	} else
-+#endif
-+		write_buf = (char *) inbuf;
-+ 	retval = io_channel_write_blk(fs->io, block, 1, write_buf);
-+	if (buf)
-+		ext2fs_free_mem(&buf);
-+	if (!retval)
-+		ext2fs_mark_changed(fs);
-+	return retval;
-+}
-+
-+/*
-+ * This function adjusts the reference count of the EA block.
-+ */
-+errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
-+				    char *block_buf, int adjust,
-+				    __u32 *newcount)
-+{
-+	errcode_t	retval;
-+	struct ext2_ext_attr_header *header;
-+	char	*buf = 0;
-+
-+	if ((blk >= fs->super->s_blocks_count) ||
-+	    (blk < fs->super->s_first_data_block))
-+		return EXT2_ET_BAD_EA_BLOCK_NUM;
-+
-+	if (!block_buf) {
-+		retval = ext2fs_get_mem(fs->blocksize, &buf);
-+		if (retval)
-+			return retval;
-+		block_buf = buf;
-+	}
-+
-+	retval = ext2fs_read_ext_attr(fs, blk, block_buf);
-+	if (retval)
-+		goto errout;
-+
-+	header = (struct ext2_ext_attr_header *) block_buf;
-+	header->h_refcount += adjust;
-+	if (newcount)
-+		*newcount = header->h_refcount;
-+
-+	retval = ext2fs_write_ext_attr(fs, blk, block_buf);
-+	if (retval)
-+		goto errout;
-+
-+errout:
-+	if (buf)
-+		ext2fs_free_mem(&buf);
-+	return retval;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/fileio.c silo-1.4.14/libext2fs/fileio.c
---- silo-1.4.14.orig/libext2fs/fileio.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/fileio.c	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,378 @@
-+/*
-+ * fileio.c --- Simple file I/O routines
-+ * 
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct ext2_file {
-+	errcode_t		magic;
-+	ext2_filsys 		fs;
-+	ext2_ino_t		ino;
-+	struct ext2_inode	inode;
-+	int 			flags;
-+	__u64			pos;
-+	blk_t			blockno;
-+	blk_t			physblock;
-+	char 			*buf;
-+};
-+
-+#define BMAP_BUFFER (file->buf + fs->blocksize)
-+
-+errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
-+			    struct ext2_inode *inode,
-+			    int flags, ext2_file_t *ret)
-+{
-+	ext2_file_t 	file;
-+	errcode_t	retval;
-+
-+	/*
-+	 * Don't let caller create or open a file for writing if the
-+	 * filesystem is read-only.
-+	 */
-+	if ((flags & (EXT2_FILE_WRITE | EXT2_FILE_CREATE)) &&
-+	    !(fs->flags & EXT2_FLAG_RW))
-+		return EXT2_ET_RO_FILSYS;
-+
-+	retval = ext2fs_get_mem(sizeof(struct ext2_file), &file);
-+	if (retval)
-+		return retval;
-+	
-+	memset(file, 0, sizeof(struct ext2_file));
-+	file->magic = EXT2_ET_MAGIC_EXT2_FILE;
-+	file->fs = fs;
-+	file->ino = ino;
-+	file->flags = flags & EXT2_FILE_MASK;
-+
-+	if (inode) {
-+		memcpy(&file->inode, inode, sizeof(struct ext2_inode));
-+	} else {
-+		retval = ext2fs_read_inode(fs, ino, &file->inode);
-+		if (retval)
-+			goto fail;
-+	}
-+	
-+	retval = ext2fs_get_mem(fs->blocksize * 3, &file->buf);
-+	if (retval)
-+		goto fail;
-+
-+	*ret = file;
-+	return 0;
-+	
-+fail:
-+	if (file->buf)
-+		ext2fs_free_mem(&file->buf);
-+	ext2fs_free_mem(&file);
-+	return retval;
-+}
-+
-+errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
-+			   int flags, ext2_file_t *ret)
-+{
-+	return ext2fs_file_open2(fs, ino, NULL, flags, ret);
-+}
-+
-+/*
-+ * This function returns the filesystem handle of a file from the structure
-+ */
-+ext2_filsys ext2fs_file_get_fs(ext2_file_t file)
-+{
-+	if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
-+		return 0;
-+	return file->fs;
-+}
-+
-+/*
-+ * This function flushes the dirty block buffer out to disk if
-+ * necessary.
-+ */
-+errcode_t ext2fs_file_flush(ext2_file_t file)
-+{
-+	errcode_t	retval;
-+	ext2_filsys fs;
-+	
-+	EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+	fs = file->fs;
-+
-+	if (!(file->flags & EXT2_FILE_BUF_VALID) ||
-+	    !(file->flags & EXT2_FILE_BUF_DIRTY))
-+		return 0;
-+
-+	/*
-+	 * OK, the physical block hasn't been allocated yet.
-+	 * Allocate it.
-+	 */
-+	if (!file->physblock) {
-+		retval = ext2fs_bmap(fs, file->ino, &file->inode,
-+				     BMAP_BUFFER, file->ino ? BMAP_ALLOC : 0,
-+				     file->blockno, &file->physblock);
-+		if (retval)
-+			return retval;
-+	}
-+
-+	retval = io_channel_write_blk(fs->io, file->physblock,
-+				      1, file->buf);
-+	if (retval)
-+		return retval;
-+
-+	file->flags &= ~EXT2_FILE_BUF_DIRTY;
-+
-+	return retval;
-+}
-+
-+/*
-+ * This function synchronizes the file's block buffer and the current
-+ * file position, possibly invalidating block buffer if necessary
-+ */
-+static errcode_t sync_buffer_position(ext2_file_t file)
-+{
-+	blk_t	b;
-+	errcode_t	retval;
-+
-+	b = file->pos / file->fs->blocksize;
-+	if (b != file->blockno) {
-+		retval = ext2fs_file_flush(file);
-+		if (retval)
-+			return retval;
-+		file->flags &= ~EXT2_FILE_BUF_VALID;
-+	}
-+	file->blockno = b;
-+	return 0;
-+}
-+
-+/*
-+ * This function loads the file's block buffer with valid data from
-+ * the disk as necessary.
-+ *
-+ * If dontfill is true, then skip initializing the buffer since we're
-+ * going to be replacing its entire contents anyway.  If set, then the
-+ * function basically only sets file->physblock and EXT2_FILE_BUF_VALID
-+ */
-+#define DONTFILL 1
-+static errcode_t load_buffer(ext2_file_t file, int dontfill)
-+{
-+	ext2_filsys	fs = file->fs;
-+	errcode_t	retval;
-+
-+	if (!(file->flags & EXT2_FILE_BUF_VALID)) {
-+		retval = ext2fs_bmap(fs, file->ino, &file->inode,
-+				     BMAP_BUFFER, 0, file->blockno,
-+				     &file->physblock);
-+		if (retval)
-+			return retval;
-+		if (!dontfill) {
-+			if (file->physblock) {
-+				retval = io_channel_read_blk(fs->io,
-+							     file->physblock, 
-+							     1, file->buf);
-+				if (retval)
-+					return retval;
-+			} else
-+				memset(file->buf, 0, fs->blocksize);
-+		}
-+		file->flags |= EXT2_FILE_BUF_VALID;
-+	}
-+	return 0;
-+}
-+	
-+
-+errcode_t ext2fs_file_close(ext2_file_t file)
-+{
-+	errcode_t	retval;
-+	
-+	EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+
-+	retval = ext2fs_file_flush(file);
-+	
-+	if (file->buf)
-+		ext2fs_free_mem(&file->buf);
-+	ext2fs_free_mem(&file);
-+
-+	return retval;
-+}
-+
-+
-+errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
-+			   unsigned int wanted, unsigned int *got)
-+{
-+	ext2_filsys	fs;
-+	errcode_t	retval = 0;
-+	unsigned int	start, c, count = 0;
-+	__u64		left;
-+	char		*ptr = (char *) buf;
-+
-+	EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+	fs = file->fs;
-+
-+	while ((file->pos < EXT2_I_SIZE(&file->inode)) && (wanted > 0)) {
-+		retval = sync_buffer_position(file);
-+		if (retval)
-+			goto fail;
-+		retval = load_buffer(file, 0);
-+		if (retval)
-+			goto fail;
-+
-+		start = file->pos % fs->blocksize;
-+		c = fs->blocksize - start;
-+		if (c > wanted)
-+			c = wanted;
-+		left = EXT2_I_SIZE(&file->inode) - file->pos ;
-+		if (c > left)
-+			c = left;
-+	
-+		memcpy(ptr, file->buf+start, c);
-+		file->pos += c;
-+		ptr += c;
-+		count += c;
-+		wanted -= c;
-+	}
-+	
-+fail:
-+	if (got)
-+		*got = count;
-+	return retval;
-+}
-+
-+
-+errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
-+			    unsigned int nbytes, unsigned int *written)
-+{
-+	ext2_filsys	fs;
-+	errcode_t	retval = 0;
-+	unsigned int	start, c, count = 0;
-+	const char	*ptr = (const char *) buf;
-+
-+	EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+	fs = file->fs;
-+
-+	if (!(file->flags & EXT2_FILE_WRITE))
-+		return EXT2_ET_FILE_RO;
-+
-+	while (nbytes > 0) {
-+		retval = sync_buffer_position(file);
-+		if (retval)
-+			goto fail;
-+		
-+		start = file->pos % fs->blocksize;
-+		c = fs->blocksize - start;
-+		if (c > nbytes)
-+			c = nbytes;
-+
-+		/*
-+		 * We only need to do a read-modify-update cycle if
-+		 * we're doing a partial write.
-+		 */
-+		retval = load_buffer(file, (c == fs->blocksize));
-+		if (retval)
-+			goto fail;
-+
-+		file->flags |= EXT2_FILE_BUF_DIRTY;
-+		memcpy(file->buf+start, ptr, c);
-+		file->pos += c;
-+		ptr += c;
-+		count += c;
-+		nbytes -= c;
-+	}
-+	
-+fail:
-+	if (written)
-+		*written = count;
-+	return retval;
-+}
-+
-+errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset,
-+			    int whence, __u64 *ret_pos)
-+{
-+	EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+
-+	if (whence == EXT2_SEEK_SET)
-+		file->pos = offset;
-+	else if (whence == EXT2_SEEK_CUR)
-+		file->pos += offset;
-+	else if (whence == EXT2_SEEK_END)
-+		file->pos = EXT2_I_SIZE(&file->inode) + offset;
-+	else
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	if (ret_pos)
-+		*ret_pos = file->pos;
-+
-+	return 0;
-+}
-+
-+errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
-+			    int whence, ext2_off_t *ret_pos)
-+{
-+	__u64		loffset, ret_loffset;
-+	errcode_t	retval;
-+	
-+	loffset = offset;
-+	retval = ext2fs_file_llseek(file, loffset, whence, &ret_loffset);
-+	if (ret_pos)
-+		*ret_pos = (ext2_off_t) ret_loffset;
-+	return retval;
-+}
-+
-+
-+/*
-+ * This function returns the size of the file, according to the inode
-+ */
-+errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size)
-+{
-+	if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
-+		return EXT2_ET_MAGIC_EXT2_FILE;
-+	*ret_size = EXT2_I_SIZE(&file->inode);
-+	return 0;
-+}
-+
-+/*
-+ * This function returns the size of the file, according to the inode
-+ */
-+ext2_off_t ext2fs_file_get_size(ext2_file_t file)
-+{
-+	__u64	size;
-+
-+	if (ext2fs_file_get_lsize(file, &size))
-+		return 0;
-+	if ((size >> 32) != 0)
-+		return 0;
-+	return size;
-+}
-+
-+/*
-+ * This function sets the size of the file, truncating it if necessary
-+ * 
-+ * XXX still need to call truncate
-+ */
-+errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size)
-+{
-+	errcode_t	retval;
-+	EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+	
-+	file->inode.i_size = size;
-+	file->inode.i_size_high = 0;
-+	if (file->ino) {
-+		retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
-+		if (retval)
-+			return retval;
-+	}
-+
-+	/* 
-+	 * XXX truncate inode if necessary
-+	 */
-+
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/finddev.c silo-1.4.14/libext2fs/finddev.c
---- silo-1.4.14.orig/libext2fs/finddev.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/finddev.c	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,208 @@
-+/*
-+ * finddev.c -- this routine attempts to find a particular device in
-+ * 	/dev
-+ * 
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <stdlib.h>
-+#include <string.h>
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#include <dirent.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_SYS_MKDEV_H
-+#include <sys/mkdev.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct dir_list {
-+	char	*name;
-+	struct dir_list *next;
-+};
-+
-+/*
-+ * This function adds an entry to the directory list
-+ */
-+static void add_to_dirlist(const char *name, struct dir_list **list)
-+{
-+	struct dir_list *dp;
-+
-+	dp = malloc(sizeof(struct dir_list));
-+	if (!dp)
-+		return;
-+	dp->name = malloc(strlen(name)+1);
-+	if (!dp->name) {
-+		free(dp);
-+		return;
-+	}
-+	strcpy(dp->name, name);
-+	dp->next = *list;
-+	*list = dp;
-+}
-+
-+/*
-+ * This function frees a directory list
-+ */
-+static void free_dirlist(struct dir_list **list)
-+{
-+	struct dir_list *dp, *next;
-+
-+	for (dp = *list; dp; dp = next) {
-+		next = dp->next;
-+		free(dp->name);
-+		free(dp);
-+	}
-+	*list = 0;
-+}
-+
-+static int scan_dir(char *dirname, dev_t device, struct dir_list **list,
-+		    char **ret_path)
-+{
-+	DIR	*dir;
-+	struct dirent *dp;
-+	char	path[1024], *cp;
-+	int	dirlen;
-+	struct stat st;
-+
-+	dirlen = strlen(dirname);
-+	if ((dir = opendir(dirname)) == NULL)
-+		return errno;
-+	dp = readdir(dir);
-+	while (dp) {
-+		if (dirlen + strlen(dp->d_name) + 2 >= sizeof(path))
-+			goto skip_to_next;
-+		if (dp->d_name[0] == '.' &&
-+		    ((dp->d_name[1] == 0) ||
-+		     ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
-+			goto skip_to_next;
-+		sprintf(path, "%s/%s", dirname, dp->d_name);
-+		if (stat(path, &st) < 0)
-+			goto skip_to_next;
-+		if (S_ISDIR(st.st_mode))
-+			add_to_dirlist(path, list);
-+		if (S_ISBLK(st.st_mode) && st.st_rdev == device) {
-+			cp = malloc(strlen(path)+1);
-+			if (!cp) {
-+				closedir(dir);
-+				return ENOMEM;
-+			}
-+			strcpy(cp, path);
-+			*ret_path = cp;
-+			goto success;
-+		}
-+	skip_to_next:
-+		dp = readdir(dir);
-+	}
-+success:
-+	closedir(dir);
-+	return 0;
-+}
-+
-+/*
-+ * This function finds the pathname to a block device with a given
-+ * device number.  It returns a pointer to allocated memory to the
-+ * pathname on success, and NULL on failure.
-+ */
-+char *ext2fs_find_block_device(dev_t device)
-+{
-+	struct dir_list *list = 0, *new_list = 0;
-+	struct dir_list *current;
-+	char	*ret_path = 0;
-+
-+	/*
-+	 * Add the starting directories to search...
-+	 */
-+	add_to_dirlist("/devices", &list);
-+	add_to_dirlist("/devfs", &list);
-+	add_to_dirlist("/dev", &list);
-+	
-+	while (list) {
-+		current = list;
-+		list = list->next;
-+#ifdef DEBUG
-+		printf("Scanning directory %s\n", current->name);
-+#endif
-+		scan_dir(current->name, device, &new_list, &ret_path);
-+		free(current->name);
-+		free(current);
-+		if (ret_path)
-+			break;
-+		/*
-+		 * If we're done checking at this level, descend to
-+		 * the next level of subdirectories. (breadth-first)
-+		 */
-+		if (list == 0) {
-+			list = new_list;
-+			new_list = 0;
-+		}
-+	}
-+	free_dirlist(&list);
-+	free_dirlist(&new_list);
-+	return ret_path;
-+}
-+
-+	
-+#ifdef DEBUG
-+int main(int argc, char** argv)
-+{
-+	char	*devname, *tmp;
-+	int	major, minor;
-+	dev_t	device;
-+	const char *errmsg = "Couldn't parse %s: %s\n";
-+
-+	if ((argc != 2) && (argc != 3)) {
-+		fprintf(stderr, "Usage: %s device_number\n", argv[0]);
-+		fprintf(stderr, "\t: %s major minor\n", argv[0]);
-+		exit(1);
-+	}
-+	if (argc == 2) {
-+		device = strtoul(argv[1], &tmp, 0);
-+		if (*tmp) {
-+			fprintf(stderr, errmsg, "device number", argv[1]);
-+			exit(1);
-+		}
-+	} else {
-+		major = strtoul(argv[1], &tmp, 0);
-+		if (*tmp) {
-+			fprintf(stderr, errmsg, "major number", argv[1]);
-+			exit(1);
-+		}
-+		minor = strtoul(argv[2], &tmp, 0);
-+		if (*tmp) {
-+			fprintf(stderr, errmsg, "minor number", argv[2]);
-+			exit(1);
-+		}
-+		device = makedev(major, minor);
-+		printf("Looking for device 0x%04x (%d:%d)\n", device,
-+		       major, minor);
-+	}
-+	devname = ext2fs_find_block_device(device);
-+	if (devname) {
-+		printf("Found device!  %s\n", devname);
-+		free(devname);
-+	} else {
-+		printf("Couldn't find device.\n");
-+	}
-+	return 0;
-+}
-+	
-+#endif
-diff -Naur silo-1.4.14.orig/libext2fs/flushb.c silo-1.4.14/libext2fs/flushb.c
---- silo-1.4.14.orig/libext2fs/flushb.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/flushb.c	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,82 @@
-+/*
-+ * flushb.c --- Hides system-dependent information for both syncing a
-+ * 	device to disk and to flush any buffers from disk cache.
-+ * 
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_SYS_IOCTL_H
-+#include <sys/ioctl.h>
-+#endif
-+#if HAVE_SYS_MOUNT_H
-+#include <sys/param.h>
-+#include <sys/mount.h>		/* This may define BLKFLSBUF */
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * For Linux, define BLKFLSBUF and FDFLUSH if necessary, since 
-+ * not all portable header file does so for us.  This really should be
-+ * fixed in the glibc header files.  (Recent glibcs appear to define
-+ * BLKFLSBUF in sys/mount.h, but FDFLUSH still doesn't seem to be
-+ * defined anywhere portable.)  Until then....
-+ */
-+#ifdef __linux__
-+#ifndef BLKFLSBUF
-+#define BLKFLSBUF	_IO(0x12,97)	/* flush buffer cache */
-+#endif
-+#ifndef FDFLUSH
-+#define FDFLUSH		_IO(2,0x4b)	/* flush floppy disk */
-+#endif
-+#endif
-+
-+/*
-+ * This function will sync a device/file, and optionally attempt to
-+ * flush the buffer cache.  The latter is basically only useful for
-+ * system benchmarks and for torturing systems in burn-in tests.  :)
-+ */
-+errcode_t ext2fs_sync_device(int fd, int flushb)
-+{
-+	/*
-+	 * We always sync the device in case we're running on old
-+	 * kernels for which we can lose data if we don't.  (There
-+	 * still is a race condition for those kernels, but this
-+	 * reduces it greatly.)
-+	 */
-+	if (fsync (fd) == -1)
-+		return errno;
-+
-+	if (flushb) {
-+
-+#ifdef BLKFLSBUF
-+		if (ioctl (fd, BLKFLSBUF, 0) == 0)
-+			return 0;
-+#else
-+#ifdef __GNUC__
-+ #warning BLKFLSBUF not defined
-+#endif /* __GNUC__ */
-+#endif
-+#ifdef FDFLUSH
-+		ioctl (fd, FDFLUSH, 0);   /* In case this is a floppy */
-+#else
-+#ifdef __GNUC__
-+ #warning FDFLUSH not defined
-+#endif /* __GNUC__ */
-+#endif
-+	}
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/freefs.c silo-1.4.14/libext2fs/freefs.c
---- silo-1.4.14.orig/libext2fs/freefs.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/freefs.c	2011-01-10 21:59:35.414677086 -0500
-@@ -0,0 +1,147 @@
-+/*
-+ * freefs.c --- free an ext2 filesystem
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache);
-+
-+void ext2fs_free(ext2_filsys fs)
-+{
-+	if (!fs || (fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS))
-+		return;
-+	if (fs->image_io != fs->io) {
-+		if (fs->image_io)
-+			io_channel_close(fs->image_io);
-+	}
-+	if (fs->io) {
-+		io_channel_close(fs->io);
-+	}
-+	if (fs->device_name)
-+		ext2fs_free_mem(&fs->device_name);
-+	if (fs->super)
-+		ext2fs_free_mem(&fs->super);
-+	if (fs->orig_super)
-+		ext2fs_free_mem(&fs->orig_super);
-+	if (fs->group_desc)
-+		ext2fs_free_mem(&fs->group_desc);
-+	if (fs->block_map)
-+		ext2fs_free_block_bitmap(fs->block_map);
-+	if (fs->inode_map)
-+		ext2fs_free_inode_bitmap(fs->inode_map);
-+
-+	if (fs->badblocks)
-+		ext2fs_badblocks_list_free(fs->badblocks);
-+	fs->badblocks = 0;
-+
-+	if (fs->dblist)
-+		ext2fs_free_dblist(fs->dblist);
-+
-+	if (fs->icache)
-+		ext2fs_free_inode_cache(fs->icache);
-+	
-+	fs->magic = 0;
-+
-+	ext2fs_free_mem(&fs);
-+}
-+
-+void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
-+{
-+	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_GENERIC_BITMAP))
-+		return;
-+
-+	bitmap->magic = 0;
-+	if (bitmap->description) {
-+		ext2fs_free_mem(&bitmap->description);
-+		bitmap->description = 0;
-+	}
-+	if (bitmap->bitmap) {
-+		ext2fs_free_mem(&bitmap->bitmap);
-+		bitmap->bitmap = 0;
-+	}
-+	ext2fs_free_mem(&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 = EXT2_ET_MAGIC_GENERIC_BITMAP;
-+	ext2fs_free_generic_bitmap(bitmap);
-+}
-+
-+/*
-+ * Free the inode cache structure
-+ */
-+static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache)
-+{
-+	if (--icache->refcount)
-+		return;
-+	if (icache->buffer)
-+		ext2fs_free_mem(&icache->buffer);
-+	if (icache->cache)
-+		ext2fs_free_mem(&icache->cache);
-+	icache->buffer_blk = 0;
-+	ext2fs_free_mem(&icache);
-+}
-+
-+/*
-+ * This procedure frees a badblocks list.
-+ */
-+void ext2fs_u32_list_free(ext2_u32_list bb)
-+{
-+	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
-+		return;
-+
-+	if (bb->list)
-+		ext2fs_free_mem(&bb->list);
-+	bb->list = 0;
-+	ext2fs_free_mem(&bb);
-+}
-+
-+void ext2fs_badblocks_list_free(ext2_badblocks_list bb)
-+{
-+	ext2fs_u32_list_free((ext2_u32_list) bb);
-+}
-+
-+
-+/*
-+ * Free a directory block list
-+ */
-+void ext2fs_free_dblist(ext2_dblist dblist)
-+{
-+	if (!dblist || (dblist->magic != EXT2_ET_MAGIC_DBLIST))
-+		return;
-+
-+	if (dblist->list)
-+		ext2fs_free_mem(&dblist->list);
-+	dblist->list = 0;
-+	if (dblist->fs && dblist->fs->dblist == dblist)
-+		dblist->fs->dblist = 0;
-+	dblist->magic = 0;
-+	ext2fs_free_mem(&dblist);
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/gen_bitmap.c silo-1.4.14/libext2fs/gen_bitmap.c
---- silo-1.4.14.orig/libext2fs/gen_bitmap.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/gen_bitmap.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,48 @@
-+/*
-+ * gen_bitmap.c --- Generic bitmap routines that used to be inlined.
-+ * 
-+ * Copyright (C) 2001 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+int 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 0;
-+	}
-+	return ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
-+}
-+
-+int 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 0;
-+	}
-+	return ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/get_pathname.c silo-1.4.14/libext2fs/get_pathname.c
---- silo-1.4.14.orig/libext2fs/get_pathname.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/get_pathname.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,157 @@
-+/*
-+ * get_pathname.c --- do directry/inode -> name translation
-+ * 
-+ * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ *
-+ * 	ext2fs_get_pathname(fs, dir, ino, name)
-+ *
-+ * 	This function translates takes two inode numbers into a
-+ * 	string, placing the result in <name>.  <dir> is the containing
-+ * 	directory inode, and <ino> is the inode number itself.  If
-+ * 	<ino> is zero, then ext2fs_get_pathname will return pathname
-+ * 	of the the directory <dir>.
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct get_pathname_struct {
-+	ext2_ino_t	search_ino;
-+	ext2_ino_t	parent;
-+	char		*name;
-+	errcode_t	errcode;
-+};
-+
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int get_pathname_proc(struct ext2_dir_entry *dirent,
-+			     int	offset EXT2FS_ATTR((unused)),
-+			     int	blocksize EXT2FS_ATTR((unused)),
-+			     char	*buf EXT2FS_ATTR((unused)),
-+			     void	*priv_data)
-+{
-+	struct get_pathname_struct	*gp;
-+	errcode_t			retval;
-+
-+	gp = (struct get_pathname_struct *) priv_data;
-+
-+	if (((dirent->name_len & 0xFF) == 2) &&
-+	    !strncmp(dirent->name, "..", 2))
-+		gp->parent = dirent->inode;
-+	if (dirent->inode == gp->search_ino) {
-+		retval = ext2fs_get_mem((dirent->name_len & 0xFF) + 1,
-+					&gp->name);
-+		if (retval) {
-+			gp->errcode = retval;
-+			return DIRENT_ABORT;
-+		}
-+		strncpy(gp->name, dirent->name, (dirent->name_len & 0xFF));
-+		gp->name[dirent->name_len & 0xFF] = '\0';
-+		return DIRENT_ABORT;
-+	}
-+	return 0;
-+}
-+
-+static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir, 
-+					 ext2_ino_t ino, int maxdepth, 
-+					 char *buf, char **name)
-+{
-+	struct get_pathname_struct gp;
-+	char	*parent_name, *ret;
-+	errcode_t	retval;
-+
-+	if (dir == ino) {
-+		retval = ext2fs_get_mem(2, name);
-+		if (retval)
-+			return retval;
-+		strcpy(*name, (dir == EXT2_ROOT_INO) ? "/" : ".");
-+		return 0;
-+	}
-+
-+	if (!dir || (maxdepth < 0)) {
-+		retval = ext2fs_get_mem(4, name);
-+		if (retval)
-+			return retval;
-+		strcpy(*name, "...");
-+		return 0;
-+	}
-+
-+	gp.search_ino = ino;
-+	gp.parent = 0;
-+	gp.name = 0;
-+	gp.errcode = 0;
-+	
-+	retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp);
-+	if (retval)
-+		goto cleanup;
-+	if (gp.errcode) {
-+		retval = gp.errcode;
-+		goto cleanup;
-+	}
-+
-+	retval = ext2fs_get_pathname_int(fs, gp.parent, dir, maxdepth-1,
-+					 buf, &parent_name);
-+	if (retval)
-+		goto cleanup;
-+	if (!ino) {
-+		*name = parent_name;
-+		return 0;
-+	}
-+	
-+	if (gp.name) 
-+		retval = ext2fs_get_mem(strlen(parent_name)+strlen(gp.name)+2,
-+					&ret);
-+	else
-+		retval = ext2fs_get_mem(strlen(parent_name)+5, &ret);
-+	if (retval)
-+		goto cleanup;
-+	
-+	ret[0] = 0;
-+	if (parent_name[1])
-+		strcat(ret, parent_name);
-+	strcat(ret, "/");
-+	if (gp.name)
-+		strcat(ret, gp.name);
-+	else
-+		strcat(ret, "???");
-+	*name = ret;
-+	ext2fs_free_mem(&parent_name);
-+	retval = 0;
-+	
-+cleanup:
-+	if (gp.name)
-+		ext2fs_free_mem(&gp.name);
-+	return retval;
-+}
-+
-+errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
-+			      char **name)
-+{
-+	char	*buf;
-+	errcode_t	retval;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	retval = ext2fs_get_mem(fs->blocksize, &buf);
-+	if (retval)
-+		return retval;
-+	if (dir == ino)
-+		ino = 0;
-+	retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name);
-+	ext2fs_free_mem(&buf);
-+	return retval;
-+	
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/getsectsize.c silo-1.4.14/libext2fs/getsectsize.c
---- silo-1.4.14.orig/libext2fs/getsectsize.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/getsectsize.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,60 @@
-+/*
-+ * getsectsize.c --- get the sector size of a device.
-+ * 
-+ * Copyright (C) 1995, 1995 Theodore Ts'o.
-+ * Copyright (C) 2003 VMware, Inc.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#define _LARGEFILE_SOURCE
-+#define _LARGEFILE64_SOURCE
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#ifdef HAVE_LINUX_FD_H
-+#include <sys/ioctl.h>
-+#include <linux/fd.h>
-+#endif
-+
-+#if defined(__linux__) && defined(_IO) && !defined(BLKSSZGET)
-+#define BLKSSZGET  _IO(0x12,104)/* get block device sector size */
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * Returns the number of blocks in a partition
-+ */
-+errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize)
-+{
-+	int	fd;
-+
-+#ifdef HAVE_OPEN64
-+	fd = open64(file, O_RDONLY);
-+#else
-+	fd = open(file, O_RDONLY);
-+#endif
-+	if (fd < 0)
-+		return errno;
-+
-+#ifdef BLKSSZGET
-+	if (ioctl(fd, BLKSSZGET, sectsize) >= 0) {
-+		close(fd);
-+		return 0;
-+	}
-+#endif
-+	*sectsize = 0;
-+	close(fd);
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/getsize.c silo-1.4.14/libext2fs/getsize.c
---- silo-1.4.14.orig/libext2fs/getsize.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/getsize.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,293 @@
-+/*
-+ * getsize.c --- get the size of a partition.
-+ * 
-+ * Copyright (C) 1995, 1995 Theodore Ts'o.
-+ * Copyright (C) 2003 VMware, Inc.
-+ *
-+ * Windows version of ext2fs_get_device_size by Chris Li, VMware.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#define _LARGEFILE_SOURCE
-+#define _LARGEFILE64_SOURCE
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#ifdef HAVE_SYS_IOCTL_H
-+#include <sys/ioctl.h>
-+#endif
-+#ifdef HAVE_LINUX_FD_H
-+#include <linux/fd.h>
-+#endif
-+#ifdef HAVE_SYS_DISKLABEL_H
-+#include <sys/disklabel.h>
-+#endif
-+#ifdef HAVE_SYS_DISK_H
-+#ifdef HAVE_SYS_QUEUE_H
-+#include <sys/queue.h> /* for LIST_HEAD */
-+#endif
-+#include <sys/disk.h>
-+#endif
-+#ifdef __linux__
-+#include <sys/utsname.h>
-+#endif
-+
-+#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
-+#define BLKGETSIZE _IO(0x12,96)	/* return device size */
-+#endif
-+
-+#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
-+#define BLKGETSIZE64 _IOR(0x12,114,size_t)	/* return device size in bytes (u64 *arg) */
-+#endif
-+
-+#ifdef APPLE_DARWIN
-+#define BLKGETSIZE DKIOCGETBLOCKCOUNT32
-+#endif /* APPLE_DARWIN */
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#if defined(__CYGWIN__) || defined (WIN32)
-+#include "windows.h"
-+#include "winioctl.h"
-+
-+#if (_WIN32_WINNT >= 0x0500)
-+#define HAVE_GET_FILE_SIZE_EX 1
-+#endif
-+
-+errcode_t ext2fs_get_device_size(const char *file, int blocksize,
-+				 blk_t *retblocks)
-+{
-+	HANDLE dev;
-+	PARTITION_INFORMATION pi;
-+	DISK_GEOMETRY gi;
-+	DWORD retbytes;
-+#ifdef HAVE_GET_FILE_SIZE_EX
-+	LARGE_INTEGER filesize;
-+#else
-+	DWORD filesize;
-+#endif /* HAVE_GET_FILE_SIZE_EX */
-+
-+	dev = CreateFile(file, GENERIC_READ, 
-+			 FILE_SHARE_READ | FILE_SHARE_WRITE ,
-+                	 NULL,  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,  NULL); 
-+ 
-+	if (dev == INVALID_HANDLE_VALUE)
-+		return EBADF;
-+	if (DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO,
-+			    &pi, sizeof(PARTITION_INFORMATION),
-+			    &pi, sizeof(PARTITION_INFORMATION),
-+			    &retbytes, NULL)) {
-+
-+		*retblocks = pi.PartitionLength.QuadPart / blocksize;
-+	
-+	} else if (DeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY,
-+				&gi, sizeof(DISK_GEOMETRY),
-+				&gi, sizeof(DISK_GEOMETRY),
-+				&retbytes, NULL)) {
-+
-+		*retblocks = gi.BytesPerSector *
-+			     gi.SectorsPerTrack *
-+			     gi.TracksPerCylinder *
-+			     gi.Cylinders.QuadPart / blocksize;
-+
-+#ifdef HAVE_GET_FILE_SIZE_EX
-+	} else if (GetFileSizeEx(dev, &filesize)) {
-+		*retblocks = filesize.QuadPart / blocksize;
-+	}
-+#else
-+	} else {
-+		filesize = GetFileSize(dev, NULL);
-+		if (INVALID_FILE_SIZE != filesize) {
-+			*retblocks = filesize / blocksize;
-+		}
-+	}
-+#endif /* HAVE_GET_FILE_SIZE_EX */
-+
-+	CloseHandle(dev);
-+	return 0;
-+}
-+
-+#else
-+
-+static int valid_offset (int fd, ext2_loff_t offset)
-+{
-+	char ch;
-+
-+	if (ext2fs_llseek (fd, offset, 0) < 0)
-+		return 0;
-+	if (read (fd, &ch, 1) < 1)
-+		return 0;
-+	return 1;
-+}
-+
-+/*
-+ * Returns the number of blocks in a partition
-+ */
-+errcode_t ext2fs_get_device_size(const char *file, int blocksize,
-+				 blk_t *retblocks)
-+{
-+	int	fd;
-+	int valid_blkgetsize64 = 1;
-+#ifdef __linux__
-+	struct 		utsname ut;
-+#endif
-+	unsigned long long size64;
-+	unsigned long	size;
-+	ext2_loff_t high, low;
-+#ifdef FDGETPRM
-+	struct floppy_struct this_floppy;
-+#endif
-+#ifdef HAVE_SYS_DISKLABEL_H
-+	int part;
-+	struct disklabel lab;
-+	struct partition *pp;
-+	char ch;
-+#endif /* HAVE_SYS_DISKLABEL_H */
-+
-+#ifdef HAVE_OPEN64
-+	fd = open64(file, O_RDONLY);
-+#else
-+	fd = open(file, O_RDONLY);
-+#endif
-+	if (fd < 0)
-+		return errno;
-+
-+#ifdef DKIOCGETBLOCKCOUNT	/* For Apple Darwin */
-+	if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) {
-+		if ((sizeof(*retblocks) < sizeof(unsigned long long))
-+		    && ((size64 / (blocksize / 512)) > 0xFFFFFFFF))
-+			return EFBIG;
-+		close(fd);
-+		*retblocks = size64 / (blocksize / 512);
-+		return 0;
-+	}
-+#endif
-+
-+#ifdef BLKGETSIZE64
-+#ifdef __linux__
-+	if ((uname(&ut) == 0) &&
-+	    ((ut.release[0] == '2') && (ut.release[1] == '.') &&
-+	     (ut.release[2] < '6') && (ut.release[3] == '.')))
-+		valid_blkgetsize64 = 0;
-+#endif
-+	if (valid_blkgetsize64 &&
-+	    ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
-+		if ((sizeof(*retblocks) < sizeof(unsigned long long))
-+		    && ((size64 / blocksize) > 0xFFFFFFFF))
-+			return EFBIG;
-+		close(fd);
-+		*retblocks = size64 / blocksize;
-+		return 0;
-+	}
-+#endif
-+
-+#ifdef BLKGETSIZE
-+	if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
-+		close(fd);
-+		*retblocks = size / (blocksize / 512);
-+		return 0;
-+	}
-+#endif
-+
-+#ifdef FDGETPRM
-+	if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
-+		close(fd);
-+		*retblocks = this_floppy.size / (blocksize / 512);
-+		return 0;
-+	}
-+#endif
-+
-+#ifdef HAVE_SYS_DISKLABEL_H
-+#if defined(DIOCGMEDIASIZE)
-+	{
-+	    off_t ms;
-+	    u_int bs;
-+	    if (ioctl(fd, DIOCGMEDIASIZE, &ms) >= 0) {
-+		*retblocks = ms / blocksize;
-+		return 0;
-+	    }
-+	}
-+#elif defined(DIOCGDINFO)
-+	/* old disklabel interface */
-+	part = strlen(file) - 1;
-+	if (part >= 0) {
-+		ch = file[part];
-+		if (isdigit(ch))
-+			part = 0;
-+		else if (ch >= 'a' && ch <= 'h')
-+			part = ch - 'a';
-+		else
-+			part = -1;
-+	}
-+	if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
-+		pp = &lab.d_partitions[part];
-+		if (pp->p_size) {
-+			close(fd);
-+			*retblocks = pp->p_size / (blocksize / 512);
-+			return 0;
-+		}
-+	}
-+#endif /* defined(DIOCG*) */
-+#endif /* HAVE_SYS_DISKLABEL_H */
-+
-+	/*
-+	 * OK, we couldn't figure it out by using a specialized ioctl,
-+	 * which is generally the best way.  So do binary search to
-+	 * find the size of the partition.
-+	 */
-+	low = 0;
-+	for (high = 1024; valid_offset (fd, high); high *= 2)
-+		low = high;
-+	while (low < high - 1)
-+	{
-+		const ext2_loff_t mid = (low + high) / 2;
-+
-+		if (valid_offset (fd, mid))
-+			low = mid;
-+		else
-+			high = mid;
-+	}
-+	valid_offset (fd, 0);
-+	close(fd);
-+	size64 = low + 1;
-+	if ((sizeof(*retblocks) < sizeof(unsigned long long))
-+	    && ((size64 / blocksize) > 0xFFFFFFFF))
-+		return EFBIG;
-+	*retblocks = size64 / blocksize;
-+	return 0;
-+}
-+
-+#endif /* WIN32 */
-+
-+#ifdef DEBUG
-+int main(int argc, char **argv)
-+{
-+	blk_t	blocks;
-+	int	retval;
-+	
-+	if (argc < 2) {
-+		fprintf(stderr, "Usage: %s device\n", argv[0]);
-+		exit(1);
-+	}
-+
-+	retval = ext2fs_get_device_size(argv[1], 1024, &blocks);
-+	if (retval) {
-+		com_err(argv[0], retval,
-+			"while calling ext2fs_get_device_size");
-+		exit(1);
-+	}
-+	printf("Device %s has %d 1k blocks.\n", argv[1], blocks);
-+	exit(0);
-+}
-+#endif
-diff -Naur silo-1.4.14.orig/libext2fs/icount.c silo-1.4.14/libext2fs/icount.c
---- silo-1.4.14.orig/libext2fs/icount.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/icount.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,483 @@
-+/*
-+ * icount.c --- an efficient inode count abstraction
-+ *
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <stdio.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * The data storage strategy used by icount relies on the observation
-+ * that most inode counts are either zero (for non-allocated inodes),
-+ * one (for most files), and only a few that are two or more
-+ * (directories and files that are linked to more than one directory).
-+ *
-+ * Also, e2fsck tends to load the icount data sequentially.
-+ *
-+ * So, we use an inode bitmap to indicate which inodes have a count of
-+ * one, and then use a sorted list to store the counts for inodes
-+ * which are greater than one.
-+ *
-+ * We also use an optional bitmap to indicate which inodes are already
-+ * in the sorted list, to speed up the use of this abstraction by
-+ * e2fsck's pass 2.  Pass 2 increments inode counts as it finds them,
-+ * so this extra bitmap avoids searching the sorted list to see if a
-+ * particular inode is on the sorted list already.
-+ */
-+
-+struct ext2_icount_el {
-+	ext2_ino_t	ino;
-+	__u16	count;
-+};
-+
-+struct ext2_icount {
-+	errcode_t		magic;
-+	ext2fs_inode_bitmap	single;
-+	ext2fs_inode_bitmap	multiple;
-+	ext2_ino_t		count;
-+	ext2_ino_t		size;
-+	ext2_ino_t		num_inodes;
-+	ext2_ino_t		cursor;
-+	struct ext2_icount_el	*list;
-+};
-+
-+void ext2fs_free_icount(ext2_icount_t icount)
-+{
-+	if (!icount)
-+		return;
-+
-+	icount->magic = 0;
-+	if (icount->list)
-+		ext2fs_free_mem(&icount->list);
-+	if (icount->single)
-+		ext2fs_free_inode_bitmap(icount->single);
-+	if (icount->multiple)
-+		ext2fs_free_inode_bitmap(icount->multiple);
-+	ext2fs_free_mem(&icount);
-+}
-+
-+errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, unsigned int size,
-+				ext2_icount_t hint, ext2_icount_t *ret)
-+{
-+	ext2_icount_t	icount;
-+	errcode_t	retval;
-+	size_t		bytes;
-+	ext2_ino_t	i;
-+
-+	if (hint) {
-+		EXT2_CHECK_MAGIC(hint, EXT2_ET_MAGIC_ICOUNT);
-+		if (hint->size > size)
-+			size = (size_t) hint->size;
-+	}
-+	
-+	retval = ext2fs_get_mem(sizeof(struct ext2_icount), &icount);
-+	if (retval)
-+		return retval;
-+	memset(icount, 0, sizeof(struct ext2_icount));
-+
-+	retval = ext2fs_allocate_inode_bitmap(fs, 0, 
-+					      &icount->single);
-+	if (retval)
-+		goto errout;
-+
-+	if (flags & EXT2_ICOUNT_OPT_INCREMENT) {
-+		retval = ext2fs_allocate_inode_bitmap(fs, 0, 
-+						      &icount->multiple);
-+		if (retval)
-+			goto errout;
-+	} else
-+		icount->multiple = 0;
-+
-+	if (size) {
-+		icount->size = size;
-+	} else {
-+		/*
-+		 * Figure out how many special case inode counts we will
-+		 * have.  We know we will need one for each directory;
-+		 * we also need to reserve some extra room for file links
-+		 */
-+		retval = ext2fs_get_num_dirs(fs, &icount->size);
-+		if (retval)
-+			goto errout;
-+		icount->size += fs->super->s_inodes_count / 50;
-+	}
-+	
-+	bytes = (size_t) (icount->size * sizeof(struct ext2_icount_el));
-+#if 0
-+	printf("Icount allocated %d entries, %d bytes.\n",
-+	       icount->size, bytes);
-+#endif
-+	retval = ext2fs_get_mem(bytes, &icount->list);
-+	if (retval)
-+		goto errout;
-+	memset(icount->list, 0, bytes);
-+
-+	icount->magic = EXT2_ET_MAGIC_ICOUNT;
-+	icount->count = 0;
-+	icount->cursor = 0;
-+	icount->num_inodes = fs->super->s_inodes_count;
-+
-+	/*
-+	 * Populate the sorted list with those entries which were
-+	 * found in the hint icount (since those are ones which will
-+	 * likely need to be in the sorted list this time around).
-+	 */
-+	if (hint) {
-+		for (i=0; i < hint->count; i++)
-+			icount->list[i].ino = hint->list[i].ino;
-+		icount->count = hint->count;
-+	}
-+
-+	*ret = icount;
-+	return 0;
-+
-+errout:
-+	ext2fs_free_icount(icount);
-+	return(retval);
-+}
-+
-+errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, 
-+			       unsigned int size,
-+			       ext2_icount_t *ret)
-+{
-+	return ext2fs_create_icount2(fs, flags, size, 0, ret);
-+}
-+
-+/*
-+ * insert_icount_el() --- Insert a new entry into the sorted list at a
-+ * 	specified position.
-+ */
-+static struct ext2_icount_el *insert_icount_el(ext2_icount_t icount,
-+					    ext2_ino_t ino, int pos)
-+{
-+	struct ext2_icount_el 	*el;
-+	errcode_t		retval;
-+	ext2_ino_t			new_size = 0;
-+	int			num;
-+
-+	if (icount->count >= icount->size) {
-+		if (icount->count) {
-+			new_size = icount->list[(unsigned)icount->count-1].ino;
-+			new_size = (ext2_ino_t) (icount->count * 
-+				((float) icount->num_inodes / new_size));
-+		}
-+		if (new_size < (icount->size + 100))
-+			new_size = icount->size + 100;
-+#if 0
-+		printf("Reallocating icount %d entries...\n", new_size);
-+#endif	
-+		retval = ext2fs_resize_mem((size_t) icount->size *
-+					   sizeof(struct ext2_icount_el),
-+					   (size_t) new_size *
-+					   sizeof(struct ext2_icount_el),
-+					   &icount->list);
-+		if (retval)
-+			return 0;
-+		icount->size = new_size;
-+	}
-+	num = (int) icount->count - pos;
-+	if (num < 0)
-+		return 0;	/* should never happen */
-+	if (num) {
-+		memmove(&icount->list[pos+1], &icount->list[pos],
-+			sizeof(struct ext2_icount_el) * num);
-+	}
-+	icount->count++;
-+	el = &icount->list[pos];
-+	el->count = 0;
-+	el->ino = ino;
-+	return el;
-+}
-+
-+/*
-+ * get_icount_el() --- given an inode number, try to find icount
-+ * 	information in the sorted list.  If the create flag is set,
-+ * 	and we can't find an entry, create one in the sorted list.
-+ */
-+static struct ext2_icount_el *get_icount_el(ext2_icount_t icount,
-+					    ext2_ino_t ino, int create)
-+{
-+	float	range;
-+	int	low, high, mid;
-+	ext2_ino_t	lowval, highval;
-+
-+	if (!icount || !icount->list)
-+		return 0;
-+
-+	if (create && ((icount->count == 0) ||
-+		       (ino > icount->list[(unsigned)icount->count-1].ino))) {
-+		return insert_icount_el(icount, ino, (unsigned) icount->count);
-+	}
-+	if (icount->count == 0)
-+		return 0;
-+	
-+	if (icount->cursor >= icount->count)
-+		icount->cursor = 0;
-+	if (ino == icount->list[icount->cursor].ino)
-+		return &icount->list[icount->cursor++];
-+#if 0
-+	printf("Non-cursor get_icount_el: %u\n", ino);
-+#endif
-+	low = 0;
-+	high = (int) icount->count-1;
-+	while (low <= high) {
-+#if 0
-+		mid = (low+high)/2;
-+#else
-+		if (low == high)
-+			mid = low;
-+		else {
-+			/* Interpolate for efficiency */
-+			lowval = icount->list[low].ino;
-+			highval = icount->list[high].ino;
-+
-+			if (ino < lowval)
-+				range = 0;
-+			else if (ino > highval)
-+				range = 1;
-+			else 
-+				range = ((float) (ino - lowval)) /
-+					(highval - lowval);
-+			mid = low + ((int) (range * (high-low)));
-+		}
-+#endif
-+		if (ino == icount->list[mid].ino) {
-+			icount->cursor = mid+1;
-+			return &icount->list[mid];
-+		}
-+		if (ino < icount->list[mid].ino)
-+			high = mid-1;
-+		else
-+			low = mid+1;
-+	}
-+	/*
-+	 * If we need to create a new entry, it should be right at
-+	 * low (where high will be left at low-1).
-+	 */
-+	if (create)
-+		return insert_icount_el(icount, ino, low);
-+	return 0;
-+}
-+
-+errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *out)
-+{
-+	errcode_t	ret = 0;
-+	unsigned int	i;
-+	const char *bad = "bad icount";
-+	
-+	EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-+
-+	if (icount->count > icount->size) {
-+		fprintf(out, "%s: count > size\n", bad);
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	}
-+	for (i=1; i < icount->count; i++) {
-+		if (icount->list[i-1].ino >= icount->list[i].ino) {
-+			fprintf(out, "%s: list[%d].ino=%u, list[%d].ino=%u\n",
-+				bad, i-1, icount->list[i-1].ino,
-+				i, icount->list[i].ino);
-+			ret = EXT2_ET_INVALID_ARGUMENT;
-+		}
-+	}
-+	return ret;
-+}
-+
-+errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino, __u16 *ret)
-+{
-+	struct ext2_icount_el	*el;
-+	
-+	EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-+
-+	if (!ino || (ino > icount->num_inodes))
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	if (ext2fs_test_inode_bitmap(icount->single, ino)) {
-+		*ret = 1;
-+		return 0;
-+	}
-+	if (icount->multiple &&
-+	    !ext2fs_test_inode_bitmap(icount->multiple, ino)) {
-+		*ret = 0;
-+		return 0;
-+	}
-+	el = get_icount_el(icount, ino, 0);
-+	if (!el) {
-+		*ret = 0;
-+		return 0;
-+	}
-+	*ret = el->count;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
-+				  __u16 *ret)
-+{
-+	struct ext2_icount_el	*el;
-+
-+	EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-+
-+	if (!ino || (ino > icount->num_inodes))
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	if (ext2fs_test_inode_bitmap(icount->single, ino)) {
-+		/*
-+		 * If the existing count is 1, then we know there is
-+		 * no entry in the list.
-+		 */
-+		el = get_icount_el(icount, ino, 1);
-+		if (!el)
-+			return EXT2_ET_NO_MEMORY;
-+		ext2fs_unmark_inode_bitmap(icount->single, ino);
-+		el->count = 2;
-+	} else if (icount->multiple) {
-+		/*
-+		 * The count is either zero or greater than 1; if the
-+		 * inode is set in icount->multiple, then there should
-+		 * be an entry in the list, so find it using
-+		 * get_icount_el().
-+		 */
-+		if (ext2fs_test_inode_bitmap(icount->multiple, ino)) {
-+			el = get_icount_el(icount, ino, 1);
-+			if (!el)
-+				return EXT2_ET_NO_MEMORY;
-+			el->count++;
-+		} else {
-+			/*
-+			 * The count was zero; mark the single bitmap
-+			 * and return.
-+			 */
-+		zero_count:
-+			ext2fs_mark_inode_bitmap(icount->single, ino);
-+			if (ret)
-+				*ret = 1;
-+			return 0;
-+		}
-+	} else {
-+		/*
-+		 * The count is either zero or greater than 1; try to
-+		 * find an entry in the list to determine which.
-+		 */
-+		el = get_icount_el(icount, ino, 0);
-+		if (!el) {
-+			/* No entry means the count was zero */
-+			goto zero_count;
-+		}
-+		el = get_icount_el(icount, ino, 1);
-+		if (!el)
-+			return EXT2_ET_NO_MEMORY;
-+		el->count++;
-+	}
-+	if (icount->multiple)
-+		ext2fs_mark_inode_bitmap(icount->multiple, ino);
-+	if (ret)
-+		*ret = el->count;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
-+				  __u16 *ret)
-+{
-+	struct ext2_icount_el	*el;
-+
-+	if (!ino || (ino > icount->num_inodes))
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-+
-+	if (ext2fs_test_inode_bitmap(icount->single, ino)) {
-+		ext2fs_unmark_inode_bitmap(icount->single, ino);
-+		if (icount->multiple)
-+			ext2fs_unmark_inode_bitmap(icount->multiple, ino);
-+		else {
-+			el = get_icount_el(icount, ino, 0);
-+			if (el)
-+				el->count = 0;
-+		}
-+		if (ret)
-+			*ret = 0;
-+		return 0;
-+	}
-+
-+	if (icount->multiple &&
-+	    !ext2fs_test_inode_bitmap(icount->multiple, ino))
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	
-+	el = get_icount_el(icount, ino, 0);
-+	if (!el || el->count == 0)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	el->count--;
-+	if (el->count == 1)
-+		ext2fs_mark_inode_bitmap(icount->single, ino);
-+	if ((el->count == 0) && icount->multiple)
-+		ext2fs_unmark_inode_bitmap(icount->multiple, ino);
-+
-+	if (ret)
-+		*ret = el->count;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
-+			      __u16 count)
-+{
-+	struct ext2_icount_el	*el;
-+
-+	if (!ino || (ino > icount->num_inodes))
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-+
-+	if (count == 1) {
-+		ext2fs_mark_inode_bitmap(icount->single, ino);
-+		if (icount->multiple)
-+			ext2fs_unmark_inode_bitmap(icount->multiple, ino);
-+		return 0;
-+	}
-+	if (count == 0) {
-+		ext2fs_unmark_inode_bitmap(icount->single, ino);
-+		if (icount->multiple) {
-+			/*
-+			 * If the icount->multiple bitmap is enabled,
-+			 * we can just clear both bitmaps and we're done
-+			 */
-+			ext2fs_unmark_inode_bitmap(icount->multiple, ino);
-+		} else {
-+			el = get_icount_el(icount, ino, 0);
-+			if (el)
-+				el->count = 0;
-+		}
-+		return 0;
-+	}
-+
-+	/*
-+	 * Get the icount element
-+	 */
-+	el = get_icount_el(icount, ino, 1);
-+	if (!el)
-+		return EXT2_ET_NO_MEMORY;
-+	el->count = count;
-+	ext2fs_unmark_inode_bitmap(icount->single, ino);
-+	if (icount->multiple)
-+		ext2fs_mark_inode_bitmap(icount->multiple, ino);
-+	return 0;
-+}
-+
-+ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount)
-+{
-+	if (!icount || icount->magic != EXT2_ET_MAGIC_ICOUNT)
-+		return 0;
-+
-+	return icount->size;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/imager.c silo-1.4.14/libext2fs/imager.c
---- silo-1.4.14.orig/libext2fs/imager.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/imager.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,387 @@
-+/*
-+ * image.c --- writes out the critical parts of the filesystem as a
-+ * 	flat file.
-+ *
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ *
-+ * Note: this uses the POSIX IO interfaces, unlike most of the other
-+ * functions in this library.  So sue me.  
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#ifndef HAVE_TYPE_SSIZE_T
-+typedef int ssize_t;
-+#endif
-+
-+/*
-+ * This function returns 1 if the specified block is all zeros
-+ */
-+static int check_zero_block(char *buf, int blocksize)
-+{
-+	char	*cp = buf;
-+	int	left = blocksize;
-+
-+	while (left > 0) {
-+		if (*cp++)
-+			return 0;
-+		left--;
-+	}
-+	return 1;
-+}
-+
-+/*
-+ * Write the inode table out as a single block.
-+ */
-+#define BUF_BLOCKS	32
-+
-+errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags)
-+{
-+	unsigned int	group, left, c, d;
-+	char		*buf, *cp;
-+	blk_t		blk;
-+	ssize_t		actual;
-+	errcode_t	retval;
-+
-+	buf = malloc(fs->blocksize * BUF_BLOCKS);
-+	if (!buf)
-+		return ENOMEM;
-+	
-+	for (group = 0; group < fs->group_desc_count; group++) {
-+		blk = fs->group_desc[(unsigned)group].bg_inode_table;
-+		if (!blk)
-+			return EXT2_ET_MISSING_INODE_TABLE;
-+		left = fs->inode_blocks_per_group;
-+		while (left) {
-+			c = BUF_BLOCKS;
-+			if (c > left)
-+				c = left;
-+			retval = io_channel_read_blk(fs->io, blk, c, buf);
-+			if (retval)
-+				goto errout;
-+			cp = buf;
-+			while (c) {
-+				if (!(flags & IMAGER_FLAG_SPARSEWRITE)) {
-+					d = c;
-+					goto skip_sparse;
-+				}
-+				/* Skip zero blocks */
-+				if (check_zero_block(cp, fs->blocksize)) {
-+					c--;
-+					blk++;
-+					left--;
-+					cp += fs->blocksize;
-+					lseek(fd, fs->blocksize, SEEK_CUR);
-+					continue;
-+				}
-+				/* Find non-zero blocks */
-+				for (d=1; d < c; d++) {
-+					if (check_zero_block(cp + d*fs->blocksize, fs->blocksize))
-+						break;
-+				}
-+			skip_sparse:
-+				actual = write(fd, cp, fs->blocksize * d);
-+				if (actual == -1) {
-+					retval = errno;
-+					goto errout;
-+				}
-+				if (actual != (ssize_t) (fs->blocksize * d)) {
-+					retval = EXT2_ET_SHORT_WRITE;
-+					goto errout;
-+				}
-+				blk += d;
-+				left -= d;
-+				cp += fs->blocksize * d;
-+				c -= d;
-+			}
-+		}
-+	}
-+	retval = 0;
-+
-+errout:
-+	free(buf);
-+	return retval;
-+}
-+
-+/*
-+ * Read in the inode table and stuff it into place
-+ */
-+errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, 
-+				  int flags EXT2FS_ATTR((unused)))
-+{
-+	unsigned int	group, c, left;
-+	char		*buf;
-+	blk_t		blk;
-+	ssize_t		actual;
-+	errcode_t	retval;
-+
-+	buf = malloc(fs->blocksize * BUF_BLOCKS);
-+	if (!buf)
-+		return ENOMEM;
-+	
-+	for (group = 0; group < fs->group_desc_count; group++) {
-+		blk = fs->group_desc[(unsigned)group].bg_inode_table;
-+		if (!blk) {
-+			retval = EXT2_ET_MISSING_INODE_TABLE;
-+			goto errout;
-+		}
-+		left = fs->inode_blocks_per_group;
-+		while (left) {
-+			c = BUF_BLOCKS;
-+			if (c > left)
-+				c = left;
-+			actual = read(fd, buf, fs->blocksize * c);
-+			if (actual == -1) {
-+				retval = errno;
-+				goto errout;
-+			}
-+			if (actual != (ssize_t) (fs->blocksize * c)) {
-+				retval = EXT2_ET_SHORT_READ;
-+				goto errout;
-+			}
-+			retval = io_channel_write_blk(fs->io, blk, c, buf);
-+			if (retval)
-+				goto errout;
-+			
-+			blk += c;
-+			left -= c;
-+		}
-+	}
-+	retval = ext2fs_flush_icache(fs);
-+
-+errout:
-+	free(buf);
-+	return retval;
-+}
-+
-+/*
-+ * Write out superblock and group descriptors
-+ */
-+errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, 
-+				   int flags EXT2FS_ATTR((unused)))
-+{
-+	char		*buf, *cp;
-+	ssize_t		actual;
-+	errcode_t	retval;
-+
-+	buf = malloc(fs->blocksize);
-+	if (!buf)
-+		return ENOMEM;
-+
-+	/*
-+	 * Write out the superblock
-+	 */
-+	memset(buf, 0, fs->blocksize);
-+	memcpy(buf, fs->super, SUPERBLOCK_SIZE);
-+	actual = write(fd, buf, fs->blocksize);
-+	if (actual == -1) {
-+		retval = errno;
-+		goto errout;
-+	}
-+	if (actual != (ssize_t) fs->blocksize) {
-+		retval = EXT2_ET_SHORT_WRITE;
-+		goto errout;
-+	}
-+
-+	/*
-+	 * Now write out the block group descriptors
-+	 */
-+	cp = (char *) fs->group_desc;
-+	actual = write(fd, cp, fs->blocksize * fs->desc_blocks);
-+	if (actual == -1) {
-+		retval = errno;
-+		goto errout;
-+	}
-+	if (actual != (ssize_t) (fs->blocksize * fs->desc_blocks)) {
-+		retval = EXT2_ET_SHORT_WRITE;
-+		goto errout;
-+	}
-+	
-+	retval = 0;
-+
-+errout:
-+	free(buf);
-+	return retval;
-+}
-+
-+/*
-+ * Read the superblock and group descriptors and overwrite them.
-+ */
-+errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, 
-+				  int flags EXT2FS_ATTR((unused)))
-+{
-+	char		*buf;
-+	ssize_t		actual, size;
-+	errcode_t	retval;
-+
-+	size = fs->blocksize * (fs->group_desc_count + 1);
-+	buf = malloc(size);
-+	if (!buf)
-+		return ENOMEM;
-+
-+	/*
-+	 * Read it all in.
-+	 */
-+	actual = read(fd, buf, size);
-+	if (actual == -1) {
-+		retval = errno;
-+		goto errout;
-+	}
-+	if (actual != size) {
-+		retval = EXT2_ET_SHORT_READ;
-+		goto errout;
-+	}
-+
-+	/*
-+	 * Now copy in the superblock and group descriptors
-+	 */
-+	memcpy(fs->super, buf, SUPERBLOCK_SIZE);
-+
-+	memcpy(fs->group_desc, buf + fs->blocksize,
-+	       fs->blocksize * fs->group_desc_count);
-+
-+	retval = 0;
-+
-+errout:
-+	free(buf);
-+	return retval;
-+}
-+
-+/*
-+ * Write the block/inode bitmaps.
-+ */
-+errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
-+{
-+	char		*ptr;
-+	int		c, size;
-+	char		zero_buf[1024];
-+	ssize_t		actual;
-+	errcode_t	retval;
-+
-+	if (flags & IMAGER_FLAG_INODEMAP) {
-+		if (!fs->inode_map) {
-+			retval = ext2fs_read_inode_bitmap(fs);
-+			if (retval)
-+				return retval;
-+		}
-+		ptr = fs->inode_map->bitmap;
-+		size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
-+	} else {
-+		if (!fs->block_map) {
-+			retval = ext2fs_read_block_bitmap(fs);
-+			if (retval)
-+				return retval;
-+		}
-+		ptr = fs->block_map->bitmap;
-+		size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-+	}
-+	size = size * fs->group_desc_count;
-+
-+	actual = write(fd, ptr, size);
-+	if (actual == -1) {
-+		retval = errno;
-+		goto errout;
-+	}
-+	if (actual != size) {
-+		retval = EXT2_ET_SHORT_WRITE;
-+		goto errout;
-+	}
-+	size = size % fs->blocksize;
-+	memset(zero_buf, 0, sizeof(zero_buf));
-+	if (size) {
-+		size = fs->blocksize - size;
-+		while (size) {
-+			c = size;
-+			if (c > (int) sizeof(zero_buf))
-+				c = sizeof(zero_buf);
-+			actual = write(fd, zero_buf, c);
-+			if (actual == -1) {
-+				retval = errno;
-+				goto errout;
-+			}
-+			if (actual != c) {
-+				retval = EXT2_ET_SHORT_WRITE;
-+				goto errout;
-+			}
-+			size -= c;
-+		}
-+	}
-+	retval = 0;
-+errout:
-+	return (retval);
-+}
-+
-+
-+/*
-+ * Read the block/inode bitmaps.
-+ */
-+errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
-+{
-+	char		*ptr, *buf = 0;
-+	int		size;
-+	ssize_t		actual;
-+	errcode_t	retval;
-+
-+	if (flags & IMAGER_FLAG_INODEMAP) {
-+		if (!fs->inode_map) {
-+			retval = ext2fs_read_inode_bitmap(fs);
-+			if (retval)
-+				return retval;
-+		}
-+		ptr = fs->inode_map->bitmap;
-+		size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
-+	} else {
-+		if (!fs->block_map) {
-+			retval = ext2fs_read_block_bitmap(fs);
-+			if (retval)
-+				return retval;
-+		}
-+		ptr = fs->block_map->bitmap;
-+		size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-+	}
-+	size = size * fs->group_desc_count;
-+
-+	buf = malloc(size);
-+	if (!buf)
-+		return ENOMEM;
-+
-+	actual = read(fd, buf, size);
-+	if (actual == -1) {
-+		retval = errno;
-+		goto errout;
-+	}
-+	if (actual != size) {
-+		retval = EXT2_ET_SHORT_WRITE;
-+		goto errout;
-+	}
-+	memcpy(ptr, buf, size);
-+	
-+	retval = 0;
-+errout:
-+	if (buf)
-+		free(buf);
-+	return (retval);
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/ind_block.c silo-1.4.14/libext2fs/ind_block.c
---- silo-1.4.14.orig/libext2fs/ind_block.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/ind_block.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,66 @@
-+/*
-+ * ind_block.c --- indirect block I/O routines
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 
-+ * 	2001, 2002, 2003, 2004, 2005 by  Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf)
-+{
-+	errcode_t	retval;
-+	blk_t		*block_nr;
-+	int		i;
-+	int		limit = fs->blocksize >> 2;
-+
-+	if ((fs->flags & EXT2_FLAG_IMAGE_FILE) &&
-+	    (fs->io != fs->image_io))
-+		memset(buf, 0, fs->blocksize);
-+	else {
-+		retval = io_channel_read_blk(fs->io, blk, 1, buf);
-+		if (retval)
-+			return retval;
-+	}
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if (fs->flags & (EXT2_FLAG_SWAP_BYTES | EXT2_FLAG_SWAP_BYTES_READ)) {
-+		block_nr = (blk_t *) buf;
-+		for (i = 0; i < limit; i++, block_nr++)
-+			*block_nr = ext2fs_swab32(*block_nr);
-+	}
-+#endif
-+	return 0;
-+}
-+
-+errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf)
-+{
-+	blk_t		*block_nr;
-+	int		i;
-+	int		limit = fs->blocksize >> 2;
-+
-+	if (fs->flags & EXT2_FLAG_IMAGE_FILE)
-+		return 0;
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if (fs->flags & (EXT2_FLAG_SWAP_BYTES | EXT2_FLAG_SWAP_BYTES_WRITE)) {
-+		block_nr = (blk_t *) buf;
-+		for (i = 0; i < limit; i++, block_nr++)
-+			*block_nr = ext2fs_swab32(*block_nr);
-+	}
-+#endif
-+	return io_channel_write_blk(fs->io, blk, 1, buf);
-+}
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/initialize.c silo-1.4.14/libext2fs/initialize.c
---- silo-1.4.14.orig/libext2fs/initialize.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/initialize.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,387 @@
-+/*
-+ * initialize.c --- initialize a filesystem handle given superblock
-+ * 	parameters.  Used by mke2fs when initializing a filesystem.
-+ * 
-+ * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#if defined(__linux__)    &&	defined(EXT2_OS_LINUX)
-+#define CREATOR_OS EXT2_OS_LINUX
-+#else
-+#if defined(__GNU__)     &&	defined(EXT2_OS_HURD)
-+#define CREATOR_OS EXT2_OS_HURD
-+#else
-+#if defined(__FreeBSD__) &&	defined(EXT2_OS_FREEBSD)
-+#define CREATOR_OS EXT2_OS_FREEBSD
-+#else
-+#if defined(LITES) 	   &&	defined(EXT2_OS_LITES)
-+#define CREATOR_OS EXT2_OS_LITES
-+#else
-+#define CREATOR_OS EXT2_OS_LINUX /* by default */
-+#endif /* defined(LITES) && defined(EXT2_OS_LITES) */
-+#endif /* defined(__FreeBSD__) && defined(EXT2_OS_FREEBSD) */
-+#endif /* defined(__GNU__)     && defined(EXT2_OS_HURD) */
-+#endif /* defined(__linux__)   && defined(EXT2_OS_LINUX) */
-+	
-+/*
-+ * 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 (86400L * 180L)
-+
-+/*
-+ * Calculate the number of GDT blocks to reserve for online filesystem growth.
-+ * The absolute maximum number of GDT blocks we can reserve is determined by
-+ * the number of block pointers that can fit into a single block.
-+ */
-+static int calc_reserved_gdt_blocks(ext2_filsys fs)
-+{
-+	struct ext2_super_block *sb = fs->super;
-+	unsigned long bpg = sb->s_blocks_per_group;
-+	unsigned int gdpb = fs->blocksize / sizeof(struct ext2_group_desc);
-+	unsigned long max_blocks = 0xffffffff;
-+	unsigned long rsv_groups;
-+	int rsv_gdb;
-+
-+	/* We set it at 1024x the current filesystem size, or
-+	 * the upper block count limit (2^32), whichever is lower.
-+	 */
-+	if (sb->s_blocks_count < max_blocks / 1024)
-+		max_blocks = sb->s_blocks_count * 1024;
-+	rsv_groups = (max_blocks - sb->s_first_data_block + bpg - 1) / bpg;
-+	rsv_gdb = (rsv_groups + gdpb - 1) / gdpb - fs->desc_blocks;
-+	if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb))
-+		rsv_gdb = EXT2_ADDR_PER_BLOCK(sb);
-+#ifdef RES_GDT_DEBUG
-+	printf("max_blocks %lu, rsv_groups = %lu, rsv_gdb = %lu\n",
-+	       max_blocks, rsv_groups, rsv_gdb);
-+#endif
-+
-+	return rsv_gdb;
-+}
-+
-+errcode_t ext2fs_initialize(const char *name, int flags,
-+			    struct ext2_super_block *param,
-+			    io_manager manager, ext2_filsys *ret_fs)
-+{
-+	ext2_filsys	fs;
-+	errcode_t	retval;
-+	struct ext2_super_block *super;
-+	int		frags_per_block;
-+	unsigned int	rem;
-+	unsigned int	overhead = 0;
-+	blk_t		group_block;
-+	unsigned int	ipg;
-+	dgrp_t		i;
-+	blk_t		numblocks;
-+	int		rsv_gdt;
-+	char		*buf;
-+
-+	if (!param || !param->s_blocks_count)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	
-+	retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
-+	if (retval)
-+		return retval;
-+	
-+	memset(fs, 0, sizeof(struct struct_ext2_filsys));
-+	fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
-+	fs->flags = flags | EXT2_FLAG_RW;
-+	fs->umask = 022;
-+#ifdef WORDS_BIGENDIAN
-+	fs->flags |= EXT2_FLAG_SWAP_BYTES;
-+#endif
-+	retval = manager->open(name, IO_FLAG_RW, &fs->io);
-+	if (retval)
-+		goto cleanup;
-+	fs->image_io = fs->io;
-+	fs->io->app_data = fs;
-+	retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name);
-+	if (retval)
-+		goto cleanup;
-+
-+	strcpy(fs->device_name, name);
-+	retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super);
-+	if (retval)
-+		goto cleanup;
-+	fs->super = super;
-+
-+	memset(super, 0, SUPERBLOCK_SIZE);
-+
-+#define set_field(field, default) (super->field = param->field ? \
-+				   param->field : (default))
-+
-+	super->s_magic = EXT2_SUPER_MAGIC;
-+	super->s_state = EXT2_VALID_FS;
-+
-+	set_field(s_log_block_size, 0);	/* default blocksize: 1024 bytes */
-+	set_field(s_log_frag_size, 0); /* default fragsize: 1024 bytes */
-+	set_field(s_first_data_block, super->s_log_block_size ? 0 : 1);
-+	set_field(s_max_mnt_count, EXT2_DFL_MAX_MNT_COUNT);
-+	set_field(s_errors, EXT2_ERRORS_DEFAULT);
-+	set_field(s_feature_compat, 0);
-+	set_field(s_feature_incompat, 0);
-+	set_field(s_feature_ro_compat, 0);
-+	set_field(s_first_meta_bg, 0);
-+	if (super->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
-+		retval = EXT2_ET_UNSUPP_FEATURE;
-+		goto cleanup;
-+	}
-+	if (super->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
-+		retval = EXT2_ET_RO_UNSUPP_FEATURE;
-+		goto cleanup;
-+	}
-+
-+	set_field(s_rev_level, EXT2_GOOD_OLD_REV);
-+	if (super->s_rev_level >= EXT2_DYNAMIC_REV) {
-+		set_field(s_first_ino, EXT2_GOOD_OLD_FIRST_INO);
-+		set_field(s_inode_size, EXT2_GOOD_OLD_INODE_SIZE);
-+	}
-+
-+	set_field(s_checkinterval, EXT2_DFL_CHECKINTERVAL);
-+	super->s_mkfs_time = super->s_lastcheck = time(NULL);
-+
-+	super->s_creator_os = CREATOR_OS;
-+
-+	fs->blocksize = EXT2_BLOCK_SIZE(super);
-+	fs->fragsize = EXT2_FRAG_SIZE(super);
-+	frags_per_block = fs->blocksize / fs->fragsize;
-+
-+	/* default: (fs->blocksize*8) blocks/group, up to 2^16 (GDT limit) */
-+	set_field(s_blocks_per_group, fs->blocksize * 8);
-+	if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super))
-+		super->s_blocks_per_group = EXT2_MAX_BLOCKS_PER_GROUP(super);
-+	super->s_frags_per_group = super->s_blocks_per_group * frags_per_block;
-+	
-+	super->s_blocks_count = param->s_blocks_count;
-+	super->s_r_blocks_count = param->s_r_blocks_count;
-+	if (super->s_r_blocks_count >= param->s_blocks_count) {
-+		retval = EXT2_ET_INVALID_ARGUMENT;
-+		goto cleanup;
-+	}
-+
-+	/*
-+	 * If we're creating an external journal device, we don't need
-+	 * to bother with the rest.
-+	 */
-+	if (super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
-+		fs->group_desc_count = 0;
-+		ext2fs_mark_super_dirty(fs);
-+		*ret_fs = fs;
-+		return 0;
-+	}
-+
-+retry:
-+	fs->group_desc_count = (super->s_blocks_count -
-+				super->s_first_data_block +
-+				EXT2_BLOCKS_PER_GROUP(super) - 1)
-+		/ EXT2_BLOCKS_PER_GROUP(super);
-+	if (fs->group_desc_count == 0) {
-+		retval = EXT2_ET_TOOSMALL;
-+		goto cleanup;
-+	}
-+	fs->desc_blocks = (fs->group_desc_count +
-+			   EXT2_DESC_PER_BLOCK(super) - 1)
-+		/ EXT2_DESC_PER_BLOCK(super);
-+
-+	i = fs->blocksize >= 4096 ? 1 : 4096 / fs->blocksize;
-+	set_field(s_inodes_count, super->s_blocks_count / i);
-+
-+	/*
-+	 * Make sure we have at least EXT2_FIRST_INO + 1 inodes, so
-+	 * that we have enough inodes for the filesystem(!)
-+	 */
-+	if (super->s_inodes_count < EXT2_FIRST_INODE(super)+1)
-+		super->s_inodes_count = EXT2_FIRST_INODE(super)+1;
-+	
-+	/*
-+	 * There should be at least as many inodes as the user
-+	 * requested.  Figure out how many inodes per group that
-+	 * should be.  But make sure that we don't allocate more than
-+	 * one bitmap's worth of inodes each group.
-+	 */
-+	ipg = (super->s_inodes_count + fs->group_desc_count - 1) /
-+		fs->group_desc_count;
-+	if (ipg > fs->blocksize * 8) {
-+		if (super->s_blocks_per_group >= 256) {
-+			/* Try again with slightly different parameters */
-+			super->s_blocks_per_group -= 8;
-+			super->s_blocks_count = param->s_blocks_count;
-+			super->s_frags_per_group = super->s_blocks_per_group *
-+				frags_per_block;
-+			goto retry;
-+		} else
-+			return EXT2_ET_TOO_MANY_INODES;
-+	}
-+
-+	if (ipg > (unsigned) EXT2_MAX_INODES_PER_GROUP(super))
-+		ipg = EXT2_MAX_INODES_PER_GROUP(super);
-+
-+	super->s_inodes_per_group = ipg;
-+	if (super->s_inodes_count > ipg * fs->group_desc_count)
-+		super->s_inodes_count = ipg * fs->group_desc_count;
-+
-+	/*
-+	 * Make sure the number of inodes per group completely fills
-+	 * the inode table blocks in the descriptor.  If not, add some
-+	 * additional inodes/group.  Waste not, want not...
-+	 */
-+	fs->inode_blocks_per_group = (((super->s_inodes_per_group *
-+					EXT2_INODE_SIZE(super)) +
-+				       EXT2_BLOCK_SIZE(super) - 1) /
-+				      EXT2_BLOCK_SIZE(super));
-+	super->s_inodes_per_group = ((fs->inode_blocks_per_group *
-+				      EXT2_BLOCK_SIZE(super)) /
-+				     EXT2_INODE_SIZE(super));
-+	/*
-+	 * Finally, make sure the number of inodes per group is a
-+	 * multiple of 8.  This is needed to simplify the bitmap
-+	 * splicing code.
-+	 */
-+	super->s_inodes_per_group &= ~7;
-+	fs->inode_blocks_per_group = (((super->s_inodes_per_group *
-+					EXT2_INODE_SIZE(super)) +
-+				       EXT2_BLOCK_SIZE(super) - 1) /
-+				      EXT2_BLOCK_SIZE(super));
-+
-+	/*
-+	 * adjust inode count to reflect the adjusted inodes_per_group
-+	 */
-+	super->s_inodes_count = super->s_inodes_per_group *
-+		fs->group_desc_count;
-+	super->s_free_inodes_count = super->s_inodes_count;
-+
-+	/*
-+	 * check the number of reserved group descriptor table blocks
-+	 */
-+	if (super->s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE)
-+		rsv_gdt = calc_reserved_gdt_blocks(fs);
-+	else
-+		rsv_gdt = 0;
-+	set_field(s_reserved_gdt_blocks, rsv_gdt);
-+	if (super->s_reserved_gdt_blocks > EXT2_ADDR_PER_BLOCK(super)) {
-+		retval = EXT2_ET_RES_GDT_BLOCKS;
-+		goto cleanup;
-+	}
-+
-+	/*
-+	 * Overhead is the number of bookkeeping blocks per group.  It
-+	 * includes the superblock backup, the group descriptor
-+	 * backups, the inode bitmap, the block bitmap, and the inode
-+	 * table.
-+	 */
-+
-+	overhead = (int) (2 + fs->inode_blocks_per_group);
-+
-+	if (ext2fs_bg_has_super(fs, fs->group_desc_count - 1))
-+		overhead += 1 + fs->desc_blocks + super->s_reserved_gdt_blocks;
-+
-+	/* This can only happen if the user requested too many inodes */
-+	if (overhead > super->s_blocks_per_group)
-+		return EXT2_ET_TOO_MANY_INODES;
-+
-+	/*
-+	 * See if the last group is big enough to support the
-+	 * necessary data structures.  If not, we need to get rid of
-+	 * it.
-+	 */
-+	rem = ((super->s_blocks_count - super->s_first_data_block) %
-+	       super->s_blocks_per_group);
-+	if ((fs->group_desc_count == 1) && rem && (rem < overhead))
-+		return EXT2_ET_TOOSMALL;
-+	if (rem && (rem < overhead+50)) {
-+		super->s_blocks_count -= rem;
-+		goto retry;
-+	}
-+
-+	/*
-+	 * At this point we know how big the filesystem will be.  So
-+	 * we can do any and all allocations that depend on the block
-+	 * count.
-+	 */
-+
-+	retval = ext2fs_get_mem(strlen(fs->device_name) + 80, &buf);
-+	if (retval)
-+		goto cleanup;
-+	
-+	sprintf(buf, "block bitmap for %s", fs->device_name);
-+	retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map);
-+	if (retval)
-+		goto cleanup;
-+	
-+	sprintf(buf, "inode bitmap for %s", fs->device_name);
-+	retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
-+	if (retval)
-+		goto cleanup;
-+
-+	ext2fs_free_mem(&buf);
-+
-+	retval = ext2fs_get_mem((size_t) fs->desc_blocks * fs->blocksize,
-+				&fs->group_desc);
-+	if (retval)
-+		goto cleanup;
-+
-+	memset(fs->group_desc, 0, (size_t) fs->desc_blocks * fs->blocksize);
-+
-+	/*
-+	 * Reserve the superblock and group descriptors for each
-+	 * group, and fill in the correct group statistics for group.
-+	 * Note that although the block bitmap, inode bitmap, and
-+	 * inode table have not been allocated (and in fact won't be
-+	 * by this routine), they are accounted for nevertheless.
-+	 */
-+	group_block = super->s_first_data_block;
-+	super->s_free_blocks_count = 0;
-+	for (i = 0; i < fs->group_desc_count; i++) {
-+		numblocks = ext2fs_reserve_super_and_bgd(fs, i, fs->block_map);
-+
-+		super->s_free_blocks_count += numblocks;
-+		fs->group_desc[i].bg_free_blocks_count = numblocks;
-+		fs->group_desc[i].bg_free_inodes_count =
-+			fs->super->s_inodes_per_group;
-+		fs->group_desc[i].bg_used_dirs_count = 0;
-+		
-+		group_block += super->s_blocks_per_group;
-+	}
-+	
-+	ext2fs_mark_super_dirty(fs);
-+	ext2fs_mark_bb_dirty(fs);
-+	ext2fs_mark_ib_dirty(fs);
-+	
-+	io_channel_set_blksize(fs->io, fs->blocksize);
-+
-+	*ret_fs = fs;
-+	return 0;
-+cleanup:
-+	ext2fs_free(fs);
-+	return retval;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/inline.c silo-1.4.14/libext2fs/inline.c
---- silo-1.4.14.orig/libext2fs/inline.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/inline.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,32 @@
-+/*
-+ * inline.c --- Includes the inlined functions defined in the header
-+ * 	files as standalone functions, in case the application program
-+ * 	is compiled with inlining turned off.
-+ * 
-+ * Copyright (C) 1993, 1994 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#define INCLUDE_INLINE_FUNCS
-+#include "ext2fs.h"
-+
-diff -Naur silo-1.4.14.orig/libext2fs/inode.c silo-1.4.14/libext2fs/inode.c
---- silo-1.4.14.orig/libext2fs/inode.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/inode.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,794 @@
-+/*
-+ * inode.c --- utility routines to read and write inodes
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+#include "e2image.h"
-+
-+struct ext2_struct_inode_scan {
-+	errcode_t		magic;
-+	ext2_filsys		fs;
-+	ext2_ino_t		current_inode;
-+	blk_t			current_block;
-+	dgrp_t			current_group;
-+	ext2_ino_t		inodes_left;
-+	blk_t			blocks_left;
-+	dgrp_t			groups_left;
-+	blk_t			inode_buffer_blocks;
-+	char *			inode_buffer;
-+	int			inode_size;
-+	char *			ptr;
-+	int			bytes_left;
-+	char			*temp_buffer;
-+	errcode_t		(*done_group)(ext2_filsys fs,
-+					      ext2_inode_scan scan,
-+					      dgrp_t group,
-+					      void * priv_data);
-+	void *			done_group_data;
-+	int			bad_block_ptr;
-+	int			scan_flags;
-+	int			reserved[6];
-+};
-+
-+/*
-+ * This routine flushes the icache, if it exists.
-+ */
-+errcode_t ext2fs_flush_icache(ext2_filsys fs)
-+{
-+	int	i;
-+	
-+	if (!fs->icache)
-+		return 0;
-+
-+	for (i=0; i < fs->icache->cache_size; i++)
-+		fs->icache->cache[i].ino = 0;
-+
-+	fs->icache->buffer_blk = 0;
-+	return 0;
-+}
-+
-+static errcode_t create_icache(ext2_filsys fs)
-+{
-+	errcode_t	retval;
-+	
-+	if (fs->icache)
-+		return 0;
-+	retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache), &fs->icache);
-+	if (retval)
-+		return retval;
-+
-+	memset(fs->icache, 0, sizeof(struct ext2_inode_cache));
-+	retval = ext2fs_get_mem(fs->blocksize, &fs->icache->buffer);
-+	if (retval) {
-+		ext2fs_free_mem(&fs->icache);
-+		return retval;
-+	}
-+	fs->icache->buffer_blk = 0;
-+	fs->icache->cache_last = -1;
-+	fs->icache->cache_size = 4;
-+	fs->icache->refcount = 1;
-+	retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache_ent)
-+				* fs->icache->cache_size,
-+				&fs->icache->cache);
-+	if (retval) {
-+		ext2fs_free_mem(&fs->icache->buffer);
-+		ext2fs_free_mem(&fs->icache);
-+		return retval;
-+	}
-+	ext2fs_flush_icache(fs);
-+	return 0;
-+}
-+
-+errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
-+				 ext2_inode_scan *ret_scan)
-+{
-+	ext2_inode_scan	scan;
-+	errcode_t	retval;
-+	errcode_t (*save_get_blocks)(ext2_filsys f, ext2_ino_t ino, blk_t *blocks);
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	/*
-+	 * If fs->badblocks isn't set, then set it --- since the inode
-+	 * scanning functions require it.
-+	 */
-+	if (fs->badblocks == 0) {
-+		/*
-+		 * Temporarly save fs->get_blocks and set it to zero,
-+		 * for compatibility with old e2fsck's.
-+		 */
-+		save_get_blocks = fs->get_blocks;
-+		fs->get_blocks = 0;
-+		retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
-+		if (retval && fs->badblocks) {
-+			ext2fs_badblocks_list_free(fs->badblocks);
-+			fs->badblocks = 0;
-+		}
-+		fs->get_blocks = save_get_blocks;
-+	}
-+
-+	retval = ext2fs_get_mem(sizeof(struct ext2_struct_inode_scan), &scan);
-+	if (retval)
-+		return retval;
-+	memset(scan, 0, sizeof(struct ext2_struct_inode_scan));
-+
-+	scan->magic = EXT2_ET_MAGIC_INODE_SCAN;
-+	scan->fs = fs;
-+	scan->inode_size = EXT2_INODE_SIZE(fs->super);
-+	scan->bytes_left = 0;
-+	scan->current_group = 0;
-+	scan->groups_left = fs->group_desc_count - 1;
-+	scan->inode_buffer_blocks = buffer_blocks ? buffer_blocks : 8;
-+	scan->current_block = scan->fs->
-+		group_desc[scan->current_group].bg_inode_table;
-+	scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
-+	scan->blocks_left = scan->fs->inode_blocks_per_group;
-+	retval = ext2fs_get_mem((size_t) (scan->inode_buffer_blocks * 
-+					  fs->blocksize),
-+				&scan->inode_buffer);
-+	scan->done_group = 0;
-+	scan->done_group_data = 0;
-+	scan->bad_block_ptr = 0;
-+	if (retval) {
-+		ext2fs_free_mem(&scan);
-+		return retval;
-+	}
-+	retval = ext2fs_get_mem(scan->inode_size, &scan->temp_buffer);
-+	if (retval) {
-+		ext2fs_free_mem(&scan->inode_buffer);
-+		ext2fs_free_mem(&scan);
-+		return retval;
-+	}
-+	if (scan->fs->badblocks && scan->fs->badblocks->num)
-+		scan->scan_flags |= EXT2_SF_CHK_BADBLOCKS;
-+	*ret_scan = scan;
-+	return 0;
-+}
-+
-+void ext2fs_close_inode_scan(ext2_inode_scan scan)
-+{
-+	if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
-+		return;
-+	
-+	ext2fs_free_mem(&scan->inode_buffer);
-+	scan->inode_buffer = NULL;
-+	ext2fs_free_mem(&scan->temp_buffer);
-+	scan->temp_buffer = NULL;
-+	ext2fs_free_mem(&scan);
-+	return;
-+}
-+
-+void ext2fs_set_inode_callback(ext2_inode_scan scan,
-+			       errcode_t (*done_group)(ext2_filsys fs,
-+						       ext2_inode_scan scan,
-+						       dgrp_t group,
-+						       void * priv_data),
-+			       void *done_group_data)
-+{
-+	if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
-+		return;
-+	
-+	scan->done_group = done_group;
-+	scan->done_group_data = done_group_data;
-+}
-+
-+int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
-+			    int clear_flags)
-+{
-+	int	old_flags;
-+
-+	if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
-+		return 0;
-+
-+	old_flags = scan->scan_flags;
-+	scan->scan_flags &= ~clear_flags;
-+	scan->scan_flags |= set_flags;
-+	return old_flags;
-+}
-+
-+/*
-+ * This function is called by ext2fs_get_next_inode when it needs to
-+ * get ready to read in a new blockgroup.
-+ */
-+static errcode_t get_next_blockgroup(ext2_inode_scan scan)
-+{
-+	scan->current_group++;
-+	scan->groups_left--;
-+			
-+	scan->current_block = scan->fs->
-+		group_desc[scan->current_group].bg_inode_table;
-+
-+	scan->current_inode = scan->current_group *
-+		EXT2_INODES_PER_GROUP(scan->fs->super);
-+
-+	scan->bytes_left = 0;
-+	scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
-+	scan->blocks_left = scan->fs->inode_blocks_per_group;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
-+					    int	group)
-+{
-+	scan->current_group = group - 1;
-+	scan->groups_left = scan->fs->group_desc_count - group;
-+	return get_next_blockgroup(scan);
-+}
-+
-+/*
-+ * This function is called by get_next_blocks() to check for bad
-+ * blocks in the inode table.
-+ *
-+ * This function assumes that badblocks_list->list is sorted in
-+ * increasing order.
-+ */
-+static errcode_t check_for_inode_bad_blocks(ext2_inode_scan scan,
-+					    blk_t *num_blocks)
-+{
-+	blk_t	blk = scan->current_block;
-+	badblocks_list	bb = scan->fs->badblocks;
-+
-+	/*
-+	 * If the inode table is missing, then obviously there are no
-+	 * bad blocks.  :-)
-+	 */
-+	if (blk == 0)
-+		return 0;
-+
-+	/*
-+	 * If the current block is greater than the bad block listed
-+	 * in the bad block list, then advance the pointer until this
-+	 * is no longer the case.  If we run out of bad blocks, then
-+	 * we don't need to do any more checking!
-+	 */
-+	while (blk > bb->list[scan->bad_block_ptr]) {
-+		if (++scan->bad_block_ptr >= bb->num) {
-+			scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
-+			return 0;
-+		}
-+	}
-+
-+	/*
-+	 * If the current block is equal to the bad block listed in
-+	 * the bad block list, then handle that one block specially.
-+	 * (We could try to handle runs of bad blocks, but that
-+	 * only increases CPU efficiency by a small amount, at the
-+	 * expense of a huge expense of code complexity, and for an
-+	 * uncommon case at that.)
-+	 */
-+	if (blk == bb->list[scan->bad_block_ptr]) {
-+		scan->scan_flags |= EXT2_SF_BAD_INODE_BLK;
-+		*num_blocks = 1;
-+		if (++scan->bad_block_ptr >= bb->num)
-+			scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
-+		return 0;
-+	}
-+
-+	/*
-+	 * If there is a bad block in the range that we're about to
-+	 * read in, adjust the number of blocks to read so that we we
-+	 * don't read in the bad block.  (Then the next block to read
-+	 * will be the bad block, which is handled in the above case.)
-+	 */
-+	if ((blk + *num_blocks) > bb->list[scan->bad_block_ptr])
-+		*num_blocks = (int) (bb->list[scan->bad_block_ptr] - blk);
-+
-+	return 0;
-+}
-+
-+/*
-+ * This function is called by ext2fs_get_next_inode when it needs to
-+ * read in more blocks from the current blockgroup's inode table.
-+ */
-+static errcode_t get_next_blocks(ext2_inode_scan scan)
-+{
-+	blk_t		num_blocks;
-+	errcode_t	retval;
-+
-+	/*
-+	 * Figure out how many blocks to read; we read at most
-+	 * inode_buffer_blocks, and perhaps less if there aren't that
-+	 * many blocks left to read.
-+	 */
-+	num_blocks = scan->inode_buffer_blocks;
-+	if (num_blocks > scan->blocks_left)
-+		num_blocks = scan->blocks_left;
-+
-+	/*
-+	 * If the past block "read" was a bad block, then mark the
-+	 * left-over extra bytes as also being bad.
-+	 */
-+	if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK) {
-+		if (scan->bytes_left)
-+			scan->scan_flags |= EXT2_SF_BAD_EXTRA_BYTES;
-+		scan->scan_flags &= ~EXT2_SF_BAD_INODE_BLK;
-+	}
-+
-+	/*
-+	 * Do inode bad block processing, if necessary.
-+	 */
-+	if (scan->scan_flags & EXT2_SF_CHK_BADBLOCKS) {
-+		retval = check_for_inode_bad_blocks(scan, &num_blocks);
-+		if (retval)
-+			return retval;
-+	}
-+		
-+	if ((scan->scan_flags & EXT2_SF_BAD_INODE_BLK) ||
-+	    (scan->current_block == 0)) {
-+		memset(scan->inode_buffer, 0,
-+		       (size_t) num_blocks * scan->fs->blocksize);
-+	} else {
-+		retval = io_channel_read_blk(scan->fs->io,
-+					     scan->current_block,
-+					     (int) num_blocks,
-+					     scan->inode_buffer);
-+		if (retval)
-+			return EXT2_ET_NEXT_INODE_READ;
-+	}
-+	scan->ptr = scan->inode_buffer;
-+	scan->bytes_left = num_blocks * scan->fs->blocksize;
-+
-+	scan->blocks_left -= num_blocks;
-+	if (scan->current_block)
-+		scan->current_block += num_blocks;
-+	return 0;
-+}
-+
-+#if 0
-+/*
-+ * Returns 1 if the entire inode_buffer has a non-zero size and
-+ * contains all zeros.  (Not just deleted inodes, since that means
-+ * that part of the inode table was used at one point; we want all
-+ * zeros, which means that the inode table is pristine.)
-+ */
-+static inline int is_empty_scan(ext2_inode_scan scan)
-+{
-+	int	i;
-+	
-+	if (scan->bytes_left == 0)
-+		return 0;
-+
-+	for (i=0; i < scan->bytes_left; i++)
-+		if (scan->ptr[i])
-+			return 0;
-+	return 1;
-+}
-+#endif
-+
-+errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan, ext2_ino_t *ino,
-+				     struct ext2_inode *inode, int bufsize)
-+{
-+	errcode_t	retval;
-+	int		extra_bytes = 0;
-+	
-+	EXT2_CHECK_MAGIC(scan, EXT2_ET_MAGIC_INODE_SCAN);
-+
-+	/*
-+	 * Do we need to start reading a new block group?
-+	 */
-+	if (scan->inodes_left <= 0) {
-+	force_new_group:
-+		if (scan->done_group) {
-+			retval = (scan->done_group)
-+				(scan->fs, scan, scan->current_group,
-+				 scan->done_group_data);
-+			if (retval)
-+				return retval;
-+		}
-+		if (scan->groups_left <= 0) {
-+			*ino = 0;
-+			return 0;
-+		}
-+		retval = get_next_blockgroup(scan);
-+		if (retval)
-+			return retval;
-+	}
-+	/*
-+	 * This is done outside the above if statement so that the
-+	 * check can be done for block group #0.
-+	 */
-+	if (scan->current_block == 0) {
-+		if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) {
-+			goto force_new_group;
-+		} else
-+			return EXT2_ET_MISSING_INODE_TABLE;
-+	}
-+	
-+
-+	/*
-+	 * Have we run out of space in the inode buffer?  If so, we
-+	 * need to read in more blocks.
-+	 */
-+	if (scan->bytes_left < scan->inode_size) {
-+		memcpy(scan->temp_buffer, scan->ptr, scan->bytes_left);
-+		extra_bytes = scan->bytes_left;
-+
-+		retval = get_next_blocks(scan);
-+		if (retval)
-+			return retval;
-+#if 0
-+		/*
-+		 * XXX test  Need check for used inode somehow.
-+		 * (Note: this is hard.)
-+		 */
-+		if (is_empty_scan(scan))
-+			goto force_new_group;
-+#endif
-+	}
-+
-+	retval = 0;
-+	if (extra_bytes) {
-+		memcpy(scan->temp_buffer+extra_bytes, scan->ptr,
-+		       scan->inode_size - extra_bytes);
-+		scan->ptr += scan->inode_size - extra_bytes;
-+		scan->bytes_left -= scan->inode_size - extra_bytes;
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+		if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+		    (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
-+			ext2fs_swap_inode_full(scan->fs, 
-+				(struct ext2_inode_large *) inode,
-+				(struct ext2_inode_large *) scan->temp_buffer, 
-+				0, bufsize);
-+		else
-+#endif
-+			*inode = *((struct ext2_inode *) scan->temp_buffer);
-+		if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES)
-+			retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
-+		scan->scan_flags &= ~EXT2_SF_BAD_EXTRA_BYTES;
-+	} else {
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+		if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+		    (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
-+			ext2fs_swap_inode_full(scan->fs, 
-+				(struct ext2_inode_large *) inode,
-+				(struct ext2_inode_large *) scan->ptr,
-+				0, bufsize);
-+		else
-+#endif
-+			memcpy(inode, scan->ptr, bufsize);
-+		scan->ptr += scan->inode_size;
-+		scan->bytes_left -= scan->inode_size;
-+		if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK)
-+			retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
-+	}
-+
-+	scan->inodes_left--;
-+	scan->current_inode++;
-+	*ino = scan->current_inode;
-+	return retval;
-+}
-+
-+errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
-+				struct ext2_inode *inode)
-+{
-+	return ext2fs_get_next_inode_full(scan, ino, inode,
-+						sizeof(struct ext2_inode));
-+}
-+
-+/*
-+ * Functions to read and write a single inode.
-+ */
-+errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
-+				 struct ext2_inode * inode, int bufsize)
-+{
-+	unsigned long 	group, block, block_nr, offset;
-+	char 		*ptr;
-+	errcode_t	retval;
-+	int 		clen, i, inodes_per_block, length;
-+	io_channel	io;
-+
-+	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;
-+	}
-+	/* Create inode cache if not present */
-+	if (!fs->icache) {
-+		retval = create_icache(fs);
-+		if (retval)
-+			return retval;
-+	}
-+	/* Check to see if it's in the inode cache */
-+	if (bufsize == sizeof(struct ext2_inode)) {
-+		/* only old good inode can be retrieve from the cache */
-+		for (i=0; i < fs->icache->cache_size; i++) {
-+			if (fs->icache->cache[i].ino == ino) {
-+				*inode = fs->icache->cache[i].inode;
-+				return 0;
-+			}
-+		}
-+	}
-+	if ((ino == 0) || (ino > fs->super->s_inodes_count))
-+		return EXT2_ET_BAD_INODE_NUM;
-+	if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
-+		inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super);
-+		block_nr = fs->image_header->offset_inode / fs->blocksize;
-+		block_nr += (ino - 1) / inodes_per_block;
-+		offset = ((ino - 1) % inodes_per_block) *
-+			EXT2_INODE_SIZE(fs->super);
-+		io = fs->image_io;
-+	} else {
-+		group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
-+		offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
-+			EXT2_INODE_SIZE(fs->super);
-+		block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
-+		if (!fs->group_desc[(unsigned)group].bg_inode_table)
-+			return EXT2_ET_MISSING_INODE_TABLE;
-+		block_nr = fs->group_desc[(unsigned)group].bg_inode_table + 
-+			block;
-+		io = fs->io;
-+	}
-+	offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
-+
-+	length = EXT2_INODE_SIZE(fs->super);
-+	if (bufsize < length)
-+		length = bufsize;
-+
-+	ptr = (char *) inode;
-+	while (length) {
-+		clen = length;
-+		if ((offset + length) > fs->blocksize)
-+			clen = fs->blocksize - offset;
-+
-+		if (block_nr != fs->icache->buffer_blk) {
-+			retval = io_channel_read_blk(io, block_nr, 1,
-+						     fs->icache->buffer);
-+			if (retval)
-+				return retval;
-+			fs->icache->buffer_blk = block_nr;
-+		}
-+
-+		memcpy(ptr, ((char *) fs->icache->buffer) + (unsigned) offset,
-+		       clen);
-+
-+		offset = 0;
-+		length -= clen;
-+		ptr += clen;
-+		block_nr++;
-+	}
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+	    (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
-+		ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) inode, 
-+				       (struct ext2_inode_large *) inode, 
-+				       0, length);
-+#endif
-+
-+	/* Update the inode cache */
-+	fs->icache->cache_last = (fs->icache->cache_last + 1) %
-+		fs->icache->cache_size;
-+	fs->icache->cache[fs->icache->cache_last].ino = ino;
-+	fs->icache->cache[fs->icache->cache_last].inode = *inode;
-+	
-+	return 0;
-+}
-+
-+errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino,
-+			    struct ext2_inode * inode)
-+{
-+	return ext2fs_read_inode_full(fs, ino, inode,
-+					sizeof(struct ext2_inode));
-+}
-+
-+errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
-+				  struct ext2_inode * inode, int bufsize)
-+{
-+	unsigned long group, block, block_nr, offset;
-+	errcode_t retval = 0;
-+	struct ext2_inode_large temp_inode, *w_inode;
-+	char *ptr;
-+	int clen, i, length;
-+
-+	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 */
-+	if (fs->icache) {
-+		for (i=0; i < fs->icache->cache_size; i++) {
-+			if (fs->icache->cache[i].ino == ino) {
-+				fs->icache->cache[i].inode = *inode;
-+				break;
-+			}
-+		}
-+	} else {
-+		retval = create_icache(fs);
-+		if (retval)
-+			return retval;
-+	}
-+		
-+	if (!(fs->flags & EXT2_FLAG_RW))
-+		return EXT2_ET_RO_FILSYS;
-+
-+	if ((ino == 0) || (ino > fs->super->s_inodes_count))
-+		return EXT2_ET_BAD_INODE_NUM;
-+
-+	length = bufsize;
-+	if (length < EXT2_INODE_SIZE(fs->super))
-+		length = EXT2_INODE_SIZE(fs->super);
-+
-+	if (length > (int) sizeof(struct ext2_inode_large)) {
-+		w_inode = malloc(length);
-+		if (!w_inode)
-+			return ENOMEM;
-+	} else
-+		w_inode = &temp_inode;
-+	memset(w_inode, 0, length);
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+	    (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
-+		ext2fs_swap_inode_full(fs, w_inode, 
-+				       (struct ext2_inode_large *) inode, 
-+				       1, bufsize);
-+	else
-+#endif
-+		memcpy(w_inode, inode, bufsize);
-+	
-+	group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
-+	offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
-+		EXT2_INODE_SIZE(fs->super);
-+	block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
-+	if (!fs->group_desc[(unsigned) group].bg_inode_table)
-+		return EXT2_ET_MISSING_INODE_TABLE;
-+	block_nr = fs->group_desc[(unsigned) group].bg_inode_table + block;
-+
-+	offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
-+
-+	length = EXT2_INODE_SIZE(fs->super);
-+	if (length > bufsize)
-+		length = bufsize;
-+
-+	ptr = (char *) w_inode;
-+
-+	while (length) {
-+		clen = length;
-+		if ((offset + length) > fs->blocksize)
-+			clen = fs->blocksize - offset;
-+
-+		if (fs->icache->buffer_blk != block_nr) {
-+			retval = io_channel_read_blk(fs->io, block_nr, 1,
-+						     fs->icache->buffer);
-+			if (retval)
-+				goto errout;
-+			fs->icache->buffer_blk = block_nr;
-+		}
-+
-+	
-+		memcpy((char *) fs->icache->buffer + (unsigned) offset, 
-+		       ptr, clen);
-+
-+		retval = io_channel_write_blk(fs->io, block_nr, 1, 
-+					      fs->icache->buffer);
-+		if (retval)
-+			goto errout;
-+
-+		offset = 0;
-+		ptr += clen;
-+		length -= clen;
-+		block_nr++;
-+	}
-+		
-+	fs->flags |= EXT2_FLAG_CHANGED;
-+errout:
-+	if (w_inode && w_inode != &temp_inode)
-+		free(w_inode);
-+	return retval;
-+}
-+
-+errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
-+			     struct ext2_inode *inode)
-+{
-+	return ext2fs_write_inode_full(fs, ino, inode,
-+				       sizeof(struct ext2_inode));
-+}
-+
-+/* 
-+ * This function should be called when writing a new inode.  It makes
-+ * sure that extra part of large inodes is initialized properly.
-+ */
-+errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
-+				 struct ext2_inode *inode)
-+{
-+	struct ext2_inode	*buf;
-+	int 			size = EXT2_INODE_SIZE(fs->super);
-+	struct ext2_inode_large	*large_inode;
-+
-+	if (size == sizeof(struct ext2_inode))
-+		return ext2fs_write_inode_full(fs, ino, inode,
-+					       sizeof(struct ext2_inode));
-+
-+	buf = malloc(size);
-+	if (!buf)
-+		return ENOMEM;
-+
-+	memset(buf, 0, size);
-+	*buf = *inode;
-+
-+	large_inode = (struct ext2_inode_large *) buf;
-+	large_inode->i_extra_isize = sizeof(struct ext2_inode_large) - 
-+		EXT2_GOOD_OLD_INODE_SIZE;
-+
-+	return ext2fs_write_inode_full(fs, ino, buf, size);
-+}
-+
-+ 
-+errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks)
-+{
-+	struct ext2_inode	inode;
-+	int			i;
-+	errcode_t		retval;
-+	
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (ino > fs->super->s_inodes_count)
-+		return EXT2_ET_BAD_INODE_NUM;
-+
-+	if (fs->get_blocks) {
-+		if (!(*fs->get_blocks)(fs, ino, blocks))
-+			return 0;
-+	}
-+	retval = ext2fs_read_inode(fs, ino, &inode);
-+	if (retval)
-+		return retval;
-+	for (i=0; i < EXT2_N_BLOCKS; i++)
-+		blocks[i] = inode.i_block[i];
-+	return 0;
-+}
-+
-+errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino)
-+{
-+	struct	ext2_inode	inode;
-+	errcode_t		retval;
-+	
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (ino > fs->super->s_inodes_count)
-+		return EXT2_ET_BAD_INODE_NUM;
-+
-+	if (fs->check_directory) {
-+		retval = (fs->check_directory)(fs, ino);
-+		if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
-+			return retval;
-+	}
-+	retval = ext2fs_read_inode(fs, ino, &inode);
-+	if (retval)
-+		return retval;
-+	if (!LINUX_S_ISDIR(inode.i_mode))
-+		return EXT2_ET_NO_DIRECTORY;
-+	return 0;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/inode_io.c silo-1.4.14/libext2fs/inode_io.c
---- silo-1.4.14.orig/libext2fs/inode_io.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/inode_io.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,270 @@
-+/*
-+ * inode_io.c --- This is allows an inode in an ext2 filesystem image
-+ * 	to be accessed via the I/O manager interface.
-+ *
-+ * Copyright (C) 2002 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * For checking structure magic numbers...
-+ */
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+	  if ((struct)->magic != (code)) return (code)
-+
-+struct inode_private_data {
-+	int				magic;
-+	char				name[32];
-+	ext2_file_t			file;
-+	ext2_filsys			fs;
-+	ext2_ino_t 			ino;
-+	struct ext2_inode		inode;
-+	int				flags;
-+	struct inode_private_data	*next;
-+};
-+
-+#define CHANNEL_HAS_INODE	0x8000
-+
-+static struct inode_private_data *top_intern;
-+static int ino_unique = 0;
-+
-+static errcode_t inode_open(const char *name, int flags, io_channel *channel);
-+static errcode_t inode_close(io_channel channel);
-+static errcode_t inode_set_blksize(io_channel channel, int blksize);
-+static errcode_t inode_read_blk(io_channel channel, unsigned long block,
-+			       int count, void *data);
-+static errcode_t inode_write_blk(io_channel channel, unsigned long block,
-+				int count, const void *data);
-+static errcode_t inode_flush(io_channel channel);
-+static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
-+				int size, const void *data);
-+
-+static struct struct_io_manager struct_inode_manager = {
-+	EXT2_ET_MAGIC_IO_MANAGER,
-+	"Inode I/O Manager",
-+	inode_open,
-+	inode_close,
-+	inode_set_blksize,
-+	inode_read_blk,
-+	inode_write_blk,
-+	inode_flush,
-+	inode_write_byte
-+};
-+
-+io_manager inode_io_manager = &struct_inode_manager;
-+
-+errcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
-+				  struct ext2_inode *inode,
-+				  char **name)
-+{
-+	struct inode_private_data 	*data;
-+	errcode_t			retval;
-+
-+	if ((retval = ext2fs_get_mem(sizeof(struct inode_private_data),
-+				     &data)))
-+		return retval;
-+	data->magic = EXT2_ET_MAGIC_INODE_IO_CHANNEL;
-+	sprintf(data->name, "%u:%d", ino, ino_unique++);
-+	data->file = 0;
-+	data->fs = fs;
-+	data->ino = ino;
-+	data->flags = 0;
-+	if (inode) {
-+		memcpy(&data->inode, inode, sizeof(struct ext2_inode));
-+		data->flags |= CHANNEL_HAS_INODE;
-+	}
-+	data->next = top_intern;
-+	top_intern = data;
-+	*name = data->name;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
-+				 char **name)
-+{
-+	return ext2fs_inode_io_intern2(fs, ino, NULL, name);
-+}
-+
-+
-+static errcode_t inode_open(const char *name, int flags, io_channel *channel)
-+{
-+	io_channel	io = NULL;
-+	struct inode_private_data *prev, *data = NULL;
-+	errcode_t	retval;
-+	int		open_flags;
-+
-+	if (name == 0)
-+		return EXT2_ET_BAD_DEVICE_NAME;
-+
-+	for (data = top_intern, prev = NULL; data;
-+	     prev = data, data = data->next)
-+		if (strcmp(name, data->name) == 0)
-+			break;
-+	if (!data)
-+		return ENOENT;
-+	if (prev)
-+		prev->next = data->next;
-+	else
-+		top_intern = data->next;
-+
-+	retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
-+	if (retval)
-+		goto cleanup;
-+	memset(io, 0, sizeof(struct struct_io_channel));
-+
-+	io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
-+	io->manager = inode_io_manager;
-+	retval = ext2fs_get_mem(strlen(name)+1, &io->name);
-+	if (retval)
-+		goto cleanup;
-+
-+	strcpy(io->name, name);
-+	io->private_data = data;
-+	io->block_size = 1024;
-+	io->read_error = 0;
-+	io->write_error = 0;
-+	io->refcount = 1;
-+
-+	open_flags = (flags & IO_FLAG_RW) ? EXT2_FILE_WRITE : 0;
-+	retval = ext2fs_file_open2(data->fs, data->ino,
-+				   (data->flags & CHANNEL_HAS_INODE) ?
-+				   &data->inode : 0, open_flags,
-+				   &data->file);
-+	if (retval)
-+		goto cleanup;
-+		
-+	*channel = io;
-+	return 0;
-+
-+cleanup:
-+	if (data) {
-+		ext2fs_free_mem(&data);
-+	}
-+	if (io)
-+		ext2fs_free_mem(&io);
-+	return retval;
-+}
-+
-+static errcode_t inode_close(io_channel channel)
-+{
-+	struct inode_private_data *data;
-+	errcode_t	retval = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct inode_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+	if (--channel->refcount > 0)
-+		return 0;
-+
-+	retval = ext2fs_file_close(data->file);
-+	
-+	ext2fs_free_mem(&channel->private_data);
-+	if (channel->name)
-+		ext2fs_free_mem(&channel->name);
-+	ext2fs_free_mem(&channel);
-+	return retval;
-+}
-+
-+static errcode_t inode_set_blksize(io_channel channel, int blksize)
-+{
-+	struct inode_private_data *data;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct inode_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+	channel->block_size = blksize;
-+	return 0;
-+}
-+
-+
-+static errcode_t inode_read_blk(io_channel channel, unsigned long block,
-+			       int count, void *buf)
-+{
-+	struct inode_private_data *data;
-+	errcode_t	retval;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct inode_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+	if ((retval = ext2fs_file_lseek(data->file,
-+					block * channel->block_size,
-+					EXT2_SEEK_SET, 0)))
-+		return retval;
-+
-+	count = (count < 0) ? -count : (count * channel->block_size);
-+
-+	return ext2fs_file_read(data->file, buf, count, 0);
-+}
-+
-+static errcode_t inode_write_blk(io_channel channel, unsigned long block,
-+				int count, const void *buf)
-+{
-+	struct inode_private_data *data;
-+	errcode_t	retval;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct inode_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+	if ((retval = ext2fs_file_lseek(data->file,
-+					block * channel->block_size,
-+					EXT2_SEEK_SET, 0)))
-+		return retval;
-+
-+	count = (count < 0) ? -count : (count * channel->block_size);
-+
-+	return ext2fs_file_write(data->file, buf, count, 0);
-+}
-+
-+static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
-+				 int size, const void *buf)
-+{
-+	struct inode_private_data *data;
-+	errcode_t	retval = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct inode_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+	if ((retval = ext2fs_file_lseek(data->file, offset,
-+					EXT2_SEEK_SET, 0)))
-+		return retval;
-+
-+	return ext2fs_file_write(data->file, buf, size, 0);
-+}
-+
-+/*
-+ * Flush data buffers to disk.  
-+ */
-+static errcode_t inode_flush(io_channel channel)
-+{
-+	struct inode_private_data *data;
-+	
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct inode_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+	return ext2fs_file_flush(data->file);
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/io_manager.c silo-1.4.14/libext2fs/io_manager.c
---- silo-1.4.14.orig/libext2fs/io_manager.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/io_manager.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,69 @@
-+/*
-+ * io_manager.c --- the I/O manager abstraction
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t io_channel_set_options(io_channel channel, const char *opts)
-+{
-+	errcode_t retval = 0;
-+	char *next, *ptr, *options, *arg;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+
-+	if (!opts)
-+		return 0;
-+
-+	if (!channel->manager->set_option)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	options = malloc(strlen(opts)+1);
-+	if (!options)
-+		return EXT2_ET_NO_MEMORY;
-+	strcpy(options, opts);
-+	ptr = options;
-+
-+	while (ptr && *ptr) {
-+		next = strchr(ptr, '&');
-+		if (next)
-+			*next++ = 0;
-+
-+		arg = strchr(ptr, '=');
-+		if (arg)
-+			*arg++ = 0;
-+
-+		retval = (channel->manager->set_option)(channel, ptr, arg);
-+		if (retval)
-+			break;
-+		ptr = next;
-+	}
-+	free(options);
-+	return retval;
-+}
-+
-+errcode_t io_channel_write_byte(io_channel channel, unsigned long offset,
-+				int count, const void *data)
-+{
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+
-+	if (channel->manager->write_byte) 
-+		return channel->manager->write_byte(channel, offset, 
-+						    count, data);
-+
-+	return EXT2_ET_UNIMPLEMENTED;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/irel.h silo-1.4.14/libext2fs/irel.h
---- silo-1.4.14.orig/libext2fs/irel.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/irel.h	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,114 @@
-+/*
-+ * irel.h
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+struct ext2_inode_reference {
-+	blk_t	block;
-+	__u16 offset;
-+};
-+
-+struct ext2_inode_relocate_entry {
-+	ext2_ino_t	new;
-+	ext2_ino_t	orig;
-+	__u16		flags;
-+	__u16		max_refs;
-+};
-+
-+typedef struct ext2_inode_relocation_table *ext2_irel;
-+
-+struct ext2_inode_relocation_table {
-+	__u32	magic;
-+	char	*name;
-+	ext2_ino_t	current;
-+	void	*priv_data;
-+
-+	/*
-+	 * Add an inode relocation entry.
-+	 */
-+	errcode_t (*put)(ext2_irel irel, ext2_ino_t old,
-+			      struct ext2_inode_relocate_entry *ent);
-+	/*
-+	 * Get an inode relocation entry.
-+	 */
-+	errcode_t (*get)(ext2_irel irel, ext2_ino_t old,
-+			      struct ext2_inode_relocate_entry *ent);
-+
-+	/*
-+	 * Get an inode relocation entry by its original inode number
-+	 */
-+	errcode_t (*get_by_orig)(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
-+				 struct ext2_inode_relocate_entry *ent);
-+
-+	/*
-+	 * Initialize for iterating over the inode relocation entries.
-+	 */
-+	errcode_t (*start_iter)(ext2_irel irel);
-+
-+	/*
-+	 * The iterator function for the inode relocation entries.
-+	 * Returns an inode number of 0 when out of entries.
-+	 */
-+	errcode_t (*next)(ext2_irel irel, ext2_ino_t *old,
-+			  struct ext2_inode_relocate_entry *ent);
-+
-+	/*
-+	 * Add an inode reference (i.e., note the fact that a
-+	 * particular block/offset contains a reference to an inode)
-+	 */
-+	errcode_t (*add_ref)(ext2_irel irel, ext2_ino_t ino,
-+			     struct ext2_inode_reference *ref);
-+
-+	/*
-+	 * Initialize for iterating over the inode references for a
-+	 * particular inode.
-+	 */
-+	errcode_t (*start_iter_ref)(ext2_irel irel, ext2_ino_t ino);
-+
-+	/*
-+	 * The iterator function for the inode references for an
-+	 * inode.  The references for only one inode can be interator
-+	 * over at a time, as the iterator state is stored in ext2_irel.
-+	 */
-+	errcode_t (*next_ref)(ext2_irel irel,
-+			      struct ext2_inode_reference *ref);
-+
-+	/*
-+	 * Move the inode relocation table from one inode number to
-+	 * another.  Note that the inode references also must move.
-+	 */
-+	errcode_t (*move)(ext2_irel irel, ext2_ino_t old, ext2_ino_t new);
-+
-+	/*
-+	 * Remove an inode relocation entry, along with all of the
-+	 * inode references.
-+	 */
-+	errcode_t (*delete)(ext2_irel irel, ext2_ino_t old);
-+
-+	/*
-+	 * Free the inode relocation table.
-+	 */
-+	errcode_t (*free)(ext2_irel irel);
-+};
-+
-+errcode_t ext2fs_irel_memarray_create(char *name, ext2_ino_t max_inode,
-+				    ext2_irel *irel);
-+
-+#define ext2fs_irel_put(irel, old, ent) ((irel)->put((irel), old, ent))
-+#define ext2fs_irel_get(irel, old, ent) ((irel)->get((irel), old, ent))
-+#define ext2fs_irel_get_by_orig(irel, orig, old, ent) \
-+			((irel)->get_by_orig((irel), orig, old, ent))
-+#define ext2fs_irel_start_iter(irel) ((irel)->start_iter((irel)))
-+#define ext2fs_irel_next(irel, old, ent) ((irel)->next((irel), old, ent))
-+#define ext2fs_irel_add_ref(irel, ino, ref) ((irel)->add_ref((irel), ino, ref))
-+#define ext2fs_irel_start_iter_ref(irel, ino) ((irel)->start_iter_ref((irel), ino))
-+#define ext2fs_irel_next_ref(irel, ref) ((irel)->next_ref((irel), ref))
-+#define ext2fs_irel_move(irel, old, new) ((irel)->move((irel), old, new))
-+#define ext2fs_irel_delete(irel, old) ((irel)->delete((irel), old))
-+#define ext2fs_irel_free(irel) ((irel)->free((irel)))
-diff -Naur silo-1.4.14.orig/libext2fs/irel_ma.c silo-1.4.14/libext2fs/irel_ma.c
---- silo-1.4.14.orig/libext2fs/irel_ma.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/irel_ma.c	2011-01-10 21:59:35.419156677 -0500
-@@ -0,0 +1,372 @@
-+/*
-+ * irel_ma.c
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <fcntl.h>
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+#include "irel.h"
-+
-+static errcode_t ima_put(ext2_irel irel, ext2_ino_t old,
-+			 struct ext2_inode_relocate_entry *ent);
-+static errcode_t ima_get(ext2_irel irel, ext2_ino_t old,
-+			 struct ext2_inode_relocate_entry *ent);
-+static errcode_t ima_get_by_orig(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
-+				 struct ext2_inode_relocate_entry *ent);
-+static errcode_t ima_start_iter(ext2_irel irel);
-+static errcode_t ima_next(ext2_irel irel, ext2_ino_t *old,
-+			  struct ext2_inode_relocate_entry *ent);
-+static errcode_t ima_add_ref(ext2_irel irel, ext2_ino_t ino,
-+			     struct ext2_inode_reference *ref);
-+static errcode_t ima_start_iter_ref(ext2_irel irel, ext2_ino_t ino);
-+static errcode_t ima_next_ref(ext2_irel irel, struct ext2_inode_reference *ref);
-+static errcode_t ima_move(ext2_irel irel, ext2_ino_t old, ext2_ino_t new);
-+static errcode_t ima_delete(ext2_irel irel, ext2_ino_t old);
-+static errcode_t ima_free(ext2_irel irel);
-+
-+/*
-+ * This data structure stores the array of inode references; there is
-+ * a structure for each inode.
-+ */
-+struct inode_reference_entry {
-+	__u16 num;
-+	struct ext2_inode_reference *refs;
-+};
-+
-+struct irel_ma {
-+	__u32 magic;
-+	ext2_ino_t max_inode;
-+	ext2_ino_t ref_current;
-+	int   ref_iter;
-+	ext2_ino_t	*orig_map;
-+	struct ext2_inode_relocate_entry *entries;
-+	struct inode_reference_entry *ref_entries;
-+};
-+
-+errcode_t ext2fs_irel_memarray_create(char *name, ext2_ino_t max_inode,
-+				      ext2_irel *new_irel)
-+{
-+	ext2_irel		irel = 0;
-+	errcode_t	retval;
-+	struct irel_ma 	*ma = 0;
-+	size_t		size;
-+
-+	*new_irel = 0;
-+
-+	/*
-+	 * Allocate memory structures
-+	 */
-+	retval = ext2fs_get_mem(sizeof(struct ext2_inode_relocation_table),
-+				&irel);
-+	if (retval)
-+		goto errout;
-+	memset(irel, 0, sizeof(struct ext2_inode_relocation_table));
-+	
-+	retval = ext2fs_get_mem(strlen(name)+1, &irel->name);
-+	if (retval)
-+		goto errout;
-+	strcpy(irel->name, name);
-+	
-+	retval = ext2fs_get_mem(sizeof(struct irel_ma), &ma);
-+	if (retval)
-+		goto errout;
-+	memset(ma, 0, sizeof(struct irel_ma));
-+	irel->priv_data = ma;
-+	
-+	size = (size_t) (sizeof(ext2_ino_t) * (max_inode+1));
-+	retval = ext2fs_get_mem(size, &ma->orig_map);
-+	if (retval)
-+		goto errout;
-+	memset(ma->orig_map, 0, size);
-+
-+	size = (size_t) (sizeof(struct ext2_inode_relocate_entry) *
-+			 (max_inode+1));
-+	retval = ext2fs_get_mem(size, &ma->entries);
-+	if (retval)
-+		goto errout;
-+	memset(ma->entries, 0, size);
-+
-+	size = (size_t) (sizeof(struct inode_reference_entry) *
-+			 (max_inode+1));
-+	retval = ext2fs_get_mem(size, &ma->ref_entries);
-+	if (retval)
-+		goto errout;
-+	memset(ma->ref_entries, 0, size);
-+	ma->max_inode = max_inode;
-+
-+	/*
-+	 * Fill in the irel data structure
-+	 */
-+	irel->put = ima_put;
-+	irel->get = ima_get;
-+	irel->get_by_orig = ima_get_by_orig;
-+	irel->start_iter = ima_start_iter;
-+	irel->next = ima_next;
-+	irel->add_ref = ima_add_ref;
-+	irel->start_iter_ref = ima_start_iter_ref;
-+	irel->next_ref = ima_next_ref;
-+	irel->move = ima_move;
-+	irel->delete = ima_delete;
-+	irel->free = ima_free;
-+	
-+	*new_irel = irel;
-+	return 0;
-+
-+errout:
-+	ima_free(irel);
-+	return retval;
-+}
-+
-+static errcode_t ima_put(ext2_irel irel, ext2_ino_t old,
-+			struct ext2_inode_relocate_entry *ent)
-+{
-+	struct inode_reference_entry	*ref_ent;
-+	struct irel_ma 			*ma;
-+	errcode_t			retval;
-+	size_t				size, old_size;
-+
-+	ma = irel->priv_data;
-+	if (old > ma->max_inode)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	/*
-+	 * Force the orig field to the correct value; the application
-+	 * program shouldn't be messing with this field.
-+	 */
-+	if (ma->entries[(unsigned) old].new == 0)
-+		ent->orig = old;
-+	else
-+		ent->orig = ma->entries[(unsigned) old].orig;
-+	
-+	/*
-+	 * If max_refs has changed, reallocate the refs array
-+	 */
-+	ref_ent = ma->ref_entries + (unsigned) old;
-+	if (ref_ent->refs && ent->max_refs !=
-+	    ma->entries[(unsigned) old].max_refs) {
-+		size = (sizeof(struct ext2_inode_reference) * ent->max_refs);
-+		old_size = (sizeof(struct ext2_inode_reference) *
-+			    ma->entries[(unsigned) old].max_refs);
-+		retval = ext2fs_resize_mem(old_size, size, &ref_ent->refs);
-+		if (retval)
-+			return retval;
-+	}
-+
-+	ma->entries[(unsigned) old] = *ent;
-+	ma->orig_map[(unsigned) ent->orig] = old;
-+	return 0;
-+}
-+
-+static errcode_t ima_get(ext2_irel irel, ext2_ino_t old,
-+			struct ext2_inode_relocate_entry *ent)
-+{
-+	struct irel_ma 	*ma;
-+
-+	ma = irel->priv_data;
-+	if (old > ma->max_inode)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	if (ma->entries[(unsigned) old].new == 0)
-+		return ENOENT;
-+	*ent = ma->entries[(unsigned) old];
-+	return 0;
-+}
-+
-+static errcode_t ima_get_by_orig(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
-+			struct ext2_inode_relocate_entry *ent)
-+{
-+	struct irel_ma 	*ma;
-+	ext2_ino_t	ino;
-+
-+	ma = irel->priv_data;
-+	if (orig > ma->max_inode)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	ino = ma->orig_map[(unsigned) orig];
-+	if (ino == 0)
-+		return ENOENT;
-+	*old = ino;
-+	*ent = ma->entries[(unsigned) ino];
-+	return 0;
-+}
-+
-+static errcode_t ima_start_iter(ext2_irel irel)
-+{
-+	irel->current = 0;
-+	return 0;
-+}
-+
-+static errcode_t ima_next(ext2_irel irel, ext2_ino_t *old,
-+			 struct ext2_inode_relocate_entry *ent)
-+{
-+	struct irel_ma 	*ma;
-+
-+	ma = irel->priv_data;
-+	while (++irel->current < ma->max_inode) {
-+		if (ma->entries[(unsigned) irel->current].new == 0)
-+			continue;
-+		*old = irel->current;
-+		*ent = ma->entries[(unsigned) irel->current];
-+		return 0;
-+	}
-+	*old = 0;
-+	return 0;
-+}
-+
-+static errcode_t ima_add_ref(ext2_irel irel, ext2_ino_t ino,
-+			     struct ext2_inode_reference *ref)
-+{
-+	struct irel_ma 	*ma;
-+	size_t		size;
-+	struct inode_reference_entry *ref_ent;
-+	struct ext2_inode_relocate_entry *ent;
-+	errcode_t		retval;
-+
-+	ma = irel->priv_data;
-+	if (ino > ma->max_inode)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	ref_ent = ma->ref_entries + (unsigned) ino;
-+	ent = ma->entries + (unsigned) ino;
-+	
-+	/*
-+	 * If the inode reference array doesn't exist, create it.
-+	 */
-+	if (ref_ent->refs == 0) {
-+		size = (size_t) ((sizeof(struct ext2_inode_reference) * 
-+				  ent->max_refs));
-+		retval = ext2fs_get_mem(size, &ref_ent->refs);
-+		if (retval)
-+			return retval;
-+		memset(ref_ent->refs, 0, size);
-+		ref_ent->num = 0;
-+	}
-+
-+	if (ref_ent->num >= ent->max_refs)
-+		return EXT2_ET_TOO_MANY_REFS;
-+
-+	ref_ent->refs[(unsigned) ref_ent->num++] = *ref;
-+	return 0;
-+}
-+
-+static errcode_t ima_start_iter_ref(ext2_irel irel, ext2_ino_t ino)
-+{
-+	struct irel_ma 	*ma;
-+
-+	ma = irel->priv_data;
-+	if (ino > ma->max_inode)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	if (ma->entries[(unsigned) ino].new == 0)
-+		return ENOENT;
-+	ma->ref_current = ino;
-+	ma->ref_iter = 0;
-+	return 0;
-+}
-+
-+static errcode_t ima_next_ref(ext2_irel irel,
-+			      struct ext2_inode_reference *ref)
-+{
-+	struct irel_ma 	*ma;
-+	struct inode_reference_entry *ref_ent;
-+
-+	ma = irel->priv_data;
-+	
-+	ref_ent = ma->ref_entries + ma->ref_current;
-+
-+	if ((ref_ent->refs == NULL) ||
-+	    (ma->ref_iter >= ref_ent->num)) {
-+		ref->block = 0;
-+		ref->offset = 0;
-+		return 0;
-+	}
-+	*ref = ref_ent->refs[ma->ref_iter++];
-+	return 0;
-+}
-+
-+
-+static errcode_t ima_move(ext2_irel irel, ext2_ino_t old, ext2_ino_t new)
-+{
-+	struct irel_ma 	*ma;
-+
-+	ma = irel->priv_data;
-+	if ((old > ma->max_inode) || (new > ma->max_inode))
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	if (ma->entries[(unsigned) old].new == 0)
-+		return ENOENT;
-+	
-+	ma->entries[(unsigned) new] = ma->entries[(unsigned) old];
-+	if (ma->ref_entries[(unsigned) new].refs)
-+		ext2fs_free_mem(&ma->ref_entries[(unsigned) new].refs);
-+	ma->ref_entries[(unsigned) new] = ma->ref_entries[(unsigned) old];
-+	
-+	ma->entries[(unsigned) old].new = 0;
-+	ma->ref_entries[(unsigned) old].num = 0;
-+	ma->ref_entries[(unsigned) old].refs = 0;
-+
-+	ma->orig_map[ma->entries[new].orig] = new;
-+	return 0;
-+}
-+
-+static errcode_t ima_delete(ext2_irel irel, ext2_ino_t old)
-+{
-+	struct irel_ma 	*ma;
-+
-+	ma = irel->priv_data;
-+	if (old > ma->max_inode)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+	if (ma->entries[(unsigned) old].new == 0)
-+		return ENOENT;
-+	
-+	ma->entries[old].new = 0;
-+	if (ma->ref_entries[(unsigned) old].refs)
-+		ext2fs_free_mem(&ma->ref_entries[(unsigned) old].refs);
-+	ma->orig_map[ma->entries[(unsigned) old].orig] = 0;
-+	
-+	ma->ref_entries[(unsigned) old].num = 0;
-+	ma->ref_entries[(unsigned) old].refs = 0;
-+	return 0;
-+}
-+
-+static errcode_t ima_free(ext2_irel irel)
-+{
-+	struct irel_ma 	*ma;
-+	ext2_ino_t	ino;
-+
-+	if (!irel)
-+		return 0;
-+
-+	ma = irel->priv_data;
-+
-+	if (ma) {
-+		if (ma->orig_map)
-+			ext2fs_free_mem(&ma->orig_map);
-+		if (ma->entries)
-+			ext2fs_free_mem(&ma->entries);
-+		if (ma->ref_entries) {
-+			for (ino = 0; ino <= ma->max_inode; ino++) {
-+				if (ma->ref_entries[(unsigned) ino].refs)
-+					ext2fs_free_mem(&ma->ref_entries[(unsigned) ino].refs);
-+			}
-+			ext2fs_free_mem(&ma->ref_entries);
-+		}
-+		ext2fs_free_mem(&ma);
-+	}
-+	if (irel->name)
-+		ext2fs_free_mem(&irel->name);
-+	ext2fs_free_mem(&irel);
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/ismounted.c silo-1.4.14/libext2fs/ismounted.c
---- silo-1.4.14.orig/libext2fs/ismounted.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/ismounted.c	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,377 @@
-+/*
-+ * ismounted.c --- Check to see if the filesystem was mounted
-+ * 
-+ * Copyright (C) 1995,1996,1997,1998,1999,2000 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#ifdef HAVE_LINUX_FD_H
-+#include <linux/fd.h>
-+#endif
-+#ifdef HAVE_MNTENT_H
-+#include <mntent.h>
-+#endif
-+#ifdef HAVE_GETMNTINFO
-+#include <paths.h>
-+#include <sys/param.h>
-+#include <sys/mount.h>
-+#endif /* HAVE_GETMNTINFO */
-+#include <string.h>
-+#include <sys/stat.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#ifdef HAVE_MNTENT_H
-+/*
-+ * Helper function which checks a file in /etc/mtab format to see if a
-+ * filesystem is mounted.  Returns an error if the file doesn't exist
-+ * or can't be opened.  
-+ */
-+static errcode_t check_mntent_file(const char *mtab_file, const char *file, 
-+				   int *mount_flags, char *mtpt, int mtlen)
-+{
-+	struct mntent 	*mnt;
-+	struct stat	st_buf;
-+	errcode_t	retval = 0;
-+	dev_t		file_dev=0, file_rdev=0;
-+	ino_t		file_ino=0;
-+	FILE 		*f;
-+	int		fd;
-+
-+	*mount_flags = 0;
-+	if ((f = setmntent (mtab_file, "r")) == NULL)
-+		return errno;
-+	if (stat(file, &st_buf) == 0) {
-+		if (S_ISBLK(st_buf.st_mode)) {
-+#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
-+			file_rdev = st_buf.st_rdev;
-+#endif	/* __GNU__ */
-+		} else {
-+			file_dev = st_buf.st_dev;
-+			file_ino = st_buf.st_ino;
-+		}
-+	}
-+	while ((mnt = getmntent (f)) != NULL) {
-+		if (strcmp(file, mnt->mnt_fsname) == 0)
-+			break;
-+		if (stat(mnt->mnt_fsname, &st_buf) == 0) {
-+			if (S_ISBLK(st_buf.st_mode)) {
-+#ifndef __GNU__
-+				if (file_rdev && (file_rdev == st_buf.st_rdev))
-+					break;
-+#endif	/* __GNU__ */
-+			} else {
-+				if (file_dev && ((file_dev == st_buf.st_dev) &&
-+						 (file_ino == st_buf.st_ino)))
-+					break;
-+			}
-+		}
-+	}
-+
-+	if (mnt == 0) {
-+#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
-+		/*
-+		 * Do an extra check to see if this is the root device.  We
-+		 * can't trust /etc/mtab, and /proc/mounts will only list
-+		 * /dev/root for the root filesystem.  Argh.  Instead we
-+		 * check if the given device has the same major/minor number
-+		 * as the device that the root directory is on.
-+		 */
-+		if (file_rdev && stat("/", &st_buf) == 0) {
-+			if (st_buf.st_dev == file_rdev) {
-+				*mount_flags = EXT2_MF_MOUNTED;
-+				if (mtpt)
-+					strncpy(mtpt, "/", mtlen);
-+				goto is_root;
-+			}
-+		}
-+#endif	/* __GNU__ */
-+		goto errout;
-+	}
-+#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */
-+	/* Validate the entry in case /etc/mtab is out of date */
-+	/* 
-+	 * We need to be paranoid, because some broken distributions
-+	 * (read: Slackware) don't initialize /etc/mtab before checking
-+	 * all of the non-root filesystems on the disk.
-+	 */
-+	if (stat(mnt->mnt_dir, &st_buf) < 0) {
-+		retval = errno;
-+		if (retval == ENOENT) {
-+#ifdef DEBUG
-+			printf("Bogus entry in %s!  (%s does not exist)\n",
-+			       mtab_file, mnt->mnt_dir);
-+#endif /* DEBUG */
-+			retval = 0;
-+		}
-+		goto errout;
-+	}
-+	if (file_rdev && (st_buf.st_dev != file_rdev)) {
-+#ifdef DEBUG
-+		printf("Bogus entry in %s!  (%s not mounted on %s)\n",
-+		       mtab_file, file, mnt->mnt_dir);
-+#endif /* DEBUG */
-+		goto errout;
-+	}
-+#endif /* __GNU__ */
-+	*mount_flags = EXT2_MF_MOUNTED;
-+	
-+#ifdef MNTOPT_RO
-+	/* Check to see if the ro option is set */
-+	if (hasmntopt(mnt, MNTOPT_RO))
-+		*mount_flags |= EXT2_MF_READONLY;
-+#endif
-+
-+	if (mtpt)
-+		strncpy(mtpt, mnt->mnt_dir, mtlen);
-+	/*
-+	 * Check to see if we're referring to the root filesystem.
-+	 * If so, do a manual check to see if we can open /etc/mtab
-+	 * read/write, since if the root is mounted read/only, the
-+	 * contents of /etc/mtab may not be accurate.
-+	 */
-+	if (!strcmp(mnt->mnt_dir, "/")) {
-+is_root:
-+#define TEST_FILE "/.ismount-test-file"		
-+		*mount_flags |= EXT2_MF_ISROOT;
-+		fd = open(TEST_FILE, O_RDWR|O_CREAT);
-+		if (fd < 0) {
-+			if (errno == EROFS)
-+				*mount_flags |= EXT2_MF_READONLY;
-+		} else
-+			close(fd);
-+		(void) unlink(TEST_FILE);
-+	}
-+	retval = 0;
-+errout:
-+	endmntent (f);
-+	return retval;
-+}
-+
-+static errcode_t check_mntent(const char *file, int *mount_flags,
-+			      char *mtpt, int mtlen)
-+{
-+	errcode_t	retval;
-+
-+#ifdef DEBUG
-+	retval = check_mntent_file("/tmp/mtab", file, mount_flags,
-+				   mtpt, mtlen);
-+	if (retval == 0)
-+		return 0;
-+#endif /* DEBUG */
-+#ifdef __linux__
-+	retval = check_mntent_file("/proc/mounts", file, mount_flags,
-+				   mtpt, mtlen);
-+	if (retval == 0 && (*mount_flags != 0))
-+		return 0;
-+#endif /* __linux__ */
-+#if defined(MOUNTED) || defined(_PATH_MOUNTED)
-+#ifndef MOUNTED
-+#define MOUNTED _PATH_MOUNTED
-+#endif /* MOUNTED */
-+	retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen);
-+	return retval;
-+#else 
-+	*mount_flags = 0;
-+	return 0;
-+#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */
-+}
-+
-+#else
-+#if defined(HAVE_GETMNTINFO)
-+
-+static errcode_t check_getmntinfo(const char *file, int *mount_flags,
-+				  char *mtpt, int mtlen)
-+{
-+	struct statfs *mp;
-+        int    len, n;
-+        const  char   *s1;
-+	char	*s2;
-+
-+        n = getmntinfo(&mp, MNT_NOWAIT);
-+        if (n == 0)
-+		return errno;
-+
-+        len = sizeof(_PATH_DEV) - 1;
-+        s1 = file;
-+        if (strncmp(_PATH_DEV, s1, len) == 0)
-+                s1 += len;
-+ 
-+	*mount_flags = 0;
-+        while (--n >= 0) {
-+                s2 = mp->f_mntfromname;
-+                if (strncmp(_PATH_DEV, s2, len) == 0) {
-+                        s2 += len - 1;
-+                        *s2 = 'r';
-+                }
-+                if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) {
-+			*mount_flags = EXT2_MF_MOUNTED;
-+			break;
-+		}
-+                ++mp;
-+	}
-+	if (mtpt)
-+		strncpy(mtpt, mp->f_mntonname, mtlen);
-+	return 0;
-+}
-+#endif /* HAVE_GETMNTINFO */
-+#endif /* HAVE_MNTENT_H */
-+
-+/*
-+ * Check to see if we're dealing with the swap device.
-+ */
-+static int is_swap_device(const char *file)
-+{
-+	FILE		*f;
-+	char		buf[1024], *cp;
-+	dev_t		file_dev;
-+	struct stat	st_buf;
-+	int		ret = 0;
-+
-+	file_dev = 0;
-+#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
-+	if ((stat(file, &st_buf) == 0) &&
-+	    S_ISBLK(st_buf.st_mode))
-+		file_dev = st_buf.st_rdev;
-+#endif	/* __GNU__ */
-+
-+	if (!(f = fopen("/proc/swaps", "r")))
-+		return 0;
-+	/* Skip the first line */
-+	fgets(buf, sizeof(buf), f);
-+	while (!feof(f)) {
-+		if (!fgets(buf, sizeof(buf), f))
-+			break;
-+		if ((cp = strchr(buf, ' ')) != NULL)
-+			*cp = 0;
-+		if ((cp = strchr(buf, '\t')) != NULL)
-+			*cp = 0;
-+		if (strcmp(buf, file) == 0) {
-+			ret++;
-+			break;
-+		}
-+#ifndef __GNU__
-+		if (file_dev && (stat(buf, &st_buf) == 0) &&
-+		    S_ISBLK(st_buf.st_mode) &&
-+		    file_dev == st_buf.st_rdev) {
-+			ret++;
-+			break;
-+		}
-+#endif 	/* __GNU__ */
-+	}
-+	fclose(f);
-+	return ret;
-+}
-+
-+
-+/*
-+ * ext2fs_check_mount_point() fills determines if the device is
-+ * mounted or otherwise busy, and fills in mount_flags with one or
-+ * more of the following flags: EXT2_MF_MOUNTED, EXT2_MF_ISROOT,
-+ * EXT2_MF_READONLY, EXT2_MF_SWAP, and EXT2_MF_BUSY.  If mtpt is
-+ * non-NULL, the directory where the device is mounted is copied to
-+ * where mtpt is pointing, up to mtlen characters.
-+ */
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
-+				  char *mtpt, int mtlen)
-+{
-+	struct stat	st_buf;
-+	errcode_t	retval = 0;
-+	int		fd;
-+
-+	if (is_swap_device(device)) {
-+		*mount_flags = EXT2_MF_MOUNTED | EXT2_MF_SWAP;
-+		strncpy(mtpt, "<swap>", mtlen);
-+	} else {
-+#ifdef HAVE_MNTENT_H
-+		retval = check_mntent(device, mount_flags, mtpt, mtlen);
-+#else 
-+#ifdef HAVE_GETMNTINFO
-+		retval = check_getmntinfo(device, mount_flags, mtpt, mtlen);
-+#else
-+#ifdef __GNUC__
-+ #warning "Can't use getmntent or getmntinfo to check for mounted filesystems!"
-+#endif
-+		*mount_flags = 0;
-+#endif /* HAVE_GETMNTINFO */
-+#endif /* HAVE_MNTENT_H */
-+	}
-+	if (retval)
-+		return retval;
-+
-+#ifdef __linux__ /* This only works on Linux 2.6+ systems */
-+	if ((stat(device, &st_buf) != 0) ||
-+	    !S_ISBLK(st_buf.st_mode))
-+		return 0;
-+	fd = open(device, O_RDONLY | O_EXCL);
-+	if (fd < 0) {
-+		if (errno == EBUSY)
-+			*mount_flags |= EXT2_MF_BUSY;
-+	} else
-+		close(fd);
-+
-+	return 0;
-+#endif
-+}
-+
-+/*
-+ * ext2fs_check_if_mounted() sets the mount_flags EXT2_MF_MOUNTED,
-+ * EXT2_MF_READONLY, and EXT2_MF_ROOT
-+ * 
-+ */
-+errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags)
-+{
-+	return ext2fs_check_mount_point(file, mount_flags, NULL, 0);
-+}
-+
-+#ifdef DEBUG
-+int main(int argc, char **argv)
-+{
-+	int	retval, mount_flags;
-+	char	mntpt[80];
-+	
-+	if (argc < 2) {
-+		fprintf(stderr, "Usage: %s device\n", argv[0]);
-+		exit(1);
-+	}
-+
-+	mntpt[0] = 0;
-+	retval = ext2fs_check_mount_point(argv[1], &mount_flags,
-+					  mntpt, sizeof(mntpt));
-+	if (retval) {
-+		com_err(argv[0], retval,
-+			"while calling ext2fs_check_if_mounted");
-+		exit(1);
-+	}
-+	printf("Device %s reports flags %02x\n", argv[1], mount_flags);
-+	if (mount_flags & EXT2_MF_BUSY)
-+		printf("\t%s is apparently in use.\n", argv[1]);
-+	if (mount_flags & EXT2_MF_MOUNTED)
-+		printf("\t%s is mounted.\n", argv[1]);
-+	if (mount_flags & EXT2_MF_SWAP)
-+		printf("\t%s is a swap device.\n", argv[1]);
-+	if (mount_flags & EXT2_MF_READONLY)
-+		printf("\t%s is read-only.\n", argv[1]);
-+	if (mount_flags & EXT2_MF_ISROOT)
-+		printf("\t%s is the root filesystem.\n", argv[1]);
-+	if (mntpt[0])
-+		printf("\t%s is mounted on %s.\n", argv[1], mntpt);
-+	exit(0);
-+}
-+#endif /* DEBUG */
-diff -Naur silo-1.4.14.orig/libext2fs/jfs_compat.h silo-1.4.14/libext2fs/jfs_compat.h
---- silo-1.4.14.orig/libext2fs/jfs_compat.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/jfs_compat.h	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,67 @@
-+
-+#ifndef _JFS_COMPAT_H
-+#define _JFS_COMPAT_H
-+
-+#include "kernel-list.h"
-+#include <errno.h>
-+#ifdef HAVE_NETINET_IN_H
-+#include <netinet/in.h>
-+#endif
-+
-+#define printk printf
-+#define KERN_ERR ""
-+#define KERN_DEBUG ""
-+
-+#define READ 0
-+#define WRITE 1
-+
-+#define cpu_to_be32(n) htonl(n)
-+#define be32_to_cpu(n) ntohl(n)
-+
-+typedef unsigned int tid_t;
-+typedef struct journal_s journal_t;
-+
-+struct buffer_head;
-+struct inode;
-+
-+struct journal_s
-+{
-+	unsigned long		j_flags;
-+	int			j_errno;
-+	struct buffer_head *	j_sb_buffer;
-+	struct journal_superblock_s *j_superblock;
-+	int			j_format_version;
-+	unsigned long		j_head;
-+	unsigned long		j_tail;
-+	unsigned long		j_free;
-+	unsigned long		j_first, j_last;
-+	kdev_t			j_dev;
-+	kdev_t			j_fs_dev;
-+	int			j_blocksize;
-+	unsigned int		j_blk_offset;
-+	unsigned int		j_maxlen;
-+	struct inode *		j_inode;
-+	tid_t			j_tail_sequence;
-+	tid_t			j_transaction_sequence;
-+	__u8			j_uuid[16];
-+	struct jbd_revoke_table_s *j_revoke;
-+};
-+
-+#define J_ASSERT(assert)						\
-+	do { if (!(assert)) {						\
-+		printf ("Assertion failure in %s() at %s line %d: "	\
-+			"\"%s\"\n",					\
-+			__FUNCTION__, __FILE__, __LINE__, # assert);	\
-+		fatal_error(e2fsck_global_ctx, 0);			\
-+	} } while (0)
-+
-+#define is_journal_abort(x) 0
-+
-+#define BUFFER_TRACE(bh, info)	do {} while (0)
-+
-+/* Need this so we can compile with configure --enable-gcc-wall */
-+#ifdef NO_INLINE_FUNCS
-+#define inline
-+#endif
-+
-+#endif /* _JFS_COMPAT_H */
-diff -Naur silo-1.4.14.orig/libext2fs/jfs_dat.h silo-1.4.14/libext2fs/jfs_dat.h
---- silo-1.4.14.orig/libext2fs/jfs_dat.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/jfs_dat.h	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,64 @@
-+/*
-+ * jfs_dat.h --- stripped down header file which only contains the JFS
-+ * 	on-disk data structures
-+ */
-+
-+#define JFS_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */
-+
-+/*
-+ * On-disk structures
-+ */
-+
-+/* 
-+ * Descriptor block types:
-+ */
-+
-+#define JFS_DESCRIPTOR_BLOCK	1
-+#define JFS_COMMIT_BLOCK	2
-+#define JFS_SUPERBLOCK		3
-+
-+/*
-+ * Standard header for all descriptor blocks:
-+ */
-+typedef struct journal_header_s
-+{
-+	__u32		h_magic;
-+	__u32		h_blocktype;
-+	__u32		h_sequence;
-+} journal_header_t;
-+
-+
-+/* 
-+ * The block tag: used to describe a single buffer in the journal 
-+ */
-+typedef struct journal_block_tag_s
-+{
-+	__u32		t_blocknr;	/* The on-disk block number */
-+	__u32		t_flags;	/* See below */
-+} journal_block_tag_t;
-+
-+/* Definitions for the journal tag flags word: */
-+#define JFS_FLAG_ESCAPE		1	/* on-disk block is escaped */
-+#define JFS_FLAG_SAME_UUID	2	/* block has same uuid as previous */
-+#define JFS_FLAG_DELETED	4	/* block deleted by this transaction */
-+#define JFS_FLAG_LAST_TAG	8	/* last tag in this descriptor block */
-+
-+
-+/*
-+ * The journal superblock
-+ */
-+typedef struct journal_superblock_s
-+{
-+	journal_header_t s_header;
-+
-+	/* Static information describing the journal */
-+	__u32		s_blocksize;	/* journal device blocksize */
-+	__u32		s_maxlen;	/* total blocks in journal file */
-+	__u32		s_first;	/* first block of log information */
-+	
-+	/* Dynamic information describing the current state of the log */
-+	__u32		s_sequence;	/* first commit ID expected in log */
-+	__u32		s_start;	/* blocknr of start of log */
-+	
-+} journal_superblock_t;
-+
-diff -Naur silo-1.4.14.orig/libext2fs/jfs_user.h silo-1.4.14/libext2fs/jfs_user.h
---- silo-1.4.14.orig/libext2fs/jfs_user.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/jfs_user.h	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,8 @@
-+#ifndef _JFS_USER_H
-+#define _JFS_USER_H
-+
-+typedef unsigned short kdev_t;
-+
-+#include "kernel-jbd.h"
-+
-+#endif /* _JFS_USER_H */
-diff -Naur silo-1.4.14.orig/libext2fs/kernel-jbd.h silo-1.4.14/libext2fs/kernel-jbd.h
---- silo-1.4.14.orig/libext2fs/kernel-jbd.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/kernel-jbd.h	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,910 @@
-+/*
-+ * linux/include/linux/jbd.h
-+ * 
-+ * Written by Stephen C. Tweedie <sct@redhat.com>
-+ *
-+ * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
-+ *
-+ * This file is part of the Linux kernel and is made available under
-+ * the terms of the GNU General Public License, version 2, or at your
-+ * option, any later version, incorporated herein by reference.
-+ *
-+ * Definitions for transaction data structures for the buffer cache
-+ * filesystem journaling support.
-+ */
-+
-+#ifndef _LINUX_JBD_H
-+#define _LINUX_JBD_H
-+
-+#if defined(CONFIG_JBD) || defined(CONFIG_JBD_MODULE) || !defined(__KERNEL__)
-+
-+/* Allow this file to be included directly into e2fsprogs */
-+#ifndef __KERNEL__
-+#include "jfs_compat.h"
-+#define JFS_DEBUG
-+#define jfs_debug jbd_debug
-+#else
-+
-+#include <linux/journal-head.h>
-+#include <linux/stddef.h>
-+#include <asm/semaphore.h>
-+#endif
-+
-+#ifndef __GNUC__
-+#define __FUNCTION__ ""
-+#endif
-+
-+#define journal_oom_retry 1
-+
-+#ifdef __STDC__
-+#ifdef CONFIG_JBD_DEBUG
-+/*
-+ * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal
-+ * consistency checks.  By default we don't do this unless
-+ * CONFIG_JBD_DEBUG is on.
-+ */
-+#define JBD_EXPENSIVE_CHECKING
-+extern int journal_enable_debug;
-+
-+#define jbd_debug(n, f, a...)						\
-+	do {								\
-+		if ((n) <= journal_enable_debug) {			\
-+			printk (KERN_DEBUG "(%s, %d): %s: ",		\
-+				__FILE__, __LINE__, __FUNCTION__);	\
-+		  	printk (f, ## a);				\
-+		}							\
-+	} while (0)
-+#else
-+#ifdef __GNUC__
-+#define jbd_debug(f, a...)	/**/
-+#else
-+#define jbd_debug(f, ...)	/**/
-+#endif	
-+#endif
-+#else
-+#define jbd_debug(x)		/* AIX doesn't do STDC */
-+#endif
-+
-+extern void * __jbd_kmalloc (char *where, size_t size, int flags, int retry);
-+#define jbd_kmalloc(size, flags) \
-+	__jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
-+#define jbd_rep_kmalloc(size, flags) \
-+	__jbd_kmalloc(__FUNCTION__, (size), (flags), 1)
-+
-+#define JFS_MIN_JOURNAL_BLOCKS 1024
-+
-+#ifdef __KERNEL__
-+typedef struct handle_s		handle_t;	/* Atomic operation type */
-+typedef struct journal_s	journal_t;	/* Journal control structure */
-+#endif
-+
-+/*
-+ * Internal structures used by the logging mechanism:
-+ */
-+
-+#define JFS_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */
-+
-+/*
-+ * On-disk structures
-+ */
-+
-+/* 
-+ * Descriptor block types:
-+ */
-+
-+#define JFS_DESCRIPTOR_BLOCK	1
-+#define JFS_COMMIT_BLOCK	2
-+#define JFS_SUPERBLOCK_V1	3
-+#define JFS_SUPERBLOCK_V2	4
-+#define JFS_REVOKE_BLOCK	5
-+
-+/*
-+ * Standard header for all descriptor blocks:
-+ */
-+typedef struct journal_header_s
-+{
-+	__u32		h_magic;
-+	__u32		h_blocktype;
-+	__u32		h_sequence;
-+} journal_header_t;
-+
-+
-+/* 
-+ * The block tag: used to describe a single buffer in the journal 
-+ */
-+typedef struct journal_block_tag_s
-+{
-+	__u32		t_blocknr;	/* The on-disk block number */
-+	__u32		t_flags;	/* See below */
-+} journal_block_tag_t;
-+
-+/* 
-+ * The revoke descriptor: used on disk to describe a series of blocks to
-+ * be revoked from the log 
-+ */
-+typedef struct journal_revoke_header_s
-+{
-+	journal_header_t r_header;
-+	int		 r_count;	/* Count of bytes used in the block */
-+} journal_revoke_header_t;
-+
-+
-+/* Definitions for the journal tag flags word: */
-+#define JFS_FLAG_ESCAPE		1	/* on-disk block is escaped */
-+#define JFS_FLAG_SAME_UUID	2	/* block has same uuid as previous */
-+#define JFS_FLAG_DELETED	4	/* block deleted by this transaction */
-+#define JFS_FLAG_LAST_TAG	8	/* last tag in this descriptor block */
-+
-+
-+/*
-+ * The journal superblock.  All fields are in big-endian byte order.
-+ */
-+typedef struct journal_superblock_s
-+{
-+/* 0x0000 */
-+	journal_header_t s_header;
-+
-+/* 0x000C */
-+	/* Static information describing the journal */
-+	__u32	s_blocksize;		/* journal device blocksize */
-+	__u32	s_maxlen;		/* total blocks in journal file */
-+	__u32	s_first;		/* first block of log information */
-+	
-+/* 0x0018 */
-+	/* Dynamic information describing the current state of the log */
-+	__u32	s_sequence;		/* first commit ID expected in log */
-+	__u32	s_start;		/* blocknr of start of log */
-+
-+/* 0x0020 */
-+	/* Error value, as set by journal_abort(). */
-+	__s32	s_errno;
-+
-+/* 0x0024 */
-+	/* Remaining fields are only valid in a version-2 superblock */
-+	__u32	s_feature_compat; 	/* compatible feature set */
-+	__u32	s_feature_incompat; 	/* incompatible feature set */
-+	__u32	s_feature_ro_compat; 	/* readonly-compatible feature set */
-+/* 0x0030 */
-+	__u8	s_uuid[16];		/* 128-bit uuid for journal */
-+
-+/* 0x0040 */
-+	__u32	s_nr_users;		/* Nr of filesystems sharing log */
-+	
-+	__u32	s_dynsuper;		/* Blocknr of dynamic superblock copy*/
-+	
-+/* 0x0048 */
-+	__u32	s_max_transaction;	/* Limit of journal blocks per trans.*/
-+	__u32	s_max_trans_data;	/* Limit of data blocks per trans. */
-+
-+/* 0x0050 */
-+	__u32	s_padding[44];
-+
-+/* 0x0100 */
-+	__u8	s_users[16*48];		/* ids of all fs'es sharing the log */
-+/* 0x0400 */
-+} journal_superblock_t;
-+
-+#define JFS_HAS_COMPAT_FEATURE(j,mask)					\
-+	((j)->j_format_version >= 2 &&					\
-+	 ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask))))
-+#define JFS_HAS_RO_COMPAT_FEATURE(j,mask)				\
-+	((j)->j_format_version >= 2 &&					\
-+	 ((j)->j_superblock->s_feature_ro_compat & cpu_to_be32((mask))))
-+#define JFS_HAS_INCOMPAT_FEATURE(j,mask)				\
-+	((j)->j_format_version >= 2 &&					\
-+	 ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask))))
-+
-+#define JFS_FEATURE_INCOMPAT_REVOKE	0x00000001
-+
-+/* Features known to this kernel version: */
-+#define JFS_KNOWN_COMPAT_FEATURES	0
-+#define JFS_KNOWN_ROCOMPAT_FEATURES	0
-+#define JFS_KNOWN_INCOMPAT_FEATURES	JFS_FEATURE_INCOMPAT_REVOKE
-+
-+#ifdef __KERNEL__
-+
-+#include <linux/fs.h>
-+#include <linux/sched.h>
-+
-+#define JBD_ASSERTIONS
-+#ifdef JBD_ASSERTIONS
-+#define J_ASSERT(assert)						\
-+do {									\
-+	if (!(assert)) {						\
-+		printk (KERN_EMERG					\
-+			"Assertion failure in %s() at %s:%d: \"%s\"\n",	\
-+			__FUNCTION__, __FILE__, __LINE__, # assert);	\
-+		BUG();							\
-+	}								\
-+} while (0)
-+
-+#if defined(CONFIG_BUFFER_DEBUG)
-+void buffer_assertion_failure(struct buffer_head *bh);
-+#define J_ASSERT_BH(bh, expr)						\
-+	do {								\
-+		if (!(expr))						\
-+			buffer_assertion_failure(bh);			\
-+		J_ASSERT(expr);						\
-+	} while (0)
-+#define J_ASSERT_JH(jh, expr)	J_ASSERT_BH(jh2bh(jh), expr)
-+#else
-+#define J_ASSERT_BH(bh, expr)	J_ASSERT(expr)
-+#define J_ASSERT_JH(jh, expr)	J_ASSERT(expr)
-+#endif
-+
-+#else
-+#define J_ASSERT(assert)
-+#endif		/* JBD_ASSERTIONS */
-+
-+enum jbd_state_bits {
-+	BH_JWrite
-+	  = BH_PrivateStart,	/* 1 if being written to log (@@@ DEBUGGING) */
-+	BH_Freed,		/* 1 if buffer has been freed (truncated) */
-+	BH_Revoked,		/* 1 if buffer has been revoked from the log */
-+	BH_RevokeValid,		/* 1 if buffer revoked flag is valid */
-+	BH_JBDDirty,		/* 1 if buffer is dirty but journaled */
-+};
-+
-+/* Return true if the buffer is one which JBD is managing */
-+static inline int buffer_jbd(struct buffer_head *bh)
-+{
-+	return __buffer_state(bh, JBD);
-+}
-+
-+static inline struct buffer_head *jh2bh(struct journal_head *jh)
-+{
-+	return jh->b_bh;
-+}
-+
-+static inline struct journal_head *bh2jh(struct buffer_head *bh)
-+{
-+	return bh->b_private;
-+}
-+
-+struct jbd_revoke_table_s;
-+
-+/* The handle_t type represents a single atomic update being performed
-+ * by some process.  All filesystem modifications made by the process go
-+ * through this handle.  Recursive operations (such as quota operations)
-+ * are gathered into a single update.
-+ *
-+ * The buffer credits field is used to account for journaled buffers
-+ * being modified by the running process.  To ensure that there is
-+ * enough log space for all outstanding operations, we need to limit the
-+ * number of outstanding buffers possible at any time.  When the
-+ * operation completes, any buffer credits not used are credited back to
-+ * the transaction, so that at all times we know how many buffers the
-+ * outstanding updates on a transaction might possibly touch. */
-+
-+struct handle_s 
-+{
-+	/* Which compound transaction is this update a part of? */
-+	transaction_t	      * h_transaction;
-+
-+	/* Number of remaining buffers we are allowed to dirty: */
-+	int			h_buffer_credits;
-+
-+	/* Reference count on this handle */
-+	int			h_ref;
-+
-+	/* Field for caller's use to track errors through large fs
-+	   operations */
-+	int			h_err;
-+
-+	/* Flags */
-+	unsigned int	h_sync:		1;	/* sync-on-close */
-+	unsigned int	h_jdata:	1;	/* force data journaling */
-+	unsigned int	h_aborted:	1;	/* fatal error on handle */
-+};
-+
-+
-+/* The transaction_t type is the guts of the journaling mechanism.  It
-+ * tracks a compound transaction through its various states:
-+ *
-+ * RUNNING:	accepting new updates
-+ * LOCKED:	Updates still running but we don't accept new ones
-+ * RUNDOWN:	Updates are tidying up but have finished requesting
-+ *		new buffers to modify (state not used for now)
-+ * FLUSH:       All updates complete, but we are still writing to disk
-+ * COMMIT:      All data on disk, writing commit record
-+ * FINISHED:	We still have to keep the transaction for checkpointing.
-+ *
-+ * The transaction keeps track of all of the buffers modified by a
-+ * running transaction, and all of the buffers committed but not yet
-+ * flushed to home for finished transactions.
-+ */
-+
-+struct transaction_s 
-+{
-+	/* Pointer to the journal for this transaction. */
-+	journal_t *		t_journal;
-+	
-+	/* Sequence number for this transaction */
-+	tid_t			t_tid;
-+	
-+	/* Transaction's current state */
-+	enum {
-+		T_RUNNING,
-+		T_LOCKED,
-+		T_RUNDOWN,
-+		T_FLUSH,
-+		T_COMMIT,
-+		T_FINISHED 
-+	}			t_state;
-+
-+	/* Where in the log does this transaction's commit start? */
-+	unsigned long		t_log_start;
-+	
-+	/* Doubly-linked circular list of all inodes owned by this
-+           transaction */	/* AKPM: unused */
-+	struct inode *		t_ilist;
-+	
-+	/* Number of buffers on the t_buffers list */
-+	int			t_nr_buffers;
-+	
-+	/* Doubly-linked circular list of all buffers reserved but not
-+           yet modified by this transaction */
-+	struct journal_head *	t_reserved_list;
-+	
-+	/* Doubly-linked circular list of all metadata buffers owned by this
-+           transaction */
-+	struct journal_head *	t_buffers;
-+	
-+	/*
-+	 * Doubly-linked circular list of all data buffers still to be
-+	 * flushed before this transaction can be committed.
-+	 * Protected by journal_datalist_lock.
-+	 */
-+	struct journal_head *	t_sync_datalist;
-+	
-+	/*
-+	 * Doubly-linked circular list of all writepage data buffers
-+	 * still to be written before this transaction can be committed.
-+	 * Protected by journal_datalist_lock.
-+	 */
-+	struct journal_head *	t_async_datalist;
-+	
-+	/* Doubly-linked circular list of all forget buffers (superceded
-+           buffers which we can un-checkpoint once this transaction
-+           commits) */
-+	struct journal_head *	t_forget;
-+	
-+	/*
-+	 * Doubly-linked circular list of all buffers still to be
-+	 * flushed before this transaction can be checkpointed.
-+	 */
-+	/* Protected by journal_datalist_lock */
-+	struct journal_head *	t_checkpoint_list;
-+	
-+	/* Doubly-linked circular list of temporary buffers currently
-+           undergoing IO in the log */
-+	struct journal_head *	t_iobuf_list;
-+	
-+	/* Doubly-linked circular list of metadata buffers being
-+           shadowed by log IO.  The IO buffers on the iobuf list and the
-+           shadow buffers on this list match each other one for one at
-+           all times. */
-+	struct journal_head *	t_shadow_list;
-+	
-+	/* Doubly-linked circular list of control buffers being written
-+           to the log. */
-+	struct journal_head *	t_log_list;
-+	
-+	/* Number of outstanding updates running on this transaction */
-+	int			t_updates;
-+
-+	/* Number of buffers reserved for use by all handles in this
-+	 * transaction handle but not yet modified. */
-+	int			t_outstanding_credits;
-+	
-+	/*
-+	 * Forward and backward links for the circular list of all
-+	 * transactions awaiting checkpoint.
-+	 */
-+	/* Protected by journal_datalist_lock */
-+	transaction_t		*t_cpnext, *t_cpprev;
-+
-+	/* When will the transaction expire (become due for commit), in
-+	 * jiffies ? */
-+	unsigned long		t_expires;
-+
-+	/* How many handles used this transaction? */
-+	int t_handle_count;
-+};
-+
-+
-+/* The journal_t maintains all of the journaling state information for a
-+ * single filesystem.  It is linked to from the fs superblock structure.
-+ * 
-+ * We use the journal_t to keep track of all outstanding transaction
-+ * activity on the filesystem, and to manage the state of the log
-+ * writing process. */
-+
-+struct journal_s
-+{
-+	/* General journaling state flags */
-+	unsigned long		j_flags;
-+
-+	/* Is there an outstanding uncleared error on the journal (from
-+	 * a prior abort)? */
-+	int			j_errno;
-+	
-+	/* The superblock buffer */
-+	struct buffer_head *	j_sb_buffer;
-+	journal_superblock_t *	j_superblock;
-+
-+	/* Version of the superblock format */
-+	int			j_format_version;
-+
-+	/* Number of processes waiting to create a barrier lock */
-+	int			j_barrier_count;
-+	
-+	/* The barrier lock itself */
-+	struct semaphore	j_barrier;
-+	
-+	/* Transactions: The current running transaction... */
-+	transaction_t *		j_running_transaction;
-+	
-+	/* ... the transaction we are pushing to disk ... */
-+	transaction_t *		j_committing_transaction;
-+	
-+	/* ... and a linked circular list of all transactions waiting
-+	 * for checkpointing. */
-+	/* Protected by journal_datalist_lock */
-+	transaction_t *		j_checkpoint_transactions;
-+
-+	/* Wait queue for waiting for a locked transaction to start
-+           committing, or for a barrier lock to be released */
-+	wait_queue_head_t	j_wait_transaction_locked;
-+	
-+	/* Wait queue for waiting for checkpointing to complete */
-+	wait_queue_head_t	j_wait_logspace;
-+	
-+	/* Wait queue for waiting for commit to complete */
-+	wait_queue_head_t	j_wait_done_commit;
-+	
-+	/* Wait queue to trigger checkpointing */
-+	wait_queue_head_t	j_wait_checkpoint;
-+	
-+	/* Wait queue to trigger commit */
-+	wait_queue_head_t	j_wait_commit;
-+	
-+	/* Wait queue to wait for updates to complete */
-+	wait_queue_head_t	j_wait_updates;
-+
-+	/* Semaphore for locking against concurrent checkpoints */
-+	struct semaphore 	j_checkpoint_sem;
-+
-+	/* The main journal lock, used by lock_journal() */
-+	struct semaphore	j_sem;
-+		
-+	/* Journal head: identifies the first unused block in the journal. */
-+	unsigned long		j_head;
-+	
-+	/* Journal tail: identifies the oldest still-used block in the
-+	 * journal. */
-+	unsigned long		j_tail;
-+
-+	/* Journal free: how many free blocks are there in the journal? */
-+	unsigned long		j_free;
-+
-+	/* Journal start and end: the block numbers of the first usable
-+	 * block and one beyond the last usable block in the journal. */
-+	unsigned long		j_first, j_last;
-+
-+	/* Device, blocksize and starting block offset for the location
-+	 * where we store the journal. */
-+	kdev_t			j_dev;
-+	int			j_blocksize;
-+	unsigned int		j_blk_offset;
-+
-+	/* Device which holds the client fs.  For internal journal this
-+	 * will be equal to j_dev. */
-+	kdev_t			j_fs_dev;
-+
-+	/* Total maximum capacity of the journal region on disk. */
-+	unsigned int		j_maxlen;
-+
-+	/* Optional inode where we store the journal.  If present, all
-+	 * journal block numbers are mapped into this inode via
-+	 * bmap(). */
-+	struct inode *		j_inode;
-+
-+	/* Sequence number of the oldest transaction in the log */
-+	tid_t			j_tail_sequence;
-+	/* Sequence number of the next transaction to grant */
-+	tid_t			j_transaction_sequence;
-+	/* Sequence number of the most recently committed transaction */
-+	tid_t			j_commit_sequence;
-+	/* Sequence number of the most recent transaction wanting commit */
-+	tid_t			j_commit_request;
-+
-+	/* Journal uuid: identifies the object (filesystem, LVM volume
-+	 * etc) backed by this journal.  This will eventually be
-+	 * replaced by an array of uuids, allowing us to index multiple
-+	 * devices within a single journal and to perform atomic updates
-+	 * across them.  */
-+
-+	__u8			j_uuid[16];
-+
-+	/* Pointer to the current commit thread for this journal */
-+	struct task_struct *	j_task;
-+
-+	/* Maximum number of metadata buffers to allow in a single
-+	 * compound commit transaction */
-+	int			j_max_transaction_buffers;
-+
-+	/* What is the maximum transaction lifetime before we begin a
-+	 * commit? */
-+	unsigned long		j_commit_interval;
-+
-+	/* The timer used to wakeup the commit thread: */
-+	struct timer_list *	j_commit_timer;
-+	int			j_commit_timer_active;
-+
-+	/* Link all journals together - system-wide */
-+	struct list_head	j_all_journals;
-+
-+	/* The revoke table: maintains the list of revoked blocks in the
-+           current transaction. */
-+	struct jbd_revoke_table_s *j_revoke;
-+};
-+
-+/* 
-+ * Journal flag definitions 
-+ */
-+#define JFS_UNMOUNT	0x001	/* Journal thread is being destroyed */
-+#define JFS_ABORT	0x002	/* Journaling has been aborted for errors. */
-+#define JFS_ACK_ERR	0x004	/* The errno in the sb has been acked */
-+#define JFS_FLUSHED	0x008	/* The journal superblock has been flushed */
-+#define JFS_LOADED	0x010	/* The journal superblock has been loaded */
-+
-+/* 
-+ * Function declarations for the journaling transaction and buffer
-+ * management
-+ */
-+
-+/* Filing buffers */
-+extern void __journal_unfile_buffer(struct journal_head *);
-+extern void journal_unfile_buffer(struct journal_head *);
-+extern void __journal_refile_buffer(struct journal_head *);
-+extern void journal_refile_buffer(struct journal_head *);
-+extern void __journal_file_buffer(struct journal_head *, transaction_t *, int);
-+extern void __journal_free_buffer(struct journal_head *bh);
-+extern void journal_file_buffer(struct journal_head *, transaction_t *, int);
-+extern void __journal_clean_data_list(transaction_t *transaction);
-+
-+/* Log buffer allocation */
-+extern struct journal_head * journal_get_descriptor_buffer(journal_t *);
-+extern unsigned long journal_next_log_block(journal_t *);
-+
-+/* Commit management */
-+extern void journal_commit_transaction(journal_t *);
-+
-+/* Checkpoint list management */
-+int __journal_clean_checkpoint_list(journal_t *journal);
-+extern void journal_remove_checkpoint(struct journal_head *);
-+extern void __journal_remove_checkpoint(struct journal_head *);
-+extern void journal_insert_checkpoint(struct journal_head *, transaction_t *);
-+extern void __journal_insert_checkpoint(struct journal_head *,transaction_t *);
-+
-+/* Buffer IO */
-+extern int 
-+journal_write_metadata_buffer(transaction_t	  *transaction,
-+			      struct journal_head  *jh_in,
-+			      struct journal_head **jh_out,
-+			      int		   blocknr);
-+
-+/* Transaction locking */
-+extern void		__wait_on_journal (journal_t *);
-+
-+/*
-+ * Journal locking.
-+ *
-+ * We need to lock the journal during transaction state changes so that
-+ * nobody ever tries to take a handle on the running transaction while
-+ * we are in the middle of moving it to the commit phase.  
-+ *
-+ * Note that the locking is completely interrupt unsafe.  We never touch
-+ * journal structures from interrupts.
-+ *
-+ * In 2.2, the BKL was required for lock_journal.  This is no longer
-+ * the case.
-+ */
-+
-+static inline void lock_journal(journal_t *journal)
-+{
-+	down(&journal->j_sem);
-+}
-+
-+/* This returns zero if we acquired the semaphore */
-+static inline int try_lock_journal(journal_t * journal)
-+{
-+	return down_trylock(&journal->j_sem);
-+}
-+
-+static inline void unlock_journal(journal_t * journal)
-+{
-+	up(&journal->j_sem);
-+}
-+
-+
-+static inline handle_t *journal_current_handle(void)
-+{
-+	return current->journal_info;
-+}
-+
-+/* The journaling code user interface:
-+ *
-+ * Create and destroy handles
-+ * Register buffer modifications against the current transaction. 
-+ */
-+
-+extern handle_t *journal_start(journal_t *, int nblocks);
-+extern handle_t *journal_try_start(journal_t *, int nblocks);
-+extern int	 journal_restart (handle_t *, int nblocks);
-+extern int	 journal_extend (handle_t *, int nblocks);
-+extern int	 journal_get_write_access (handle_t *, struct buffer_head *);
-+extern int	 journal_get_create_access (handle_t *, struct buffer_head *);
-+extern int	 journal_get_undo_access (handle_t *, struct buffer_head *);
-+extern int	 journal_dirty_data (handle_t *,
-+				struct buffer_head *, int async);
-+extern int	 journal_dirty_metadata (handle_t *, struct buffer_head *);
-+extern void	 journal_release_buffer (handle_t *, struct buffer_head *);
-+extern void	 journal_forget (handle_t *, struct buffer_head *);
-+extern void	 journal_sync_buffer (struct buffer_head *);
-+extern int	 journal_flushpage(journal_t *, struct page *, unsigned long);
-+extern int	 journal_try_to_free_buffers(journal_t *, struct page *, int);
-+extern int	 journal_stop(handle_t *);
-+extern int	 journal_flush (journal_t *);
-+
-+extern void	 journal_lock_updates (journal_t *);
-+extern void	 journal_unlock_updates (journal_t *);
-+
-+extern journal_t * journal_init_dev(kdev_t dev, kdev_t fs_dev,
-+				int start, int len, int bsize);
-+extern journal_t * journal_init_inode (struct inode *);
-+extern int	   journal_update_format (journal_t *);
-+extern int	   journal_check_used_features 
-+		   (journal_t *, unsigned long, unsigned long, unsigned long);
-+extern int	   journal_check_available_features 
-+		   (journal_t *, unsigned long, unsigned long, unsigned long);
-+extern int	   journal_set_features 
-+		   (journal_t *, unsigned long, unsigned long, unsigned long);
-+extern int	   journal_create     (journal_t *);
-+extern int	   journal_load       (journal_t *journal);
-+extern void	   journal_destroy    (journal_t *);
-+extern int	   journal_recover    (journal_t *journal);
-+extern int	   journal_wipe       (journal_t *, int);
-+extern int	   journal_skip_recovery (journal_t *);
-+extern void	   journal_update_superblock (journal_t *, int);
-+extern void	   __journal_abort      (journal_t *);
-+extern void	   journal_abort      (journal_t *, int);
-+extern int	   journal_errno      (journal_t *);
-+extern void	   journal_ack_err    (journal_t *);
-+extern int	   journal_clear_err  (journal_t *);
-+extern unsigned long journal_bmap(journal_t *journal, unsigned long blocknr);
-+extern int	    journal_force_commit(journal_t *journal);
-+
-+/*
-+ * journal_head management
-+ */
-+extern struct journal_head
-+		*journal_add_journal_head(struct buffer_head *bh);
-+extern void	journal_remove_journal_head(struct buffer_head *bh);
-+extern void	__journal_remove_journal_head(struct buffer_head *bh);
-+extern void	journal_unlock_journal_head(struct journal_head *jh);
-+
-+/* Primary revoke support */
-+#define JOURNAL_REVOKE_DEFAULT_HASH 256
-+extern int	   journal_init_revoke(journal_t *, int);
-+extern void	   journal_destroy_revoke_caches(void);
-+extern int	   journal_init_revoke_caches(void);
-+
-+extern void	   journal_destroy_revoke(journal_t *);
-+extern int	   journal_revoke (handle_t *,
-+				unsigned long, struct buffer_head *);
-+extern int	   journal_cancel_revoke(handle_t *, struct journal_head *);
-+extern void	   journal_write_revoke_records(journal_t *, transaction_t *);
-+
-+/* Recovery revoke support */
-+extern int	   journal_set_revoke(journal_t *, unsigned long, tid_t);
-+extern int	   journal_test_revoke(journal_t *, unsigned long, tid_t);
-+extern void	   journal_clear_revoke(journal_t *);
-+extern void	   journal_brelse_array(struct buffer_head *b[], int n);
-+
-+/* The log thread user interface:
-+ *
-+ * Request space in the current transaction, and force transaction commit
-+ * transitions on demand.
-+ */
-+
-+extern int	log_space_left (journal_t *); /* Called with journal locked */
-+extern tid_t	log_start_commit (journal_t *, transaction_t *);
-+extern void	log_wait_commit (journal_t *, tid_t);
-+extern int	log_do_checkpoint (journal_t *, int);
-+
-+extern void	log_wait_for_space(journal_t *, int nblocks);
-+extern void	__journal_drop_transaction(journal_t *, transaction_t *);
-+extern int	cleanup_journal_tail(journal_t *);
-+
-+/* Reduce journal memory usage by flushing */
-+extern void shrink_journal_memory(void);
-+
-+/* Debugging code only: */
-+
-+#define jbd_ENOSYS() \
-+do {								      \
-+	printk (KERN_ERR "JBD unimplemented function " __FUNCTION__); \
-+	current->state = TASK_UNINTERRUPTIBLE;			      \
-+	schedule();						      \
-+} while (1)
-+
-+/*
-+ * is_journal_abort
-+ *
-+ * Simple test wrapper function to test the JFS_ABORT state flag.  This
-+ * bit, when set, indicates that we have had a fatal error somewhere,
-+ * either inside the journaling layer or indicated to us by the client
-+ * (eg. ext3), and that we and should not commit any further
-+ * transactions.  
-+ */
-+
-+static inline int is_journal_aborted(journal_t *journal)
-+{
-+	return journal->j_flags & JFS_ABORT;
-+}
-+
-+static inline int is_handle_aborted(handle_t *handle)
-+{
-+	if (handle->h_aborted)
-+		return 1;
-+	return is_journal_aborted(handle->h_transaction->t_journal);
-+}
-+
-+static inline void journal_abort_handle(handle_t *handle)
-+{
-+	handle->h_aborted = 1;
-+}
-+
-+/* Not all architectures define BUG() */
-+#ifndef BUG
-+#define BUG() do { \
-+        printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-+	* ((char *) 0) = 0; \
-+ } while (0)
-+#endif /* BUG */
-+
-+#else
-+
-+extern int	   journal_recover    (journal_t *journal);
-+extern int	   journal_skip_recovery (journal_t *);
-+
-+/* Primary revoke support */
-+extern int	   journal_init_revoke(journal_t *, int);
-+extern void	   journal_destroy_revoke_caches(void);
-+extern int	   journal_init_revoke_caches(void);
-+
-+/* Recovery revoke support */
-+extern int	   journal_set_revoke(journal_t *, unsigned long, tid_t);
-+extern int	   journal_test_revoke(journal_t *, unsigned long, tid_t);
-+extern void	   journal_clear_revoke(journal_t *);
-+extern void	   journal_brelse_array(struct buffer_head *b[], int n);
-+
-+extern void	   journal_destroy_revoke(journal_t *);
-+#endif /* __KERNEL__   */
-+
-+/* Comparison functions for transaction IDs: perform comparisons using
-+ * modulo arithmetic so that they work over sequence number wraps. */
-+
-+static inline int tid_gt(tid_t x, tid_t y)
-+{
-+	int difference = (x - y);
-+	return (difference > 0);
-+}
-+
-+static inline int tid_geq(tid_t x, tid_t y)
-+{
-+	int difference = (x - y);
-+	return (difference >= 0);
-+}
-+
-+extern int journal_blocks_per_page(struct inode *inode);
-+
-+/*
-+ * Definitions which augment the buffer_head layer
-+ */
-+
-+/* journaling buffer types */
-+#define BJ_None		0	/* Not journaled */
-+#define BJ_SyncData	1	/* Normal data: flush before commit */
-+#define BJ_AsyncData	2	/* writepage data: wait on it before commit */
-+#define BJ_Metadata	3	/* Normal journaled metadata */
-+#define BJ_Forget	4	/* Buffer superceded by this transaction */
-+#define BJ_IO		5	/* Buffer is for temporary IO use */
-+#define BJ_Shadow	6	/* Buffer contents being shadowed to the log */
-+#define BJ_LogCtl	7	/* Buffer contains log descriptors */
-+#define BJ_Reserved	8	/* Buffer is reserved for access by journal */
-+#define BJ_Types	9
-+ 
-+extern int jbd_blocks_per_page(struct inode *inode);
-+
-+#ifdef __KERNEL__
-+
-+extern spinlock_t jh_splice_lock;
-+/*
-+ * Once `expr1' has been found true, take jh_splice_lock
-+ * and then reevaluate everything.
-+ */
-+#define SPLICE_LOCK(expr1, expr2)				\
-+	({							\
-+		int ret = (expr1);				\
-+		if (ret) {					\
-+			spin_lock(&jh_splice_lock);		\
-+			ret = (expr1) && (expr2);		\
-+			spin_unlock(&jh_splice_lock);		\
-+		}						\
-+		ret;						\
-+	})
-+
-+/*
-+ * A number of buffer state predicates.  They test for
-+ * buffer_jbd() because they are used in core kernel code.
-+ *
-+ * These will be racy on SMP unless we're *sure* that the
-+ * buffer won't be detached from the journalling system
-+ * in parallel.
-+ */
-+
-+/* Return true if the buffer is on journal list `list' */
-+static inline int buffer_jlist_eq(struct buffer_head *bh, int list)
-+{
-+	return SPLICE_LOCK(buffer_jbd(bh), bh2jh(bh)->b_jlist == list);
-+}
-+
-+/* Return true if this bufer is dirty wrt the journal */
-+static inline int buffer_jdirty(struct buffer_head *bh)
-+{
-+	return buffer_jbd(bh) && __buffer_state(bh, JBDDirty);
-+}
-+
-+/* Return true if it's a data buffer which journalling is managing */
-+static inline int buffer_jbd_data(struct buffer_head *bh)
-+{
-+	return SPLICE_LOCK(buffer_jbd(bh),
-+			bh2jh(bh)->b_jlist == BJ_SyncData ||
-+			bh2jh(bh)->b_jlist == BJ_AsyncData);
-+}
-+
-+#ifdef CONFIG_SMP
-+#define assert_spin_locked(lock)	J_ASSERT(spin_is_locked(lock))
-+#else
-+#define assert_spin_locked(lock)	do {} while(0)
-+#endif
-+
-+#define buffer_trace_init(bh)	do {} while (0)
-+#define print_buffer_fields(bh)	do {} while (0)
-+#define print_buffer_trace(bh)	do {} while (0)
-+#define BUFFER_TRACE(bh, info)	do {} while (0)
-+#define BUFFER_TRACE2(bh, bh2, info)	do {} while (0)
-+#define JBUFFER_TRACE(jh, info)	do {} while (0)
-+
-+#endif	/* __KERNEL__ */
-+
-+#endif	/* CONFIG_JBD || CONFIG_JBD_MODULE || !__KERNEL__ */
-+
-+/*
-+ * Compatibility no-ops which allow the kernel to compile without CONFIG_JBD
-+ * go here.
-+ */
-+
-+#if defined(__KERNEL__) && !(defined(CONFIG_JBD) || defined(CONFIG_JBD_MODULE))
-+
-+#define J_ASSERT(expr)			do {} while (0)
-+#define J_ASSERT_BH(bh, expr)		do {} while (0)
-+#define buffer_jbd(bh)			0
-+#define buffer_jlist_eq(bh, val)	0
-+#define journal_buffer_journal_lru(bh)	0
-+
-+#endif	/* defined(__KERNEL__) && !defined(CONFIG_JBD) */
-+#endif	/* _LINUX_JBD_H */
-diff -Naur silo-1.4.14.orig/libext2fs/kernel-list.h silo-1.4.14/libext2fs/kernel-list.h
---- silo-1.4.14.orig/libext2fs/kernel-list.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/kernel-list.h	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,112 @@
-+#ifndef _LINUX_LIST_H
-+#define _LINUX_LIST_H
-+
-+/*
-+ * Simple doubly linked list implementation.
-+ *
-+ * Some of the internal functions ("__xxx") are useful when
-+ * manipulating whole lists rather than single entries, as
-+ * sometimes we already know the next/prev entries and we can
-+ * generate better code by using them directly rather than
-+ * using the generic single-entry routines.
-+ */
-+
-+struct list_head {
-+	struct list_head *next, *prev;
-+};
-+
-+#define LIST_HEAD_INIT(name) { &(name), &(name) }
-+
-+#define LIST_HEAD(name) \
-+	struct list_head name = { &name, &name }
-+
-+#define INIT_LIST_HEAD(ptr) do { \
-+	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
-+} while (0)
-+
-+#if (!defined(__GNUC__) && !defined(__WATCOMC__))
-+#define __inline__
-+#endif
-+
-+/*
-+ * Insert a new entry between two known consecutive entries. 
-+ *
-+ * This is only for internal list manipulation where we know
-+ * the prev/next entries already!
-+ */
-+static __inline__ void __list_add(struct list_head * new,
-+	struct list_head * prev,
-+	struct list_head * next)
-+{
-+	next->prev = new;
-+	new->next = next;
-+	new->prev = prev;
-+	prev->next = new;
-+}
-+
-+/*
-+ * Insert a new entry after the specified head..
-+ */
-+static __inline__ void list_add(struct list_head *new, struct list_head *head)
-+{
-+	__list_add(new, head, head->next);
-+}
-+
-+/*
-+ * Insert a new entry at the tail
-+ */
-+static __inline__ void list_add_tail(struct list_head *new, struct list_head *head)
-+{
-+	__list_add(new, head->prev, head);
-+}
-+
-+/*
-+ * Delete a list entry by making the prev/next entries
-+ * point to each other.
-+ *
-+ * This is only for internal list manipulation where we know
-+ * the prev/next entries already!
-+ */
-+static __inline__ void __list_del(struct list_head * prev,
-+				  struct list_head * next)
-+{
-+	next->prev = prev;
-+	prev->next = next;
-+}
-+
-+static __inline__ void list_del(struct list_head *entry)
-+{
-+	__list_del(entry->prev, entry->next);
-+}
-+
-+static __inline__ int list_empty(struct list_head *head)
-+{
-+	return head->next == head;
-+}
-+
-+/*
-+ * Splice in "list" into "head"
-+ */
-+static __inline__ void list_splice(struct list_head *list, struct list_head *head)
-+{
-+	struct list_head *first = list->next;
-+
-+	if (first != list) {
-+		struct list_head *last = list->prev;
-+		struct list_head *at = head->next;
-+
-+		first->prev = head;
-+		head->next = first;
-+
-+		last->next = at;
-+		at->prev = last;
-+	}
-+}
-+
-+#define list_entry(ptr, type, member) \
-+	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-+
-+#define list_for_each(pos, head) \
-+        for (pos = (head)->next; pos != (head); pos = pos->next)
-+
-+#endif
-diff -Naur silo-1.4.14.orig/libext2fs/link.c silo-1.4.14/libext2fs/link.c
---- silo-1.4.14.orig/libext2fs/link.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/link.c	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,134 @@
-+/*
-+ * link.c --- create links in a ext2fs directory
-+ * 
-+ * Copyright (C) 1993, 1994 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct link_struct  {
-+	const char	*name;
-+	int		namelen;
-+	ext2_ino_t	inode;
-+	int		flags;
-+	int		done;
-+	struct ext2_super_block *sb;
-+};	
-+
-+static int link_proc(struct ext2_dir_entry *dirent,
-+		     int	offset,
-+		     int	blocksize,
-+		     char	*buf,
-+		     void	*priv_data)
-+{
-+	struct link_struct *ls = (struct link_struct *) priv_data;
-+	struct ext2_dir_entry *next;
-+	int rec_len, min_rec_len;
-+	int ret = 0;
-+
-+	rec_len = EXT2_DIR_REC_LEN(ls->namelen);
-+
-+	/*
-+	 * See if the following directory entry (if any) is unused;
-+	 * if so, absorb it into this one.
-+	 */
-+	next = (struct ext2_dir_entry *) (buf + offset + dirent->rec_len);
-+	if ((offset + dirent->rec_len < blocksize - 8) &&
-+	    (next->inode == 0) &&
-+	    (offset + dirent->rec_len + next->rec_len <= blocksize)) {
-+		dirent->rec_len += next->rec_len;
-+		ret = DIRENT_CHANGED;
-+	}
-+
-+	/*
-+	 * If the directory entry is used, see if we can split the
-+	 * directory entry to make room for the new name.  If so,
-+	 * truncate it and return.
-+	 */
-+	if (dirent->inode) {
-+		min_rec_len = EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
-+		if (dirent->rec_len < (min_rec_len + rec_len))
-+			return ret;
-+		rec_len = dirent->rec_len - min_rec_len;
-+		dirent->rec_len = min_rec_len;
-+		next = (struct ext2_dir_entry *) (buf + offset +
-+						  dirent->rec_len);
-+		next->inode = 0;
-+		next->name_len = 0;
-+		next->rec_len = rec_len;
-+		return DIRENT_CHANGED;
-+	}
-+
-+	/*
-+	 * If we get this far, then the directory entry is not used.
-+	 * See if we can fit the request entry in.  If so, do it.
-+	 */
-+	if (dirent->rec_len < rec_len)
-+		return ret;
-+	dirent->inode = ls->inode;
-+	dirent->name_len = ls->namelen;
-+	strncpy(dirent->name, ls->name, ls->namelen);
-+	if (ls->sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
-+		dirent->name_len |= (ls->flags & 0x7) << 8;
-+
-+	ls->done++;
-+	return DIRENT_ABORT|DIRENT_CHANGED;
-+}
-+
-+/*
-+ * Note: the low 3 bits of the flags field are used as the directory
-+ * entry filetype.
-+ */
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name, 
-+		      ext2_ino_t ino, int flags)
-+{
-+	errcode_t		retval;
-+	struct link_struct	ls;
-+	struct ext2_inode	inode;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (!(fs->flags & EXT2_FLAG_RW))
-+		return EXT2_ET_RO_FILSYS;
-+
-+	ls.name = name;
-+	ls.namelen = name ? strlen(name) : 0;
-+	ls.inode = ino;
-+	ls.flags = flags;
-+	ls.done = 0;
-+	ls.sb = fs->super;
-+
-+	retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
-+				    0, link_proc, &ls);
-+	if (retval)
-+		return retval;
-+
-+	if (!ls.done)
-+		return EXT2_ET_DIR_NO_SPACE;
-+
-+	if ((retval = ext2fs_read_inode(fs, dir, &inode)) != 0)
-+		return retval;
-+
-+	if (inode.i_flags & EXT2_INDEX_FL) {
-+		inode.i_flags &= ~EXT2_INDEX_FL;
-+		if ((retval = ext2fs_write_inode(fs, dir, &inode)) != 0)
-+			return retval;
-+	}
-+
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/llseek.c silo-1.4.14/libext2fs/llseek.c
---- silo-1.4.14.orig/libext2fs/llseek.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/llseek.c	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,138 @@
-+/*
-+ * llseek.c -- stub calling the llseek system call
-+ *
-+ * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#define _LARGEFILE_SOURCE
-+#define _LARGEFILE64_SOURCE
-+
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef __MSDOS__
-+#include <io.h>
-+#endif
-+#include "et/com_err.h"
-+#include "ext2fs/ext2_io.h"
-+
-+#ifdef __linux__
-+
-+#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
-+
-+#define my_llseek lseek64
-+
-+#else
-+#if defined(HAVE_LLSEEK)
-+#include <syscall.h>
-+
-+#ifndef HAVE_LLSEEK_PROTOTYPE
-+extern long long llseek (int fd, long long offset, int origin);
-+#endif
-+
-+#define my_llseek llseek
-+
-+#else	/* ! HAVE_LLSEEK */
-+
-+#if defined(__alpha__) || defined (__ia64__)
-+
-+#define llseek lseek
-+
-+#else /* !__alpha__ && !__ia64__*/
-+
-+#include <linux/unistd.h>
-+
-+#ifndef __NR__llseek
-+#define __NR__llseek            140
-+#endif
-+
-+#ifndef __i386__
-+static int _llseek (unsigned int, unsigned long,
-+		   unsigned long, ext2_loff_t *, unsigned int);
-+
-+static _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high,
-+		 unsigned long, offset_low,ext2_loff_t *,result,
-+		 unsigned int, origin)
-+#endif
-+
-+static ext2_loff_t my_llseek (int fd, ext2_loff_t offset, int origin)
-+{
-+	ext2_loff_t result;
-+	int retval;
-+
-+#ifndef __i386__
-+	retval = _llseek(fd, ((unsigned long long) offset) >> 32,
-+#else			  
-+	retval = syscall(__NR__llseek, fd, (unsigned long long) (offset >> 32),
-+#endif
-+			  ((unsigned long long) offset) & 0xffffffff,
-+			&result, origin);
-+	return (retval == -1 ? (ext2_loff_t) retval : result);
-+}
-+
-+#endif	/* __alpha__ || __ia64__ */
-+
-+#endif /* HAVE_LLSEEK */
-+#endif /* defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) */
-+
-+ext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin)
-+{
-+	ext2_loff_t result;
-+	static int do_compat = 0;
-+
-+	if ((sizeof(off_t) >= sizeof(ext2_loff_t)) ||
-+	    (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1))))
-+		return lseek(fd, (off_t) offset, origin);
-+
-+	if (do_compat) {
-+		errno = EINVAL;
-+		return -1;
-+	}
-+	
-+	result = my_llseek (fd, offset, origin);
-+	if (result == -1 && errno == ENOSYS) {
-+		/*
-+		 * Just in case this code runs on top of an old kernel
-+		 * which does not support the llseek system call
-+		 */
-+		do_compat++;
-+		errno = EINVAL;
-+	}
-+	return result;
-+}
-+
-+#else /* !linux */
-+
-+#ifndef EINVAL
-+#define EINVAL EXT2_ET_INVALID_ARGUMENT
-+#endif
-+
-+ext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin)
-+{
-+#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
-+	return lseek64 (fd, offset, origin);
-+#else
-+	if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
-+	    (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
-+		errno = EINVAL;
-+		return -1;
-+	}
-+	return lseek (fd, (off_t) offset, origin);
-+#endif
-+}
-+
-+#endif 	/* linux */
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/lookup.c silo-1.4.14/libext2fs/lookup.c
---- silo-1.4.14.orig/libext2fs/lookup.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/lookup.c	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,69 @@
-+/*
-+ * lookup.c --- ext2fs directory lookup operations
-+ * 
-+ * Copyright (C) 1993, 1994, 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct lookup_struct  {
-+	const char	*name;
-+	int		len;
-+	ext2_ino_t	*inode;
-+	int		found;
-+};	
-+
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int lookup_proc(struct ext2_dir_entry *dirent,
-+		       int	offset EXT2FS_ATTR((unused)),
-+		       int	blocksize EXT2FS_ATTR((unused)),
-+		       char	*buf EXT2FS_ATTR((unused)),
-+		       void	*priv_data)
-+{
-+	struct lookup_struct *ls = (struct lookup_struct *) priv_data;
-+
-+	if (ls->len != (dirent->name_len & 0xFF))
-+		return 0;
-+	if (strncmp(ls->name, dirent->name, (dirent->name_len & 0xFF)))
-+		return 0;
-+	*ls->inode = dirent->inode;
-+	ls->found++;
-+	return DIRENT_ABORT;
-+}
-+
-+
-+errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
-+			int namelen, char *buf, ext2_ino_t *inode)
-+{
-+	errcode_t	retval;
-+	struct lookup_struct ls;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	ls.name = name;
-+	ls.len = namelen;
-+	ls.inode = inode;
-+	ls.found = 0;
-+
-+	retval = ext2fs_dir_iterate(fs, dir, 0, buf, lookup_proc, &ls);
-+	if (retval)
-+		return retval;
-+
-+	return (ls.found) ? 0 : EXT2_ET_FILE_NOT_FOUND;
-+}
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/mkdir.c silo-1.4.14/libext2fs/mkdir.c
---- silo-1.4.14.orig/libext2fs/mkdir.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/mkdir.c	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,142 @@
-+/*
-+ * mkdir.c --- make a directory in the filesystem
-+ * 
-+ * Copyright (C) 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#ifndef EXT2_FT_DIR
-+#define EXT2_FT_DIR		2
-+#endif
-+
-+errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
-+		       const char *name)
-+{
-+	errcode_t		retval;
-+	struct ext2_inode	parent_inode, inode;
-+	ext2_ino_t		ino = inum;
-+	ext2_ino_t		scratch_ino;
-+	blk_t			blk;
-+	char			*block = 0;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	/*
-+	 * Allocate an inode, if necessary
-+	 */
-+	if (!ino) {
-+		retval = ext2fs_new_inode(fs, parent, LINUX_S_IFDIR | 0755,
-+					  0, &ino);
-+		if (retval)
-+			goto cleanup;
-+	}
-+
-+	/*
-+	 * Allocate a data block for the directory
-+	 */
-+	retval = ext2fs_new_block(fs, 0, 0, &blk);
-+	if (retval)
-+		goto cleanup;
-+
-+	/*
-+	 * Create a scratch template for the directory
-+	 */
-+	retval = ext2fs_new_dir_block(fs, ino, parent, &block);
-+	if (retval)
-+		goto cleanup;
-+
-+	/*
-+	 * Get the parent's inode, if necessary
-+	 */
-+	if (parent != ino) {
-+		retval = ext2fs_read_inode(fs, parent, &parent_inode);
-+		if (retval)
-+			goto cleanup;
-+	} else
-+		memset(&parent_inode, 0, sizeof(parent_inode));
-+
-+	/*
-+	 * Create the inode structure....
-+	 */
-+	memset(&inode, 0, sizeof(struct ext2_inode));
-+	inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask);
-+	inode.i_uid = inode.i_gid = 0;
-+	inode.i_blocks = fs->blocksize / 512;
-+	inode.i_block[0] = blk;
-+	inode.i_links_count = 2;
-+	inode.i_ctime = inode.i_atime = inode.i_mtime = time(NULL);
-+	inode.i_size = fs->blocksize;
-+
-+	/*
-+	 * Write out the inode and inode data block
-+	 */
-+	retval = ext2fs_write_dir_block(fs, blk, block);
-+	if (retval)
-+		goto cleanup;
-+	retval = ext2fs_write_new_inode(fs, ino, &inode); 
-+	if (retval)
-+		goto cleanup;
-+
-+	/*
-+	 * Link the directory into the filesystem hierarchy
-+	 */
-+	if (name) {
-+		retval = ext2fs_lookup(fs, parent, name, strlen(name), 0,
-+				       &scratch_ino);
-+		if (!retval) {
-+			retval = EXT2_ET_DIR_EXISTS;
-+			name = 0;
-+			goto cleanup;
-+		}
-+		if (retval != EXT2_ET_FILE_NOT_FOUND)
-+			goto cleanup;
-+		retval = ext2fs_link(fs, parent, name, ino, EXT2_FT_DIR);
-+		if (retval)
-+			goto cleanup;
-+	}
-+
-+	/*
-+	 * Update parent inode's counts
-+	 */
-+	if (parent != ino) {
-+		parent_inode.i_links_count++;
-+		retval = ext2fs_write_inode(fs, parent, &parent_inode);
-+		if (retval)
-+			goto cleanup;
-+	}
-+	
-+	/*
-+	 * Update accounting....
-+	 */
-+	ext2fs_block_alloc_stats(fs, blk, +1);
-+	ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
-+
-+cleanup:
-+	if (block)
-+		ext2fs_free_mem(&block);
-+	return retval;
-+
-+}
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/mkjournal.c silo-1.4.14/libext2fs/mkjournal.c
---- silo-1.4.14.orig/libext2fs/mkjournal.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/mkjournal.c	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,425 @@
-+/*
-+ * mkjournal.c --- make a journal for a filesystem
-+ *
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#if HAVE_SYS_IOCTL_H
-+#include <sys/ioctl.h>
-+#endif
-+#if HAVE_NETINET_IN_H
-+#include <netinet/in.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "e2p/e2p.h"
-+#include "ext2fs.h"
-+#include "jfs_user.h"
-+
-+/*
-+ * This function automatically sets up the journal superblock and
-+ * returns it as an allocated block.
-+ */
-+errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
-+					   __u32 size, int flags,
-+					   char  **ret_jsb)
-+{
-+	errcode_t		retval;
-+	journal_superblock_t	*jsb;
-+
-+	if (size < 1024)
-+		return EXT2_ET_JOURNAL_TOO_SMALL;
-+
-+	if ((retval = ext2fs_get_mem(fs->blocksize, &jsb)))
-+		return retval;
-+
-+	memset (jsb, 0, fs->blocksize);
-+
-+	jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
-+	if (flags & EXT2_MKJOURNAL_V1_SUPER)
-+		jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V1);
-+	else
-+		jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
-+	jsb->s_blocksize = htonl(fs->blocksize);
-+	jsb->s_maxlen = htonl(size);
-+	jsb->s_nr_users = htonl(1);
-+	jsb->s_first = htonl(1);
-+	jsb->s_sequence = htonl(1);
-+	memcpy(jsb->s_uuid, fs->super->s_uuid, sizeof(fs->super->s_uuid));
-+	/*
-+	 * If we're creating an external journal device, we need to
-+	 * adjust these fields.
-+	 */
-+	if (fs->super->s_feature_incompat &
-+	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
-+		jsb->s_nr_users = 0;
-+		if (fs->blocksize == 1024)
-+			jsb->s_first = htonl(3);
-+		else
-+			jsb->s_first = htonl(2);
-+	}
-+
-+	*ret_jsb = (char *) jsb;
-+	return 0;
-+}
-+
-+/*
-+ * This function writes a journal using POSIX routines.  It is used
-+ * for creating external journals and creating journals on live
-+ * filesystems.
-+ */
-+static errcode_t write_journal_file(ext2_filsys fs, char *filename,
-+				    blk_t size, int flags)
-+{
-+	errcode_t	retval;
-+	char		*buf = 0;
-+	int		fd, ret_size;
-+	blk_t		i;
-+
-+	if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf)))
-+		return retval;
-+
-+	/* Open the device or journal file */
-+	if ((fd = open(filename, O_WRONLY)) < 0) {
-+		retval = errno;
-+		goto errout;
-+	}
-+
-+	/* Write the superblock out */
-+	retval = EXT2_ET_SHORT_WRITE;
-+	ret_size = write(fd, buf, fs->blocksize);
-+	if (ret_size < 0) {
-+		retval = errno;
-+		goto errout;
-+	}
-+	if (ret_size != (int) fs->blocksize)
-+		goto errout;
-+	memset(buf, 0, fs->blocksize);
-+
-+	for (i = 1; i < size; i++) {
-+		ret_size = write(fd, buf, fs->blocksize);
-+		if (ret_size < 0) {
-+			retval = errno;
-+			goto errout;
-+		}
-+		if (ret_size != (int) fs->blocksize)
-+			goto errout;
-+	}
-+	close(fd);
-+
-+	retval = 0;
-+errout:
-+	ext2fs_free_mem(&buf);
-+	return retval;
-+}
-+
-+/*
-+ * Helper function for creating the journal using direct I/O routines
-+ */
-+struct mkjournal_struct {
-+	int		num_blocks;
-+	int		newblocks;
-+	char		*buf;
-+	errcode_t	err;
-+};
-+
-+static int mkjournal_proc(ext2_filsys	fs,
-+			   blk_t	*blocknr,
-+			   e2_blkcnt_t	blockcnt,
-+			   blk_t	ref_block EXT2FS_ATTR((unused)),
-+			   int		ref_offset EXT2FS_ATTR((unused)),
-+			   void		*priv_data)
-+{
-+	struct mkjournal_struct *es = (struct mkjournal_struct *) priv_data;
-+	blk_t	new_blk;
-+	static blk_t	last_blk = 0;
-+	errcode_t	retval;
-+	
-+	if (*blocknr) {
-+		last_blk = *blocknr;
-+		return 0;
-+	}
-+	retval = ext2fs_new_block(fs, last_blk, 0, &new_blk);
-+	if (retval) {
-+		es->err = retval;
-+		return BLOCK_ABORT;
-+	}
-+	if (blockcnt > 0)
-+		es->num_blocks--;
-+
-+	es->newblocks++;
-+	retval = io_channel_write_blk(fs->io, new_blk, 1, es->buf);
-+
-+	if (blockcnt == 0)
-+		memset(es->buf, 0, fs->blocksize);
-+
-+	if (retval) {
-+		es->err = retval;
-+		return BLOCK_ABORT;
-+	}
-+	*blocknr = new_blk;
-+	last_blk = new_blk;
-+	ext2fs_block_alloc_stats(fs, new_blk, +1);
-+
-+	if (es->num_blocks == 0)
-+		return (BLOCK_CHANGED | BLOCK_ABORT);
-+	else
-+		return BLOCK_CHANGED;
-+	
-+}
-+
-+/*
-+ * This function creates a journal using direct I/O routines.
-+ */
-+static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
-+				     blk_t size, int flags)
-+{
-+	char			*buf;
-+	errcode_t		retval;
-+	struct ext2_inode	inode;
-+	struct mkjournal_struct	es;
-+
-+	if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf)))
-+		return retval;
-+	
-+	if ((retval = ext2fs_read_bitmaps(fs)))
-+		return retval;
-+
-+	if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
-+		return retval;
-+
-+	if (inode.i_blocks > 0)
-+		return EEXIST;
-+
-+	es.num_blocks = size;
-+	es.newblocks = 0;
-+	es.buf = buf;
-+	es.err = 0;
-+
-+	retval = ext2fs_block_iterate2(fs, journal_ino, BLOCK_FLAG_APPEND,
-+				       0, mkjournal_proc, &es);
-+	if (es.err) {
-+		retval = es.err;
-+		goto errout;
-+	}
-+
-+	if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
-+		goto errout;
-+
-+ 	inode.i_size += fs->blocksize * size;
-+	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
-+	inode.i_mtime = inode.i_ctime = time(0);
-+	inode.i_links_count = 1;
-+	inode.i_mode = LINUX_S_IFREG | 0600;
-+
-+	if ((retval = ext2fs_write_inode(fs, journal_ino, &inode)))
-+		goto errout;
-+	retval = 0;
-+
-+	memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
-+	fs->super->s_jnl_blocks[16] = inode.i_size;
-+	fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
-+	ext2fs_mark_super_dirty(fs);
-+
-+errout:
-+	ext2fs_free_mem(&buf);
-+	return retval;
-+}
-+
-+/*
-+ * This function adds a journal device to a filesystem
-+ */
-+errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev)
-+{
-+	struct stat	st;
-+	errcode_t	retval;
-+	char		buf[1024];
-+	journal_superblock_t	*jsb;
-+	int		start;
-+	__u32		i, nr_users;
-+
-+	/* Make sure the device exists and is a block device */
-+	if (stat(journal_dev->device_name, &st) < 0)
-+		return errno;
-+	
-+	if (!S_ISBLK(st.st_mode))
-+		return EXT2_ET_JOURNAL_NOT_BLOCK; /* Must be a block device */
-+
-+	/* Get the journal superblock */
-+	start = 1;
-+	if (journal_dev->blocksize == 1024)
-+		start++;
-+	if ((retval = io_channel_read_blk(journal_dev->io, start, -1024, buf)))
-+		return retval;
-+
-+	jsb = (journal_superblock_t *) buf;
-+	if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) ||
-+	    (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2)))
-+		return EXT2_ET_NO_JOURNAL_SB;
-+
-+	if (ntohl(jsb->s_blocksize) != (unsigned long) fs->blocksize)
-+		return EXT2_ET_UNEXPECTED_BLOCK_SIZE;
-+
-+	/* Check and see if this filesystem has already been added */
-+	nr_users = ntohl(jsb->s_nr_users);
-+	for (i=0; i < nr_users; i++) {
-+		if (memcmp(fs->super->s_uuid,
-+			   &jsb->s_users[i*16], 16) == 0)
-+			break;
-+	}
-+	if (i >= nr_users) {
-+		memcpy(&jsb->s_users[nr_users*16],
-+		       fs->super->s_uuid, 16);
-+		jsb->s_nr_users = htonl(nr_users+1);
-+	}
-+
-+	/* Writeback the journal superblock */
-+	if ((retval = io_channel_write_blk(journal_dev->io, start, -1024, buf)))
-+		return retval;
-+	
-+	fs->super->s_journal_inum = 0;
-+	fs->super->s_journal_dev = st.st_rdev;
-+	memcpy(fs->super->s_journal_uuid, jsb->s_uuid,
-+	       sizeof(fs->super->s_journal_uuid));
-+	fs->super->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
-+	ext2fs_mark_super_dirty(fs);
-+	return 0;
-+}
-+
-+/*
-+ * This function adds a journal inode to a filesystem, using either
-+ * POSIX routines if the filesystem is mounted, or using direct I/O
-+ * functions if it is not.
-+ */
-+errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, int flags)
-+{
-+	errcode_t		retval;
-+	ext2_ino_t		journal_ino;
-+	struct stat		st;
-+	char			jfile[1024];
-+	int			fd, mount_flags, f;
-+
-+	if ((retval = ext2fs_check_mount_point(fs->device_name, &mount_flags,
-+					       jfile, sizeof(jfile)-10)))
-+		return retval;
-+
-+	if (mount_flags & EXT2_MF_MOUNTED) {
-+		strcat(jfile, "/.journal");
-+
-+		/*
-+		 * If .../.journal already exists, make sure any 
-+		 * immutable or append-only flags are cleared.
-+		 */
-+#if defined(HAVE_CHFLAGS) && defined(UF_NODUMP)
-+		(void) chflags (jfile, 0);
-+#else
-+#if HAVE_EXT2_IOCTLS
-+		fd = open(jfile, O_RDONLY);
-+		if (fd >= 0) {
-+			f = 0;
-+			ioctl(fd, EXT2_IOC_SETFLAGS, &f);
-+			close(fd);
-+		}
-+#endif
-+#endif
-+
-+		/* Create the journal file */
-+		if ((fd = open(jfile, O_CREAT|O_WRONLY, 0600)) < 0)
-+			return errno;
-+
-+		if ((retval = write_journal_file(fs, jfile, size, flags)))
-+			goto errout;
-+		
-+		/* Get inode number of the journal file */
-+		if (fstat(fd, &st) < 0)
-+			goto errout;
-+
-+#if defined(HAVE_CHFLAGS) && defined(UF_NODUMP)
-+		retval = fchflags (fd, UF_NODUMP|UF_IMMUTABLE);
-+#else
-+#if HAVE_EXT2_IOCTLS
-+		f = EXT2_NODUMP_FL | EXT2_IMMUTABLE_FL;
-+		retval = ioctl(fd, EXT2_IOC_SETFLAGS, &f);
-+#endif
-+#endif
-+		if (retval)
-+			goto errout;
-+		
-+		close(fd);
-+		journal_ino = st.st_ino;
-+	} else {
-+		journal_ino = EXT2_JOURNAL_INO;
-+		if ((retval = write_journal_inode(fs, journal_ino,
-+						  size, flags)))
-+			return retval;
-+	}
-+	
-+	fs->super->s_journal_inum = journal_ino;
-+	fs->super->s_journal_dev = 0;
-+	memset(fs->super->s_journal_uuid, 0,
-+	       sizeof(fs->super->s_journal_uuid));
-+	fs->super->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
-+
-+	ext2fs_mark_super_dirty(fs);
-+	return 0;
-+errout:
-+	close(fd);
-+	return retval;
-+}
-+
-+#ifdef DEBUG
-+main(int argc, char **argv)
-+{
-+	errcode_t	retval;
-+	char		*device_name;
-+	ext2_filsys 	fs;
-+
-+	if (argc < 2) {
-+		fprintf(stderr, "Usage: %s filesystem\n", argv[0]);
-+		exit(1);
-+	}
-+	device_name = argv[1];
-+	
-+	retval = ext2fs_open (device_name, EXT2_FLAG_RW, 0, 0,
-+			      unix_io_manager, &fs);
-+	if (retval) {
-+		com_err(argv[0], retval, "while opening %s", device_name);
-+		exit(1);
-+	}
-+
-+	retval = ext2fs_add_journal_inode(fs, 1024);
-+	if (retval) {
-+		com_err(argv[0], retval, "while adding journal to %s",
-+			device_name);
-+		exit(1);
-+	}
-+	retval = ext2fs_flush(fs);
-+	if (retval) {
-+		printf("Warning, had trouble writing out superblocks.\n");
-+	}
-+	ext2fs_close(fs);
-+	exit(0);
-+	
-+}
-+#endif
-diff -Naur silo-1.4.14.orig/libext2fs/namei.c silo-1.4.14/libext2fs/namei.c
---- silo-1.4.14.orig/libext2fs/namei.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/namei.c	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,205 @@
-+/*
-+ * namei.c --- ext2fs directory lookup operations
-+ * 
-+ * Copyright (C) 1993, 1994, 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+/* #define NAMEI_DEBUG */
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+static errcode_t open_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t base,
-+			    const char *pathname, size_t pathlen, int follow,
-+			    int link_count, char *buf, ext2_ino_t *res_inode);
-+
-+static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
-+			     ext2_ino_t inode, int link_count,
-+			     char *buf, ext2_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 (ext2fs_inode_data_blocks(fs,&ei)) {
-+		retval = ext2fs_get_mem(fs->blocksize, &buffer);
-+		if (retval)
-+			return retval;
-+		retval = io_channel_read_blk(fs->io, ei.i_block[0], 1, buffer);
-+		if (retval) {
-+			ext2fs_free_mem(&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)
-+		ext2fs_free_mem(&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, ext2_ino_t root, ext2_ino_t dir,
-+			   const char *pathname, int pathlen,
-+			   int link_count, char *buf,
-+			   const char **name, int *namelen,
-+			   ext2_ino_t *res_inode)
-+{
-+	char c;
-+	const char *thisname;
-+	int len;
-+	ext2_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, ext2_ino_t root, ext2_ino_t base,
-+			    const char *pathname, size_t pathlen, int follow,
-+			    int link_count, char *buf, ext2_ino_t *res_inode)
-+{
-+	const char *basename;
-+	int namelen;
-+	ext2_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, ext2_ino_t root, ext2_ino_t cwd,
-+		       const char *name, ext2_ino_t *inode)
-+{
-+	char *buf;
-+	errcode_t retval;
-+	
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	retval = ext2fs_get_mem(fs->blocksize, &buf);
-+	if (retval)
-+		return retval;
-+	
-+	retval = open_namei(fs, root, cwd, name, strlen(name), 0, 0,
-+			    buf, inode);
-+
-+	ext2fs_free_mem(&buf);
-+	return retval;
-+}
-+
-+errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+			      const char *name, ext2_ino_t *inode)
-+{
-+	char *buf;
-+	errcode_t retval;
-+	
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	retval = ext2fs_get_mem(fs->blocksize, &buf);
-+	if (retval)
-+		return retval;
-+	
-+	retval = open_namei(fs, root, cwd, name, strlen(name), 1, 0,
-+			    buf, inode);
-+
-+	ext2fs_free_mem(&buf);
-+	return retval;
-+}
-+
-+errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+			ext2_ino_t inode, ext2_ino_t *res_inode)
-+{
-+	char *buf;
-+	errcode_t retval;
-+	
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	retval = ext2fs_get_mem(fs->blocksize, &buf);
-+	if (retval)
-+		return retval;
-+
-+	retval = follow_link(fs, root, cwd, inode, 0, buf, res_inode);
-+
-+	ext2fs_free_mem(&buf);
-+	return retval;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/native.c silo-1.4.14/libext2fs/native.c
---- silo-1.4.14.orig/libext2fs/native.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/native.c	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,27 @@
-+/*
-+ * native.c --- returns the ext2_flag for a native byte order
-+ * 
-+ * Copyright (C) 1996 Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+int ext2fs_native_flag(void)
-+{
-+#ifdef WORDS_BIGENDIAN
-+	return EXT2_FLAG_SWAP_BYTES;
-+#else
-+	return 0;
-+#endif
-+}
-+
-+	
-+	
-diff -Naur silo-1.4.14.orig/libext2fs/newdir.c silo-1.4.14/libext2fs/newdir.c
---- silo-1.4.14.orig/libext2fs/newdir.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/newdir.c	2011-01-10 21:59:35.423156126 -0500
-@@ -0,0 +1,72 @@
-+/*
-+ * newdir.c --- create a new directory block
-+ * 
-+ * Copyright (C) 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#ifndef EXT2_FT_DIR
-+#define EXT2_FT_DIR		2
-+#endif
-+
-+/*
-+ * Create new directory block
-+ */
-+errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
-+			       ext2_ino_t parent_ino, char **block)
-+{
-+	struct ext2_dir_entry 	*dir = NULL;
-+	errcode_t		retval;
-+	char			*buf;
-+	int			rec_len;
-+	int			filetype = 0;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	retval = ext2fs_get_mem(fs->blocksize, &buf);
-+	if (retval)
-+		return retval;
-+	memset(buf, 0, fs->blocksize);
-+	dir = (struct ext2_dir_entry *) buf;
-+	dir->rec_len = fs->blocksize;
-+
-+	if (dir_ino) {
-+		if (fs->super->s_feature_incompat &
-+		    EXT2_FEATURE_INCOMPAT_FILETYPE)
-+			filetype = EXT2_FT_DIR << 8;
-+		/*
-+		 * Set up entry for '.'
-+		 */
-+		dir->inode = dir_ino;
-+		dir->name_len = 1 | filetype;
-+		dir->name[0] = '.';
-+		rec_len = dir->rec_len - EXT2_DIR_REC_LEN(1);
-+		dir->rec_len = EXT2_DIR_REC_LEN(1);
-+
-+		/*
-+		 * Set up entry for '..'
-+		 */
-+		dir = (struct ext2_dir_entry *) (buf + dir->rec_len);
-+		dir->rec_len = rec_len;
-+		dir->inode = parent_ino;
-+		dir->name_len = 2 | filetype;
-+		dir->name[0] = '.';
-+		dir->name[1] = '.';
-+		
-+	}
-+	*block = buf;
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/nt_io.c silo-1.4.14/libext2fs/nt_io.c
---- silo-1.4.14.orig/libext2fs/nt_io.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/nt_io.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,1513 @@
-+/*
-+ * nt_io.c --- This is the Nt I/O interface to the I/O manager.
-+ *
-+ * Implements a one-block write-through cache.
-+ *
-+ * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
-+ * Copyright (C) 1998 Andrey Shedel (andreys@ns.cr.cyco.com)
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+#include "config.h"
-+#endif
-+
-+
-+//
-+// I need some warnings to disable...
-+//
-+
-+
-+#pragma warning(disable:4514) // unreferenced inline function has been removed
-+#pragma warning(push,4)
-+
-+#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union)
-+#pragma warning(disable:4214) // nonstandard extension used : bit field types other than int
-+#pragma warning(disable:4115) // named type definition in parentheses
-+
-+#include <ntddk.h>
-+#include <ntdddisk.h>
-+#include <ntstatus.h>
-+
-+#pragma warning(pop)
-+
-+
-+//
-+// Some native APIs.
-+//
-+
-+NTSYSAPI
-+ULONG
-+NTAPI
-+RtlNtStatusToDosError(
-+    IN NTSTATUS Status
-+   );
-+
-+NTSYSAPI
-+NTSTATUS
-+NTAPI
-+NtClose(
-+    IN HANDLE Handle
-+   );
-+
-+
-+NTSYSAPI
-+NTSTATUS
-+NTAPI
-+NtOpenFile(
-+    OUT PHANDLE FileHandle,
-+    IN ACCESS_MASK DesiredAccess,
-+    IN POBJECT_ATTRIBUTES ObjectAttributes,
-+    OUT PIO_STATUS_BLOCK IoStatusBlock,
-+    IN ULONG ShareAccess,
-+    IN ULONG OpenOptions
-+    );
-+
-+NTSYSAPI
-+NTSTATUS
-+NTAPI
-+NtFlushBuffersFile(
-+    IN HANDLE FileHandle,
-+    OUT PIO_STATUS_BLOCK IoStatusBlock
-+   );
-+
-+
-+NTSYSAPI
-+NTSTATUS
-+NTAPI
-+NtReadFile(
-+    IN HANDLE FileHandle,
-+    IN HANDLE Event OPTIONAL,
-+    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
-+    IN PVOID ApcContext OPTIONAL,
-+    OUT PIO_STATUS_BLOCK IoStatusBlock,
-+    OUT PVOID Buffer,
-+    IN ULONG Length,
-+    IN PLARGE_INTEGER ByteOffset OPTIONAL,
-+    IN PULONG Key OPTIONAL
-+    );
-+
-+NTSYSAPI
-+NTSTATUS
-+NTAPI
-+NtWriteFile(
-+    IN HANDLE FileHandle,
-+    IN HANDLE Event OPTIONAL,
-+    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
-+    IN PVOID ApcContext OPTIONAL,
-+    OUT PIO_STATUS_BLOCK IoStatusBlock,
-+    IN PVOID Buffer,
-+    IN ULONG Length,
-+    IN PLARGE_INTEGER ByteOffset OPTIONAL,
-+    IN PULONG Key OPTIONAL
-+    );
-+
-+NTSYSAPI
-+NTSTATUS
-+NTAPI
-+NtDeviceIoControlFile(
-+    IN HANDLE FileHandle,
-+    IN HANDLE Event OPTIONAL,
-+    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
-+    IN PVOID ApcContext OPTIONAL,
-+    OUT PIO_STATUS_BLOCK IoStatusBlock,
-+    IN ULONG IoControlCode,
-+    IN PVOID InputBuffer OPTIONAL,
-+    IN ULONG InputBufferLength,
-+    OUT PVOID OutputBuffer OPTIONAL,
-+    IN ULONG OutputBufferLength
-+    );
-+
-+NTSYSAPI
-+NTSTATUS
-+NTAPI
-+NtFsControlFile(
-+    IN HANDLE FileHandle,
-+    IN HANDLE Event OPTIONAL,
-+    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
-+    IN PVOID ApcContext OPTIONAL,
-+    OUT PIO_STATUS_BLOCK IoStatusBlock,
-+    IN ULONG IoControlCode,
-+    IN PVOID InputBuffer OPTIONAL,
-+    IN ULONG InputBufferLength,
-+    OUT PVOID OutputBuffer OPTIONAL,
-+    IN ULONG OutputBufferLength
-+    );
-+
-+
-+NTSYSAPI
-+NTSTATUS
-+NTAPI
-+NtDelayExecution(
-+    IN BOOLEAN Alertable,
-+    IN PLARGE_INTEGER Interval
-+    );
-+
-+
-+#define FSCTL_LOCK_VOLUME               CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
-+#define FSCTL_UNLOCK_VOLUME             CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
-+#define FSCTL_DISMOUNT_VOLUME           CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
-+#define FSCTL_IS_VOLUME_MOUNTED         CTL_CODE(FILE_DEVICE_FILE_SYSTEM,10, METHOD_BUFFERED, FILE_ANY_ACCESS)
-+
-+
-+//
-+// useful macros
-+//
-+
-+#define BooleanFlagOn(Flags,SingleFlag) ((BOOLEAN)((((Flags) & (SingleFlag)) != 0)))
-+
-+
-+//
-+// Include Win32 error codes.
-+//
-+
-+#include <winerror.h>
-+
-+//
-+// standard stuff
-+//
-+
-+#include <assert.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <malloc.h>
-+
-+#include <linux/types.h>
-+#include "ext2_fs.h"
-+#include <errno.h>
-+
-+#include "et/com_err.h"
-+#include "ext2fs/ext2fs.h"
-+#include "ext2fs/ext2_err.h"
-+
-+
-+
-+
-+//
-+// For checking structure magic numbers...
-+//
-+
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+	  if ((struct)->magic != (code)) return (code)
-+
-+#define EXT2_ET_MAGIC_NT_IO_CHANNEL  0x10ed
-+
-+
-+//
-+// Private data block
-+//
-+
-+typedef struct _NT_PRIVATE_DATA {
-+	int	   magic;
-+	HANDLE Handle;
-+	int	   Flags;
-+	PCHAR  Buffer;
-+	__u32  BufferBlockNumber;
-+	ULONG  BufferSize;
-+	BOOLEAN OpenedReadonly;
-+	BOOLEAN Written;
-+}NT_PRIVATE_DATA, *PNT_PRIVATE_DATA;
-+
-+
-+
-+//
-+// Standard interface prototypes
-+//
-+
-+static errcode_t nt_open(const char *name, int flags, io_channel *channel);
-+static errcode_t nt_close(io_channel channel);
-+static errcode_t nt_set_blksize(io_channel channel, int blksize);
-+static errcode_t nt_read_blk(io_channel channel, unsigned long block,
-+			       int count, void *data);
-+static errcode_t nt_write_blk(io_channel channel, unsigned long block,
-+				int count, const void *data);
-+static errcode_t nt_flush(io_channel channel);
-+
-+static struct struct_io_manager struct_nt_manager = {
-+	EXT2_ET_MAGIC_IO_MANAGER,
-+	"NT I/O Manager",
-+	nt_open,
-+	nt_close,
-+	nt_set_blksize,
-+	nt_read_blk,
-+	nt_write_blk,
-+	nt_flush
-+};
-+
-+
-+
-+//
-+// function to get API
-+//
-+
-+io_manager nt_io_manager()
-+{
-+	return &struct_nt_manager;
-+}
-+
-+
-+
-+
-+
-+//
-+// This is a code to convert Win32 errors to unix errno
-+//
-+
-+typedef struct {
-+	ULONG WinError;
-+	int errnocode;
-+}ERROR_ENTRY;
-+
-+static ERROR_ENTRY ErrorTable[] = {
-+        {  ERROR_INVALID_FUNCTION,       EINVAL    },
-+        {  ERROR_FILE_NOT_FOUND,         ENOENT    },
-+        {  ERROR_PATH_NOT_FOUND,         ENOENT    },
-+        {  ERROR_TOO_MANY_OPEN_FILES,    EMFILE    },
-+        {  ERROR_ACCESS_DENIED,          EACCES    },
-+        {  ERROR_INVALID_HANDLE,         EBADF     },
-+        {  ERROR_ARENA_TRASHED,          ENOMEM    },
-+        {  ERROR_NOT_ENOUGH_MEMORY,      ENOMEM    },
-+        {  ERROR_INVALID_BLOCK,          ENOMEM    },
-+        {  ERROR_BAD_ENVIRONMENT,        E2BIG     },
-+        {  ERROR_BAD_FORMAT,             ENOEXEC   },
-+        {  ERROR_INVALID_ACCESS,         EINVAL    },
-+        {  ERROR_INVALID_DATA,           EINVAL    },
-+        {  ERROR_INVALID_DRIVE,          ENOENT    },
-+        {  ERROR_CURRENT_DIRECTORY,      EACCES    },
-+        {  ERROR_NOT_SAME_DEVICE,        EXDEV     },
-+        {  ERROR_NO_MORE_FILES,          ENOENT    },
-+        {  ERROR_LOCK_VIOLATION,         EACCES    },
-+        {  ERROR_BAD_NETPATH,            ENOENT    },
-+        {  ERROR_NETWORK_ACCESS_DENIED,  EACCES    },
-+        {  ERROR_BAD_NET_NAME,           ENOENT    },
-+        {  ERROR_FILE_EXISTS,            EEXIST    },
-+        {  ERROR_CANNOT_MAKE,            EACCES    },
-+        {  ERROR_FAIL_I24,               EACCES    },
-+        {  ERROR_INVALID_PARAMETER,      EINVAL    },
-+        {  ERROR_NO_PROC_SLOTS,          EAGAIN    },
-+        {  ERROR_DRIVE_LOCKED,           EACCES    },
-+        {  ERROR_BROKEN_PIPE,            EPIPE     },
-+        {  ERROR_DISK_FULL,              ENOSPC    },
-+        {  ERROR_INVALID_TARGET_HANDLE,  EBADF     },
-+        {  ERROR_INVALID_HANDLE,         EINVAL    },
-+        {  ERROR_WAIT_NO_CHILDREN,       ECHILD    },
-+        {  ERROR_CHILD_NOT_COMPLETE,     ECHILD    },
-+        {  ERROR_DIRECT_ACCESS_HANDLE,   EBADF     },
-+        {  ERROR_NEGATIVE_SEEK,          EINVAL    },
-+        {  ERROR_SEEK_ON_DEVICE,         EACCES    },
-+        {  ERROR_DIR_NOT_EMPTY,          ENOTEMPTY },
-+        {  ERROR_NOT_LOCKED,             EACCES    },
-+        {  ERROR_BAD_PATHNAME,           ENOENT    },
-+        {  ERROR_MAX_THRDS_REACHED,      EAGAIN    },
-+        {  ERROR_LOCK_FAILED,            EACCES    },
-+        {  ERROR_ALREADY_EXISTS,         EEXIST    },
-+        {  ERROR_FILENAME_EXCED_RANGE,   ENOENT    },
-+        {  ERROR_NESTING_NOT_ALLOWED,    EAGAIN    },
-+        {  ERROR_NOT_ENOUGH_QUOTA,       ENOMEM    }
-+};
-+
-+
-+
-+
-+static
-+unsigned
-+_MapDosError (
-+    IN ULONG WinError
-+   )
-+{
-+	int i;
-+
-+	//
-+	// Lookup
-+	//
-+
-+	for (i = 0; i < (sizeof(ErrorTable)/sizeof(ErrorTable[0])); ++i)
-+	{
-+		if (WinError == ErrorTable[i].WinError)
-+		{
-+			return ErrorTable[i].errnocode;
-+		}
-+	}
-+
-+	//
-+	// not in table. Check ranges
-+	//
-+
-+	if ((WinError >= ERROR_WRITE_PROTECT) &&
-+		(WinError <= ERROR_SHARING_BUFFER_EXCEEDED))
-+	{
-+		return EACCES;
-+	}
-+	else if ((WinError >= ERROR_INVALID_STARTING_CODESEG) &&
-+			 (WinError <= ERROR_INFLOOP_IN_RELOC_CHAIN))
-+	{
-+		return ENOEXEC;
-+	}
-+	else
-+	{
-+		return EINVAL;
-+	}
-+}
-+
-+
-+
-+
-+
-+
-+
-+//
-+// Function to map NT status to dos error.
-+//
-+
-+static
-+__inline
-+unsigned
-+_MapNtStatus(
-+    IN NTSTATUS Status
-+   )
-+{
-+	return _MapDosError(RtlNtStatusToDosError(Status));
-+}
-+
-+
-+
-+
-+
-+//
-+// Helper functions to make things easyer
-+//
-+
-+static
-+NTSTATUS
-+_OpenNtName(
-+    IN PCSTR Name,
-+    IN BOOLEAN Readonly,
-+    OUT PHANDLE Handle,
-+    OUT PBOOLEAN OpenedReadonly OPTIONAL
-+   )
-+{
-+	UNICODE_STRING UnicodeString;
-+	ANSI_STRING    AnsiString;
-+	WCHAR Buffer[512];
-+	NTSTATUS Status;
-+	OBJECT_ATTRIBUTES ObjectAttributes;
-+	IO_STATUS_BLOCK IoStatusBlock;
-+
-+	//
-+	// Make Unicode name from inlut string
-+	//
-+
-+	UnicodeString.Buffer = &Buffer[0];
-+	UnicodeString.Length = 0;
-+	UnicodeString.MaximumLength = sizeof(Buffer); // in bytes!!!
-+
-+	RtlInitAnsiString(&AnsiString, Name);
-+
-+	Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
-+
-+	if(!NT_SUCCESS(Status))
-+	{
-+		return Status; // Unpappable character?
-+	}
-+
-+	//
-+	// Initialize object
-+	//
-+
-+	InitializeObjectAttributes(&ObjectAttributes,
-+							   &UnicodeString,
-+							   OBJ_CASE_INSENSITIVE,
-+							   NULL,
-+							   NULL );
-+
-+	//
-+	// Try to open it in initial mode
-+	//
-+
-+	if(ARGUMENT_PRESENT(OpenedReadonly))
-+	{
-+		*OpenedReadonly = Readonly;
-+	}
-+
-+
-+	Status = NtOpenFile(Handle,
-+						SYNCHRONIZE | FILE_READ_DATA | (Readonly ? 0 : FILE_WRITE_DATA),
-+						&ObjectAttributes,
-+						&IoStatusBlock,
-+						FILE_SHARE_WRITE | FILE_SHARE_READ,
-+						FILE_SYNCHRONOUS_IO_NONALERT);
-+
-+	if(!NT_SUCCESS(Status))
-+	{
-+		//
-+		// Maybe was just mounted? wait 0.5 sec and retry.
-+		//
-+
-+		LARGE_INTEGER Interval;
-+		Interval.QuadPart = -5000000; // 0.5 sec. from now
-+
-+		NtDelayExecution(FALSE, &Interval);
-+
-+		Status = NtOpenFile(Handle,
-+							SYNCHRONIZE | FILE_READ_DATA | (Readonly ? 0 : FILE_WRITE_DATA),
-+							&ObjectAttributes,
-+							&IoStatusBlock,
-+							FILE_SHARE_WRITE | FILE_SHARE_READ,
-+							FILE_SYNCHRONOUS_IO_NONALERT);
-+
-+		//
-+		// Try to satisfy mode
-+		//
-+
-+		if((STATUS_ACCESS_DENIED == Status) && !Readonly)
-+		{
-+			if(ARGUMENT_PRESENT(OpenedReadonly))
-+			{
-+				*OpenedReadonly = TRUE;
-+			}
-+
-+			Status = NtOpenFile(Handle,
-+							SYNCHRONIZE | FILE_READ_DATA,
-+							&ObjectAttributes,
-+							&IoStatusBlock,
-+							FILE_SHARE_WRITE | FILE_SHARE_READ,
-+							FILE_SYNCHRONOUS_IO_NONALERT);
-+		}
-+	}
-+
-+
-+
-+	//
-+	// done
-+	//
-+
-+	return Status;
-+}
-+
-+
-+static
-+NTSTATUS
-+_OpenDriveLetter(
-+    IN CHAR Letter,
-+    IN BOOLEAN ReadOnly,
-+    OUT PHANDLE Handle,
-+    OUT PBOOLEAN OpenedReadonly OPTIONAL
-+   )
-+{
-+	CHAR Buffer[100];
-+
-+	sprintf(Buffer, "\\DosDevices\\%c:", Letter);
-+
-+	return _OpenNtName(Buffer, ReadOnly, Handle, OpenedReadonly);
-+}
-+
-+
-+//
-+// Flush device
-+//
-+
-+static
-+__inline
-+NTSTATUS
-+_FlushDrive(
-+		IN HANDLE Handle
-+		)
-+{
-+	IO_STATUS_BLOCK IoStatusBlock;
-+	return NtFlushBuffersFile(Handle, &IoStatusBlock);
-+}
-+
-+
-+//
-+// lock drive
-+//
-+
-+static
-+__inline
-+NTSTATUS
-+_LockDrive(
-+		IN HANDLE Handle
-+		)
-+{
-+	IO_STATUS_BLOCK IoStatusBlock;
-+	return NtFsControlFile(Handle, 0, 0, 0, &IoStatusBlock, FSCTL_LOCK_VOLUME, 0, 0, 0, 0);
-+}
-+
-+
-+//
-+// unlock drive
-+//
-+
-+static
-+__inline
-+NTSTATUS
-+_UnlockDrive(
-+	IN HANDLE Handle
-+	)
-+{
-+	IO_STATUS_BLOCK IoStatusBlock;
-+	return NtFsControlFile(Handle, 0, 0, 0, &IoStatusBlock, FSCTL_UNLOCK_VOLUME, 0, 0, 0, 0);
-+}
-+
-+static
-+__inline
-+NTSTATUS
-+_DismountDrive(
-+	IN HANDLE Handle
-+	)
-+{
-+	IO_STATUS_BLOCK IoStatusBlock;
-+	return NtFsControlFile(Handle, 0, 0, 0, &IoStatusBlock, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0);
-+}
-+
-+
-+//
-+// is mounted
-+//
-+
-+static
-+__inline
-+BOOLEAN
-+_IsMounted(
-+	IN HANDLE Handle
-+	)
-+{
-+	IO_STATUS_BLOCK IoStatusBlock;
-+	NTSTATUS Status;
-+	Status = NtFsControlFile(Handle, 0, 0, 0, &IoStatusBlock, FSCTL_IS_VOLUME_MOUNTED, 0, 0, 0, 0);
-+	return (BOOLEAN)(STATUS_SUCCESS == Status);
-+}
-+
-+
-+static
-+__inline
-+NTSTATUS
-+_CloseDisk(
-+		IN HANDLE Handle
-+		)
-+{
-+	return NtClose(Handle);
-+}
-+
-+
-+
-+
-+//
-+// Make NT name from any recognized name
-+//
-+
-+static
-+PCSTR
-+_NormalizeDeviceName(
-+    IN PCSTR Device,
-+    IN PSTR NormalizedDeviceNameBuffer
-+   )
-+{
-+	int PartitionNumber = -1;
-+	UCHAR DiskNumber;
-+	PSTR p;
-+
-+
-+	//
-+	// Do not try to parse NT name
-+	//
-+
-+	if('\\' == *Device)
-+		return Device;
-+
-+
-+
-+	//
-+	// Strip leading '/dev/' if any
-+	//
-+
-+	if(('/' == *(Device)) &&
-+		('d' == *(Device + 1)) &&
-+		('e' == *(Device + 2)) &&
-+		('v' == *(Device + 3)) &&
-+		('/' == *(Device + 4)))
-+	{
-+		Device += 5;
-+	}
-+
-+	if('\0' == *Device)
-+	{
-+		return NULL;
-+	}
-+
-+
-+	//
-+	// forms: hda[n], fd[n]
-+	//
-+
-+	if('d' != *(Device + 1))
-+	{
-+		return NULL;
-+	}
-+
-+	if('h' == *Device)
-+	{
-+		if((*(Device + 2) < 'a') || (*(Device + 2) > ('a' + 9)) ||
-+		   ((*(Device + 3) != '\0') &&
-+			((*(Device + 4) != '\0') ||
-+			 ((*(Device + 3) < '0') || (*(Device + 3) > '9'))
-+			)
-+		   )
-+		  )
-+		{
-+			return NULL;
-+		}
-+
-+		DiskNumber = (UCHAR)(*(Device + 2) - 'a');
-+
-+		if(*(Device + 3) != '\0')
-+		{
-+			PartitionNumber = (*(Device + 3) - '0');
-+		}
-+
-+	}
-+	else if('f' == *Device)
-+	{
-+		//
-+		// 3-d letted should be a digit.
-+		//
-+
-+		if((*(Device + 3) != '\0') ||
-+		   (*(Device + 2) < '0') || (*(Device + 2) > '9'))
-+		{
-+			return NULL;
-+		}
-+
-+		DiskNumber = (UCHAR)(*(Device + 2) - '0');
-+
-+	}
-+	else
-+	{
-+		//
-+		// invalid prefix
-+		//
-+
-+		return NULL;
-+	}
-+
-+
-+
-+	//
-+	// Prefix
-+	//
-+
-+	strcpy(NormalizedDeviceNameBuffer, "\\Device\\");
-+
-+	//
-+	// Media name
-+	//
-+
-+	switch(*Device)
-+	{
-+
-+	case 'f':
-+		strcat(NormalizedDeviceNameBuffer, "Floppy0");
-+		break;
-+
-+	case 'h':
-+		strcat(NormalizedDeviceNameBuffer, "Harddisk0");
-+		break;
-+	}
-+
-+
-+	p = NormalizedDeviceNameBuffer + strlen(NormalizedDeviceNameBuffer) - 1;
-+	*p = (CHAR)(*p + DiskNumber);
-+
-+
-+	//
-+	// Partition nr.
-+	//
-+
-+	if(PartitionNumber >= 0)
-+	{
-+		strcat(NormalizedDeviceNameBuffer, "\\Partition0");
-+
-+		p = NormalizedDeviceNameBuffer + strlen(NormalizedDeviceNameBuffer) - 1;
-+		*p = (CHAR)(*p + PartitionNumber);
-+	}
-+
-+
-+	return NormalizedDeviceNameBuffer;
-+}
-+
-+
-+
-+
-+static
-+VOID
-+_GetDeviceSize(
-+    IN HANDLE h,
-+    OUT unsigned __int64 *FsSize
-+   )
-+{
-+	PARTITION_INFORMATION pi;
-+	DISK_GEOMETRY gi;
-+	NTSTATUS Status;
-+	IO_STATUS_BLOCK IoStatusBlock;
-+
-+	//
-+	// Zero it
-+	//
-+
-+	*FsSize = 0;
-+
-+	//
-+	// Call driver
-+	//
-+
-+	RtlZeroMemory(&pi, sizeof(PARTITION_INFORMATION));
-+
-+	Status = NtDeviceIoControlFile(
-+		h, NULL, NULL, NULL, &IoStatusBlock, IOCTL_DISK_GET_PARTITION_INFO,
-+		&pi, sizeof(PARTITION_INFORMATION),
-+		&pi, sizeof(PARTITION_INFORMATION));
-+
-+
-+	if(NT_SUCCESS(Status))
-+	{
-+		*FsSize = pi.PartitionLength.QuadPart;
-+	}
-+	else if(STATUS_INVALID_DEVICE_REQUEST == Status)
-+	{
-+		//
-+		// No partitions: get device info.
-+		//
-+
-+		RtlZeroMemory(&gi, sizeof(DISK_GEOMETRY));
-+
-+		Status = NtDeviceIoControlFile(
-+				h, NULL, NULL, NULL, &IoStatusBlock, IOCTL_DISK_GET_DRIVE_GEOMETRY,
-+				&gi, sizeof(DISK_GEOMETRY),
-+				&gi, sizeof(DISK_GEOMETRY));
-+
-+
-+		if(NT_SUCCESS(Status))
-+		{
-+			*FsSize =
-+				gi.BytesPerSector *
-+				gi.SectorsPerTrack *
-+				gi.TracksPerCylinder *
-+				gi.Cylinders.QuadPart;
-+		}
-+
-+	}
-+}
-+
-+
-+
-+//
-+// Open device by name.
-+//
-+
-+static
-+BOOLEAN
-+_Ext2OpenDevice(
-+    IN PCSTR Name,
-+    IN BOOLEAN ReadOnly,
-+    OUT PHANDLE Handle,
-+    OUT PBOOLEAN OpenedReadonly OPTIONAL,
-+    OUT unsigned *Errno OPTIONAL
-+   )
-+{
-+	CHAR NormalizedDeviceName[512];
-+	NTSTATUS Status;
-+
-+	if(NULL == Name)
-+	{
-+		//
-+		// Set not found
-+		//
-+
-+		if(ARGUMENT_PRESENT(Errno))
-+			*Errno = ENOENT;
-+
-+		return FALSE;
-+	}
-+
-+
-+	if((((*Name) | 0x20) >= 'a') && (((*Name) | 0x20) <= 'z') &&
-+		(':' == *(Name + 1)) && ('\0' == *(Name + 2)))
-+	{
-+		Status = _OpenDriveLetter(*Name, ReadOnly, Handle, OpenedReadonly);
-+	}
-+	else
-+	{
-+		//
-+		// Make name
-+		//
-+
-+		Name = _NormalizeDeviceName(Name, NormalizedDeviceName);
-+
-+		if(NULL == Name)
-+		{
-+			//
-+			// Set not found
-+			//
-+
-+			if(ARGUMENT_PRESENT(Errno))
-+				*Errno = ENOENT;
-+
-+			return FALSE;
-+		}
-+
-+		//
-+		// Try to open it
-+		//
-+
-+		Status = _OpenNtName(Name, ReadOnly, Handle, OpenedReadonly);
-+	}
-+
-+
-+	if(!NT_SUCCESS(Status))
-+	{
-+		if(ARGUMENT_PRESENT(Errno))
-+			*Errno = _MapNtStatus(Status);
-+
-+		return FALSE;
-+	}
-+
-+	return TRUE;
-+}
-+
-+
-+//
-+// Raw block io. Sets dos errno
-+//
-+
-+static
-+BOOLEAN
-+_BlockIo(
-+    IN HANDLE Handle,
-+    IN LARGE_INTEGER Offset,
-+    IN ULONG Bytes,
-+    IN OUT PCHAR Buffer,
-+    IN BOOLEAN Read,
-+    OUT unsigned* Errno
-+   )
-+{
-+	IO_STATUS_BLOCK IoStatusBlock;
-+	NTSTATUS Status;
-+
-+	//
-+	// Should be aligned
-+	//
-+
-+	ASSERT(0 == (Bytes % 512));
-+	ASSERT(0 == (Offset.LowPart % 512));
-+
-+
-+	//
-+	// perform io
-+	//
-+
-+	if(Read)
-+	{
-+		Status = NtReadFile(Handle, NULL, NULL, NULL,
-+			&IoStatusBlock, Buffer, Bytes, &Offset, NULL);
-+	}
-+	else
-+	{
-+		Status = NtWriteFile(Handle, NULL, NULL, NULL,
-+			&IoStatusBlock, Buffer, Bytes, &Offset, NULL);
-+	}
-+
-+
-+	//
-+	// translate error
-+	//
-+
-+	if(NT_SUCCESS(Status))
-+	{
-+		*Errno = 0;
-+		return TRUE;
-+	}
-+
-+	*Errno = _MapNtStatus(Status);
-+
-+	return FALSE;
-+}
-+
-+
-+
-+__inline
-+BOOLEAN
-+_RawWrite(
-+    IN HANDLE Handle,
-+    IN LARGE_INTEGER Offset,
-+    IN ULONG Bytes,
-+    OUT const CHAR* Buffer,
-+    OUT unsigned* Errno
-+   )
-+{
-+	return _BlockIo(Handle, Offset, Bytes, (PCHAR)Buffer, FALSE, Errno);
-+}
-+
-+__inline
-+BOOLEAN
-+_RawRead(
-+    IN HANDLE Handle,
-+    IN LARGE_INTEGER Offset,
-+    IN ULONG Bytes,
-+    IN PCHAR Buffer,
-+    OUT unsigned* Errno
-+   )
-+{
-+	return _BlockIo(Handle, Offset, Bytes, Buffer, TRUE, Errno);
-+}
-+
-+
-+
-+__inline
-+BOOLEAN
-+_SetPartType(
-+    IN HANDLE Handle,
-+    IN UCHAR Type
-+   )
-+{
-+	IO_STATUS_BLOCK IoStatusBlock;
-+	return STATUS_SUCCESS == NtDeviceIoControlFile(
-+												   Handle, NULL, NULL, NULL, &IoStatusBlock, IOCTL_DISK_SET_PARTITION_INFO,
-+												   &Type, sizeof(Type),
-+												   NULL, 0);
-+}
-+
-+
-+
-+//--------------------- interface part
-+
-+//
-+// Interface functions.
-+// Is_mounted is set to 1 if the device is mounted, 0 otherwise
-+//
-+
-+errcode_t
-+ext2fs_check_if_mounted(const char *file, int *mount_flags)
-+{
-+	HANDLE h;
-+	BOOLEAN Readonly;
-+
-+	*mount_flags = 0;
-+
-+	if(!_Ext2OpenDevice(file, TRUE, &h, &Readonly, NULL))
-+	{
-+		return 0;
-+	}
-+
-+
-+	__try{
-+		*mount_flags &= _IsMounted(h) ? EXT2_MF_MOUNTED : 0;
-+	}
-+	__finally{
-+		_CloseDisk(h);
-+	}
-+
-+	return 0;
-+}
-+
-+
-+
-+//
-+// Returns the number of blocks in a partition
-+//
-+
-+static __int64 FsSize = 0;
-+static char knowndevice[1024] = "";
-+
-+
-+errcode_t
-+ext2fs_get_device_size(const char *file, int blocksize,
-+				 blk_t *retblocks)
-+{
-+	HANDLE h;
-+	BOOLEAN Readonly;
-+
-+	if((0 == FsSize) || (0 != strcmp(knowndevice, file)))
-+	{
-+
-+		if(!_Ext2OpenDevice(file, TRUE, &h, &Readonly, NULL))
-+		{
-+			return 0;
-+		}
-+
-+
-+		__try{
-+
-+			//
-+			// Get size
-+			//
-+
-+			_GetDeviceSize(h, &FsSize);
-+			strcpy(knowndevice, file);
-+		}
-+		__finally{
-+			_CloseDisk(h);
-+		}
-+
-+	}
-+
-+	*retblocks = (blk_t)(unsigned __int64)(FsSize / blocksize);
-+	UNREFERENCED_PARAMETER(file);
-+	return 0;
-+}
-+
-+
-+
-+
-+
-+
-+//
-+// Table elements
-+//
-+
-+
-+static
-+errcode_t
-+nt_open(const char *name, int flags, io_channel *channel)
-+{
-+	io_channel      io = NULL;
-+	PNT_PRIVATE_DATA NtData = NULL;
-+	errcode_t Errno = 0;
-+
-+	//
-+	// Check name
-+	//
-+
-+	if (NULL == name)
-+	{
-+		return EXT2_ET_BAD_DEVICE_NAME;
-+	}
-+
-+	__try{
-+
-+		//
-+		// Allocate channel handle
-+		//
-+
-+		io = (io_channel) malloc(sizeof(struct struct_io_channel));
-+
-+		if (NULL == io)
-+		{
-+			Errno = ENOMEM;
-+			__leave;
-+		}
-+
-+		RtlZeroMemory(io, sizeof(struct struct_io_channel));
-+		io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
-+
-+		NtData = (PNT_PRIVATE_DATA)malloc(sizeof(NT_PRIVATE_DATA));
-+
-+		if (NULL == NtData)
-+		{
-+			Errno = ENOMEM;
-+			__leave;
-+		}
-+
-+
-+		io->manager = nt_io_manager();
-+		io->name = malloc(strlen(name) + 1);
-+		if (NULL == io->name)
-+		{
-+			Errno = ENOMEM;
-+			__leave;
-+		}
-+
-+		strcpy(io->name, name);
-+		io->private_data = NtData;
-+		io->block_size = 1024;
-+		io->read_error = 0;
-+		io->write_error = 0;
-+		io->refcount = 1;
-+
-+		//
-+		// Initialize data
-+		//
-+
-+		RtlZeroMemory(NtData, sizeof(NT_PRIVATE_DATA));
-+
-+		NtData->magic = EXT2_ET_MAGIC_NT_IO_CHANNEL;
-+		NtData->BufferBlockNumber = 0xffffffff;
-+		NtData->BufferSize = 1024;
-+		NtData->Buffer = malloc(NtData->BufferSize);
-+
-+		if (NULL == NtData->Buffer)
-+		{
-+			Errno = ENOMEM;
-+			__leave;
-+		}
-+
-+		//
-+		// Open it
-+		//
-+
-+		if(!_Ext2OpenDevice(name, (BOOLEAN)!BooleanFlagOn(flags, EXT2_FLAG_RW), &NtData->Handle, &NtData->OpenedReadonly, &Errno))
-+		{
-+			__leave;
-+		}
-+
-+
-+		//
-+		// get size
-+		//
-+
-+		_GetDeviceSize(NtData->Handle, &FsSize);
-+		strcpy(knowndevice, name);
-+
-+
-+		//
-+		// Lock/dismount
-+		//
-+
-+		if(!NT_SUCCESS(_LockDrive(NtData->Handle)) /*|| !NT_SUCCESS(_DismountDrive(NtData->Handle))*/)
-+		{
-+			NtData->OpenedReadonly = TRUE;
-+		}
-+
-+		//
-+		// Done
-+		//
-+
-+		*channel = io;
-+
-+
-+	}
-+	__finally{
-+
-+		if(0 != Errno)
-+		{
-+			//
-+			// Cleanup
-+			//
-+
-+			if (NULL != io)
-+			{
-+				if(NULL != io->name)
-+				{
-+					free(io->name);
-+				}
-+
-+				free(io);
-+			}
-+
-+			if (NULL != NtData)
-+			{
-+				if(NULL != NtData->Handle)
-+				{
-+					_UnlockDrive(NtData->Handle);
-+					_CloseDisk(NtData->Handle);
-+				}
-+
-+				if(NULL != NtData->Buffer)
-+				{
-+					free(NtData->Buffer);
-+				}
-+
-+				free(NtData);
-+			}
-+		}
-+	}
-+
-+	return Errno;
-+}
-+
-+
-+//
-+// Close api
-+//
-+
-+static
-+errcode_t
-+nt_close(io_channel channel)
-+{
-+	PNT_PRIVATE_DATA NtData = NULL;
-+
-+	if(NULL == channel)
-+	{
-+		return 0;
-+	}
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	NtData = (PNT_PRIVATE_DATA) channel->private_data;
-+	EXT2_CHECK_MAGIC(NtData, EXT2_ET_MAGIC_NT_IO_CHANNEL);
-+
-+	if (--channel->refcount > 0)
-+	{
-+		return 0;
-+	}
-+
-+	if(NULL != channel->name)
-+	{
-+		free(channel->name);
-+	}
-+
-+
-+	free(channel);
-+
-+	if (NULL != NtData)
-+	{
-+		if(NULL != NtData->Handle)
-+		{
-+			_DismountDrive(NtData->Handle);
-+			_UnlockDrive(NtData->Handle);
-+			_CloseDisk(NtData->Handle);
-+		}
-+
-+		if(NULL != NtData->Buffer)
-+		{
-+			free(NtData->Buffer);
-+		}
-+
-+		free(NtData);
-+	}
-+
-+	return 0;
-+}
-+
-+
-+
-+//
-+// set block size
-+//
-+
-+static
-+errcode_t
-+nt_set_blksize(io_channel channel, int blksize)
-+{
-+	PNT_PRIVATE_DATA NtData = NULL;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	NtData = (PNT_PRIVATE_DATA) channel->private_data;
-+	EXT2_CHECK_MAGIC(NtData, EXT2_ET_MAGIC_NT_IO_CHANNEL);
-+
-+	if (channel->block_size != blksize)
-+	{
-+		channel->block_size = blksize;
-+
-+		free(NtData->Buffer);
-+		NtData->BufferBlockNumber = 0xffffffff;
-+		NtData->BufferSize = channel->block_size;
-+		ASSERT(0 == (NtData->BufferSize % 512));
-+
-+		NtData->Buffer = malloc(NtData->BufferSize);
-+
-+		if (NULL == NtData->Buffer)
-+		{
-+			return ENOMEM;
-+		}
-+
-+	}
-+
-+	return 0;
-+}
-+
-+
-+//
-+// read block
-+//
-+
-+static
-+errcode_t
-+nt_read_blk(io_channel channel, unsigned long block,
-+			       int count, void *buf)
-+{
-+	PVOID BufferToRead;
-+	ULONG SizeToRead;
-+	ULONG Size;
-+	LARGE_INTEGER Offset;
-+	PNT_PRIVATE_DATA NtData = NULL;
-+	unsigned Errno = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	NtData = (PNT_PRIVATE_DATA) channel->private_data;
-+	EXT2_CHECK_MAGIC(NtData, EXT2_ET_MAGIC_NT_IO_CHANNEL);
-+
-+	//
-+	// If it's in the cache, use it!
-+	//
-+
-+	if ((1 == count) &&
-+		(block == NtData->BufferBlockNumber) &&
-+		(NtData->BufferBlockNumber != 0xffffffff))
-+	{
-+		memcpy(buf, NtData->Buffer, channel->block_size);
-+		return 0;
-+	}
-+
-+	Size = (count < 0) ? (ULONG)(-count) : (ULONG)(count * channel->block_size);
-+
-+	Offset.QuadPart = block * channel->block_size;
-+
-+	//
-+	// If not fit to the block
-+	//
-+
-+	if(Size <= NtData->BufferSize)
-+	{
-+		//
-+		// Update the cache
-+		//
-+
-+		NtData->BufferBlockNumber = block;
-+		BufferToRead = NtData->Buffer;
-+		SizeToRead = NtData->BufferSize;
-+	}
-+	else
-+	{
-+		SizeToRead = Size;
-+		BufferToRead = buf;
-+		ASSERT(0 == (SizeToRead % channel->block_size));
-+	}
-+
-+	if(!_RawRead(NtData->Handle, Offset, SizeToRead, BufferToRead, &Errno))
-+	{
-+
-+		if (channel->read_error)
-+		{
-+			return (channel->read_error)(channel, block, count, buf,
-+					       Size, 0, Errno);
-+		}
-+		else
-+		{
-+			return Errno;
-+		}
-+	}
-+
-+
-+	if(BufferToRead != buf)
-+	{
-+		ASSERT(Size <= SizeToRead);
-+		memcpy(buf, BufferToRead, Size);
-+	}
-+
-+	return 0;
-+}
-+
-+
-+//
-+// write block
-+//
-+
-+static
-+errcode_t
-+nt_write_blk(io_channel channel, unsigned long block,
-+				int count, const void *buf)
-+{
-+	ULONG SizeToWrite;
-+	LARGE_INTEGER Offset;
-+	PNT_PRIVATE_DATA NtData = NULL;
-+	unsigned Errno = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	NtData = (PNT_PRIVATE_DATA) channel->private_data;
-+	EXT2_CHECK_MAGIC(NtData, EXT2_ET_MAGIC_NT_IO_CHANNEL);
-+
-+	if(NtData->OpenedReadonly)
-+	{
-+		return EACCES;
-+	}
-+
-+	if (count == 1)
-+	{
-+		SizeToWrite = channel->block_size;
-+	}
-+	else
-+	{
-+		NtData->BufferBlockNumber = 0xffffffff;
-+
-+		if (count < 0)
-+		{
-+			SizeToWrite = (ULONG)(-count);
-+		}
-+		else
-+		{
-+			SizeToWrite = (ULONG)(count * channel->block_size);
-+		}
-+	}
-+
-+
-+	ASSERT(0 == (SizeToWrite % 512));
-+	Offset.QuadPart = block * channel->block_size;
-+
-+	if(!_RawWrite(NtData->Handle, Offset, SizeToWrite, buf, &Errno))
-+	{
-+		if (channel->write_error)
-+		{
-+			return (channel->write_error)(channel, block, count, buf,
-+						SizeToWrite, 0, Errno);
-+		}
-+		else
-+		{
-+			return Errno;
-+		}
-+	}
-+
-+
-+	//
-+	// Stash a copy.
-+	//
-+
-+	if(SizeToWrite >= NtData->BufferSize)
-+	{
-+		NtData->BufferBlockNumber = block;
-+		memcpy(NtData->Buffer, buf, NtData->BufferSize);
-+	}
-+
-+	NtData->Written = TRUE;
-+
-+	return 0;
-+
-+}
-+
-+
-+
-+//
-+// Flush data buffers to disk.  Since we are currently using a
-+// write-through cache, this is a no-op.
-+//
-+
-+static
-+errcode_t
-+nt_flush(io_channel channel)
-+{
-+	PNT_PRIVATE_DATA NtData = NULL;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	NtData = (PNT_PRIVATE_DATA) channel->private_data;
-+	EXT2_CHECK_MAGIC(NtData, EXT2_ET_MAGIC_NT_IO_CHANNEL);
-+
-+	if(NtData->OpenedReadonly)
-+	{
-+		return 0; // EACCESS;
-+	}
-+
-+
-+	//
-+	// Flush file buffers.
-+	//
-+
-+	_FlushDrive(NtData->Handle);
-+
-+
-+	//
-+	// Test and correct partition type.
-+	//
-+
-+	if(NtData->Written)
-+	{
-+		_SetPartType(NtData->Handle, 0x83);
-+	}
-+
-+	return 0;
-+}
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/openfs.c silo-1.4.14/libext2fs/openfs.c
---- silo-1.4.14.orig/libext2fs/openfs.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/openfs.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,326 @@
-+/*
-+ * openfs.c --- open an ext2 filesystem
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+
-+
-+#include "ext2fs.h"
-+#include "e2image.h"
-+
-+blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, dgrp_t i)
-+{
-+	int	bg;
-+	int	has_super = 0;
-+	int	ret_blk;
-+
-+	if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
-+	    (i < fs->super->s_first_meta_bg))
-+		return (group_block + i + 1);
-+
-+	bg = (fs->blocksize / sizeof (struct ext2_group_desc)) * i;
-+	if (ext2fs_bg_has_super(fs, bg))
-+		has_super = 1;
-+	ret_blk = (fs->super->s_first_data_block + has_super + 
-+		   (bg * fs->super->s_blocks_per_group));
-+	/*
-+	 * If group_block is not the normal value, we're trying to use
-+	 * the backup group descriptors and superblock --- so use the
-+	 * alternate location of the second block group in the
-+	 * metablock group.  Ideally we should be testing each bg
-+	 * descriptor block individually for correctness, but we don't
-+	 * have the infrastructure in place to do that.
-+	 */
-+	if (group_block != fs->super->s_first_data_block &&
-+	    ((ret_blk + fs->super->s_blocks_per_group) <
-+	     fs->super->s_blocks_count))
-+		ret_blk += fs->super->s_blocks_per_group;
-+	return ret_blk;
-+}
-+
-+errcode_t ext2fs_open(const char *name, int flags, int superblock,
-+		      unsigned int block_size, io_manager manager, 
-+		      ext2_filsys *ret_fs)
-+{
-+	return ext2fs_open2(name, 0, flags, superblock, block_size, 
-+			    manager, ret_fs);
-+}
-+
-+/*
-+ *  Note: if superblock is non-zero, block-size must also be non-zero.
-+ * 	Superblock and block_size can be zero to use the default size.
-+ *
-+ * Valid flags for ext2fs_open()
-+ * 
-+ * 	EXT2_FLAG_RW	- Open the filesystem for read/write.
-+ * 	EXT2_FLAG_FORCE - Open the filesystem even if some of the
-+ *				features aren't supported.
-+ *	EXT2_FLAG_JOURNAL_DEV_OK - Open an ext3 journal device
-+ */
-+errcode_t ext2fs_open2(const char *name, const char *io_options,
-+		       int flags, int superblock,
-+		       unsigned int block_size, io_manager manager, 
-+		       ext2_filsys *ret_fs)
-+{
-+	ext2_filsys	fs;
-+	errcode_t	retval;
-+	unsigned long	i;
-+	int		j, groups_per_block, blocks_per_group;
-+	blk_t		group_block, blk;
-+	char		*dest, *cp;
-+	struct ext2_group_desc *gdp;
-+	
-+	EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);
-+
-+	retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
-+	if (retval)
-+		return retval;
-+	
-+	memset(fs, 0, sizeof(struct struct_ext2_filsys));
-+	fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
-+	fs->flags = flags;
-+	fs->umask = 022;
-+	retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name);
-+	if (retval)
-+		goto cleanup;
-+	strcpy(fs->device_name, name);
-+	cp = strchr(fs->device_name, '?');
-+	if (!io_options && cp) {
-+		*cp++ = 0;
-+		io_options = cp;
-+	}
-+		
-+	retval = manager->open(fs->device_name, 
-+			       (flags & EXT2_FLAG_RW) ? IO_FLAG_RW : 0,
-+			       &fs->io);
-+	if (retval)
-+		goto cleanup;
-+	if (io_options && 
-+	    (retval = io_channel_set_options(fs->io, io_options)))
-+		goto cleanup;
-+	fs->image_io = fs->io;
-+	fs->io->app_data = fs;
-+	retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->super);
-+	if (retval)
-+		goto cleanup;
-+	if (flags & EXT2_FLAG_IMAGE_FILE) {
-+		retval = ext2fs_get_mem(sizeof(struct ext2_image_hdr),
-+					&fs->image_header);
-+		if (retval)
-+			goto cleanup;
-+		retval = io_channel_read_blk(fs->io, 0,
-+					     -sizeof(struct ext2_image_hdr),
-+					     fs->image_header);
-+		if (retval)
-+			goto cleanup;
-+		if (fs->image_header->magic_number != EXT2_ET_MAGIC_E2IMAGE)
-+			return EXT2_ET_MAGIC_E2IMAGE;
-+		superblock = 1;
-+		block_size = fs->image_header->fs_blocksize;
-+	}
-+
-+	/*
-+	 * If the user specifies a specific block # for the
-+	 * superblock, then he/she must also specify the block size!
-+	 * Otherwise, read the master superblock located at offset
-+	 * SUPERBLOCK_OFFSET from the start of the partition.
-+	 *
-+	 * Note: we only save a backup copy of the superblock if we
-+	 * are reading the superblock from the primary superblock location.
-+	 */
-+	if (superblock) {
-+		if (!block_size) {
-+			retval = EXT2_ET_INVALID_ARGUMENT;
-+			goto cleanup;
-+		}
-+		io_channel_set_blksize(fs->io, block_size);
-+		group_block = superblock;
-+		fs->orig_super = 0;
-+	} else {
-+		io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET);
-+		superblock = 1;
-+		group_block = 0;
-+		retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->orig_super);
-+		if (retval)
-+			goto cleanup;
-+	}
-+	retval = io_channel_read_blk(fs->io, superblock, -SUPERBLOCK_SIZE,
-+				     fs->super);
-+	if (retval)
-+		goto cleanup;
-+	if (fs->orig_super)
-+		memcpy(fs->orig_super, fs->super, SUPERBLOCK_SIZE);
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+	if ((fs->super->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) ||
-+	    (fs->flags & EXT2_FLAG_SWAP_BYTES)) {
-+		fs->flags |= EXT2_FLAG_SWAP_BYTES;
-+
-+		ext2fs_swap_super(fs->super);
-+	}
-+#endif
-+	
-+	if (fs->super->s_magic != EXT2_SUPER_MAGIC) {
-+		retval = EXT2_ET_BAD_MAGIC;
-+		goto cleanup;
-+	}
-+	if (fs->super->s_rev_level > EXT2_LIB_CURRENT_REV) {
-+		retval = EXT2_ET_REV_TOO_HIGH;
-+		goto cleanup;
-+	}
-+
-+	/*
-+	 * Check for feature set incompatibility
-+	 */
-+	if (!(flags & EXT2_FLAG_FORCE)) {
-+		if (fs->super->s_feature_incompat &
-+		    ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
-+			retval = EXT2_ET_UNSUPP_FEATURE;
-+			goto cleanup;
-+		}
-+		if ((flags & EXT2_FLAG_RW) &&
-+		    (fs->super->s_feature_ro_compat &
-+		     ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)) {
-+			retval = EXT2_ET_RO_UNSUPP_FEATURE;
-+			goto cleanup;
-+		}
-+		if (!(flags & EXT2_FLAG_JOURNAL_DEV_OK) &&
-+		    (fs->super->s_feature_incompat &
-+		     EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
-+			retval = EXT2_ET_UNSUPP_FEATURE;
-+			goto cleanup;
-+		}
-+	}
-+	
-+	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) +
-+				       EXT2_BLOCK_SIZE(fs->super) - 1) /
-+				      EXT2_BLOCK_SIZE(fs->super));
-+	if (block_size) {
-+		if (block_size != fs->blocksize) {
-+			retval = EXT2_ET_UNEXPECTED_BLOCK_SIZE;
-+			goto cleanup;
-+		}
-+	}
-+	/*
-+	 * Set the blocksize to the filesystem's blocksize.
-+	 */
-+	io_channel_set_blksize(fs->io, fs->blocksize);
-+
-+	/*
-+	 * If this is an external journal device, don't try to read
-+	 * the group descriptors, because they're not there.
-+	 */
-+	if (fs->super->s_feature_incompat &
-+	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
-+		fs->group_desc_count = 0;
-+		*ret_fs = fs;
-+		return 0;
-+	}
-+	
-+	/*
-+	 * Read group descriptors
-+	 */
-+	blocks_per_group = EXT2_BLOCKS_PER_GROUP(fs->super);
-+	if (blocks_per_group == 0 ||
-+	    blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super) ||
-+	    fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super)) {
-+		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
-+		goto cleanup;
-+	}
-+	fs->group_desc_count = (fs->super->s_blocks_count -
-+				fs->super->s_first_data_block +
-+				blocks_per_group - 1) / blocks_per_group;
-+	fs->desc_blocks = (fs->group_desc_count +
-+			   EXT2_DESC_PER_BLOCK(fs->super) - 1)
-+		/ EXT2_DESC_PER_BLOCK(fs->super);
-+	retval = ext2fs_get_mem(fs->desc_blocks * fs->blocksize,
-+				&fs->group_desc);
-+	if (retval)
-+		goto cleanup;
-+	if (!group_block)
-+		group_block = fs->super->s_first_data_block;
-+	dest = (char *) fs->group_desc;
-+	groups_per_block = fs->blocksize / sizeof(struct ext2_group_desc);
-+	for (i=0 ; i < fs->desc_blocks; i++) {
-+		blk = ext2fs_descriptor_block_loc(fs, group_block, i);
-+		retval = io_channel_read_blk(fs->io, blk, 1, dest);
-+		if (retval)
-+			goto cleanup;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+		if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-+			gdp = (struct ext2_group_desc *) dest;
-+			for (j=0; j < groups_per_block; j++)
-+				ext2fs_swap_group_desc(gdp++);
-+		}
-+#endif
-+		dest += fs->blocksize;
-+	}
-+
-+	*ret_fs = fs;
-+	return 0;
-+cleanup:
-+	ext2fs_free(fs);
-+	return retval;
-+}
-+
-+/*
-+ * Set/get the filesystem data I/O channel.
-+ * 
-+ * These functions are only valid if EXT2_FLAG_IMAGE_FILE is true.
-+ */
-+errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io)
-+{
-+	if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
-+		return EXT2_ET_NOT_IMAGE_FILE;
-+	if (old_io) {
-+		*old_io = (fs->image_io == fs->io) ? 0 : fs->io;
-+	}
-+	return 0;
-+}
-+
-+errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io)
-+{
-+	if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
-+		return EXT2_ET_NOT_IMAGE_FILE;
-+	fs->io = new_io ? new_io : fs->image_io;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io)
-+{
-+	if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
-+		return EXT2_ET_NOT_IMAGE_FILE;
-+	fs->io = fs->image_io = new_io;
-+	fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_RW | 
-+		EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
-+	fs->flags &= ~EXT2_FLAG_IMAGE_FILE;
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/read_bb.c silo-1.4.14/libext2fs/read_bb.c
---- silo-1.4.14.orig/libext2fs/read_bb.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/read_bb.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,97 @@
-+/*
-+ * read_bb --- read the bad blocks inode
-+ *
-+ * Copyright (C) 1994 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct read_bb_record {
-+	ext2_badblocks_list	bb_list;
-+	errcode_t	err;
-+};
-+
-+/*
-+ * Helper function for ext2fs_read_bb_inode()
-+ */
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int mark_bad_block(ext2_filsys fs, blk_t *block_nr,
-+			  e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), 
-+			  blk_t ref_block EXT2FS_ATTR((unused)),
-+			  int ref_offset EXT2FS_ATTR((unused)), 
-+			  void *priv_data)
-+{
-+	struct read_bb_record *rb = (struct read_bb_record *) priv_data;
-+	
-+	if (blockcnt < 0)
-+		return 0;
-+	
-+	if ((*block_nr < fs->super->s_first_data_block) ||
-+	    (*block_nr >= fs->super->s_blocks_count))
-+		return 0;	/* Ignore illegal blocks */
-+
-+	rb->err = ext2fs_badblocks_list_add(rb->bb_list, *block_nr);
-+	if (rb->err)
-+		return BLOCK_ABORT;
-+	return 0;
-+}
-+
-+/*
-+ * Reads the current bad blocks from the bad blocks inode.
-+ */
-+errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
-+{
-+	errcode_t	retval;
-+	struct read_bb_record rb;
-+	struct ext2_inode inode;
-+	blk_t	numblocks;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (!*bb_list) {
-+		retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
-+		if (retval)
-+			return retval;
-+		if (inode.i_blocks < 500)
-+			numblocks = (inode.i_blocks /
-+				     (fs->blocksize / 512)) + 20;
-+		else
-+			numblocks = 500;
-+		retval = ext2fs_badblocks_list_create(bb_list, numblocks);
-+		if (retval)
-+			return retval;
-+	}
-+
-+	rb.bb_list = *bb_list;
-+	rb.err = 0;
-+	retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, 0, 0,
-+				      mark_bad_block, &rb);
-+	if (retval)
-+		return retval;
-+
-+	return rb.err;
-+}
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/read_bb_file.c silo-1.4.14/libext2fs/read_bb_file.c
---- silo-1.4.14.orig/libext2fs/read_bb_file.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/read_bb_file.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,97 @@
-+/*
-+ * read_bb_file.c --- read a list of bad blocks from a FILE *
-+ *
-+ * Copyright (C) 1994, 1995, 2000 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * Reads a list of bad blocks from  a FILE *
-+ */
-+errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f, 
-+			       ext2_badblocks_list *bb_list,
-+			       void *priv_data,
-+			       void (*invalid)(ext2_filsys fs,
-+					       blk_t blk,
-+					       char *badstr,
-+					       void *priv_data))
-+{
-+	errcode_t	retval;
-+	blk_t		blockno;
-+	int		count;
-+	char		buf[128];
-+
-+	if (fs)
-+		EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (!*bb_list) {
-+		retval = ext2fs_badblocks_list_create(bb_list, 10);
-+		if (retval)
-+			return retval;
-+	}
-+
-+	while (!feof (f)) {
-+		if (fgets(buf, sizeof(buf), f) == NULL)
-+			break;
-+		count = sscanf(buf, "%u", &blockno);
-+		if (count <= 0)
-+			continue;
-+		if (fs &&
-+		    ((blockno < fs->super->s_first_data_block) ||
-+		    (blockno >= fs->super->s_blocks_count))) {
-+			if (invalid)
-+				(invalid)(fs, blockno, buf, priv_data);
-+			continue;
-+		}
-+		retval = ext2fs_badblocks_list_add(*bb_list, blockno);
-+		if (retval)
-+			return retval;
-+	}
-+	return 0;
-+}
-+
-+static void call_compat_invalid(ext2_filsys fs, blk_t blk,
-+				char *badstr EXT2FS_ATTR((unused)), 
-+				void *priv_data)
-+{
-+	void (*invalid)(ext2_filsys, blk_t);
-+
-+	invalid = (void (*)(ext2_filsys, blk_t)) priv_data;
-+	if (invalid)
-+		invalid(fs, blk);
-+}
-+
-+
-+/*
-+ * Reads a list of bad blocks from  a FILE *
-+ */
-+errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f, 
-+			      ext2_badblocks_list *bb_list,
-+			      void (*invalid)(ext2_filsys fs, blk_t blk))
-+{
-+	return ext2fs_read_bb_FILE2(fs, f, bb_list, (void *) invalid,
-+				    call_compat_invalid);
-+}
-+
-+
-diff -Naur silo-1.4.14.orig/libext2fs/res_gdt.c silo-1.4.14/libext2fs/res_gdt.c
---- silo-1.4.14.orig/libext2fs/res_gdt.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/res_gdt.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,220 @@
-+/*
-+ * res_gdt.c --- reserve blocks for growing the group descriptor table
-+ *               during online resizing.
-+ *
-+ * Copyright (C) 2002 Andreas Dilger
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <time.h>
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * Iterate through the groups which hold BACKUP superblock/GDT copies in an
-+ * ext3 filesystem.  The counters should be initialized to 1, 5, and 7 before
-+ * calling this for the first time.  In a sparse filesystem it will be the
-+ * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
-+ * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
-+ */
-+static unsigned int list_backups(ext2_filsys fs, unsigned int *three,
-+				 unsigned int *five, unsigned int *seven)
-+{
-+	unsigned int *min = three;
-+	int mult = 3;
-+	unsigned int ret;
-+
-+	if (!(fs->super->s_feature_ro_compat &
-+	      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
-+		ret = *min;
-+		*min += 1;
-+		return ret;
-+	}
-+
-+	if (*five < *min) {
-+		min = five;
-+		mult = 5;
-+	}
-+	if (*seven < *min) {
-+		min = seven;
-+		mult = 7;
-+	}
-+
-+	ret = *min;
-+	*min *= mult;
-+
-+	return ret;
-+}
-+
-+/*
-+ * This code assumes that the reserved blocks have already been marked in-use
-+ * during ext2fs_initialize(), so that they are not allocated for other
-+ * uses before we can add them to the resize inode (which has to come
-+ * after the creation of the inode table).
-+ */
-+errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
-+{
-+	errcode_t		retval, retval2;
-+	struct ext2_super_block	*sb;
-+	struct ext2_inode	inode;
-+	__u32			*dindir_buf, *gdt_buf;
-+	int			rsv_add;
-+	unsigned long long	apb, inode_size;
-+	blk_t			dindir_blk, rsv_off, gdt_off, gdt_blk;
-+	int			dindir_dirty = 0, inode_dirty = 0;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	sb = fs->super;
-+
-+	retval = ext2fs_get_mem(2 * fs->blocksize, (void **)&dindir_buf);
-+	if (retval)
-+		goto out_free;
-+	gdt_buf = (__u32 *)((char *)dindir_buf + fs->blocksize);
-+
-+	retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
-+	if (retval)
-+		goto out_free;
-+
-+	/* Maximum possible file size (we donly use the dindirect blocks) */
-+	apb = EXT2_ADDR_PER_BLOCK(sb);
-+	rsv_add = fs->blocksize / 512;
-+	if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) {
-+#ifdef RES_GDT_DEBUG
-+		printf("reading GDT dindir %u\n", dindir_blk);
-+#endif
-+		retval = ext2fs_read_ind_block(fs, dindir_blk, dindir_buf);
-+		if (retval)
-+			goto out_inode;
-+	} else {
-+		blk_t goal = 3 + sb->s_reserved_gdt_blocks +
-+			fs->desc_blocks + fs->inode_blocks_per_group;
-+
-+		retval = ext2fs_alloc_block(fs, goal, 0, &dindir_blk);
-+		if (retval)
-+			goto out_free;
-+		inode.i_mode = LINUX_S_IFREG | 0600;
-+		inode.i_links_count = 1;
-+		inode.i_block[EXT2_DIND_BLOCK] = dindir_blk;
-+		inode.i_blocks = rsv_add;
-+		memset(dindir_buf, 0, fs->blocksize);
-+#ifdef RES_GDT_DEBUG
-+		printf("allocated GDT dindir %u\n", dindir_blk);
-+#endif
-+		dindir_dirty = inode_dirty = 1;
-+		inode_size = apb*apb + apb + EXT2_NDIR_BLOCKS;
-+		inode_size *= fs->blocksize;
-+		inode.i_size = inode_size & 0xFFFFFFFF;
-+		inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
-+		if(inode.i_size_high) {
-+			sb->s_feature_ro_compat |=
-+				EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
-+		}
-+		inode.i_ctime = time(0);
-+	}
-+
-+	for (rsv_off = 0, gdt_off = fs->desc_blocks,
-+	     gdt_blk = sb->s_first_data_block + 1 + fs->desc_blocks;
-+	     rsv_off < sb->s_reserved_gdt_blocks;
-+	     rsv_off++, gdt_off++, gdt_blk++) {
-+		unsigned int three = 1, five = 5, seven = 7;
-+		unsigned int grp, last = 0;
-+		int gdt_dirty = 0;
-+
-+		gdt_off %= apb;
-+		if (!dindir_buf[gdt_off]) {
-+			/* FIXME XXX XXX
-+			blk_t new_blk;
-+
-+			retval = ext2fs_new_block(fs, gdt_blk, 0, &new_blk);
-+			if (retval)
-+				goto out_free;
-+			if (new_blk != gdt_blk) {
-+				// XXX free block
-+				retval = -1; // XXX
-+			}
-+			*/
-+			gdt_dirty = dindir_dirty = inode_dirty = 1;
-+			memset(gdt_buf, 0, fs->blocksize);
-+			dindir_buf[gdt_off] = gdt_blk;
-+			inode.i_blocks += rsv_add;
-+#ifdef RES_GDT_DEBUG
-+			printf("added primary GDT block %u at %u[%u]\n",
-+			       gdt_blk, dindir_blk, gdt_off);
-+#endif
-+		} else if (dindir_buf[gdt_off] == gdt_blk) {
-+#ifdef RES_GDT_DEBUG
-+			printf("reading primary GDT block %u\n", gdt_blk);
-+#endif
-+			retval = ext2fs_read_ind_block(fs, gdt_blk, gdt_buf);
-+			if (retval)
-+				goto out_dindir;
-+		} else {
-+#ifdef RES_GDT_DEBUG
-+			printf("bad primary GDT %u != %u at %u[%u]\n",
-+			       dindir_buf[gdt_off], gdt_blk,dindir_blk,gdt_off);
-+#endif
-+			retval = EXT2_ET_RESIZE_INODE_CORRUPT;
-+			goto out_dindir;
-+		}
-+
-+		while ((grp = list_backups(fs, &three, &five, &seven)) <
-+		       fs->group_desc_count) {
-+			blk_t expect = gdt_blk + grp * sb->s_blocks_per_group;
-+
-+			if (!gdt_buf[last]) {
-+#ifdef RES_GDT_DEBUG
-+				printf("added backup GDT %u grp %u@%u[%u]\n",
-+				       expect, grp, gdt_blk, last);
-+#endif
-+				gdt_buf[last] = expect;
-+				inode.i_blocks += rsv_add;
-+				gdt_dirty = inode_dirty = 1;
-+			} else if (gdt_buf[last] != expect) {
-+#ifdef RES_GDT_DEBUG
-+				printf("bad backup GDT %u != %u at %u[%u]\n",
-+				       gdt_buf[last], expect, gdt_blk, last);
-+#endif
-+				retval = EXT2_ET_RESIZE_INODE_CORRUPT;
-+				goto out_dindir;
-+			}
-+			last++;
-+		}
-+		if (gdt_dirty) {
-+#ifdef RES_GDT_DEBUG
-+			printf("writing primary GDT block %u\n", gdt_blk);
-+#endif
-+			retval = ext2fs_write_ind_block(fs, gdt_blk, gdt_buf);
-+			if (retval)
-+				goto out_dindir;
-+		}
-+	}
-+
-+out_dindir:
-+	if (dindir_dirty) {
-+		retval2 = ext2fs_write_ind_block(fs, dindir_blk, dindir_buf);
-+		if (!retval)
-+			retval = retval2;
-+	}
-+out_inode:
-+#ifdef RES_GDT_DEBUG
-+	printf("inode.i_blocks = %u, i_size = %u\n", inode.i_blocks,
-+	       inode.i_size);
-+#endif
-+	if (inode_dirty) {
-+		inode.i_atime = inode.i_mtime = time(0);
-+		retval2 = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
-+		if (!retval)
-+			retval = retval2;
-+	}
-+out_free:
-+	ext2fs_free_mem((void **)&dindir_buf);
-+	return retval;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/rs_bitmap.c silo-1.4.14/libext2fs/rs_bitmap.c
---- silo-1.4.14.orig/libext2fs/rs_bitmap.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/rs_bitmap.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,106 @@
-+/*
-+ * rs_bitmap.c --- routine for changing the size of a bitmap
-+ *
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_resize_generic_bitmap(__u32 new_end, __u32 new_real_end,
-+				       ext2fs_generic_bitmap bmap)
-+{
-+	errcode_t	retval;
-+	size_t		size, new_size;
-+	__u32		bitno;
-+
-+	if (!bmap)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_GENERIC_BITMAP);
-+
-+	/*
-+	 * If we're expanding the bitmap, make sure all of the new
-+	 * parts of the bitmap are zero.
-+	 */
-+	if (new_end > bmap->end) {
-+		bitno = bmap->real_end;
-+		if (bitno > new_end)
-+			bitno = new_end;
-+		for (; bitno > bmap->end; bitno--)
-+			ext2fs_clear_bit(bitno - bmap->start, bmap->bitmap);
-+	}
-+	if (new_real_end == bmap->real_end) {
-+		bmap->end = new_end;
-+		return 0;
-+	}
-+	
-+	size = ((bmap->real_end - bmap->start) / 8) + 1;
-+	new_size = ((new_real_end - bmap->start) / 8) + 1;
-+
-+	if (size != new_size) {
-+		retval = ext2fs_resize_mem(size, new_size, &bmap->bitmap);
-+		if (retval)
-+			return retval;
-+	}
-+	if (new_size > size)
-+		memset(bmap->bitmap + size, 0, new_size - size);
-+
-+	bmap->end = new_end;
-+	bmap->real_end = new_real_end;
-+	return 0;
-+}
-+
-+errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
-+				     ext2fs_inode_bitmap bmap)
-+{
-+	errcode_t	retval;
-+	
-+	if (!bmap)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_INODE_BITMAP);
-+
-+	bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
-+	retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
-+					      bmap);
-+	bmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
-+	return retval;
-+}
-+
-+errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
-+				     ext2fs_block_bitmap bmap)
-+{
-+	errcode_t	retval;
-+	
-+	if (!bmap)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
-+
-+	bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
-+	retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
-+					      bmap);
-+	bmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
-+	return retval;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/rw_bitmaps.c silo-1.4.14/libext2fs/rw_bitmaps.c
---- silo-1.4.14.orig/libext2fs/rw_bitmaps.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/rw_bitmaps.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,300 @@
-+/*
-+ * rw_bitmaps.c --- routines to read and write the  inode and block bitmaps.
-+ *
-+ * Copyright (C) 1993, 1994, 1994, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+#include "e2image.h"
-+
-+#if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
-+/*
-+ * On the PowerPC, the big-endian variant of the ext2 filesystem
-+ * has its bitmaps stored as 32-bit words with bit 0 as the LSB
-+ * of each word.  Thus a bitmap with only bit 0 set would be, as
-+ * a string of bytes, 00 00 00 01 00 ...
-+ * To cope with this, we byte-reverse each word of a bitmap if
-+ * we have a big-endian filesystem, that is, if we are *not*
-+ * byte-swapping other word-sized numbers.
-+ */
-+#define EXT2_BIG_ENDIAN_BITMAPS
-+#endif
-+
-+#ifdef EXT2_BIG_ENDIAN_BITMAPS
-+static void ext2fs_swap_bitmap(ext2_filsys fs, char *bitmap, int nbytes)
-+{
-+	__u32 *p = (__u32 *) bitmap;
-+	int n;
-+		
-+	for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
-+		*p = ext2fs_swab32(*p);
-+}
-+#endif
-+
-+errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs)
-+{
-+	dgrp_t 		i;
-+	size_t		nbytes;
-+	errcode_t	retval;
-+	char * inode_bitmap = fs->inode_map->bitmap;
-+	char * bitmap_block = NULL;
-+	blk_t		blk;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (!(fs->flags & EXT2_FLAG_RW))
-+		return EXT2_ET_RO_FILSYS;
-+	if (!inode_bitmap)
-+		return 0;
-+	nbytes = (size_t) ((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
-+	
-+	retval = ext2fs_get_mem(fs->blocksize, &bitmap_block);
-+	if (retval)
-+		return retval;
-+	memset(bitmap_block, 0xff, fs->blocksize);
-+	for (i = 0; i < fs->group_desc_count; i++) {
-+		memcpy(bitmap_block, inode_bitmap, nbytes);
-+		blk = fs->group_desc[i].bg_inode_bitmap;
-+		if (blk) {
-+#ifdef EXT2_BIG_ENDIAN_BITMAPS
-+			if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+			      (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
-+				ext2fs_swap_bitmap(fs, bitmap_block, nbytes);
-+#endif
-+			retval = io_channel_write_blk(fs->io, blk, 1,
-+						      bitmap_block);
-+			if (retval)
-+				return EXT2_ET_INODE_BITMAP_WRITE;
-+		}
-+		inode_bitmap += nbytes;
-+	}
-+	fs->flags &= ~EXT2_FLAG_IB_DIRTY;
-+	ext2fs_free_mem(&bitmap_block);
-+	return 0;
-+}
-+
-+errcode_t ext2fs_write_block_bitmap (ext2_filsys fs)
-+{
-+	dgrp_t 		i;
-+	unsigned int	j;
-+	int		nbytes;
-+	unsigned int	nbits;
-+	errcode_t	retval;
-+	char * block_bitmap = fs->block_map->bitmap;
-+	char * bitmap_block = NULL;
-+	blk_t		blk;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (!(fs->flags & EXT2_FLAG_RW))
-+		return EXT2_ET_RO_FILSYS;
-+	if (!block_bitmap)
-+		return 0;
-+	nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-+	retval = ext2fs_get_mem(fs->blocksize, &bitmap_block);
-+	if (retval)
-+		return retval;
-+	memset(bitmap_block, 0xff, fs->blocksize);
-+	for (i = 0; i < fs->group_desc_count; i++) {
-+		memcpy(bitmap_block, block_bitmap, nbytes);
-+		if (i == fs->group_desc_count - 1) {
-+			/* Force bitmap padding for the last group */
-+			nbits = ((fs->super->s_blocks_count
-+				  - fs->super->s_first_data_block)
-+				 % EXT2_BLOCKS_PER_GROUP(fs->super));
-+			if (nbits)
-+				for (j = nbits; j < fs->blocksize * 8; j++)
-+					ext2fs_set_bit(j, bitmap_block);
-+		}
-+		blk = fs->group_desc[i].bg_block_bitmap;
-+		if (blk) {
-+#ifdef EXT2_BIG_ENDIAN_BITMAPS
-+			if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+			      (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
-+				ext2fs_swap_bitmap(fs, bitmap_block, nbytes);
-+#endif
-+			retval = io_channel_write_blk(fs->io, blk, 1,
-+						      bitmap_block);
-+			if (retval)
-+				return EXT2_ET_BLOCK_BITMAP_WRITE;
-+		}
-+		block_bitmap += nbytes;
-+	}
-+	fs->flags &= ~EXT2_FLAG_BB_DIRTY;
-+	ext2fs_free_mem(&bitmap_block);
-+	return 0;
-+}
-+
-+static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
-+{
-+	dgrp_t i;
-+	char *block_bitmap = 0, *inode_bitmap = 0;
-+	char *buf;
-+	errcode_t retval;
-+	int block_nbytes = (int) EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-+	int inode_nbytes = (int) EXT2_INODES_PER_GROUP(fs->super) / 8;
-+	blk_t	blk;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	fs->write_bitmaps = ext2fs_write_bitmaps;
-+
-+	retval = ext2fs_get_mem(strlen(fs->device_name) + 80, &buf);
-+	if (retval)
-+		return retval;
-+	if (do_block) {
-+		if (fs->block_map)
-+			ext2fs_free_block_bitmap(fs->block_map);
-+		sprintf(buf, "block bitmap for %s", fs->device_name);
-+		retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map);
-+		if (retval)
-+			goto cleanup;
-+		block_bitmap = fs->block_map->bitmap;
-+	}
-+	if (do_inode) {
-+		if (fs->inode_map)
-+			ext2fs_free_inode_bitmap(fs->inode_map);
-+		sprintf(buf, "inode bitmap for %s", fs->device_name);
-+		retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
-+		if (retval)
-+			goto cleanup;
-+		inode_bitmap = fs->inode_map->bitmap;
-+	}
-+	ext2fs_free_mem(&buf);
-+
-+	if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
-+		if (inode_bitmap) {
-+			blk = (fs->image_header->offset_inodemap /
-+			       fs->blocksize);
-+			retval = io_channel_read_blk(fs->image_io, blk,
-+			     -(inode_nbytes * fs->group_desc_count),
-+			     inode_bitmap);
-+			if (retval)
-+				goto cleanup;
-+		}
-+		if (block_bitmap) {
-+			blk = (fs->image_header->offset_blockmap /
-+			       fs->blocksize);
-+			retval = io_channel_read_blk(fs->image_io, blk, 
-+			     -(block_nbytes * fs->group_desc_count),
-+			     block_bitmap);
-+			if (retval)
-+				goto cleanup;
-+		}
-+		return 0;
-+	}
-+
-+	for (i = 0; i < fs->group_desc_count; i++) {
-+		if (block_bitmap) {
-+			blk = fs->group_desc[i].bg_block_bitmap;
-+			if (blk) {
-+				retval = io_channel_read_blk(fs->io, blk,
-+					     -block_nbytes, block_bitmap);
-+				if (retval) {
-+					retval = EXT2_ET_BLOCK_BITMAP_READ;
-+					goto cleanup;
-+				}
-+#ifdef EXT2_BIG_ENDIAN_BITMAPS
-+				if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+				      (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
-+					ext2fs_swap_bitmap(fs, block_bitmap, block_nbytes);
-+#endif
-+			} else
-+				memset(block_bitmap, 0, block_nbytes);
-+			block_bitmap += block_nbytes;
-+		}
-+		if (inode_bitmap) {
-+			blk = fs->group_desc[i].bg_inode_bitmap;
-+			if (blk) {
-+				retval = io_channel_read_blk(fs->io, blk,
-+					     -inode_nbytes, inode_bitmap);
-+				if (retval) {
-+					retval = EXT2_ET_INODE_BITMAP_READ;
-+					goto cleanup;
-+				}
-+#ifdef EXT2_BIG_ENDIAN_BITMAPS
-+				if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+				      (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
-+					ext2fs_swap_bitmap(fs, inode_bitmap, inode_nbytes);
-+#endif
-+			} else
-+				memset(inode_bitmap, 0, inode_nbytes);
-+			inode_bitmap += inode_nbytes;
-+		}
-+	}
-+	return 0;
-+	
-+cleanup:
-+	if (do_block) {
-+		ext2fs_free_mem(&fs->block_map);
-+		fs->block_map = 0;
-+	}
-+	if (do_inode) {
-+		ext2fs_free_mem(&fs->inode_map);
-+		fs->inode_map = 0;
-+	}
-+	if (buf)
-+		ext2fs_free_mem(&buf);
-+	return retval;
-+}
-+
-+errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs)
-+{
-+	return read_bitmaps(fs, 1, 0);
-+}
-+
-+errcode_t ext2fs_read_block_bitmap(ext2_filsys fs)
-+{
-+	return read_bitmaps(fs, 0, 1);
-+}
-+
-+errcode_t ext2fs_read_bitmaps(ext2_filsys fs)
-+{
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (fs->inode_map && fs->block_map)
-+		return 0;
-+
-+	return read_bitmaps(fs, !fs->inode_map, !fs->block_map);
-+}
-+
-+errcode_t ext2fs_write_bitmaps(ext2_filsys fs)
-+{
-+	errcode_t	retval;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (fs->block_map && ext2fs_test_bb_dirty(fs)) {
-+		retval = ext2fs_write_block_bitmap(fs);
-+		if (retval)
-+			return retval;
-+	}
-+	if (fs->inode_map && ext2fs_test_ib_dirty(fs)) {
-+		retval = ext2fs_write_inode_bitmap(fs);
-+		if (retval)
-+			return retval;
-+	}
-+	return 0;
-+}	
-+
-diff -Naur silo-1.4.14.orig/libext2fs/sparse.c silo-1.4.14/libext2fs/sparse.c
---- silo-1.4.14.orig/libext2fs/sparse.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/sparse.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,78 @@
-+/*
-+ * sparse.c --- find the groups in an ext2 filesystem with metadata backups
-+ *
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ * Copyright (C) 2002 Andreas Dilger.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+static int test_root(int a, int b)
-+{
-+	if (a == 0)
-+		return 1;
-+	while (1) {
-+		if (a == 1)
-+			return 1;
-+		if (a % b)
-+			return 0;
-+		a = a / b;
-+	}
-+}
-+
-+int ext2fs_bg_has_super(ext2_filsys fs, int group_block)
-+{
-+	if (!(fs->super->s_feature_ro_compat &
-+	      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
-+		return 1;
-+
-+	if (test_root(group_block, 3) || (test_root(group_block, 5)) ||
-+	    test_root(group_block, 7))
-+		return 1;
-+
-+	return 0;
-+}
-+
-+/*
-+ * Iterate through the groups which hold BACKUP superblock/GDT copies in an
-+ * ext3 filesystem.  The counters should be initialized to 1, 5, and 7 before
-+ * calling this for the first time.  In a sparse filesystem it will be the
-+ * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
-+ * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
-+ */
-+unsigned int ext2fs_list_backups(ext2_filsys fs, unsigned int *three,
-+				 unsigned int *five, unsigned int *seven)
-+{
-+	unsigned int *min = three;
-+	int mult = 3;
-+	unsigned int ret;
-+
-+	if (!(fs->super->s_feature_ro_compat &
-+	      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
-+		ret = *min;
-+		*min += 1;
-+		return ret;
-+	}
-+
-+	if (*five < *min) {
-+		min = five;
-+		mult = 5;
-+	}
-+	if (*seven < *min) {
-+		min = seven;
-+		mult = 7;
-+	}
-+
-+	ret = *min;
-+	*min *= mult;
-+
-+	return ret;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/swapfs.c silo-1.4.14/libext2fs/swapfs.c
---- silo-1.4.14.orig/libext2fs/swapfs.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/swapfs.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,237 @@
-+/*
-+ * swapfs.c --- swap ext2 filesystem data structures
-+ * 
-+ * Copyright (C) 1995, 1996, 2002 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+#include <ext2fs/ext2_ext_attr.h>
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+void ext2fs_swap_super(struct ext2_super_block * sb)
-+{
-+  	int i;
-+	sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count);
-+	sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count);
-+	sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count);
-+	sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count);
-+	sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count);
-+	sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block);
-+	sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size);
-+	sb->s_log_frag_size = ext2fs_swab32(sb->s_log_frag_size);
-+	sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group);
-+	sb->s_frags_per_group = ext2fs_swab32(sb->s_frags_per_group);
-+	sb->s_inodes_per_group = ext2fs_swab32(sb->s_inodes_per_group);
-+	sb->s_mtime = ext2fs_swab32(sb->s_mtime);
-+	sb->s_wtime = ext2fs_swab32(sb->s_wtime);
-+	sb->s_mnt_count = ext2fs_swab16(sb->s_mnt_count);
-+	sb->s_max_mnt_count = ext2fs_swab16(sb->s_max_mnt_count);
-+	sb->s_magic = ext2fs_swab16(sb->s_magic);
-+	sb->s_state = ext2fs_swab16(sb->s_state);
-+	sb->s_errors = ext2fs_swab16(sb->s_errors);
-+	sb->s_minor_rev_level = ext2fs_swab16(sb->s_minor_rev_level);
-+	sb->s_lastcheck = ext2fs_swab32(sb->s_lastcheck);
-+	sb->s_checkinterval = ext2fs_swab32(sb->s_checkinterval);
-+	sb->s_creator_os = ext2fs_swab32(sb->s_creator_os);
-+	sb->s_rev_level = ext2fs_swab32(sb->s_rev_level);
-+	sb->s_def_resuid = ext2fs_swab16(sb->s_def_resuid);
-+	sb->s_def_resgid = ext2fs_swab16(sb->s_def_resgid);
-+	sb->s_first_ino = ext2fs_swab32(sb->s_first_ino);
-+	sb->s_inode_size = ext2fs_swab16(sb->s_inode_size);
-+	sb->s_block_group_nr = ext2fs_swab16(sb->s_block_group_nr);
-+	sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat);
-+	sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat);
-+	sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat);
-+	sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap);
-+	sb->s_reserved_gdt_blocks = ext2fs_swab16(sb->s_reserved_gdt_blocks);
-+	sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
-+	sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
-+	sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
-+	sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts);
-+	sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
-+	sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time);
-+	for (i=0; i < 4; i++)
-+		sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
-+	for (i=0; i < 17; i++)
-+		sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
-+
-+}
-+
-+void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
-+{
-+	gdp->bg_block_bitmap = ext2fs_swab32(gdp->bg_block_bitmap);
-+	gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap);
-+	gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table);
-+	gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count);
-+	gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count);
-+	gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
-+}
-+
-+void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header)
-+{
-+	struct ext2_ext_attr_header *from_header =
-+		(struct ext2_ext_attr_header *)from;
-+	struct ext2_ext_attr_header *to_header =
-+		(struct ext2_ext_attr_header *)to;
-+	struct ext2_ext_attr_entry *from_entry, *to_entry;
-+	char *from_end = (char *)from_header + bufsize;
-+	int n;
-+
-+	if (to_header != from_header)
-+		memcpy(to_header, from_header, bufsize);
-+
-+	from_entry = (struct ext2_ext_attr_entry *)from_header;
-+	to_entry   = (struct ext2_ext_attr_entry *)to_header;
-+
-+	if (has_header) {
-+		to_header->h_magic    = ext2fs_swab32(from_header->h_magic);
-+		to_header->h_blocks   = ext2fs_swab32(from_header->h_blocks);
-+		to_header->h_refcount = ext2fs_swab32(from_header->h_refcount);
-+		for (n=0; n<4; n++)
-+			to_header->h_reserved[n] =
-+				ext2fs_swab32(from_header->h_reserved[n]);
-+		from_entry = (struct ext2_ext_attr_entry *)(from_header+1);
-+		to_entry   = (struct ext2_ext_attr_entry *)(to_header+1);
-+	}
-+
-+	while ((char *)from_entry < from_end && *(__u32 *)from_entry) {
-+		to_entry->e_value_offs  =	
-+			ext2fs_swab16(from_entry->e_value_offs);
-+		to_entry->e_value_block =	
-+			ext2fs_swab32(from_entry->e_value_block);
-+		to_entry->e_value_size  =	
-+			ext2fs_swab32(from_entry->e_value_size);
-+		from_entry = EXT2_EXT_ATTR_NEXT(from_entry);
-+		to_entry   = EXT2_EXT_ATTR_NEXT(to_entry);
-+	}
-+}
-+
-+void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
-+			    struct ext2_inode_large *f, int hostorder,
-+			    int bufsize)
-+{
-+	unsigned i;
-+	int islnk = 0;
-+	__u32 *eaf, *eat;
-+
-+	if (hostorder && LINUX_S_ISLNK(f->i_mode))
-+		islnk = 1;
-+	t->i_mode = ext2fs_swab16(f->i_mode);
-+	if (!hostorder && LINUX_S_ISLNK(t->i_mode))
-+		islnk = 1;
-+	t->i_uid = ext2fs_swab16(f->i_uid);
-+	t->i_size = ext2fs_swab32(f->i_size);
-+	t->i_atime = ext2fs_swab32(f->i_atime);
-+	t->i_ctime = ext2fs_swab32(f->i_ctime);
-+	t->i_mtime = ext2fs_swab32(f->i_mtime);
-+	t->i_dtime = ext2fs_swab32(f->i_dtime);
-+	t->i_gid = ext2fs_swab16(f->i_gid);
-+	t->i_links_count = ext2fs_swab16(f->i_links_count);
-+	t->i_blocks = ext2fs_swab32(f->i_blocks);
-+	t->i_flags = ext2fs_swab32(f->i_flags);
-+	t->i_file_acl = ext2fs_swab32(f->i_file_acl);
-+	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
-+	if (!islnk || ext2fs_inode_data_blocks(fs, (struct ext2_inode *)t)) {
-+		for (i = 0; i < EXT2_N_BLOCKS; i++)
-+			t->i_block[i] = ext2fs_swab32(f->i_block[i]);
-+	} else if (t != f) {
-+		for (i = 0; i < EXT2_N_BLOCKS; i++)
-+			t->i_block[i] = f->i_block[i];
-+	}
-+	t->i_generation = ext2fs_swab32(f->i_generation);
-+	t->i_faddr = ext2fs_swab32(f->i_faddr);
-+
-+	switch (fs->super->s_creator_os) {
-+	case EXT2_OS_LINUX:
-+		t->osd1.linux1.l_i_reserved1 =
-+			ext2fs_swab32(f->osd1.linux1.l_i_reserved1);
-+		t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
-+		t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
-+		t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
-+		t->osd2.linux2.l_i_uid_high =
-+		  ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
-+		t->osd2.linux2.l_i_gid_high =
-+		  ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
-+		t->osd2.linux2.l_i_reserved2 =
-+			ext2fs_swab32(f->osd2.linux2.l_i_reserved2);
-+		break;
-+	case EXT2_OS_HURD:
-+		t->osd1.hurd1.h_i_translator =
-+		  ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
-+		t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
-+		t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
-+		t->osd2.hurd2.h_i_mode_high =
-+		  ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
-+		t->osd2.hurd2.h_i_uid_high =
-+		  ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
-+		t->osd2.hurd2.h_i_gid_high =
-+		  ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
-+		t->osd2.hurd2.h_i_author =
-+		  ext2fs_swab32 (f->osd2.hurd2.h_i_author);
-+		break;
-+	case EXT2_OS_MASIX:
-+		t->osd1.masix1.m_i_reserved1 =
-+			ext2fs_swab32(f->osd1.masix1.m_i_reserved1);
-+		t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
-+		t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
-+		t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
-+		t->osd2.masix2.m_i_reserved2[0] =
-+			ext2fs_swab32(f->osd2.masix2.m_i_reserved2[0]);
-+		t->osd2.masix2.m_i_reserved2[1] =
-+			ext2fs_swab32(f->osd2.masix2.m_i_reserved2[1]);
-+		break;
-+	}
-+
-+	if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
-+		return; /* no i_extra_isize field */
-+
-+	t->i_extra_isize = ext2fs_swab16(f->i_extra_isize);
-+	if (t->i_extra_isize > EXT2_INODE_SIZE(fs->super) -
-+				sizeof(struct ext2_inode)) {
-+		/* this is error case: i_extra_size is too large */
-+		return;
-+	}
-+
-+	i = sizeof(struct ext2_inode) + t->i_extra_isize + sizeof(__u32);
-+	if (bufsize < (int) i)
-+		return; /* no space for EA magic */
-+
-+	eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) +
-+					f->i_extra_isize);
-+
-+	if (ext2fs_swab32(*eaf) != EXT2_EXT_ATTR_MAGIC)
-+		return; /* it seems no magic here */
-+
-+	eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) +
-+					f->i_extra_isize);
-+	*eat = ext2fs_swab32(*eaf);
-+
-+	/* convert EA(s) */
-+	ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
-+			     bufsize - sizeof(struct ext2_inode) -
-+			     t->i_extra_isize - sizeof(__u32), 0);
-+
-+}
-+
-+void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
-+		       struct ext2_inode *f, int hostorder)
-+{
-+	ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) t,
-+				(struct ext2_inode_large *) f, hostorder,
-+				sizeof(struct ext2_inode));
-+}
-+
-+#endif
-diff -Naur silo-1.4.14.orig/libext2fs/test_io.c silo-1.4.14/libext2fs/test_io.c
---- silo-1.4.14.orig/libext2fs/test_io.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/test_io.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,411 @@
-+/*
-+ * test_io.c --- This is the Test I/O interface.
-+ *
-+ * Copyright (C) 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#ifdef HAVE_SYS_PRCTL_H
-+#include <sys/prctl.h>
-+#else
-+#define PR_GET_DUMPABLE 3
-+#endif
-+#if (!defined(HAVE_PRCTL) && defined(linux))
-+#include <sys/syscall.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * For checking structure magic numbers...
-+ */
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+	  if ((struct)->magic != (code)) return (code)
-+  
-+struct test_private_data {
-+	int	magic;
-+	io_channel real;
-+	int flags;
-+	FILE *outfile;
-+	unsigned long block;
-+	int read_abort_count, write_abort_count;
-+	void (*read_blk)(unsigned long block, int count, errcode_t err);
-+	void (*write_blk)(unsigned long block, int count, errcode_t err);
-+	void (*set_blksize)(int blksize, errcode_t err);
-+	void (*write_byte)(unsigned long block, int count, errcode_t err);
-+};
-+
-+static errcode_t test_open(const char *name, int flags, io_channel *channel);
-+static errcode_t test_close(io_channel channel);
-+static errcode_t test_set_blksize(io_channel channel, int blksize);
-+static errcode_t test_read_blk(io_channel channel, unsigned long block,
-+			       int count, void *data);
-+static errcode_t test_write_blk(io_channel channel, unsigned long block,
-+				int count, const void *data);
-+static errcode_t test_flush(io_channel channel);
-+static errcode_t test_write_byte(io_channel channel, unsigned long offset,
-+				 int count, const void *buf);
-+static errcode_t test_set_option(io_channel channel, const char *option, 
-+				 const char *arg);
-+
-+static struct struct_io_manager struct_test_manager = {
-+	EXT2_ET_MAGIC_IO_MANAGER,
-+	"Test I/O Manager",
-+	test_open,
-+	test_close,
-+	test_set_blksize,
-+	test_read_blk,
-+	test_write_blk,
-+	test_flush,
-+	test_write_byte,
-+	test_set_option
-+};
-+
-+io_manager test_io_manager = &struct_test_manager;
-+
-+/*
-+ * These global variable can be set by the test program as
-+ * necessary *before* calling test_open
-+ */
-+io_manager test_io_backing_manager = 0;
-+void (*test_io_cb_read_blk)
-+	(unsigned long block, int count, errcode_t err) = 0;
-+void (*test_io_cb_write_blk)
-+	(unsigned long block, int count, errcode_t err) = 0;
-+void (*test_io_cb_set_blksize)
-+	(int blksize, errcode_t err) = 0;
-+void (*test_io_cb_write_byte)
-+	(unsigned long block, int count, errcode_t err) = 0;
-+
-+/*
-+ * Test flags
-+ */
-+#define TEST_FLAG_READ			0x01
-+#define TEST_FLAG_WRITE			0x02
-+#define TEST_FLAG_SET_BLKSIZE		0x04
-+#define TEST_FLAG_FLUSH			0x08
-+#define TEST_FLAG_DUMP			0x10
-+#define TEST_FLAG_SET_OPTION		0x20
-+
-+static void test_dump_block(io_channel channel,
-+			    struct test_private_data *data,
-+			    unsigned long block, const void *buf)
-+{
-+	const unsigned char *cp;
-+	FILE *f = data->outfile;
-+	int	i;
-+	unsigned long	cksum = 0;
-+
-+	for (i=0, cp = buf; i < channel->block_size; i++, cp++) {
-+		cksum += *cp;
-+	}
-+	fprintf(f, "Contents of block %lu, checksum %08lu: \n", block, cksum);
-+	for (i=0, cp = buf; i < channel->block_size; i++, cp++) {
-+		if ((i % 16) == 0)
-+			fprintf(f, "%04x: ", i);
-+		fprintf(f, "%02x%c", *cp, ((i % 16) == 15) ? '\n' : ' ');
-+	}
-+}
-+
-+static void test_abort(io_channel channel, unsigned long block)
-+{
-+	struct test_private_data *data;
-+	FILE *f;
-+
-+	data = (struct test_private_data *) channel->private_data;
-+	f = data->outfile;
-+	test_flush(channel);
-+
-+	fprintf(f, "Aborting due to I/O to block %lu\n", block);
-+	fflush(f);
-+	abort();
-+}
-+
-+static char *safe_getenv(const char *arg)
-+{
-+	if ((getuid() != geteuid()) || (getgid() != getegid()))
-+		return NULL;
-+#if HAVE_PRCTL
-+	if (prctl(PR_GET_DUMPABLE) == 0)
-+		return NULL;
-+#else
-+#if (defined(linux) && defined(SYS_prctl))
-+	if (syscall(SYS_prctl, PR_GET_DUMPABLE) == 0)
-+		return NULL;
-+#endif
-+#endif
-+
-+#ifdef HAVE___SECURE_GETENV
-+	return __secure_getenv(arg);
-+#else
-+	return getenv(arg);
-+#endif
-+}
-+
-+static errcode_t test_open(const char *name, int flags, io_channel *channel)
-+{
-+	io_channel	io = NULL;
-+	struct test_private_data *data = NULL;
-+	errcode_t	retval;
-+	char		*value;
-+
-+	if (name == 0)
-+		return EXT2_ET_BAD_DEVICE_NAME;
-+	retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
-+	if (retval)
-+		return retval;
-+	memset(io, 0, sizeof(struct struct_io_channel));
-+	io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
-+	retval = ext2fs_get_mem(sizeof(struct test_private_data), &data);
-+	if (retval) {
-+		retval = EXT2_ET_NO_MEMORY;
-+		goto cleanup;
-+	}
-+	io->manager = test_io_manager;
-+	retval = ext2fs_get_mem(strlen(name)+1, &io->name);
-+	if (retval)
-+		goto cleanup;
-+
-+	strcpy(io->name, name);
-+	io->private_data = data;
-+	io->block_size = 1024;
-+	io->read_error = 0;
-+	io->write_error = 0;
-+	io->refcount = 1;
-+
-+	memset(data, 0, sizeof(struct test_private_data));
-+	data->magic = EXT2_ET_MAGIC_TEST_IO_CHANNEL;
-+	if (test_io_backing_manager) {
-+		retval = test_io_backing_manager->open(name, flags,
-+						       &data->real);
-+		if (retval)
-+			goto cleanup;
-+	} else
-+		data->real = 0;
-+	data->read_blk = 	test_io_cb_read_blk;
-+	data->write_blk = 	test_io_cb_write_blk;
-+	data->set_blksize = 	test_io_cb_set_blksize;
-+	data->write_byte = 	test_io_cb_write_byte;
-+
-+	data->outfile = NULL;
-+	if ((value = safe_getenv("TEST_IO_LOGFILE")) != NULL)
-+		data->outfile = fopen(value, "w");
-+	if (!data->outfile)
-+		data->outfile = stderr;
-+
-+	data->flags = 0;
-+	if ((value = safe_getenv("TEST_IO_FLAGS")) != NULL)
-+		data->flags = strtoul(value, NULL, 0);
-+	
-+	data->block = 0;
-+	if ((value = safe_getenv("TEST_IO_BLOCK")) != NULL)
-+		data->block = strtoul(value, NULL, 0);
-+
-+	data->read_abort_count = 0;
-+	if ((value = safe_getenv("TEST_IO_READ_ABORT")) != NULL)
-+		data->read_abort_count = strtoul(value, NULL, 0);
-+
-+	data->write_abort_count = 0;
-+	if ((value = safe_getenv("TEST_IO_WRITE_ABORT")) != NULL)
-+		data->write_abort_count = strtoul(value, NULL, 0);
-+	
-+	*channel = io;
-+	return 0;
-+
-+cleanup:
-+	if (io)
-+		ext2fs_free_mem(&io);
-+	if (data)
-+		ext2fs_free_mem(&data);
-+	return retval;
-+}
-+
-+static errcode_t test_close(io_channel channel)
-+{
-+	struct test_private_data *data;
-+	errcode_t	retval = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct test_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+	if (--channel->refcount > 0)
-+		return 0;
-+	
-+	if (data->real)
-+		retval = io_channel_close(data->real);
-+
-+	if (data->outfile && data->outfile != stderr)
-+		fclose(data->outfile);
-+	
-+	ext2fs_free_mem(&channel->private_data);
-+	if (channel->name)
-+		ext2fs_free_mem(&channel->name);
-+	ext2fs_free_mem(&channel);
-+	return retval;
-+}
-+
-+static errcode_t test_set_blksize(io_channel channel, int blksize)
-+{
-+	struct test_private_data *data;
-+	errcode_t	retval = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct test_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+	if (data->real)
-+		retval = io_channel_set_blksize(data->real, blksize);
-+	if (data->set_blksize)
-+		data->set_blksize(blksize, retval);
-+	if (data->flags & TEST_FLAG_SET_BLKSIZE)
-+		fprintf(data->outfile,
-+			"Test_io: set_blksize(%d) returned %s\n",
-+			blksize, retval ? error_message(retval) : "OK");
-+	channel->block_size = blksize;
-+	return retval;
-+}
-+
-+
-+static errcode_t test_read_blk(io_channel channel, unsigned long block,
-+			       int count, void *buf)
-+{
-+	struct test_private_data *data;
-+	errcode_t	retval = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct test_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+	if (data->real)
-+		retval = io_channel_read_blk(data->real, block, count, buf);
-+	if (data->read_blk)
-+		data->read_blk(block, count, retval);
-+	if (data->flags & TEST_FLAG_READ)
-+		fprintf(data->outfile,
-+			"Test_io: read_blk(%lu, %d) returned %s\n",
-+			block, count, retval ? error_message(retval) : "OK");
-+	if (data->block && data->block == block) {
-+		if (data->flags & TEST_FLAG_DUMP)
-+			test_dump_block(channel, data, block, buf);
-+		if (--data->read_abort_count == 0)
-+			test_abort(channel, block);
-+	} 
-+	return retval;
-+}
-+
-+static errcode_t test_write_blk(io_channel channel, unsigned long block,
-+			       int count, const void *buf)
-+{
-+	struct test_private_data *data;
-+	errcode_t	retval = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct test_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+	if (data->real)
-+		retval = io_channel_write_blk(data->real, block, count, buf);
-+	if (data->write_blk)
-+		data->write_blk(block, count, retval);
-+	if (data->flags & TEST_FLAG_WRITE)
-+		fprintf(data->outfile,
-+			"Test_io: write_blk(%lu, %d) returned %s\n",
-+			block, count, retval ? error_message(retval) : "OK");
-+	if (data->block && data->block == block) {
-+		if (data->flags & TEST_FLAG_DUMP)
-+			test_dump_block(channel, data, block, buf);
-+		if (--data->write_abort_count == 0)
-+			test_abort(channel, block);
-+	}
-+	return retval;
-+}
-+
-+static errcode_t test_write_byte(io_channel channel, unsigned long offset,
-+			       int count, const void *buf)
-+{
-+	struct test_private_data *data;
-+	errcode_t	retval = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct test_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+	if (data->real && data->real->manager->write_byte)
-+		retval = io_channel_write_byte(data->real, offset, count, buf);
-+	if (data->write_byte)
-+		data->write_byte(offset, count, retval);
-+	if (data->flags & TEST_FLAG_WRITE)
-+		fprintf(data->outfile,
-+			"Test_io: write_byte(%lu, %d) returned %s\n",
-+			offset, count, retval ? error_message(retval) : "OK");
-+	return retval;
-+}
-+
-+/*
-+ * Flush data buffers to disk.
-+ */
-+static errcode_t test_flush(io_channel channel)
-+{
-+	struct test_private_data *data;
-+	errcode_t	retval = 0;
-+	
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct test_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+	if (data->real)
-+		retval = io_channel_flush(data->real);
-+	
-+	if (data->flags & TEST_FLAG_FLUSH)
-+		fprintf(data->outfile, "Test_io: flush() returned %s\n",
-+			retval ? error_message(retval) : "OK");
-+	
-+	return retval;
-+}
-+
-+static errcode_t test_set_option(io_channel channel, const char *option, 
-+				 const char *arg)
-+{
-+	struct test_private_data *data;
-+	errcode_t	retval = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct test_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+
-+	if (data->flags & TEST_FLAG_SET_OPTION)
-+		fprintf(data->outfile, "Test_io: set_option(%s, %s) ", 
-+			option, arg);
-+	if (data->real && data->real->manager->set_option) {
-+		retval = (data->real->manager->set_option)(data->real, 
-+							   option, arg);
-+		if (data->flags & TEST_FLAG_SET_OPTION)
-+			fprintf(data->outfile, "returned %s\n",
-+				retval ? error_message(retval) : "OK");
-+	} else {
-+		if (data->flags & TEST_FLAG_SET_OPTION)
-+			fprintf(data->outfile, "not implemented\n");
-+	}
-+	return retval;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/tst_badblocks.c silo-1.4.14/libext2fs/tst_badblocks.c
---- silo-1.4.14.orig/libext2fs/tst_badblocks.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/tst_badblocks.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,293 @@
-+/*
-+ * This testing program makes sure the badblocks implementation works.
-+ *
-+ * Copyright (C) 1996 by Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#define ADD_BLK	0x0001
-+#define DEL_BLK	0x0002
-+
-+blk_t test1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0 };
-+blk_t test2[] = { 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 1 };
-+blk_t test3[] = { 3, 1, 4, 5, 9, 2, 7, 10, 5, 6, 10, 8, 0 };
-+blk_t test4[] = { 20, 50, 12, 17, 13, 2, 66, 23, 56, 0 };
-+blk_t test4a[] = {
-+ 	20, 1,
-+	50, 1,
-+	3, 0,
-+	17, 1,
-+	18, 0,
-+	16, 0,
-+	11, 0,
-+	12, 1,
-+	13, 1,
-+	14, 0, 
-+	80, 0,
-+	45, 0,
-+	66, 1,
-+	0 };
-+blk_t test5[] = { 31, 20, 17, 51, 23, 1, 56, 57, 0 };
-+blk_t test5a[] = {
-+	50, ADD_BLK,
-+	51, DEL_BLK,
-+	57, DEL_BLK,
-+	66, ADD_BLK,
-+	31, DEL_BLK,
-+	12, ADD_BLK,
-+	2, ADD_BLK,
-+	13, ADD_BLK,
-+	1, DEL_BLK,
-+	0
-+	};
-+		
-+
-+static int test_fail = 0;
-+
-+static errcode_t create_test_list(blk_t *vec, badblocks_list *ret)
-+{
-+	errcode_t	retval;
-+	badblocks_list	bb;
-+	int		i;
-+	
-+	retval = ext2fs_badblocks_list_create(&bb, 5);
-+	if (retval) {
-+		com_err("create_test_list", retval, "while creating list");
-+		return retval;
-+	}
-+	for (i=0; vec[i]; i++) {
-+		retval = ext2fs_badblocks_list_add(bb, vec[i]);
-+		if (retval) {
-+			com_err("create_test_list", retval,
-+				"while adding test vector %d", i);
-+			ext2fs_badblocks_list_free(bb);
-+			return retval;
-+		}
-+	}
-+	*ret = bb;
-+	return 0;
-+}
-+
-+static void print_list(badblocks_list bb, int verify)
-+{
-+	errcode_t	retval;
-+	badblocks_iterate	iter;
-+	blk_t			blk;
-+	int			i, ok;
-+	
-+	retval = ext2fs_badblocks_list_iterate_begin(bb, &iter);
-+	if (retval) {
-+		com_err("print_list", retval, "while setting up iterator");
-+		return;
-+	}
-+	ok = i = 1;
-+	while (ext2fs_badblocks_list_iterate(iter, &blk)) {
-+		printf("%d ", blk);
-+		if (i++ != blk)
-+			ok = 0;
-+	}
-+	ext2fs_badblocks_list_iterate_end(iter);
-+	if (verify) {
-+		if (ok)
-+			printf("--- OK");
-+		else {
-+			printf("--- NOT OK");
-+			test_fail++;
-+		}
-+	}
-+}
-+
-+static void validate_test_seq(badblocks_list bb, blk_t *vec)
-+{
-+	int	i, match, ok;
-+
-+	for (i = 0; vec[i]; i += 2) {
-+		match = ext2fs_badblocks_list_test(bb, vec[i]);
-+		if (match == vec[i+1])
-+			ok = 1;
-+		else {
-+			ok = 0;
-+			test_fail++;
-+		}
-+		printf("\tblock %d is %s --- %s\n", vec[i],
-+		       match ? "present" : "absent",
-+		       ok ? "OK" : "NOT OK");
-+	}
-+}
-+
-+static void do_test_seq(badblocks_list bb, blk_t *vec)
-+{
-+	int	i, match;
-+
-+	for (i = 0; vec[i]; i += 2) {
-+		switch (vec[i+1]) {
-+		case ADD_BLK:
-+			ext2fs_badblocks_list_add(bb, vec[i]);
-+			match = ext2fs_badblocks_list_test(bb, vec[i]);
-+			printf("Adding block %d --- now %s\n", vec[i], 
-+			       match ? "present" : "absent");
-+			if (!match) {
-+				printf("FAILURE!\n");
-+				test_fail++;
-+			}
-+			break;
-+		case DEL_BLK:
-+			ext2fs_badblocks_list_del(bb, vec[i]);
-+			match = ext2fs_badblocks_list_test(bb, vec[i]);
-+			printf("Removing block %d --- now %s\n", vec[i], 
-+			       ext2fs_badblocks_list_test(bb, vec[i]) ? 
-+			       "present" : "absent");
-+			if (match) {
-+				printf("FAILURE!\n");
-+				test_fail++;
-+			}
-+			break;
-+		}
-+	}
-+}
-+
-+
-+int file_test(badblocks_list bb)
-+{
-+	badblocks_list new_bb = 0;
-+	errcode_t	retval;
-+	FILE	*f;
-+
-+	f = tmpfile();
-+	if (!f) {
-+		fprintf(stderr, "Error opening temp file: %s\n",
-+			error_message(errno));
-+		return 1;
-+	}
-+	retval = ext2fs_write_bb_FILE(bb, 0, f);
-+	if (retval) {
-+		com_err("file_test", retval, "while writing bad blocks");
-+		return 1;
-+	}
-+
-+	rewind(f);
-+	retval = ext2fs_read_bb_FILE2(0, f, &new_bb, 0, 0);
-+	if (retval) {
-+		com_err("file_test", retval, "while reading bad blocks");
-+		return 1;
-+	}
-+	fclose(f);
-+
-+	if (ext2fs_badblocks_equal(bb, new_bb)) {
-+		printf("Block bitmap matched after reading and writing.\n");
-+	} else {
-+		printf("Block bitmap NOT matched.\n");
-+		test_fail++;
-+	}
-+	return 0;
-+}
-+
-+
-+int main(int argc, char **argv)
-+{
-+	badblocks_list bb1, bb2, bb3, bb4, bb5;
-+	int	equal;
-+	errcode_t	retval;
-+
-+	bb1 = bb2 = bb3 = bb4 = bb5 = 0;
-+
-+	printf("test1: ");
-+	retval = create_test_list(test1, &bb1);
-+	if (retval == 0)
-+		print_list(bb1, 1);
-+	printf("\n");
-+	
-+	printf("test2: ");
-+	retval = create_test_list(test2, &bb2);
-+	if (retval == 0)
-+		print_list(bb2, 1);
-+	printf("\n");
-+
-+	printf("test3: ");
-+	retval = create_test_list(test3, &bb3);
-+	if (retval == 0)
-+		print_list(bb3, 1);
-+	printf("\n");
-+	
-+	printf("test4: ");
-+	retval = create_test_list(test4, &bb4);
-+	if (retval == 0) {
-+		print_list(bb4, 0);
-+		printf("\n");
-+		validate_test_seq(bb4, test4a);
-+	}
-+	printf("\n");
-+
-+	printf("test5: ");
-+	retval = create_test_list(test5, &bb5);
-+	if (retval == 0) {
-+		print_list(bb5, 0);
-+		printf("\n");
-+		do_test_seq(bb5, test5a);
-+		printf("After test5 sequence: ");
-+		print_list(bb5, 0);
-+		printf("\n");
-+	}
-+	printf("\n");
-+
-+	if (bb1 && bb2 && bb3 && bb4 && bb5) {
-+		printf("Comparison tests:\n");
-+		equal = ext2fs_badblocks_equal(bb1, bb2);
-+		printf("bb1 and bb2 are %sequal.\n", equal ? "" : "NOT "); 
-+		if (equal)
-+			test_fail++;
-+
-+		equal = ext2fs_badblocks_equal(bb1, bb3);
-+		printf("bb1 and bb3 are %sequal.\n", equal ? "" : "NOT "); 
-+		if (!equal)
-+			test_fail++;
-+		
-+		equal = ext2fs_badblocks_equal(bb1, bb4);
-+		printf("bb1 and bb4 are %sequal.\n", equal ? "" : "NOT "); 
-+		if (equal)
-+			test_fail++;
-+
-+		equal = ext2fs_badblocks_equal(bb4, bb5);
-+		printf("bb4 and bb5 are %sequal.\n", equal ? "" : "NOT "); 
-+		if (!equal)
-+			test_fail++;
-+		printf("\n");
-+	}
-+	
-+	file_test(bb4);
-+	
-+	if (test_fail == 0)
-+		printf("ext2fs library badblocks tests checks out OK!\n");
-+
-+	if (bb1)
-+		ext2fs_badblocks_list_free(bb1);
-+	if (bb2)
-+		ext2fs_badblocks_list_free(bb2);
-+	if (bb3)
-+		ext2fs_badblocks_list_free(bb3);
-+	if (bb4)
-+		ext2fs_badblocks_list_free(bb4);
-+
-+	return test_fail;
-+
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/tst_bitops.c silo-1.4.14/libext2fs/tst_bitops.c
---- silo-1.4.14.orig/libext2fs/tst_bitops.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/tst_bitops.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,44 @@
-+/*
-+ * This testing program makes sure the bitops functions work
-+ *
-+ * Copyright (C) 2001 by Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+/* #define _EXT2_USE_C_VERSIONS_ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+unsigned char bitarray[] = {
-+	0x80, 0xF0, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0, 0x10, 0x20, 0x00, 0x00
-+	};
-+
-+main(int argc, char **argv)
-+{
-+	int	i, size;
-+
-+	size = sizeof(bitarray)*8;
-+	i = ext2fs_find_first_bit_set(bitarray, size);
-+	while (i < size) {
-+		printf("Bit set: %d\n", i);
-+		i = ext2fs_find_next_bit_set(bitarray, size, i+1);
-+	}
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/tst_byteswap.c silo-1.4.14/libext2fs/tst_byteswap.c
---- silo-1.4.14.orig/libext2fs/tst_byteswap.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/tst_byteswap.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,92 @@
-+/*
-+ * This testing program makes sure the byteswap functions work
-+ *
-+ * Copyright (C) 2000 by Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+__u16 test1[] = {
-+	0x0001, 0x0100,
-+	0x1234, 0x3412,
-+	0xff00, 0x00ff,
-+	0x4000, 0x0040,
-+	0xfeff, 0xfffe,
-+	0x0000, 0x0000
-+	};
-+
-+__u32 test2[] = {
-+	0x00000001, 0x01000000,
-+	0x80000000, 0x00000080,
-+	0x12345678, 0x78563412,
-+	0xffff0000, 0x0000ffff,
-+	0x00ff0000, 0x0000ff00,
-+	0xff000000, 0x000000ff,
-+	0x00000000, 0x00000000
-+	};
-+
-+int main(int argc, char **argv)
-+{
-+	int	i;
-+	int	errors = 0;
-+
-+	printf("Testing ext2fs_swab16\n");
-+	i=0;
-+	do {
-+		printf("swab16(0x%04x) = 0x%04x\n", test1[i],
-+		       ext2fs_swab16(test1[i]));
-+		if (ext2fs_swab16(test1[i]) != test1[i+1]) {
-+			printf("Error!!!   %04x != %04x\n",
-+			       ext2fs_swab16(test1[i]), test1[i+1]);
-+			errors++;
-+		}
-+		if (ext2fs_swab16(test1[i+1]) != test1[i]) {
-+			printf("Error!!!   %04x != %04x\n",
-+			       ext2fs_swab16(test1[i+1]), test1[i]);
-+			errors++;
-+		}
-+		i += 2;
-+	} while (test1[i] != 0);
-+	
-+	printf("Testing ext2fs_swab32\n");
-+	i = 0;
-+	do {
-+		printf("swab32(0x%08x) = 0x%08x\n", test2[i],
-+		       ext2fs_swab32(test2[i]));
-+		if (ext2fs_swab32(test2[i]) != test2[i+1]) {
-+			printf("Error!!!   %04x != %04x\n",
-+			       ext2fs_swab32(test2[i]), test2[i+1]);
-+			errors++;
-+		}
-+		if (ext2fs_swab32(test2[i+1]) != test2[i]) {
-+			printf("Error!!!   %04x != %04x\n",
-+			       ext2fs_swab32(test2[i+1]), test2[i]);
-+			errors++;
-+		}
-+		i += 2;
-+	} while (test2[i] != 0);
-+
-+	if (!errors)
-+		printf("No errors found in the byteswap implementation!\n");
-+	
-+	return errors;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/tst_getsectsize.c silo-1.4.14/libext2fs/tst_getsectsize.c
---- silo-1.4.14.orig/libext2fs/tst_getsectsize.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/tst_getsectsize.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,47 @@
-+/*
-+ * tst_getsize.c --- this function tests the getsize function
-+ * 
-+ * Copyright (C) 1997 by Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+int main(int argc, char **argv)
-+{
-+	int	sectsize;
-+	int	retval;
-+	
-+	if (argc < 2) {
-+		fprintf(stderr, "Usage: %s device\n", argv[0]);
-+		exit(1);
-+	}
-+
-+	retval = ext2fs_get_device_sectsize(argv[1], &sectsize);
-+	if (retval) {
-+		com_err(argv[0], retval,
-+			"while calling ext2fs_get_device_sectsize");
-+		exit(1);
-+	}
-+	printf("Device %s has a hardware sector size of %d.\n",
-+	       argv[1], sectsize);
-+	exit(0);
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/tst_getsize.c silo-1.4.14/libext2fs/tst_getsize.c
---- silo-1.4.14.orig/libext2fs/tst_getsize.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/tst_getsize.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,44 @@
-+/*
-+ * tst_getsize.c --- this function tests the getsize function
-+ * 
-+ * Copyright (C) 1997 by Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+int main(int argc, const char *argv[])
-+{
-+	errcode_t	retval;
-+	blk_t		blocks;
-+
-+	if (argc < 2) {
-+		fprintf(stderr, "%s device\n", argv[0]);
-+		exit(1);
-+	}
-+	retval = ext2fs_get_device_size(argv[1], 1024, &blocks);
-+	if (retval) {
-+		com_err(argv[0], retval, "while getting device size");
-+		exit(1);
-+	}
-+	printf("%s is device has %d blocks.\n", argv[1], blocks);
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/tst_iscan.c silo-1.4.14/libext2fs/tst_iscan.c
---- silo-1.4.14.orig/libext2fs/tst_iscan.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/tst_iscan.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,218 @@
-+/*
-+ * tst_inode.c --- this function tests the inode scan function
-+ * 
-+ * Copyright (C) 1996 by Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+blk_t test_vec[] = { 8, 12, 24, 34, 43, 44, 100, 0 };
-+
-+ext2_filsys	test_fs;
-+ext2fs_block_bitmap bad_block_map, touched_map;
-+ext2fs_inode_bitmap bad_inode_map;
-+badblocks_list	test_badblocks;
-+
-+int first_no_comma = 1;
-+int failed = 0;
-+
-+static void test_read_blk(unsigned long block, int count, errcode_t err)
-+{
-+	int	i;
-+
-+	if (first_no_comma)
-+		first_no_comma = 0;
-+	else
-+		printf(", ");
-+
-+	if (count > 1)
-+		printf("%lu-%lu", block, block+count-1);
-+	else
-+		printf("%lu", block);
-+
-+	for (i=0; i < count; i++, block++) {
-+		if (ext2fs_test_block_bitmap(touched_map, block)) {
-+			printf("\nDuplicate block?!? --- %lu\n", block);
-+			failed++;
-+			first_no_comma = 1;
-+		}
-+		ext2fs_mark_block_bitmap(touched_map, block);
-+	}
-+}
-+
-+/*
-+ * Setup the variables for doing the inode scan test.
-+ */
-+static void setup(void)
-+{
-+	errcode_t	retval;
-+	int		i;
-+	struct ext2_super_block param;
-+
-+	initialize_ext2_error_table();
-+
-+	memset(&param, 0, sizeof(param));
-+	param.s_blocks_count = 12000;
-+
-+
-+	test_io_cb_read_blk = test_read_blk;
-+	
-+	retval = ext2fs_initialize("test fs", 0, &param,
-+				   test_io_manager, &test_fs);
-+	if (retval) {
-+		com_err("setup", retval,
-+			"While initializing filesystem");
-+		exit(1);
-+	}
-+	retval = ext2fs_allocate_tables(test_fs);
-+	if (retval) {
-+		com_err("setup", retval,
-+			"While allocating tables for test filesystem");
-+		exit(1);
-+	}
-+	retval = ext2fs_allocate_block_bitmap(test_fs, "bad block map",
-+					      &bad_block_map);
-+	if (retval) {
-+		com_err("setup", retval,
-+			"While allocating bad_block bitmap");
-+		exit(1);
-+	}
-+	retval = ext2fs_allocate_block_bitmap(test_fs, "touched map",
-+					      &touched_map);
-+	if (retval) {
-+		com_err("setup", retval,
-+			"While allocating touched block bitmap");
-+		exit(1);
-+	}
-+	retval = ext2fs_allocate_inode_bitmap(test_fs, "bad inode map",
-+					      &bad_inode_map);
-+	if (retval) {
-+		com_err("setup", retval,
-+			"While allocating bad inode bitmap");
-+		exit(1);
-+	}
-+	
-+	retval = ext2fs_badblocks_list_create(&test_badblocks, 5);
-+	if (retval) {
-+		com_err("setup", retval, "while creating badblocks list");
-+		exit(1);
-+	}
-+	for (i=0; test_vec[i]; i++) {
-+		retval = ext2fs_badblocks_list_add(test_badblocks, test_vec[i]);
-+		if (retval) {
-+			com_err("setup", retval,
-+				"while adding test vector %d", i);
-+			exit(1);
-+		}
-+		ext2fs_mark_block_bitmap(bad_block_map, test_vec[i]);
-+	}
-+	test_fs->badblocks = test_badblocks;
-+}
-+
-+/*
-+ * Iterate using inode_scan
-+ */
-+static void iterate(void)
-+{
-+	struct ext2_inode inode;
-+	ext2_inode_scan	scan;
-+	errcode_t	retval;
-+	ext2_ino_t	ino;
-+
-+	retval = ext2fs_open_inode_scan(test_fs, 8, &scan);
-+	if (retval) {
-+		com_err("iterate", retval, "While opening inode scan");
-+		exit(1);
-+	}
-+	printf("Reading blocks: ");
-+	retval = ext2fs_get_next_inode(scan, &ino, &inode);
-+	if (retval) {
-+		com_err("iterate", retval, "while reading first inode");
-+		exit(1);
-+	}
-+	while (ino) {
-+		retval = ext2fs_get_next_inode(scan, &ino, &inode);
-+		if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
-+			ext2fs_mark_inode_bitmap(bad_inode_map, ino);
-+			continue;
-+		}
-+		if (retval) {
-+			com_err("iterate", retval,
-+				"while getting next inode");
-+			exit(1);
-+		}
-+	}
-+	printf("\n");
-+	ext2fs_close_inode_scan(scan);
-+}
-+
-+/*
-+ * Verify the touched map
-+ */
-+static void check_map(void)
-+{
-+	int	i, j, first=1;
-+	unsigned long	blk;
-+
-+	for (i=0; test_vec[i]; i++) {
-+		if (ext2fs_test_block_bitmap(touched_map, test_vec[i])) {
-+			printf("Bad block was touched --- %d\n", test_vec[i]);
-+			failed++;
-+			first_no_comma = 1;
-+		}
-+		ext2fs_mark_block_bitmap(touched_map, test_vec[i]);
-+	}
-+	for (i = 0; i < test_fs->group_desc_count; i++) {
-+		for (j=0, blk = test_fs->group_desc[i].bg_inode_table;
-+		     j < test_fs->inode_blocks_per_group;
-+		     j++, blk++) {
-+			if (!ext2fs_test_block_bitmap(touched_map, blk) &&
-+			    !ext2fs_test_block_bitmap(bad_block_map, blk)) {
-+				printf("Missing block --- %lu\n", blk);
-+				failed++;
-+			}
-+		}
-+	}
-+	printf("Bad inodes: ");
-+	for (i=1; i <= test_fs->super->s_inodes_count; i++) {
-+		if (ext2fs_test_inode_bitmap(bad_inode_map, i)) {
-+			if (first)
-+				first = 0;
-+			else
-+				printf(", ");
-+			printf("%d", i);
-+		}
-+	}
-+	printf("\n");
-+}
-+
-+
-+int main(int argc, char **argv)
-+{
-+	setup();
-+	iterate();
-+	check_map();
-+	if (!failed)
-+		printf("Inode scan tested OK!\n");
-+	return failed;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/unix_io.c silo-1.4.14/libext2fs/unix_io.c
---- silo-1.4.14.orig/libext2fs/unix_io.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/unix_io.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,710 @@
-+/*
-+ * unix_io.c --- This is the Unix (well, really POSIX) implementation
-+ * 	of the I/O manager.
-+ *
-+ * Implements a one-block write-through cache.
-+ *
-+ * Includes support for Windows NT support under Cygwin. 
-+ *
-+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-+ * 	2002 by Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#define _LARGEFILE_SOURCE
-+#define _LARGEFILE64_SOURCE
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#ifdef __linux__
-+#include <sys/utsname.h>
-+#endif
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#if HAVE_SYS_RESOURCE_H
-+#include <sys/resource.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * For checking structure magic numbers...
-+ */
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+	  if ((struct)->magic != (code)) return (code)
-+
-+struct unix_cache {
-+	char		*buf;
-+	unsigned long	block;
-+	int		access_time;
-+	unsigned	dirty:1;
-+	unsigned	in_use:1;
-+};
-+
-+#define CACHE_SIZE 8
-+#define WRITE_DIRECT_SIZE 4	/* Must be smaller than CACHE_SIZE */
-+#define READ_DIRECT_SIZE 4	/* Should be smaller than CACHE_SIZE */
-+
-+struct unix_private_data {
-+	int	magic;
-+	int	dev;
-+	int	flags;
-+	int	access_time;
-+	ext2_loff_t offset;
-+	struct unix_cache cache[CACHE_SIZE];
-+};
-+
-+static errcode_t unix_open(const char *name, int flags, io_channel *channel);
-+static errcode_t unix_close(io_channel channel);
-+static errcode_t unix_set_blksize(io_channel channel, int blksize);
-+static errcode_t unix_read_blk(io_channel channel, unsigned long block,
-+			       int count, void *data);
-+static errcode_t unix_write_blk(io_channel channel, unsigned long block,
-+				int count, const void *data);
-+static errcode_t unix_flush(io_channel channel);
-+static errcode_t unix_write_byte(io_channel channel, unsigned long offset,
-+				int size, const void *data);
-+static errcode_t unix_set_option(io_channel channel, const char *option, 
-+				 const char *arg);
-+
-+static void reuse_cache(io_channel channel, struct unix_private_data *data,
-+		 struct unix_cache *cache, unsigned long block);
-+
-+/* __FreeBSD_kernel__ is defined by GNU/kFreeBSD - the FreeBSD kernel
-+ * does not know buffered block devices - everything is raw. */
-+#if defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-+#define NEED_BOUNCE_BUFFER
-+#else
-+#undef NEED_BOUNCE_BUFFER
-+#endif
-+
-+static struct struct_io_manager struct_unix_manager = {
-+	EXT2_ET_MAGIC_IO_MANAGER,
-+	"Unix I/O Manager",
-+	unix_open,
-+	unix_close,
-+	unix_set_blksize,
-+	unix_read_blk,
-+	unix_write_blk,
-+	unix_flush,
-+#ifdef NEED_BOUNCE_BUFFER
-+	0,
-+#else
-+	unix_write_byte,
-+#endif
-+	unix_set_option
-+};
-+
-+io_manager unix_io_manager = &struct_unix_manager;
-+
-+/*
-+ * Here are the raw I/O functions
-+ */
-+#ifndef NEED_BOUNCE_BUFFER
-+static errcode_t raw_read_blk(io_channel channel,
-+			      struct unix_private_data *data,
-+			      unsigned long block,
-+			      int count, void *buf)
-+{
-+	errcode_t	retval;
-+	ssize_t		size;
-+	ext2_loff_t	location;
-+	int		actual = 0;
-+
-+	size = (count < 0) ? -count : count * channel->block_size;
-+	location = ((ext2_loff_t) block * channel->block_size) + data->offset;
-+	if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
-+		retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
-+		goto error_out;
-+	}
-+	actual = read(data->dev, buf, size);
-+	if (actual != size) {
-+		if (actual < 0)
-+			actual = 0;
-+		retval = EXT2_ET_SHORT_READ;
-+		goto error_out;
-+	}
-+	return 0;
-+	
-+error_out:
-+	memset((char *) buf+actual, 0, size-actual);
-+	if (channel->read_error)
-+		retval = (channel->read_error)(channel, block, count, buf,
-+					       size, actual, retval);
-+	return retval;
-+}
-+#else /* NEED_BOUNCE_BUFFER */
-+/*
-+ * Windows and FreeBSD block devices only allow sector alignment IO in offset and size
-+ */
-+static errcode_t raw_read_blk(io_channel channel,
-+			      struct unix_private_data *data,
-+			      unsigned long block,
-+			      int count, void *buf)
-+{
-+	errcode_t	retval;
-+	size_t		size, alignsize, fragment;
-+	ext2_loff_t	location;
-+	int		total = 0, actual;
-+#define BLOCKALIGN 512
-+	char		sector[BLOCKALIGN];
-+
-+	size = (count < 0) ? -count : count * channel->block_size;
-+	location = ((ext2_loff_t) block * channel->block_size) + data->offset;
-+#ifdef DEBUG
-+	printf("count=%d, size=%d, block=%d, blk_size=%d, location=%lx\n",
-+	 		count, size, block, channel->block_size, location);
-+#endif
-+	if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
-+		retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
-+		goto error_out;
-+	}
-+	fragment = size % BLOCKALIGN;
-+	alignsize = size - fragment;
-+	if (alignsize) {
-+		actual = read(data->dev, buf, alignsize);
-+		if (actual != alignsize)
-+			goto short_read;
-+	}
-+	if (fragment) {
-+		actual = read(data->dev, sector, BLOCKALIGN);
-+		if (actual != BLOCKALIGN)
-+			goto short_read;
-+		memcpy(buf+alignsize, sector, fragment);
-+	}
-+	return 0;
-+
-+short_read:
-+	if (actual>0)
-+		total += actual;
-+	retval = EXT2_ET_SHORT_READ;
-+
-+error_out:
-+	memset((char *) buf+total, 0, size-actual);
-+	if (channel->read_error)
-+		retval = (channel->read_error)(channel, block, count, buf,
-+					       size, actual, retval);
-+	return retval;
-+}
-+#endif
-+
-+static errcode_t raw_write_blk(io_channel channel,
-+			       struct unix_private_data *data,
-+			       unsigned long block,
-+			       int count, const void *buf)
-+{
-+	ssize_t		size;
-+	ext2_loff_t	location;
-+	int		actual = 0;
-+	errcode_t	retval;
-+
-+	if (count == 1)
-+		size = channel->block_size;
-+	else {
-+		if (count < 0)
-+			size = -count;
-+		else
-+			size = count * channel->block_size;
-+	}
-+
-+	location = ((ext2_loff_t) block * channel->block_size) + data->offset;
-+	if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
-+		retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
-+		goto error_out;
-+	}
-+	
-+	actual = write(data->dev, buf, size);
-+	if (actual != size) {
-+		retval = EXT2_ET_SHORT_WRITE;
-+		goto error_out;
-+	}
-+	return 0;
-+	
-+error_out:
-+	if (channel->write_error)
-+		retval = (channel->write_error)(channel, block, count, buf,
-+						size, actual, retval);
-+	return retval;
-+}
-+
-+
-+/*
-+ * Here we implement the cache functions
-+ */
-+
-+/* Allocate the cache buffers */
-+static errcode_t alloc_cache(io_channel channel,
-+			     struct unix_private_data *data)
-+{
-+	errcode_t		retval;
-+	struct unix_cache	*cache;
-+	int			i;
-+	
-+	data->access_time = 0;
-+	for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
-+		cache->block = 0;
-+		cache->access_time = 0;
-+		cache->dirty = 0;
-+		cache->in_use = 0;
-+		if ((retval = ext2fs_get_mem(channel->block_size,
-+					     &cache->buf)))
-+			return retval;
-+	}
-+	return 0;
-+}
-+
-+/* Free the cache buffers */
-+static void free_cache(struct unix_private_data *data)
-+{
-+	struct unix_cache	*cache;
-+	int			i;
-+	
-+	data->access_time = 0;
-+	for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
-+		cache->block = 0;
-+		cache->access_time = 0;
-+		cache->dirty = 0;
-+		cache->in_use = 0;
-+		if (cache->buf)
-+			ext2fs_free_mem(&cache->buf);
-+		cache->buf = 0;
-+	}
-+}
-+
-+#ifndef NO_IO_CACHE
-+/*
-+ * Try to find a block in the cache.  If the block is not found, and
-+ * eldest is a non-zero pointer, then fill in eldest with the cache
-+ * entry to that should be reused.
-+ */
-+static struct unix_cache *find_cached_block(struct unix_private_data *data,
-+					    unsigned long block,
-+					    struct unix_cache **eldest)
-+{
-+	struct unix_cache	*cache, *unused_cache, *oldest_cache;
-+	int			i;
-+	
-+	unused_cache = oldest_cache = 0;
-+	for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
-+		if (!cache->in_use) {
-+			if (!unused_cache)
-+				unused_cache = cache;
-+			continue;
-+		}
-+		if (cache->block == block) {
-+			cache->access_time = ++data->access_time;
-+			return cache;
-+		}
-+		if (!oldest_cache ||
-+		    (cache->access_time < oldest_cache->access_time))
-+			oldest_cache = cache;
-+	}
-+	if (eldest)
-+		*eldest = (unused_cache) ? unused_cache : oldest_cache;
-+	return 0;
-+}
-+
-+/*
-+ * Reuse a particular cache entry for another block.
-+ */
-+static void reuse_cache(io_channel channel, struct unix_private_data *data,
-+		 struct unix_cache *cache, unsigned long block)
-+{
-+	if (cache->dirty && cache->in_use)
-+		raw_write_blk(channel, data, cache->block, 1, cache->buf);
-+
-+	cache->in_use = 1;
-+	cache->dirty = 0;
-+	cache->block = block;
-+	cache->access_time = ++data->access_time;
-+}
-+
-+/*
-+ * Flush all of the blocks in the cache
-+ */
-+static errcode_t flush_cached_blocks(io_channel channel,
-+				     struct unix_private_data *data,
-+				     int invalidate)
-+
-+{
-+	struct unix_cache	*cache;
-+	errcode_t		retval, retval2;
-+	int			i;
-+	
-+	retval2 = 0;
-+	for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
-+		if (!cache->in_use)
-+			continue;
-+		
-+		if (invalidate)
-+			cache->in_use = 0;
-+		
-+		if (!cache->dirty)
-+			continue;
-+		
-+		retval = raw_write_blk(channel, data,
-+				       cache->block, 1, cache->buf);
-+		if (retval)
-+			retval2 = retval;
-+		else
-+			cache->dirty = 0;
-+	}
-+	return retval2;
-+}
-+#endif /* NO_IO_CACHE */
-+
-+static errcode_t unix_open(const char *name, int flags, io_channel *channel)
-+{
-+	io_channel	io = NULL;
-+	struct unix_private_data *data = NULL;
-+	errcode_t	retval;
-+	int		open_flags;
-+	struct stat	st;
-+#ifdef __linux__
-+	struct 		utsname ut;
-+#endif
-+
-+	if (name == 0)
-+		return EXT2_ET_BAD_DEVICE_NAME;
-+	retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
-+	if (retval)
-+		return retval;
-+	memset(io, 0, sizeof(struct struct_io_channel));
-+	io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
-+	retval = ext2fs_get_mem(sizeof(struct unix_private_data), &data);
-+	if (retval)
-+		goto cleanup;
-+
-+	io->manager = unix_io_manager;
-+	retval = ext2fs_get_mem(strlen(name)+1, &io->name);
-+	if (retval)
-+		goto cleanup;
-+
-+	strcpy(io->name, name);
-+	io->private_data = data;
-+	io->block_size = 1024;
-+	io->read_error = 0;
-+	io->write_error = 0;
-+	io->refcount = 1;
-+
-+	memset(data, 0, sizeof(struct unix_private_data));
-+	data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL;
-+
-+	if ((retval = alloc_cache(io, data)))
-+		goto cleanup;
-+
-+	open_flags = (flags & IO_FLAG_RW) ? O_RDWR : O_RDONLY;
-+#ifdef HAVE_OPEN64
-+	data->dev = open64(io->name, open_flags);
-+#else
-+	data->dev = open(io->name, open_flags);
-+#endif
-+	if (data->dev < 0) {
-+		retval = errno;
-+		goto cleanup;
-+	}
-+
-+#ifdef __linux__
-+#undef RLIM_INFINITY
-+#if (defined(__alpha__) || ((defined(__sparc__) || defined(__mips__)) && (SIZEOF_LONG == 4)))
-+#define RLIM_INFINITY	((unsigned long)(~0UL>>1))
-+#else
-+#define RLIM_INFINITY  (~0UL)
-+#endif
-+	/*
-+	 * Work around a bug in 2.4.10-2.4.18 kernels where writes to
-+	 * block devices are wrongly getting hit by the filesize
-+	 * limit.  This workaround isn't perfect, since it won't work
-+	 * if glibc wasn't built against 2.2 header files.  (Sigh.)
-+	 * 
-+	 */
-+	if ((flags & IO_FLAG_RW) &&
-+	    (uname(&ut) == 0) &&
-+	    ((ut.release[0] == '2') && (ut.release[1] == '.') &&
-+	     (ut.release[2] == '4') && (ut.release[3] == '.') &&
-+	     (ut.release[4] == '1') && (ut.release[5] >= '0') &&
-+	     (ut.release[5] < '8')) &&
-+	    (fstat(data->dev, &st) == 0) &&
-+	    (S_ISBLK(st.st_mode))) {
-+		struct rlimit	rlim;
-+		
-+		rlim.rlim_cur = rlim.rlim_max = (unsigned long) RLIM_INFINITY;
-+		setrlimit(RLIMIT_FSIZE, &rlim);
-+		getrlimit(RLIMIT_FSIZE, &rlim);
-+		if (((unsigned long) rlim.rlim_cur) <
-+		    ((unsigned long) rlim.rlim_max)) {
-+			rlim.rlim_cur = rlim.rlim_max;
-+			setrlimit(RLIMIT_FSIZE, &rlim);
-+		}
-+	}
-+#endif
-+	*channel = io;
-+	return 0;
-+
-+cleanup:
-+	if (data) {
-+		free_cache(data);
-+		ext2fs_free_mem(&data);
-+	}
-+	if (io)
-+		ext2fs_free_mem(&io);
-+	return retval;
-+}
-+
-+static errcode_t unix_close(io_channel channel)
-+{
-+	struct unix_private_data *data;
-+	errcode_t	retval = 0;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct unix_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+	if (--channel->refcount > 0)
-+		return 0;
-+
-+#ifndef NO_IO_CACHE
-+	retval = flush_cached_blocks(channel, data, 0);
-+#endif
-+
-+	if (close(data->dev) < 0)
-+		retval = errno;
-+	free_cache(data);
-+
-+	ext2fs_free_mem(&channel->private_data);
-+	if (channel->name)
-+		ext2fs_free_mem(&channel->name);
-+	ext2fs_free_mem(&channel);
-+	return retval;
-+}
-+
-+static errcode_t unix_set_blksize(io_channel channel, int blksize)
-+{
-+	struct unix_private_data *data;
-+	errcode_t		retval;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct unix_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+	if (channel->block_size != blksize) {
-+#ifndef NO_IO_CACHE
-+		if ((retval = flush_cached_blocks(channel, data, 0)))
-+			return retval;
-+#endif
-+		
-+		channel->block_size = blksize;
-+		free_cache(data);
-+		if ((retval = alloc_cache(channel, data)))
-+			return retval;
-+	}
-+	return 0;
-+}
-+
-+
-+static errcode_t unix_read_blk(io_channel channel, unsigned long block,
-+			       int count, void *buf)
-+{
-+	struct unix_private_data *data;
-+	struct unix_cache *cache, *reuse[READ_DIRECT_SIZE];
-+	errcode_t	retval;
-+	char		*cp;
-+	int		i, j;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct unix_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+#ifdef NO_IO_CACHE
-+	return raw_read_blk(channel, data, block, count, buf);
-+#else
-+	/*
-+	 * If we're doing an odd-sized read or a very large read,
-+	 * flush out the cache and then do a direct read.
-+	 */
-+	if (count < 0 || count > WRITE_DIRECT_SIZE) {
-+		if ((retval = flush_cached_blocks(channel, data, 0)))
-+			return retval;
-+		return raw_read_blk(channel, data, block, count, buf);
-+	}
-+
-+	cp = buf;
-+	while (count > 0) {
-+		/* If it's in the cache, use it! */
-+		if ((cache = find_cached_block(data, block, &reuse[0]))) {
-+#ifdef DEBUG
-+			printf("Using cached block %d\n", block);
-+#endif
-+			memcpy(cp, cache->buf, channel->block_size);
-+			count--;
-+			block++;
-+			cp += channel->block_size;
-+			continue;
-+		}
-+		/*
-+		 * Find the number of uncached blocks so we can do a
-+		 * single read request
-+		 */
-+		for (i=1; i < count; i++)
-+			if (find_cached_block(data, block+i, &reuse[i]))
-+				break;
-+#ifdef DEBUG
-+		printf("Reading %d blocks starting at %d\n", i, block);
-+#endif
-+		if ((retval = raw_read_blk(channel, data, block, i, cp)))
-+			return retval;
-+		
-+		/* Save the results in the cache */
-+		for (j=0; j < i; j++) {
-+			count--;
-+			cache = reuse[j];
-+			reuse_cache(channel, data, cache, block++);
-+			memcpy(cache->buf, cp, channel->block_size);
-+			cp += channel->block_size;
-+		}
-+	}
-+	return 0;
-+#endif /* NO_IO_CACHE */
-+}
-+
-+static errcode_t unix_write_blk(io_channel channel, unsigned long block,
-+				int count, const void *buf)
-+{
-+	struct unix_private_data *data;
-+	struct unix_cache *cache, *reuse;
-+	errcode_t	retval = 0;
-+	const char	*cp;
-+	int		writethrough;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct unix_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+#ifdef NO_IO_CACHE
-+	return raw_write_blk(channel, data, block, count, buf);
-+#else	
-+	/*
-+	 * If we're doing an odd-sized write or a very large write,
-+	 * flush out the cache completely and then do a direct write.
-+	 */
-+	if (count < 0 || count > WRITE_DIRECT_SIZE) {
-+		if ((retval = flush_cached_blocks(channel, data, 1)))
-+			return retval;
-+		return raw_write_blk(channel, data, block, count, buf);
-+	}
-+
-+	/*
-+	 * For a moderate-sized multi-block write, first force a write
-+	 * if we're in write-through cache mode, and then fill the
-+	 * cache with the blocks.
-+	 */
-+	writethrough = channel->flags & CHANNEL_FLAGS_WRITETHROUGH;
-+	if (writethrough)
-+		retval = raw_write_blk(channel, data, block, count, buf);
-+	
-+	cp = buf;
-+	while (count > 0) {
-+		cache = find_cached_block(data, block, &reuse);
-+		if (!cache) {
-+			cache = reuse;
-+			reuse_cache(channel, data, cache, block);
-+		}
-+		memcpy(cache->buf, cp, channel->block_size);
-+		cache->dirty = !writethrough;
-+		count--;
-+		block++;
-+		cp += channel->block_size;
-+	}
-+	return retval;
-+#endif /* NO_IO_CACHE */
-+}
-+
-+static errcode_t unix_write_byte(io_channel channel, unsigned long offset,
-+				 int size, const void *buf)
-+{
-+	struct unix_private_data *data;
-+	errcode_t	retval = 0;
-+	ssize_t		actual;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct unix_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+#ifndef NO_IO_CACHE
-+	/*
-+	 * Flush out the cache completely
-+	 */
-+	if ((retval = flush_cached_blocks(channel, data, 1)))
-+		return retval;
-+#endif
-+
-+	if (lseek(data->dev, offset + data->offset, SEEK_SET) < 0)
-+		return errno;
-+	
-+	actual = write(data->dev, buf, size);
-+	if (actual != size)
-+		return EXT2_ET_SHORT_WRITE;
-+
-+	return 0;
-+}
-+
-+/*
-+ * Flush data buffers to disk.  
-+ */
-+static errcode_t unix_flush(io_channel channel)
-+{
-+	struct unix_private_data *data;
-+	errcode_t retval = 0;
-+	
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct unix_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+#ifndef NO_IO_CACHE
-+	retval = flush_cached_blocks(channel, data, 0);
-+#endif
-+	fsync(data->dev);
-+	return retval;
-+}
-+
-+static errcode_t unix_set_option(io_channel channel, const char *option, 
-+				 const char *arg)
-+{
-+	struct unix_private_data *data;
-+	unsigned long tmp;
-+	char *end;
-+
-+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+	data = (struct unix_private_data *) channel->private_data;
-+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+	if (!strcmp(option, "offset")) {
-+		if (!arg)
-+			return EXT2_ET_INVALID_ARGUMENT;
-+
-+		tmp = strtoul(arg, &end, 0);
-+		if (*end)
-+			return EXT2_ET_INVALID_ARGUMENT;
-+		data->offset = tmp;
-+		return 0;
-+	}
-+	return EXT2_ET_INVALID_ARGUMENT;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/unlink.c silo-1.4.14/libext2fs/unlink.c
---- silo-1.4.14.orig/libext2fs/unlink.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/unlink.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,99 @@
-+/*
-+ * unlink.c --- delete links in a ext2fs directory
-+ * 
-+ * Copyright (C) 1993, 1994, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct link_struct  {
-+	const char	*name;
-+	int		namelen;
-+	ext2_ino_t	inode;
-+	int		flags;
-+	struct ext2_dir_entry *prev;
-+	int		done;
-+};	
-+
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int unlink_proc(struct ext2_dir_entry *dirent,
-+		     int	offset EXT2FS_ATTR((unused)),
-+		     int	blocksize EXT2FS_ATTR((unused)),
-+		     char	*buf EXT2FS_ATTR((unused)),
-+		     void	*priv_data)
-+{
-+	struct link_struct *ls = (struct link_struct *) priv_data;
-+	struct ext2_dir_entry *prev;
-+
-+	prev = ls->prev;
-+	ls->prev = dirent;
-+
-+	if (ls->name) {
-+		if ((dirent->name_len & 0xFF) != ls->namelen)
-+			return 0;
-+		if (strncmp(ls->name, dirent->name, dirent->name_len & 0xFF))
-+			return 0;
-+	}
-+	if (ls->inode) {
-+		if (dirent->inode != ls->inode)
-+			return 0;
-+	} else {
-+		if (!dirent->inode)
-+			return 0;
-+	}
-+
-+	if (prev) 
-+		prev->rec_len += dirent->rec_len;
-+	else
-+		dirent->inode = 0;
-+	ls->done++;
-+	return DIRENT_ABORT|DIRENT_CHANGED;
-+}
-+
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir,
-+			const char *name, ext2_ino_t ino,
-+			int flags EXT2FS_ATTR((unused)))
-+{
-+	errcode_t	retval;
-+	struct link_struct ls;
-+
-+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+	if (!name && !ino)
-+		return EXT2_ET_INVALID_ARGUMENT;
-+
-+	if (!(fs->flags & EXT2_FLAG_RW))
-+		return EXT2_ET_RO_FILSYS;
-+
-+	ls.name = name;
-+	ls.namelen = name ? strlen(name) : 0;
-+	ls.inode = ino;
-+	ls.flags = 0;
-+	ls.done = 0;
-+	ls.prev = 0;
-+
-+	retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY, 
-+				    0, unlink_proc, &ls);
-+	if (retval)
-+		return retval;
-+
-+	return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE;
-+}
-+
-diff -Naur silo-1.4.14.orig/libext2fs/valid_blk.c silo-1.4.14/libext2fs/valid_blk.c
---- silo-1.4.14.orig/libext2fs/valid_blk.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/valid_blk.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,56 @@
-+/*
-+ * valid_blk.c --- does the inode have valid blocks?
-+ *
-+ * Copyright 1997 by Theodore Ts'o
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * This function returns 1 if the inode's block entries actually
-+ * contain block entries.
-+ */
-+int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode)
-+{
-+	/*
-+	 * Only directories, regular files, and some symbolic links
-+	 * have valid block entries.
-+	 */
-+	if (!LINUX_S_ISDIR(inode->i_mode) && !LINUX_S_ISREG(inode->i_mode) &&
-+	    !LINUX_S_ISLNK(inode->i_mode))
-+		return 0;
-+	
-+	/*
-+	 * If the symbolic link is a "fast symlink", then the symlink
-+	 * target is stored in the block entries.
-+	 */
-+	if (LINUX_S_ISLNK (inode->i_mode)) {
-+		if (inode->i_file_acl == 0) {
-+			/* With no EA block, we can rely on i_blocks */
-+			if (inode->i_blocks == 0)
-+				return 0;
-+		} else {
-+			/* With an EA block, life gets more tricky */
-+			if (inode->i_size >= EXT2_N_BLOCKS*4)
-+				return 1; /* definitely using i_block[] */
-+			if (inode->i_size > 4 && inode->i_block[1] == 0)
-+				return 1; /* definitely using i_block[] */
-+			return 0; /* Probably a fast symlink */
-+		}
-+	}
-+	return 1;
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/version.c silo-1.4.14/libext2fs/version.c
---- silo-1.4.14.orig/libext2fs/version.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/version.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,52 @@
-+/*
-+ * version.c --- Return the version of the ext2 library
-+ *
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <stdio.h>
-+#include <ctype.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#include "version.h"
-+
-+static const char *lib_version = E2FSPROGS_VERSION;
-+static const char *lib_date = E2FSPROGS_DATE;
-+
-+int ext2fs_parse_version_string(const char *ver_string)
-+{
-+	const char *cp;
-+	int version = 0;
-+
-+	for (cp = ver_string; *cp; cp++) {
-+		if (*cp == '.')
-+			continue;
-+		if (!isdigit(*cp))
-+			break;
-+		version = (version * 10) + (*cp - '0');
-+	}
-+	return version;
-+}
-+
-+
-+int ext2fs_get_library_version(const char **ver_string,
-+			       const char **date_string)
-+{
-+	if (ver_string)
-+		*ver_string = lib_version;
-+	if (date_string)
-+		*date_string = lib_date;
-+
-+	return ext2fs_parse_version_string(lib_version);
-+}
-diff -Naur silo-1.4.14.orig/libext2fs/version.h silo-1.4.14/libext2fs/version.h
---- silo-1.4.14.orig/libext2fs/version.h	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/version.h	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,11 @@
-+/*
-+ * version.h --- controls the version number printed by the e2fs
-+ * programs.
-+ * 
-+ * Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-+ * 2004, 2005 by Theodore Ts'o.  This file may be redistributed under
-+ * the GNU Public License.
-+ */
-+
-+#define E2FSPROGS_VERSION "1.38"
-+#define E2FSPROGS_DATE "30-Jun-2005"
-diff -Naur silo-1.4.14.orig/libext2fs/write_bb_file.c silo-1.4.14/libext2fs/write_bb_file.c
---- silo-1.4.14.orig/libext2fs/write_bb_file.c	1969-12-31 19:00:00.000000000 -0500
-+++ silo-1.4.14/libext2fs/write_bb_file.c	2011-01-10 21:59:35.427156659 -0500
-@@ -0,0 +1,34 @@
-+/*
-+ * write_bb_file.c --- write a list of bad blocks to a FILE *
-+ *
-+ * Copyright (C) 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
-+			       unsigned int flags EXT2FS_ATTR((unused)),
-+			       FILE *f)
-+{
-+	badblocks_iterate	bb_iter;
-+	blk_t			blk;
-+	errcode_t		retval;
-+
-+	retval = ext2fs_badblocks_list_iterate_begin(bb_list, &bb_iter);
-+	if (retval)
-+		return retval;
-+
-+	while (ext2fs_badblocks_list_iterate(bb_iter, &blk)) {
-+		fprintf(f, "%d\n", blk);
-+	}
-+	ext2fs_badblocks_list_iterate_end(bb_iter);
-+	return 0;
-+}
-diff -Naur silo-1.4.14.orig/second/Makefile silo-1.4.14/second/Makefile
---- silo-1.4.14.orig/second/Makefile	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/second/Makefile	2011-01-10 21:59:35.427156659 -0500
-@@ -27,10 +27,10 @@
- LDFLAGS_LARGE=-N -Ttext $(LARGE_RELOC)
- 
- .c.o:
--	$(CC) $(CFLAGS) -c $*.c -o $@
-+	$(CC-SILO) $(CFLAGS) -c $*.c -o $@
- 
- .S.o:
--	$(CC) $(CFLAGS) -c $*.S -o $@
-+	$(CC-SILO) $(CFLAGS) -c $*.S -o $@
- 
- # The ordering here is very significant. Please add new object files to OBJS5 only.
- OBJS1 = crt0.o
-@@ -43,8 +43,8 @@
- OBJS4 = main.o
- OBJS4N = mainnet.o
- OBJS5 = cmdline.o disk.o file.o misc.o cfg.o strtol.o ranges.o timer.o \
--	memory.o fs/libfs.a mul.o ../common/rem.o ../common/sdiv.o umul.o \
--	../common/stringops2.o ls.o muldi3.o
-+	memory.o fs/libfs.a ../common/rem.o ../common/sdiv.o umul.o \
-+	../common/stringops2.o ls.o muldi3.o ../libext2fs/libext2fs.a
- OBJS = $(OBJS1) $(OBJS2) $(OBJS3) bmark.o $(OBJS4) $(OBJS5)
- OBJSNET = $(OBJS1) $(OBJS2N) $(OBJS3) bmark.o $(OBJS4N) $(OBJS5)
- 
-@@ -53,18 +53,21 @@
- # Should really switch to autoconf...
- all: second.b silotftp.b
- 
-+../libext2fs/libext2fs.a:
-+	@make -C ../libext2fs
-+
- fs/libfs.a: $(FS_OBJS)
- 	$(RM) $@
- 	$(AR) rc $@ $(FS_OBJS)
- 
- second: $(OBJS) mark.o
--	$(LD) $(LDFLAGS_SMALL) -Bstatic -o second $(OBJS) -lext2fs mark.o
--	$(LD) $(LDFLAGS_LARGE) -Bstatic -o second2 $(OBJS) -lext2fs mark.o
-+	$(LD) $(LDFLAGS_SMALL) -Bstatic -o second $(OBJS) mark.o
-+	$(LD) $(LDFLAGS_LARGE) -Bstatic -o second2 $(OBJS) mark.o
- 	$(NM) second | grep -v '*ABS*' | sort > second.map
- 
- silotftp: $(OBJSNET) mark.o
--	$(LD) $(LDFLAGS_SMALL) -Bstatic -o silotftp $(OBJSNET) -lext2fs mark.o
--	$(LD) $(LDFLAGS_LARGE) -Bstatic -o silotftp2 $(OBJSNET) -lext2fs mark.o
-+	$(LD) $(LDFLAGS_SMALL) -Bstatic -o silotftp $(OBJSNET) mark.o
-+	$(LD) $(LDFLAGS_LARGE) -Bstatic -o silotftp2 $(OBJSNET) mark.o
- 	$(NM) silotftp | grep -v '*ABS*' | sort > silotftp.map
- 
- second.l: second
-@@ -73,31 +76,31 @@
- file.o:	       file.c
- 
- decompnet.o:   decomp.c
--	$(CC) $(CFLAGS) -DTFTP -DVERSION='"$(VERSION)"' -c -o $@ $<
-+	$(CC-SILO) $(CFLAGS) -DTFTP -DVERSION='"$(VERSION)"' -c -o $@ $<
- 
- decomp.o: decomp.c
--	$(CC) $(CFLAGS) -DVERSION='"$(VERSION)"' -c $<
-+	$(CC-SILO) $(CFLAGS) -DVERSION='"$(VERSION)"' -c $<
- 
- mainnet.o:   main.c
--	$(CC) $(CFLAGS) -DTFTP -c -o $@ $<
-+	$(CC-SILO) $(CFLAGS) -DTFTP -c -o $@ $<
- 
- malloc.o: ../common/malloc.c
--	$(CC) $(CFLAGS) -c -o $@ $<
-+	$(CC-SILO) $(CFLAGS) -c -o $@ $<
- 
- util:	util.c
--	$(CC) -DSMALL_RELOC=$(SMALL_RELOC) -DLARGE_RELOC=$(LARGE_RELOC) -o $@ $<
-+	$(BUILD_CC) -DSMALL_RELOC=$(SMALL_RELOC) -DLARGE_RELOC=$(LARGE_RELOC) -o $@ $<
- 
- clean:
- 	$(RM) *.o fs/*.o second* silotftp* util fs/libfs.a
- 
- crt0.o:	crt0.S
--	$(CC) $(CFLAGS) -c -Wa,-Av9 -DIMGVERSION='"SILO$(IMGVERSION)"' crt0.S
-+	$(CC-SILO) $(CFLAGS) -c -Wa,-Av9 -DIMGVERSION='"SILO$(IMGVERSION)"' crt0.S
- 
- memory.o: memory.c
--	$(CC) $(CFLAGS) -c -Wa,-Av9 memory.c
-+	$(CC-SILO) $(CFLAGS) -c -Wa,-Av9 memory.c
- 
- timer.o: timer.c
--	$(CC) $(CFLAGS) -c -Wa,-Av9a timer.c
-+	$(CC-SILO) $(CFLAGS) -c -Wa,-Av9a timer.c
- 
- second.b: second util
- 	$(ELFTOAOUT) -o second.aout second
-diff -Naur silo-1.4.14.orig/second/ls.c silo-1.4.14/second/ls.c
---- silo-1.4.14.orig/second/ls.c	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/second/ls.c	2011-01-10 21:59:35.430765491 -0500
-@@ -19,10 +19,10 @@
-    USA.  */
- 
- #include <silo.h>
-+#include <linux/types.h>
- #include <stringops.h>
- 
- typedef int FILE;
--#include <linux/types.h>
- #include <ext2fs/ext2_fs.h>
- #include <ext2fs/ext2fs.h>
- 
-diff -Naur silo-1.4.14.orig/silo/silo.c silo-1.4.14/silo/silo.c
---- silo-1.4.14.orig/silo/silo.c	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/silo/silo.c	2011-01-10 21:59:35.430765491 -0500
-@@ -128,8 +128,8 @@
-     unsigned short nsect;	/* Sectors per track */
-     unsigned char spare3[4];	/* Even more magic... */
-     struct sun_partition {
--	unsigned long start_cylinder;
--	unsigned long num_sectors;
-+	unsigned int start_cylinder;
-+	unsigned int num_sectors;
-     } partitions[8];
-     unsigned short magic;	/* Magic number */
-     unsigned short csum;	/* Label xor'd checksum */
-diff -Naur silo-1.4.14.orig/silo/silocheck.c silo-1.4.14/silo/silocheck.c
---- silo-1.4.14.orig/silo/silocheck.c	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/silo/silocheck.c	2011-01-10 21:59:35.430765491 -0500
-@@ -101,8 +101,8 @@
-     unsigned short nsect;	/* Sectors per track */
-     unsigned char spare3[4];	/* Even more magic... */
-     struct sun_partition {
--	unsigned long start_cylinder;
--	unsigned long num_sectors;
-+	unsigned int start_cylinder;
-+	unsigned int num_sectors;
-     } partitions[8];
-     unsigned short magic;	/* Magic number */
-     unsigned short csum;	/* Label xor'd checksum */
-diff -Naur silo-1.4.14.orig/tilo/Makefile silo-1.4.14/tilo/Makefile
---- silo-1.4.14.orig/tilo/Makefile	2008-06-12 12:39:12.000000000 -0400
-+++ silo-1.4.14/tilo/Makefile	2011-01-10 21:59:35.430765491 -0500
-@@ -14,10 +14,10 @@
- all: maketilo
- 
- .c.o:
--	$(CC) $(CFLAGS) -c $*.c
-+	$(CC-SILO) $(CFLAGS) -c $*.c
- 
- .S.o:
--	$(CC) $(CFLAGS) -c $*.S
-+	$(CC-SILO) $(CFLAGS) -c $*.S
- 
- OBJS_COMMON = ../common/printf.o ../common/jmp.o ../common/prom.o \
- 	../common/tree.o ../common/console.o ../common/stringops1.o \
-@@ -45,19 +45,19 @@
- 
- 
- mallocl.o: ../common/malloc.c
--	$(CC) $(CFLAGS) -DMALLOC_BASE=0x4D0000 -c -o $@ $<
-+	$(CC-SILO) $(CFLAGS) -DMALLOC_BASE=0x4D0000 -c -o $@ $<
- 
- malloc.o: ../common/malloc.c
--	$(CC) $(CFLAGS) -DMALLOC_BASE=0x3D0000 -c -o $@ $<
-+	$(CC-SILO) $(CFLAGS) -DMALLOC_BASE=0x3D0000 -c -o $@ $<
- 
- tilol.o: tilo.c
--	$(CC) $(CFLAGS) -DLARGETILO -c -o $@ $<
-+	$(CC-SILO) $(CFLAGS) -DLARGETILO -c -o $@ $<
- 
- crt0.o:	crt0.S
--	$(CC) $(CFLAGS) -c -Wa,-Av9 -o $@ $<
-+	$(CC-SILO) $(CFLAGS) -c -Wa,-Av9 -o $@ $<
- 
- crt0l.o: crt0.S
--	$(CC) $(CFLAGS) -c -Wa,-Av9 -DLARGETILO -o $@ $<
-+	$(CC-SILO) $(CFLAGS) -c -Wa,-Av9 -DLARGETILO -o $@ $<
- 
- clean:
- 	$(RM) *.o boot boot2 *.out b.h b2.h maketilo
Index: patches/silo-1.4.14-fixes-3.patch
===================================================================
--- patches/silo-1.4.14-fixes-3.patch	(revision 711fda6399a27324c9ead48533f16ba15b862cc1)
+++ patches/silo-1.4.14-fixes-3.patch	(revision 711fda6399a27324c9ead48533f16ba15b862cc1)
@@ -0,0 +1,1216 @@
+diff -Naur silo-1.4.14.orig/Rules.make silo-1.4.14/Rules.make
+--- silo-1.4.14.orig/Rules.make	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/Rules.make	2012-09-01 19:14:27.000000000 +0000
+@@ -1,4 +1,4 @@
+-VERSION=1.4.14
++VERSION=1.4.14_git20120901
+ IMGVERSION=0.99
+ SHELL=/bin/bash
+ RM=rm -f
+@@ -18,8 +18,8 @@
+ 		> /dev/null 2>&1; then echo "y"; else echo "n"; fi;)
+ 
+ CFLAGS = -Os -Wall -I. -I../include -fomit-frame-pointer \
+-	-fno-strict-aliasing -DSMALL_RELOC=$(SMALL_RELOC) \
+-	-DLARGE_RELOC=$(LARGE_RELOC)
++	-fno-strict-aliasing -U_FORTIFY_SOURCE \
++        -DSMALL_RELOC=$(SMALL_RELOC) -DLARGE_RELOC=$(LARGE_RELOC)
+ 
+ ifeq ($(call cc-option-yn, -fno-stack-protector),y)
+ CFLAGS += -fno-stack-protector
+diff -Naur silo-1.4.14.orig/common/.gitignore silo-1.4.14/common/.gitignore
+--- silo-1.4.14.orig/common/.gitignore	1970-01-01 00:00:00.000000000 +0000
++++ silo-1.4.14/common/.gitignore	2012-09-01 19:05:11.000000000 +0000
+@@ -0,0 +1,4 @@
++#
++# Generated files
++#
++bin2h
+diff -Naur silo-1.4.14.orig/common/divdi3.S silo-1.4.14/common/divdi3.S
+--- silo-1.4.14.orig/common/divdi3.S	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/common/divdi3.S	2012-09-01 19:06:01.000000000 +0000
+@@ -20,6 +20,8 @@
+ 	.data
+ 	.align 8
+ 	.globl	__clz_tab
++        .register %g2,#scratch
++        .register %g3,#scratch
+ __clz_tab:
+ 	.byte	0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
+ 	.byte	6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
+diff -Naur silo-1.4.14.orig/common/malloc.c silo-1.4.14/common/malloc.c
+--- silo-1.4.14.orig/common/malloc.c	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/common/malloc.c	2012-09-01 19:05:11.000000000 +0000
+@@ -18,6 +18,8 @@
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+    USA.  */
+ 
++#include <stringops.h>
++
+ #ifndef MALLOC_BASE
+ extern unsigned long _start;
+ static char *malloc_ptr = ((char *)&_start) + 0x30000;
+@@ -27,6 +29,12 @@
+ 
+ static char *last_alloc = 0;
+ 
++static char *align_ptr_to(char *ptr, unsigned long align)
++{
++    return (char *) ((((unsigned long) ptr) + (align - 1UL)) &
++		     ~(align - 1UL));
++}
++
+ void *malloc (int size)
+ {
+     char *caddr;
+@@ -34,10 +42,51 @@
+     caddr = malloc_ptr;
+     malloc_ptr += size;
+     last_alloc = caddr;
+-    malloc_ptr = (char *) ((((unsigned long) malloc_ptr) + 7) & (~7));
++    malloc_ptr = align_ptr_to(malloc_ptr, 8UL);
+     return caddr;
+ }
+ 
++void *calloc (int nmemb, int memb_size)
++{
++    char *ret;
++    int size;
++
++    if (!nmemb || !memb_size)
++        return (void *) 0;
++
++    size = nmemb * memb_size;
++    ret = malloc(size);
++
++    if (ret)
++        memset(ret, 0, size);
++
++    return ret;
++}
++
++int posix_memalign(void **memptr, unsigned long alignment, unsigned long size)
++{
++    char *caddr;
++
++    if (alignment & (alignment - 1UL))
++        return -1;
++    if (alignment & (sizeof(void *) - 1UL))
++        return -1;
++
++    if (size == 0) {
++      *memptr = (void *) 0;
++      return 0;
++    }
++
++    caddr = align_ptr_to(malloc_ptr, alignment);
++    malloc_ptr = (caddr + size);
++    last_alloc = caddr;
++    malloc_ptr = align_ptr_to(malloc_ptr, 8UL);
++
++    *memptr = caddr;
++
++    return 0;
++}
++
+ void free (void *m)
+ {
+     if (m == last_alloc)
+diff -Naur silo-1.4.14.orig/common/printf.c silo-1.4.14/common/printf.c
+--- silo-1.4.14.orig/common/printf.c	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/common/printf.c	2012-09-01 19:05:11.000000000 +0000
+@@ -21,6 +21,7 @@
+    USA.  */
+ 
+ #include "promlib.h"
++#include <stringops.h>
+ 
+ /*
+  * This part is rewritten by Igor Timkin <ivt@msu.su>. Than I
+@@ -147,3 +148,91 @@
+     vprintf (fmt, x1);
+     va_end (x1);
+ }
++
++static int sprintn (char *str, long long n, int b)
++{
++    static char prbuf[33];
++    register char *cp;
++    int count = 0;
++
++    if (b == 10 && n < 0) {
++	memset (str + count, '-', 1);
++	count++;
++	n = -n;
++    }
++    cp = prbuf;
++    do
++	*cp++ = "0123456789ABCDEF"[(unsigned int) (((unsigned long)n) % b)];
++    while ((n = ((unsigned long long)n) / b & 0x0FFFFFFFFFFFFFFFULL));
++    do {
++	memset (str + count, *--cp, 1);
++	count++;
++    } while (cp > prbuf);
++
++    return count;
++}
++
++int vsprintf (char *str, char *fmt, va_list adx)
++{
++    register int c;
++    char *s;
++    int count = 0;
++
++    for (;;) {
++	while ((c = *fmt++) != '%') {
++	    memset (str + count, c, 1);
++	    if (c == '\0') {
++		return count;
++	    }
++	}
++	c = *fmt++;
++	if (c == 'd' || c == 'o' || c == 'x' || c == 'X') {
++	    count += sprintn (str + count, (long long) va_arg (adx, unsigned),
++			     c == 'o' ? 8 : (c == 'd' ? 10 : 16));
++	} else if (c == 'c') {
++	    memset (str + count, va_arg (adx, unsigned), 1);
++	    count++;
++	} else if (c == 's') {
++	    if ((s = va_arg (adx, char *)) == NULL)
++		s = (char *)"(null)";
++	    while ((c = *s++)) {
++		memset (str + count, c, 1);
++		count++;
++	    }
++	} else if (c == 'l' || c == 'O') {
++	    count += sprintn (str + count, (long long) va_arg (adx, long), c == 'l' ? 10 : 8);
++	} else if (c == 'L') {
++	    int hex = 0;
++	    if (*fmt == 'x') {
++		fmt++;
++		hex = 1;
++	    }
++	    count += sprintn (str + count, (long long) va_arg (adx, long long), hex ? 16 : 10);
++	} else {
++	    /* This is basically what libc's printf does */
++	    memset (str + count, '%', 1);
++	    count++;
++	    memset (str + count, c, 1);
++	    count++;
++	}
++    }
++
++    return count;
++}
++
++/*
++ * Scaled down version of C Library sprintf.
++ * Only %c %s %d (==%u) %o %x %X %l %O are recognized.
++ */
++
++int sprintf (char *s, char *format, ...)
++{
++    va_list arg;
++    int done;
++
++    va_start (arg, format);
++    done = vsprintf (s, format, arg);
++    va_end (arg);
++
++    return done;
++}
+diff -Naur silo-1.4.14.orig/common/udivdi3.S silo-1.4.14/common/udivdi3.S
+--- silo-1.4.14.orig/common/udivdi3.S	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/common/udivdi3.S	2012-09-01 19:09:16.000000000 +0000
+@@ -20,6 +20,8 @@
+ 	.text
+ 	.align 4
+ 	.globl __udivdi3
++        .register %g2,#scratch
++        .register %g3,#scratch
+ __udivdi3:
+ 	save %sp,-104,%sp
+ 	mov %i3,%o3
+diff -Naur silo-1.4.14.orig/first/.gitignore silo-1.4.14/first/.gitignore
+--- silo-1.4.14.orig/first/.gitignore	1970-01-01 00:00:00.000000000 +0000
++++ silo-1.4.14/first/.gitignore	2012-09-01 19:05:11.000000000 +0000
+@@ -0,0 +1,16 @@
++#
++# Generated files
++#
++fd
++fd.b
++fd.h
++first
++first.b
++first.h
++generic
++generic.b
++generic.h
++ieee32.b
++ultra
++ultra.b
++ultra.h
+diff -Naur silo-1.4.14.orig/first-isofs/.gitignore silo-1.4.14/first-isofs/.gitignore
+--- silo-1.4.14.orig/first-isofs/.gitignore	1970-01-01 00:00:00.000000000 +0000
++++ silo-1.4.14/first-isofs/.gitignore	2012-09-01 19:05:11.000000000 +0000
+@@ -0,0 +1,5 @@
++#
++# Generated files
++#
++isofs
++isofs.b
+diff -Naur silo-1.4.14.orig/include/ext2fs/ext2fs.h silo-1.4.14/include/ext2fs/ext2fs.h
+--- silo-1.4.14.orig/include/ext2fs/ext2fs.h	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/include/ext2fs/ext2fs.h	2012-09-01 19:05:11.000000000 +0000
+@@ -39,7 +39,7 @@
+  */
+ #define EXT2_LIB_CURRENT_REV	0
+ 
+-#ifdef HAVE_SYS_TYPES_H
++#if defined(HAVE_SYS_TYPES_H)
+ #include <sys/types.h>
+ #endif
+ 
+diff -Naur silo-1.4.14.orig/include/silo.h silo-1.4.14/include/silo.h
+--- silo-1.4.14.orig/include/silo.h	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/include/silo.h	2012-09-01 19:05:11.000000000 +0000
+@@ -87,6 +87,8 @@
+ void silo_disk_close(void);
+ /* printf.c */
+ int vprintf (char *, va_list);
++int vsprintf (char *str, char *fmt, va_list adx);
++int sprintf (char *s, char *format, ...);
+ int putchar (int);
+ /* malloc.c */
+ void *malloc (int);
+@@ -123,6 +125,7 @@
+ int decompress (char *, char *, unsigned char (*)(void), void (*)(void));
+ /* main.c */
+ extern enum arch architecture;
++extern int sun4v_cpu;
+ /* timer.c */
+ int init_timer ();
+ void close_timer ();
+diff -Naur silo-1.4.14.orig/include/stringops.h silo-1.4.14/include/stringops.h
+--- silo-1.4.14.orig/include/stringops.h	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/include/stringops.h	2012-09-01 19:05:11.000000000 +0000
+@@ -2,14 +2,13 @@
+ #define __STRINGOPS_H
+ 
+ #include <silo.h>
++#include <stddef.h>
+ 
+ /* common */
+ #ifndef __SIZE_TYPE__
+ #define __SIZE_TYPE__ long unsigned int
+ #endif
+-#ifndef _LINUX_TYPES_H
+ typedef __SIZE_TYPE__ size_t;
+-#endif
+ 
+ /* stringops1.c */
+ char *strcpy(char *, const char *);
+diff -Naur silo-1.4.14.orig/second/.gitignore silo-1.4.14/second/.gitignore
+--- silo-1.4.14.orig/second/.gitignore	1970-01-01 00:00:00.000000000 +0000
++++ silo-1.4.14/second/.gitignore	2012-09-01 19:05:11.000000000 +0000
+@@ -0,0 +1,12 @@
++#
++# Generated files
++#
++second
++second.b
++second.b2
++second2
++silotftp
++silotftp.b
++silotftp.b2
++silotftp2
++util
+diff -Naur silo-1.4.14.orig/second/Makefile silo-1.4.14/second/Makefile
+--- silo-1.4.14.orig/second/Makefile	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/second/Makefile	2012-09-01 19:05:11.000000000 +0000
+@@ -58,13 +58,13 @@
+ 	$(AR) rc $@ $(FS_OBJS)
+ 
+ second: $(OBJS) mark.o
+-	$(LD) $(LDFLAGS_SMALL) -Bstatic -o second $(OBJS) -lext2fs mark.o
+-	$(LD) $(LDFLAGS_LARGE) -Bstatic -o second2 $(OBJS) -lext2fs mark.o
++	$(LD) $(LDFLAGS_SMALL) -Bstatic -o second $(OBJS) mark.o `$(CC) -print-libgcc-file-name`
++	$(LD) $(LDFLAGS_LARGE) -Bstatic -o second2 $(OBJS) mark.o `$(CC) -print-libgcc-file-name`
+ 	$(NM) second | grep -v '*ABS*' | sort > second.map
+ 
+ silotftp: $(OBJSNET) mark.o
+-	$(LD) $(LDFLAGS_SMALL) -Bstatic -o silotftp $(OBJSNET) -lext2fs mark.o
+-	$(LD) $(LDFLAGS_LARGE) -Bstatic -o silotftp2 $(OBJSNET) -lext2fs mark.o
++	$(LD) $(LDFLAGS_SMALL) -Bstatic -o silotftp $(OBJSNET) mark.o `$(CC) -print-libgcc-file-name`
++	$(LD) $(LDFLAGS_LARGE) -Bstatic -o silotftp2 $(OBJSNET) mark.o `$(CC) -print-libgcc-file-name`
+ 	$(NM) silotftp | grep -v '*ABS*' | sort > silotftp.map
+ 
+ second.l: second
+diff -Naur silo-1.4.14.orig/second/file.c silo-1.4.14/second/file.c
+--- silo-1.4.14.orig/second/file.c	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/second/file.c	2012-09-01 19:05:11.000000000 +0000
+@@ -19,6 +19,7 @@
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+    USA.  */
+ 
++#include <sys/types.h>
+ #include <silo.h>
+ #include <file.h>
+ #include <stringops.h>
+diff -Naur silo-1.4.14.orig/second/fs/ext2.c silo-1.4.14/second/fs/ext2.c
+--- silo-1.4.14.orig/second/fs/ext2.c	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/second/fs/ext2.c	2012-09-01 19:05:11.000000000 +0000
+@@ -3,6 +3,7 @@
+    Copyright (C) 1996 Maurizio Plaza
+    		 1996,1997,1999 Jakub Jelinek
+ 		 2001 Ben Collins
++		 2012 David S. Miller
+    
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+@@ -27,118 +28,654 @@
+ static ino_t inode = 0;
+ struct fs_ops ext2_fs_ops;
+ 
+-void com_err (const char *a, long i, const char *fmt,...)
++#define EXT2_SUPER_MAGIC	0xEF53
++
++static __u32 ext2_to_cpu_32(__u32 v)
+ {
+-    printf ((char *) fmt);
++	const __u8 *p = (const __u8 *) &v;
++
++	return ((__u32)p[3] << 24 |
++		(__u32)p[2] << 16 |
++		(__u32)p[1] <<  8 |
++		(__u32)p[0]);
+ }
+ 
+-static void ext2fs_error (int errcode)
++static __u16 ext2_to_cpu_16(__u16 v)
+ {
+-#if 0
+-    int i;
+-    for (i = 0; i < sizeof (ext2errors) / sizeof (ext2errors[0]); i++)
+-    	if (ext2errors[i].errnum == errcode) {
+-    	    printf ("%s", ext2errors [i].desc);
+-    	    return;
+-    	}
+-#endif
+-    printf ("Unknown ext2 error: %d", errcode);
++	const __u8 *p = (const __u8 *) &v;
++
++	return ((__u16)p[1] << 8) | ((__u16)p[0]);
+ }
+ 
+-static int open_ext2 (char *device)
++struct silo_ext2_state {
++	struct ext2_super_block	*super;
++
++	void			*scratch_block[4];
++	__u32			scratch_block_blk[4];
++
++	__u32			inode_size;
++	__u32			block_size;
++	__u32			addr_per_block;
++	__u32			addr_per_block_bits;
++	__u32			desc_per_block;
++	__u32			desc_per_block_bits;
++};
++static struct silo_ext2_state *sstate;
++
++static __u32 ext2_inode_size(struct silo_ext2_state *s)
+ {
+-    int retval;
++	__u32 rev = ext2_to_cpu_32(s->super->s_rev_level);
+ 
+-    retval = ext2fs_open (device, EXT2_FLAG_DIRTY, 0, 0, silo_io_manager, &fs);
+-    if (retval == EXT2_ET_BAD_MAGIC)
+-        return 0;
+-    if (retval) {
+-        printf ("\n");
+-        ext2fs_error (retval);
+-        printf ("\n");
+-	return 0;
+-    }
+-    root = EXT2_ROOT_INO;
+-    return 1;
++	if (rev == 0)
++		return 128;
++
++	return ext2_to_cpu_16(s->super->s_inode_size);
+ }
+ 
+-static int dump_block_ext2 (ext2_filsys fs, blk_t *blocknr,
+-			    int blockcnt, void *private)
++static __u32 ext2_block_size(struct silo_ext2_state *s)
+ {
+-    return dump_block(blocknr, blockcnt);
++	__u32 x = ext2_to_cpu_32(s->super->s_log_block_size);
++
++	x += 1;
++
++	return ((__u32) 1 << x) * 512;
+ }
+ 
+-static int dump_ext2 (void)
++static void read_scratch_block(struct silo_ext2_state *s, __u32 block, int N)
+ {
+-    if (ext2fs_block_iterate (fs, inode, 0, 0, dump_block_ext2, 0))
++	if (s->scratch_block_blk[N] == block)
++		return;
++	io_channel_read_blk(fs->io, block, 1, s->scratch_block[N]);
++	s->scratch_block_blk[N] = block;
++}
++
++static void read_data(struct silo_ext2_state *s, __u32 block, __u32 off, __u32 len, void *buf)
++{
++	read_scratch_block(s, block, 0);
++	memcpy(buf, s->scratch_block[0] + off, len);
++}
++
++static int has_extents(struct ext2_inode *ip)
++{
++	if (ext2_to_cpu_32(ip->i_flags) & 0x80000)
++		return 1;
+ 	return 0;
++}
++
++#define EXT4_EXT_MAGIC		0xf30a
++
++struct ext4_extent_header {
++	__u16	eh_magic;
++	__u16	eh_entries;
++	__u16	eh_max;
++	__u16	eh_depth;
++	__u32	eh_generation;
++};
++
++struct ext4_extent_idx {
++	__u32	ei_block;
++	__u32	ei_leaf_lo;
++	__u16	ei_leaf_hi;
++	__u16	ei_unused;
++};
++
++struct ext4_extent {
++	__u32	ee_block;
++	__u16	ee_len;
++	__u16	ee_start_hi;
++	__u32	ee_start_lo;
++};
++
++static struct ext4_extent_header *search_leaf(struct silo_ext2_state *s,
++					      struct ext2_inode *ip,
++					      unsigned long long file_block)
++{
++	struct ext4_extent_header *ehp;
++
++	ehp = (struct ext4_extent_header *) &ip->i_block[0];
++	for (;;) {
++		unsigned long long ext_block, hi, lo;
++		struct ext4_extent_idx *idxp;
++		int i;
++
++		idxp = (struct ext4_extent_idx *) (ehp + 1);
++
++		if (ext2_to_cpu_16(ehp->eh_magic) != EXT4_EXT_MAGIC)
++			return (struct ext4_extent_header *) 0;
++
++		if (ehp->eh_depth == ext2_to_cpu_16(0))
++			return ehp;
++
++		for (i = 0; i < ext2_to_cpu_16(ehp->eh_entries); i++, idxp++)
++			if (file_block < ext2_to_cpu_32(idxp->ei_block))
++				break;
++
++		if (i == 0)
++			return (struct ext4_extent_header *) 0;
++
++		idxp -= 1;
++
++		hi = ((unsigned long long)ext2_to_cpu_16(idxp->ei_leaf_hi)) << 32;
++		lo = ext2_to_cpu_32(idxp->ei_leaf_lo);
++		ext_block = hi | lo;
++
++		read_scratch_block(s, ext_block, 0);
++		ehp = (struct ext4_extent_header *) s->scratch_block[0];
++	}
++}
++
++#define BLOCK_MAP_ERROR (~0ULL)
++
++static int block_to_path(struct silo_ext2_state *s, struct ext2_inode *ip,
++			 int offsets[4], long file_block)
++{
++	int ptrs_bits = s->addr_per_block_bits;
++	int ptrs = s->addr_per_block;
++	const long direct_blocks = EXT2_NDIR_BLOCKS,
++		indirect_blocks = ptrs,
++		double_blocks = (1 << (ptrs_bits * 2));
++	int n = 0;
++
++	if (file_block < 0) {
++		printf("EXT2: Illegal file block %ld\n", file_block);
++	} else if (file_block < direct_blocks) {
++		offsets[n++] = file_block;
++	} else if ((file_block -= direct_blocks) < indirect_blocks) {
++		offsets[n++] = EXT2_IND_BLOCK;
++		offsets[n++] = file_block;
++	} else if ((file_block -= indirect_blocks) < double_blocks) {
++		offsets[n++] = EXT2_DIND_BLOCK;
++		offsets[n++] = file_block >> ptrs_bits;
++		offsets[n++] = file_block & (ptrs - 1);
++	} else if (((file_block -= double_blocks) >> (ptrs_bits * 2)) < ptrs) {
++		offsets[n++] = EXT2_TIND_BLOCK;
++		offsets[n++] = file_block >> (ptrs_bits * 2);
++		offsets[n++] = (file_block >> ptrs_bits) & (ptrs - 1);
++		offsets[n++] = file_block & (ptrs - 1);
++	} else {
++		printf("EXT2: File block %ld is too big\n", file_block);
++	}
++
++	return n;
++}
++
++static unsigned long long resolve_path(struct silo_ext2_state *s,
++				       struct ext2_inode *ip,
++				       int *offsets, int depth)
++{
++	__u32 *p = ip->i_block + *offsets;
++
++	while (--depth) {
++		__u32 block = ext2_to_cpu_32(*p);
++
++		read_scratch_block(s, block, depth);
++		p = (__u32 *) s->scratch_block[depth] + *++offsets;
++	}
++
++	return ext2_to_cpu_32(*p);
++}
++
++static unsigned long long resolve_extent(struct silo_ext2_state *s,
++					 struct ext4_extent_header *ehp,
++					 unsigned long long file_block)
++{
++	unsigned long long hi, lo;
++	struct ext4_extent *ep;
++	int i;
++
++	ep = (struct ext4_extent *) (ehp + 1);
++
++	for (i = 0; i < ext2_to_cpu_16(ehp->eh_entries); i++, ep++)
++		if (file_block < ext2_to_cpu_32(ep->ee_block))
++			break;
++
++	if (i == 0)
++		return BLOCK_MAP_ERROR;
++
++	ep -= 1;
++	file_block -= ext2_to_cpu_32(ep->ee_block);
++	if (file_block >= ext2_to_cpu_16(ep->ee_len))
++		return BLOCK_MAP_ERROR;
+ 
+-    return dump_finish ();
++	hi = ((unsigned long long)ext2_to_cpu_16(ep->ee_start_hi)) << 32;
++	lo = ext2_to_cpu_32(ep->ee_start_lo);
++
++	return (hi | lo) + file_block;
+ }
+ 
+-static int ls_ext2_proc(struct ext2_dir_entry *dirent, int offset,
+-			int blocksize, char *buf, void *private)
++static unsigned long long file_to_disk_block(struct silo_ext2_state *s,
++					     struct ext2_inode *ip,
++					     unsigned long long file_block)
+ {
+-    struct ext2_inode ino;
+-    int sl = 0, name_len = dirent->name_len & 0xFF;
+-    char name[256], symlink[256];
++	if (has_extents(ip)) {
++		struct ext4_extent_header *ehp = search_leaf(s, ip, file_block);
+ 
+-    strncpy(name, dirent->name, name_len);
+-    name[name_len] = 0;
++		if (ehp)
++			return resolve_extent(s, ehp, file_block);
+ 
+-    if (ext2fs_read_inode(fs, dirent->inode, &ino))
+-	strcpy (name, "--- error ---");
++		printf("EXT2: Extent leaf search for block %d failed\n",
++		       (int) file_block);
+ 
+-    if (LINUX_S_ISLNK (ino.i_mode)) {
+-	sl = 1;
+-	if (ext2fs_inode_data_blocks(fs, &ino)) {
+-	    if (io_channel_read_blk(fs->io, ino.i_block[0], 1, symlink))
+-		ino.i_size = 0;
++		return BLOCK_MAP_ERROR;
+ 	} else {
+-	    strncpy (symlink, (char *)&(ino.i_block[0]),ino.i_size);
++		int depth, offsets[4];
++
++		depth = block_to_path(s, ip, offsets, file_block);
++		if (depth)
++			return resolve_path(s, ip, offsets, depth);
++
++		printf("EXT2: block --> path on block %d failed\n",
++		       (int) file_block);
++
++		return BLOCK_MAP_ERROR;
++	}
++}
++
++static void read_file(struct silo_ext2_state *s, struct ext2_inode *ip,
++		      __u32 off, __u32 len, void *buf)
++{
++	unsigned long long disk_block;
++
++	disk_block = file_to_disk_block(s, ip, off / s->block_size);
++
++	read_scratch_block(s, disk_block, 0);
++	memcpy(buf, s->scratch_block[0] + (off % s->block_size), len);
++}
++
++static void read_group(struct silo_ext2_state *s, __u32 grp_no,
++		       struct ext2_group_desc *grp)
++{
++	__u32 first = ext2_to_cpu_32(s->super->s_first_data_block);
++	__u32 blk, offset;
++
++	blk = first + 1 + (grp_no >> s->desc_per_block_bits);
++	offset = (grp_no & (s->desc_per_block - 1)) * sizeof(*grp);
++
++	read_data(s, blk, offset, sizeof(*grp), grp);
++}
++
++static void read_inode(struct silo_ext2_state *s, __u32 ino, struct ext2_inode *ip)
++{
++	__u32 grp_no, blk_no, inode_in_block, ipg, ipb;
++	struct ext2_super_block *sb = s->super;
++	struct ext2_group_desc gd;
++
++	ipg = ext2_to_cpu_32(sb->s_inodes_per_group);
++
++	grp_no = (ino - 1) / ipg;
++	read_group(s, grp_no, &gd);
++
++	blk_no = (ino - 1) % ipg;
++	inode_in_block = blk_no;
++
++	ipb = s->block_size / s->inode_size;
++	blk_no /= ipb;
++	inode_in_block %= ipb;
++
++	read_data(s,
++		  ext2_to_cpu_32(gd.bg_inode_table) + blk_no,
++		  inode_in_block * s->inode_size,
++		  sizeof(struct ext2_inode), ip);
++}
++
++static int calc_ilog2(__u32 n)
++{
++	int i = 0;
++
++	while ((n >>= 1) != 0)
++		i++;
++
++	return i;
++}
++
++static int open_ext2(char *device)
++{
++	struct silo_ext2_state *s = malloc(sizeof(*s));
++	struct ext2_super_block *sb;
++	int err, i;
++
++	if (!s) {
++		printf("Cannot allocate silo_ext2_state\n");
++		return 0;
++	}
++	memset(s, 0, sizeof(*s));
++
++	fs = malloc(sizeof(*fs));
++	if (!fs) {
++		printf("Cannot allocate ext2_filsys\n");
++		goto out_free_s;
++	}
++	memset(fs, 0, sizeof(*fs));
++	err = silo_io_manager->open(device, 0, &fs->io);
++	if (err) {
++		printf("I/O manager open failed (err=%d)\n", err);
++		goto out_free_fs;
++	}
++	fs->io->app_data = fs;
++
++	sb = s->super = malloc(1024);
++	if (!sb) {
++		printf("Cannot allocate ext2 super block\n");
++		goto out_free_fs;
++	}
++
++	io_channel_set_blksize(fs->io, 1024);
++	err = io_channel_read_blk(fs->io, 1, -1024, sb);
++
++	if (ext2_to_cpu_16(sb->s_magic) != EXT2_SUPER_MAGIC) {
++		printf("EXT2 superblock magic is wrong\n");
++		goto out_free_super;
++	}
++
++	s->inode_size = ext2_inode_size(s);
++	s->block_size = ext2_block_size(s);
++
++	io_channel_set_blksize(fs->io, s->block_size);
++
++	s->addr_per_block = s->block_size / sizeof(__u32);
++	s->addr_per_block_bits = calc_ilog2(s->addr_per_block);
++	s->desc_per_block = s->block_size / sizeof(struct ext2_group_desc);
++	s->desc_per_block_bits = calc_ilog2(s->desc_per_block);
++
++	s->scratch_block[0] = malloc(s->block_size * 4);
++	if (!s->scratch_block[0]) {
++		printf("Cannot allocate ext2 scratch blocks\n");
++		goto out_free_super;
++	}
++	for (i = 1; i < 4; i++)
++		s->scratch_block[i] =
++			s->scratch_block[i - 1] + s->block_size;
++	for (i = 0; i < 4; i++)
++		s->scratch_block_blk[i] = ~(__u32)0;
++
++	root = EXT2_ROOT_INO;
++
++	sstate = s;
++
++	return 1;
++
++out_free_super:
++	free(s->super);
++
++out_free_fs:
++	free(fs);
++	fs = NULL;
++
++out_free_s:
++	free(s);
++	return 0;
++}
++
++void close_ext2 (void)
++{
++	struct silo_ext2_state *s = sstate;
++
++	if (s) {
++		free(s->scratch_block[0]);
++		free(s->super);
++		free(s);
++
++		sstate = (struct silo_ext2_state *) 0;
+ 	}
+-	symlink[ino.i_size] = 0;
+-    }
++}
++
++static int dump_ext2 (void)
++{
++	struct silo_ext2_state *s = sstate;
++	struct ext2_inode ei;
++	long file_offset;
++	int sz, blk_sz;
++	int blk_cnt;
++
++	read_inode(s, inode, &ei);
++
++	sz = ext2_to_cpu_32(ei.i_size);
++	blk_sz = s->block_size;
++
++	blk_cnt = 0;
++	for (file_offset = 0; file_offset < sz; file_offset += blk_sz) {
++		blk_t disk_block;
++
++		disk_block = file_to_disk_block(s, &ei,
++						file_offset / blk_sz);
++		if (disk_block == BLOCK_MAP_ERROR)
++			return 0;
++
++		if (disk_block)
++			dump_block(&disk_block, blk_cnt);
++
++		blk_cnt++;
++	}
++
++	return dump_finish ();
++}
++
++static char *read_symlink(struct silo_ext2_state *s, struct ext2_inode *ip, char *namebuf)
++{
++	__u32 isize = ext2_to_cpu_32(ip->i_size);
++
++	if (isize <= 60)
++		return (char *) &ip->i_block[0];
++
++	read_data(s, ext2_to_cpu_32(ip->i_block[0]), 0, isize, namebuf);
++
++	return namebuf;
++}
++
++static int is_symlink(__u16 mode)
++{
++	if ((mode & 0xf000) == 0xa000)
++		return 1;
++	return 0;
++}
++
++typedef int (*dir_callback_t)(struct silo_ext2_state *, struct ext2_dir_entry_2 *, void *);
++
++static int ls_callback(struct silo_ext2_state *s, struct ext2_dir_entry_2 *dirent, void *priv_data)
++{
++	struct ext2_inode e_ino;
++	char *sym = (char *) 0;
++	char symlink_buf[256];
++
++	read_inode(s, ext2_to_cpu_32(dirent->inode), &e_ino);
++
++	if (is_symlink(ext2_to_cpu_16(e_ino.i_mode)))
++		sym = read_symlink(s, &e_ino, symlink_buf);
++
++	register_silo_inode(ext2_to_cpu_32(e_ino.i_mtime),
++			    ext2_to_cpu_32(e_ino.i_size),
++			    ext2_to_cpu_16(e_ino.i_mode),
++			    ext2_to_cpu_16(e_ino.i_uid),
++			    ext2_to_cpu_16(e_ino.i_gid),
++			    dirent->name, sym);
++	return 0;
++}
++
++static void iterate_dir(struct silo_ext2_state *s, __u32 ino, dir_callback_t cb, void *cb_arg)
++{
++	struct ext2_dir_entry_2 e;
++	struct ext2_inode ei;
++	__u32 off, size;
+ 
+-    register_silo_inode(ino.i_mtime, ino.i_size, ino.i_mode, ino.i_uid,
+-			ino.i_gid, name, sl ? symlink : NULL);
++	read_inode(s, ino, &ei);
++	size = ext2_to_cpu_32(ei.i_size);
+ 
+-    return 0;
++	for (off = 0; off < size; ) {
++		read_file(s, &ei, off, 8, &e);
++
++		if (ext2_to_cpu_16(e.rec_len) == 0)
++			break;
++
++		if (ext2_to_cpu_32(e.inode) == 0 ||
++		    e.name_len == 0) {
++			off += ext2_to_cpu_16(e.rec_len);
++			continue;
++		}
++
++		read_file(s, &ei, off + 8, e.name_len, &e.name[0]);
++		e.name[e.name_len] = 0;
++
++		if (cb(s, &e, cb_arg))
++			break;
++
++		off += ext2_to_cpu_16(e.rec_len);
++	}
+ }
+ 
+ static int ls_ext2 (void)
+ {
+-    return ext2fs_dir_iterate (fs, inode, DIRENT_FLAG_INCLUDE_EMPTY,
+-				 0, ls_ext2_proc, NULL);
++	struct silo_ext2_state *s = sstate;
++
++	iterate_dir(s, inode, ls_callback, 0);
++
++	return 0;
++}
++
++static int ino_size_ext2 (void)
++{
++	struct silo_ext2_state *s = sstate;
++	struct ext2_inode ei = { };
++
++	read_inode(s, inode, &ei);
++
++	return ext2_to_cpu_32(ei.i_size);
++}
++
++struct namei_cb_arg {
++	const char	*name;
++	int		len;
++	ino_t		*ino;
++	int		found;
++};
++
++static int lookup_cb(struct silo_ext2_state *s, struct ext2_dir_entry_2 *dirent, void *priv_data)
++{
++	struct namei_cb_arg *p = priv_data;
++
++	if (p->len != dirent->name_len)
++		return 0;
++	if (strncmp(p->name, dirent->name, p->len))
++		return 0;
++	p->found = 1;
++	*p->ino = ext2_to_cpu_32(dirent->inode);
++	return 1;
+ }
+ 
+-static int ino_size_ext2 (void) {
+-    struct ext2_inode ei;
+-    int retval;
++static int do_lookup(struct silo_ext2_state *s, __u32 dir_ino, const char *name,
++		     int namelen, ino_t *ret_ino)
++{
++	struct namei_cb_arg arg;
++
++	arg.name = name;
++	arg.len = namelen;
++	arg.ino = ret_ino;
++	arg.found = 0;
++
++	iterate_dir(s, dir_ino, lookup_cb, &arg);
+ 
+-    if ((retval = ext2fs_read_inode (fs, inode, &ei))) {
+-	printf ("\n");
+-	ext2fs_error (retval);
+-	printf ("\n");
++	return arg.found ? 0 : -1;
++}
++
++static int open_namei(struct silo_ext2_state *s, const char *name,
++		      int namelen, ino_t root, ino_t base, ino_t *ret_ino);
++
++static int follow_link(struct silo_ext2_state *s, ino_t root, ino_t dir,
++		       ino_t inode, ino_t *res_inode)
++{
++	struct ext2_inode ei = { };
++	char symlink_buf[256];
++	char *sym;
++
++	read_inode(s, inode, &ei);
++	if (!is_symlink(ext2_to_cpu_16(ei.i_mode))) {
++		*res_inode = inode;
++		return 0;
++	}
++	sym = read_symlink(s, &ei, symlink_buf);
++	return open_namei(s, sym, ext2_to_cpu_32(ei.i_size), root, dir, res_inode);
++}
++
++static int dir_namei(struct silo_ext2_state *s, ino_t root, ino_t dir,
++		     const char *pathname, int pathlen,
++		     const char **name, int *namelen,
++		     ino_t *res_inode)
++{
++	const char *thisname;
++	int len, retval;
++	ino_t inode;
++	char c;
++
++	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 = do_lookup(s, dir, thisname, len, &inode);
++		if (retval)
++			return retval;
++		retval = follow_link(s, root, dir, inode, &dir);
++		if (retval)
++			return retval;
++	}
++	*name = thisname;
++	*namelen = len;
++	*res_inode = dir;
+ 	return 0;
+-    }
+-    return ei.i_size;
+ }
+ 
+-static int namei_follow_ext2 (const char *filename) {
+-    int ret = ext2fs_namei_follow (fs, root, root, filename, &inode);
++static int open_namei(struct silo_ext2_state *s, const char *name,
++		      int namelen, ino_t root, ino_t base, ino_t *ret_ino)
++{
++	const char *base_name;
++	ino_t dir_ino, inode;
++	int ret;
++
++	ret = dir_namei(s, root, base, name, namelen,
++			&base_name, &namelen, &dir_ino);
++	if (ret)
++		return ret;
++
++	if (!namelen) {
++		*ret_ino = dir_ino;
++		return 0;
++	}
+ 
+-    ext2_fs_ops.have_inode = (inode) ? 1 : 0;
++	ret = do_lookup(s, dir_ino, base_name, namelen, &inode);
++	if (ret)
++		return ret;
++
++	ret = follow_link(s, root, dir_ino, inode, &inode);
++	if (ret)
++		return ret;
+ 
+-    return ret;
++	*ret_ino = inode;
++	return 0;
+ }
+ 
+-static void print_error_ext2 (int error_val) {
+-    ext2fs_error (error_val);
++static int namei_follow_ext2 (const char *filename)
++{
++	int ret;
++
++	ret = open_namei(sstate, filename, strlen(filename),
++			 root, root, &inode);
++
++	ext2_fs_ops.have_inode = inode ? 1 : 0;
++
++	return ret;
+ }
+ 
+-void close_ext2 (void) {
+-    ext2fs_close(fs);
++static void print_error_ext2 (int error_val)
++{
++	printf("error: %d", error_val);
+ }
+ 
+ struct fs_ops ext2_fs_ops = {
+@@ -152,14 +689,3 @@
+     .namei_follow	= namei_follow_ext2,
+     .have_inode		= 0,
+ };
+-
+-/* These are silly stubs to satisfy libext2fs symbols */
+-unsigned long time(void)
+-{
+-        return 0;
+-}
+-
+-void *realloc(void *p, int size)
+-{
+-        return NULL;
+-}
+diff -Naur silo-1.4.14.orig/second/ls.c silo-1.4.14/second/ls.c
+--- silo-1.4.14.orig/second/ls.c	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/second/ls.c	2012-09-01 19:05:11.000000000 +0000
+@@ -18,6 +18,7 @@
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+    USA.  */
+ 
++#include <sys/types.h>
+ #include <silo.h>
+ #include <stringops.h>
+ 
+diff -Naur silo-1.4.14.orig/second/main.c silo-1.4.14/second/main.c
+--- silo-1.4.14.orig/second/main.c	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/second/main.c	2012-09-01 19:05:11.000000000 +0000
+@@ -25,8 +25,7 @@
+ /* TODO: This file is a good candidate for rewrite from scratch.  */
+ 
+ #include <silo.h>
+-#include <asm/page.h>
+-#include <linux/elf.h>
++#include <elf.h>
+ #include <stringops.h>
+ 
+ #ifndef NULL
+@@ -65,6 +64,7 @@
+     CMD_LS
+ } load_cmd;
+ enum arch architecture;
++int sun4v_cpu;
+ static int timer_status = 0;
+ static char *initrd_start;
+ static int initrd_size;
+diff -Naur silo-1.4.14.orig/second/misc.c silo-1.4.14/second/misc.c
+--- silo-1.4.14.orig/second/misc.c	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/second/misc.c	2012-09-01 19:05:11.000000000 +0000
+@@ -501,7 +501,7 @@
+         if ((i = prom_searchsiblings(i, "MicroSPARC-IIep")) != 0) {
+             return sun4p;
+         }
+-        return sun4u;
++	buffer[4] = 'u';
+     }
+     i = prom_getproperty (prom_root_node, "compatability", buffer, 8);
+ 
+@@ -517,8 +517,10 @@
+ 	return sun4d;
+     case 'e':
+ 	return sun4e;
+-    case 'u':
+     case 'v':
++	sun4v_cpu = 1;
++	/* FALLTHRU */
++    case 'u':
+ 	return sun4u;
+     default:
+     	for(i = 0; i < NUM_SUN_MACHINES; i++)
+diff -Naur silo-1.4.14.orig/second/muldi3.S silo-1.4.14/second/muldi3.S
+--- silo-1.4.14.orig/second/muldi3.S	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/second/muldi3.S	2012-09-01 19:11:45.000000000 +0000
+@@ -20,6 +20,8 @@
+ 	.text
+ 	.align 4
+ 	.globl __muldi3
++        .register %g2,#scratch
++        .register %g3,#scratch
+ __muldi3:
+ 	save  %sp, -104, %sp
+ 	wr  %g0, %i1, %y
+diff -Naur silo-1.4.14.orig/second/timer.c silo-1.4.14/second/timer.c
+--- silo-1.4.14.orig/second/timer.c	2008-06-12 16:39:12.000000000 +0000
++++ silo-1.4.14/second/timer.c	2012-09-01 19:05:11.000000000 +0000
+@@ -156,7 +156,7 @@
+     }
+     if (!foundcpu || !clock_frequency)
+         clock_frequency = prom_getint(prom_root_node, "clock-frequency") / 100;
+-    if (notimer) {
++    if (notimer && !sun4v_cpu) {
+         sun4u_notimer = 1;
+         __asm__ __volatile__ ("\t"
+         	"rd	%%tick_cmpr, %%g1\n\t"
+diff -Naur silo-1.4.14.orig/silo/.gitignore silo-1.4.14/silo/.gitignore
+--- silo-1.4.14.orig/silo/.gitignore	1970-01-01 00:00:00.000000000 +0000
++++ silo-1.4.14/silo/.gitignore	2012-09-01 19:05:11.000000000 +0000
+@@ -0,0 +1,6 @@
++#
++# Generated files
++#
++floppy.h
++silo
++silocheck
+diff -Naur silo-1.4.14.orig/tilo/.gitignore silo-1.4.14/tilo/.gitignore
+--- silo-1.4.14.orig/tilo/.gitignore	1970-01-01 00:00:00.000000000 +0000
++++ silo-1.4.14/tilo/.gitignore	2012-09-01 19:05:11.000000000 +0000
+@@ -0,0 +1,10 @@
++#
++# Generated files
++#
++b.h
++b.out
++b2.h
++b2.out
++boot
++boot2
++maketilo
