[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/Makefile.in b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/Makefile.in
new file mode 100644
index 0000000..87678c6
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/Makefile.in
@@ -0,0 +1,974 @@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+top_builddir = ../..
+my_dir = lib/ext2fs
+INSTALL = @INSTALL@
+
+@MCONFIG@
+
+@DEBUGFS_CMT@DEBUGFS_LIB_OBJS = bb_compat.o inode_io.o write_bb_file.o
+
+MK_CMDS=	_SS_DIR_OVERRIDE=../ss ../ss/mk_cmds
+
+@RESIZER_CMT@RESIZE_LIB_OBJS = dupfs.o
+@TEST_IO_CMT@TEST_IO_LIB_OBJS = test_io.o
+@IMAGER_CMT@E2IMAGE_LIB_OBJS = imager.o
+
+OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
+	$(TEST_IO_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 \
+	blkmap64_ba.o \
+	blkmap64_rb.o \
+	blknum.o \
+	block.o \
+	bmap.o \
+	check_desc.o \
+	closefs.o \
+	crc16.o \
+	crc32c.o \
+	csum.o \
+	dblist.o \
+	dblist_dir.o \
+	dirblock.o \
+	dirhash.o \
+	dir_iterate.o \
+	expanddir.o \
+	ext_attr.o \
+	extent.o \
+	fileio.o \
+	finddev.o \
+	flushb.o \
+	freefs.o \
+	gen_bitmap.o \
+	gen_bitmap64.o \
+	get_pathname.o \
+	getsize.o \
+	getsectsize.o \
+	i_block.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 \
+	mmp.o \
+	namei.o \
+	native.o \
+	newdir.o \
+	openfs.o \
+	progress.o \
+	punch.o \
+	qcow2.o \
+	read_bb.o \
+	read_bb_file.o \
+	res_gdt.o \
+	rw_bitmaps.o \
+	swapfs.o \
+	symlink.o \
+	tdb.o \
+	undo_io.o \
+	unix_io.o \
+	unlink.o \
+	valid_blk.o \
+	version.o \
+	rbtree.o
+
+SRCS= ext2_err.c \
+	$(srcdir)/alloc.c \
+	$(srcdir)/alloc_sb.c \
+	$(srcdir)/alloc_stats.c \
+	$(srcdir)/alloc_tables.c \
+	$(srcdir)/badblocks.c \
+	$(srcdir)/bb_compat.c \
+	$(srcdir)/bb_inode.c \
+	$(srcdir)/bitmaps.c \
+	$(srcdir)/bitops.c \
+	$(srcdir)/blkmap64_ba.c \
+	$(srcdir)/blkmap64_rb.c \
+	$(srcdir)/block.c \
+	$(srcdir)/bmap.c \
+	$(srcdir)/check_desc.c \
+	$(srcdir)/closefs.c \
+	$(srcdir)/crc16.c \
+	$(srcdir)/crc32c.c \
+	$(srcdir)/gen_crc32ctable.c \
+	$(srcdir)/csum.c \
+	$(srcdir)/dblist.c \
+	$(srcdir)/dblist_dir.c \
+	$(srcdir)/dirblock.c \
+	$(srcdir)/dirhash.c \
+	$(srcdir)/dir_iterate.c \
+	$(srcdir)/dupfs.c \
+	$(srcdir)/expanddir.c \
+	$(srcdir)/ext_attr.c \
+	$(srcdir)/extent.c \
+	$(srcdir)/fileio.c \
+	$(srcdir)/finddev.c \
+	$(srcdir)/flushb.c \
+	$(srcdir)/freefs.c \
+	$(srcdir)/gen_bitmap.c \
+	$(srcdir)/gen_bitmap64.c \
+	$(srcdir)/get_pathname.c \
+	$(srcdir)/getsize.c \
+	$(srcdir)/getsectsize.c \
+	$(srcdir)/i_block.c \
+	$(srcdir)/icount.c \
+	$(srcdir)/ind_block.c \
+	$(srcdir)/initialize.c \
+	$(srcdir)/inline.c \
+	$(srcdir)/inode.c \
+	$(srcdir)/inode_io.c \
+	$(srcdir)/imager.c \
+	$(srcdir)/io_manager.c \
+	$(srcdir)/ismounted.c \
+	$(srcdir)/link.c \
+	$(srcdir)/llseek.c \
+	$(srcdir)/lookup.c \
+	$(srcdir)/mkdir.c \
+	$(srcdir)/mkjournal.c \
+	$(srcdir)/mmp.c	\
+	$(srcdir)/namei.c \
+	$(srcdir)/native.c \
+	$(srcdir)/newdir.c \
+	$(srcdir)/openfs.c \
+	$(srcdir)/progress.c \
+	$(srcdir)/punch.c \
+	$(srcdir)/qcow2.c \
+	$(srcdir)/read_bb.c \
+	$(srcdir)/read_bb_file.c \
+	$(srcdir)/res_gdt.c \
+	$(srcdir)/rw_bitmaps.c \
+	$(srcdir)/swapfs.c \
+	$(srcdir)/symlink.c \
+	$(srcdir)/tdb.c \
+	$(srcdir)/test_io.c \
+	$(srcdir)/tst_badblocks.c \
+	$(srcdir)/tst_bitops.c \
+	$(srcdir)/tst_byteswap.c \
+	$(srcdir)/tst_getsize.c \
+	$(srcdir)/tst_iscan.c \
+	$(srcdir)/undo_io.c \
+	$(srcdir)/unix_io.c \
+	$(srcdir)/unlink.c \
+	$(srcdir)/valid_blk.c \
+	$(srcdir)/version.c \
+	$(srcdir)/write_bb_file.c \
+	$(srcdir)/rbtree.c \
+
+HFILES= bitops.h ext2fs.h ext2_io.h ext2_fs.h ext2_ext_attr.h ext3_extents.h \
+	tdb.h qcow2.h
+HFILES_IN=  ext2_err.h ext2_types.h
+
+LIBRARY= libext2fs
+LIBDIR= ext2fs
+
+ELF_VERSION = 2.4
+ELF_SO_VERSION = 2
+ELF_IMAGE = libext2fs
+ELF_MYDIR = ext2fs
+ELF_INSTALL_DIR = $(root_libdir)
+ELF_OTHER_LIBS = -lcom_err
+
+BSDLIB_VERSION = 2.1
+BSDLIB_IMAGE = libext2fs
+BSDLIB_MYDIR = ext2fs
+BSDLIB_INSTALL_DIR = $(root_libdir)
+
+@MAKEFILE_LIBRARY@
+@MAKEFILE_ELF@
+@MAKEFILE_BSDLIB@
+@MAKEFILE_PROFILE@
+@MAKEFILE_CHECKER@
+
+all:: ext2fs.pc
+
+.c.o:
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+	$(Q) $(CHECK_CMD) $(ALL_CFLAGS) $<
+@PROFILE_CMT@	$(Q) $(CC) $(ALL_CFLAGS) -g -pg -o profiled/$*.o -c $<
+@CHECKER_CMT@	$(Q) $(CC) $(ALL_CFLAGS) -checker -g -o checker/$*.o -c $<
+@ELF_CMT@	$(Q) $(CC) $(ALL_CFLAGS) -fPIC -o elfshared/$*.o -c $<
+@BSDLIB_CMT@	$(Q) $(CC) $(ALL_CFLAGS) $(BSDLIB_PIC_FLAG) -o pic/$*.o -c $<
+
+COMPILE_ET=../et/compile_et --build-tree
+
+DISTFILES= Makefile *.c *.h image
+
+ext2_err.et: $(DEP_SUBSTITUTE) $(srcdir)/ext2_err.et.in
+	$(E) "	SUBST $@"
+	$(Q) $(SUBSTITUTE) $(srcdir)/ext2_err.et.in ext2_err.et
+
+ext2_err.c ext2_err.h: ext2_err.et
+	$(E) "	COMPILE_ET ext2_err.et"
+	$(Q) $(COMPILE_ET) ext2_err.et
+
+ext2fs.pc: $(srcdir)/ext2fs.pc.in $(top_builddir)/config.status
+	$(E) "	CONFIG.STATUS $@"
+	$(Q) cd $(top_builddir); CONFIG_FILES=lib/ext2fs/ext2fs.pc ./config.status
+
+tst_badblocks: tst_badblocks.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_badblocks tst_badblocks.o $(STATIC_LIBEXT2FS) \
+		$(STATIC_LIBCOM_ERR)
+
+tst_icount: $(srcdir)/icount.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_icount $(srcdir)/icount.c -DDEBUG $(ALL_CFLAGS) \
+		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+
+tst_iscan: tst_iscan.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_iscan tst_iscan.o $(STATIC_LIBEXT2FS) \
+		$(STATIC_LIBCOM_ERR)
+
+tst_getsize: tst_getsize.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_getsize tst_getsize.o $(STATIC_LIBEXT2FS) \
+		$(STATIC_LIBCOM_ERR)
+
+tst_ismounted: $(srcdir)/ismounted.c $(STATIC_LIBEXT2FS) \
+		$(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_ismounted $(srcdir)/ismounted.c \
+		$(STATIC_LIBEXT2FS) -DDEBUG $(ALL_CFLAGS) \
+		$(STATIC_LIBCOM_ERR)
+
+tst_byteswap: tst_byteswap.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_byteswap tst_byteswap.o $(STATIC_LIBEXT2FS) \
+		$(STATIC_LIBCOM_ERR)
+
+tst_bitops: tst_bitops.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_bitops tst_bitops.o $(ALL_CFLAGS) \
+		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+
+tst_getsectsize: tst_getsectsize.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_sectgetsize tst_getsectsize.o \
+		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+
+tst_types.o: $(srcdir)/tst_types.c ext2_types.h 
+
+tst_types: tst_types.o ext2_types.h 
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_types tst_types.o 
+
+tst_super_size.o: $(srcdir)/tst_super_size.c $(srcdir)/ext2_fs.h
+
+tst_super_size: tst_super_size.o
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_super_size tst_super_size.o 
+
+tst_fs_struct.o: $(srcdir)/tst_fs_struct.c $(srcdir)/ext2fs.h
+
+tst_fs_struct: tst_fs_struct.o
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_fs_struct tst_fs_struct.o 
+
+tst_inode_size.o: $(srcdir)/tst_inode_size.c $(srcdir)/ext2_fs.h
+
+tst_inode_size: tst_inode_size.o
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_inode_size tst_inode_size.o 
+
+ext2_tdbtool: tdbtool.o
+	$(E) "	LD $@"
+	$(Q) $(CC) -o ext2_tdbtool tdbtool.o tdb.o
+
+extent_dbg.c: $(srcdir)/extent_dbg.ct
+	$(E) "	MK_CMDS $<"
+	$(Q) $(MK_CMDS) $(srcdir)/extent_dbg.ct
+
+debug_cmds.c debug_cmds.h: $(top_srcdir)/debugfs/debug_cmds.ct
+	$(E) "	MK_CMDS $<"
+	$(Q) $(MK_CMDS) $(top_srcdir)/debugfs/debug_cmds.ct
+
+extent_cmds.c extent_cmds.h: $(top_srcdir)/debugfs/extent_cmds.ct
+	$(E) "	MK_CMDS $<"
+	$(Q) $(MK_CMDS) $(top_srcdir)/debugfs/extent_cmds.ct
+
+DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \
+	lsdel.o dump.o set_fields.o logdump.o htree.o unused.o \
+	e2freefrag.o filefrag.o extent_inode.o extent_cmds.o zap.o
+
+debugfs.o: $(top_srcdir)/debugfs/debugfs.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+extent_inode.o: $(top_srcdir)/debugfs/extent_inode.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+util.o: $(top_srcdir)/debugfs/util.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+ncheck.o: $(top_srcdir)/debugfs/ncheck.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+icheck.o: $(top_srcdir)/debugfs/icheck.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+ls.o: $(top_srcdir)/debugfs/ls.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+lsdel.o: $(top_srcdir)/debugfs/lsdel.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+dump.o: $(top_srcdir)/debugfs/dump.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+set_fields.o: $(top_srcdir)/debugfs/set_fields.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+logdump.o: $(top_srcdir)/debugfs/logdump.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+htree.o: $(top_srcdir)/debugfs/htree.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+unused.o: $(top_srcdir)/debugfs/unused.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+zap.o: $(top_srcdir)/debugfs/zap.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+e2freefrag.o: $(top_srcdir)/misc/e2freefrag.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -DDEBUGFS -I$(top_srcdir)/debugfs -c $< -o $@
+
+filefrag.o: $(top_srcdir)/debugfs/filefrag.c
+	$(E) "	CC $<"
+	$(Q) $(CC) $(ALL_CFLAGS) -c $< -o $@
+
+tst_bitmaps_cmd.c: tst_bitmaps_cmd.ct
+	$(E) "	MK_CMDS $@"
+	$(Q) DIR=$(srcdir) $(MK_CMDS) $(srcdir)/tst_bitmaps_cmd.ct
+
+tst_bitmaps: tst_bitmaps.o tst_bitmaps_cmd.o $(STATIC_LIBEXT2FS) \
+		$(DEPSTATIC_LIBSS) $(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o $@ tst_bitmaps.o tst_bitmaps_cmd.o $(ALL_CFLAGS) \
+		$(STATIC_LIBEXT2FS) $(STATIC_LIBSS) $(STATIC_LIBCOM_ERR)
+
+tst_extents: $(srcdir)/extent.c $(DEBUG_OBJS) $(DEPSTATIC_LIBSS) \
+	$(STATIC_LIBE2P) $(DEPLIBUUID) $(DEPLIBBLKID) $(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_extents $(srcdir)/extent.c \
+		$(ALL_CFLAGS) -DDEBUG $(DEBUG_OBJS) $(STATIC_LIBSS) \
+		$(STATIC_LIBE2P) $(STATIC_LIBEXT2FS) $(LIBBLKID) $(LIBUUID) \
+		$(STATIC_LIBCOM_ERR) -I $(top_srcdir)/debugfs
+
+tst_inline: $(srcdir)/inline.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_inline $(srcdir)/inline.c $(ALL_CFLAGS) -DDEBUG \
+		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+
+tst_csum: csum.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR) $(STATIC_LIBE2P) \
+		$(top_srcdir)/lib/e2p/e2p.h
+	$(E) "	LD $@"
+	$(Q) $(CC) -o tst_csum $(srcdir)/csum.c -DDEBUG \
+		$(ALL_CFLAGS) $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) \
+		$(STATIC_LIBE2P)
+
+tst_crc32c: $(srcdir)/crc32c.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
+	$(Q) $(CC) $(BUILD_LDFLAGS) $(ALL_CFLAGS) -o tst_crc32c $(srcdir)/crc32c.c \
+		-DUNITTEST $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+
+mkjournal: mkjournal.c $(STATIC_LIBEXT2FS) $(DEPLIBCOM_ERR)
+	$(E) "	LD $@"
+	$(Q) $(CC) -o mkjournal $(srcdir)/mkjournal.c -DDEBUG $(STATIC_LIBEXT2FS) $(LIBCOM_ERR) $(ALL_CFLAGS)
+
+check:: tst_bitops tst_badblocks tst_iscan tst_types tst_icount \
+    tst_super_size tst_types tst_inode_size tst_csum tst_crc32c tst_bitmaps \
+    tst_inline
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_bitops
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_badblocks
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_iscan
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_types
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_icount
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_super_size
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_inode_size
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_csum
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_inline
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_crc32c
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) \
+		./tst_bitmaps -f $(srcdir)/tst_bitmaps_cmds > tst_bitmaps_out
+	diff $(srcdir)/tst_bitmaps_exp tst_bitmaps_out
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) \
+		./tst_bitmaps -t 2 -f $(srcdir)/tst_bitmaps_cmds > tst_bitmaps_out
+	diff $(srcdir)/tst_bitmaps_exp tst_bitmaps_out
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) \
+		./tst_bitmaps -t 3 -f $(srcdir)/tst_bitmaps_cmds > tst_bitmaps_out
+	diff $(srcdir)/tst_bitmaps_exp tst_bitmaps_out
+	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) \
+		./tst_bitmaps -l -f $(srcdir)/tst_bitmaps_cmds > tst_bitmaps_out
+	diff $(srcdir)/tst_bitmaps_exp tst_bitmaps_out
+
+installdirs::
+	$(E) "	MKINSTALLDIRS $(libdir) $(includedir)/ext2fs"
+	$(Q) $(MKINSTALLDIRS) $(DESTDIR)$(libdir) \
+		$(DESTDIR)$(includedir)/ext2fs $(DESTDIR)$(libdir)/pkgconfig
+
+install:: all $(HFILES) $(HFILES_IN) installdirs ext2fs.pc
+	$(E) "	INSTALL_DATA $(libdir)/libext2fs.a"
+	$(Q) $(INSTALL_DATA) libext2fs.a $(DESTDIR)$(libdir)/libext2fs.a
+	-$(Q) $(RANLIB) $(DESTDIR)$(libdir)/libext2fs.a
+	$(Q) $(CHMOD) $(LIBMODE) $(DESTDIR)$(libdir)/libext2fs.a
+	$(Q) for i in $(HFILES); do \
+		echo "	INSTALL_DATA $(includedir)/ext2fs/$$i"; \
+		$(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir)/ext2fs/$$i; \
+	done
+	$(Q) for i in $(HFILES_IN); do \
+		echo "	INSTALL_DATA $(includedir)/ext2fs/$$i"; \
+		$(INSTALL_DATA) $$i $(DESTDIR)$(includedir)/ext2fs/$$i; \
+	done
+	$(E) "	INSTALL_DATA $(libdir)/pkgconfig/ext2fs.pc"
+	$(Q) $(INSTALL_DATA) ext2fs.pc $(DESTDIR)$(libdir)/pkgconfig/ext2fs.pc
+
+uninstall::
+	$(RM) -f $(DESTDIR)$(libdir)/libext2fs.a \
+		$(DESTDIR)$(libdir)/pkgconfig/ext2fs.pc
+	$(RM) -rf $(DESTDIR)$(includedir)/ext2fs 
+
+clean::
+	$(RM) -f \#* *.s *.o *.a *~ *.bak core profiled/* checker/* \
+		tst_badblocks tst_iscan ext2_err.et ext2_err.c ext2_err.h \
+		tst_byteswap tst_ismounted tst_getsize tst_sectgetsize \
+		tst_bitops tst_types tst_icount tst_super_size tst_csum \
+		tst_bitmaps tst_bitmaps_out tst_extents tst_inline \
+		tst_inline_data tst_inode_size tst_bitmaps_cmd.c \
+		ext2_tdbtool mkjournal debug_cmds.c extent_cmds.c \
+		../libext2fs.a ../libext2fs_p.a ../libext2fs_chk.a \
+		crc32c_table.h gen_crc32ctable tst_crc32c
+
+mostlyclean:: clean
+distclean:: clean
+	$(RM) -f .depend ext2_err.c ext2_err.h Makefile ext2fs.pc \
+		$(srcdir)/TAGS $(srcdir)/Makefile.in.old
+#
+# Hack to parallel makes recognize dependencies correctly.
+#
+$(top_builddir)/lib/ext2fs/ext2_err.h: ext2_err.h
+
+$(OBJS): subdirs
+
+gen_crc32ctable: $(srcdir)/gen_crc32ctable.c
+	$(E) "	CC $@"
+	$(Q) $(BUILD_CC) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o gen_crc32ctable \
+		$(srcdir)/gen_crc32ctable.c
+
+crc32c_table.h: gen_crc32ctable
+	$(E) "	GEN32CTABLE $@"
+	$(Q) ./gen_crc32ctable > crc32c_table.h
+
+# +++ Dependency line eater +++
+# 
+# Makefile dependencies follow.  This must be the last section in
+# the Makefile.in file
+#
+ext2_err.o: ext2_err.c
+alloc.o: $(srcdir)/alloc.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+alloc_sb.o: $(srcdir)/alloc_sb.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+alloc_stats.o: $(srcdir)/alloc_stats.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+alloc_tables.o: $(srcdir)/alloc_tables.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/ext2fsP.h
+badblocks.o: $(srcdir)/badblocks.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+bb_compat.o: $(srcdir)/bb_compat.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+bb_inode.o: $(srcdir)/bb_inode.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+bitmaps.o: $(srcdir)/bitmaps.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/bmap64.h
+bitops.o: $(srcdir)/bitops.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+blkmap64_ba.o: $(srcdir)/blkmap64_ba.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h $(srcdir)/bmap64.h
+blkmap64_rb.o: $(srcdir)/blkmap64_rb.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h $(srcdir)/bmap64.h $(srcdir)/rbtree.h
+block.o: $(srcdir)/block.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+bmap.o: $(srcdir)/bmap.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+check_desc.o: $(srcdir)/check_desc.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+closefs.o: $(srcdir)/closefs.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+crc16.o: $(srcdir)/crc16.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(top_builddir)/lib/ext2fs/ext2_types.h \
+ $(srcdir)/crc16.h
+crc32c.o: $(srcdir)/crc32c.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/crc32c_defs.h $(srcdir)/ext2fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2_fs.h \
+ $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h crc32c_table.h
+gen_crc32ctable.o: $(srcdir)/gen_crc32ctable.c $(srcdir)/crc32c_defs.h
+csum.o: $(srcdir)/csum.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/crc16.h
+dblist.o: $(srcdir)/dblist.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+dblist_dir.o: $(srcdir)/dblist_dir.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+dirblock.o: $(srcdir)/dirblock.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+dirhash.o: $(srcdir)/dirhash.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+dir_iterate.o: $(srcdir)/dir_iterate.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+dupfs.o: $(srcdir)/dupfs.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+expanddir.o: $(srcdir)/expanddir.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+ext_attr.o: $(srcdir)/ext_attr.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+extent.o: $(srcdir)/extent.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h $(srcdir)/e2image.h
+fileio.o: $(srcdir)/fileio.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+finddev.o: $(srcdir)/finddev.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/ext2fsP.h
+flushb.o: $(srcdir)/flushb.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+freefs.o: $(srcdir)/freefs.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+gen_bitmap.o: $(srcdir)/gen_bitmap.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+gen_bitmap64.o: $(srcdir)/gen_bitmap64.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h $(srcdir)/bmap64.h
+get_pathname.o: $(srcdir)/get_pathname.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+getsize.o: $(srcdir)/getsize.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+getsectsize.o: $(srcdir)/getsectsize.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+i_block.o: $(srcdir)/i_block.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+icount.o: $(srcdir)/icount.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/tdb.h
+ind_block.o: $(srcdir)/ind_block.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+initialize.o: $(srcdir)/initialize.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+inline.o: $(srcdir)/inline.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+inode.o: $(srcdir)/inode.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h $(srcdir)/e2image.h
+inode_io.o: $(srcdir)/inode_io.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+imager.o: $(srcdir)/imager.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+io_manager.o: $(srcdir)/io_manager.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+ismounted.o: $(srcdir)/ismounted.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+link.o: $(srcdir)/link.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+llseek.o: $(srcdir)/llseek.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h
+lookup.o: $(srcdir)/lookup.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+mkdir.o: $(srcdir)/mkdir.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+mkjournal.o: $(srcdir)/mkjournal.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/e2p/e2p.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext2fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h $(srcdir)/jfs_user.h $(srcdir)/kernel-jbd.h \
+ $(srcdir)/jfs_compat.h $(srcdir)/kernel-list.h
+mmp.o: $(srcdir)/mmp.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
+namei.o: $(srcdir)/namei.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/ext2fsP.h
+native.o: $(srcdir)/native.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+newdir.o: $(srcdir)/newdir.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+openfs.o: $(srcdir)/openfs.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/e2image.h
+progress.o: $(srcdir)/progress.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2_fs.h \
+ $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h $(srcdir)/ext2fsP.h
+punch.o: $(srcdir)/punch.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+qcow2.o: $(srcdir)/qcow2.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2_fs.h \
+ $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h $(srcdir)/qcow2.h
+read_bb.o: $(srcdir)/read_bb.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+read_bb_file.o: $(srcdir)/read_bb_file.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+res_gdt.o: $(srcdir)/res_gdt.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+rw_bitmaps.o: $(srcdir)/rw_bitmaps.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/e2image.h
+swapfs.o: $(srcdir)/swapfs.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+symlink.o: $(srcdir)/symlink.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+tdb.o: $(srcdir)/tdb.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/tdb.h
+test_io.o: $(srcdir)/test_io.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+tst_badblocks.o: $(srcdir)/tst_badblocks.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+tst_bitops.o: $(srcdir)/tst_bitops.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+tst_byteswap.o: $(srcdir)/tst_byteswap.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+tst_getsize.o: $(srcdir)/tst_getsize.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+tst_iscan.o: $(srcdir)/tst_iscan.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+undo_io.o: $(srcdir)/undo_io.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/tdb.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+unix_io.o: $(srcdir)/unix_io.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+unlink.o: $(srcdir)/unlink.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+valid_blk.o: $(srcdir)/valid_blk.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+version.o: $(srcdir)/version.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(top_srcdir)/version.h
+write_bb_file.o: $(srcdir)/write_bb_file.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+rbtree.o: $(srcdir)/rbtree.c $(srcdir)/rbtree.h
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc.c
new file mode 100644
index 0000000..0c829ed
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc.c
@@ -0,0 +1,335 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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"
+
+/*
+ * Check for uninit block bitmaps and deal with them appropriately
+ */
+static void check_block_uninit(ext2_filsys fs, ext2fs_block_bitmap map,
+			       dgrp_t group)
+{
+	blk_t		i;
+	blk64_t		blk, super_blk, old_desc_blk, new_desc_blk;
+	int		old_desc_blocks;
+
+	if (!(EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) ||
+	    !(ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT)))
+		return;
+
+	blk = ext2fs_group_first_block2(fs, group);
+
+	ext2fs_super_and_bgd_loc2(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;
+
+	for (i=0; i < fs->super->s_blocks_per_group; i++, blk++)
+		ext2fs_fast_unmark_block_bitmap2(map, blk);
+
+	blk = ext2fs_group_first_block2(fs, group);
+	for (i=0; i < fs->super->s_blocks_per_group; i++, blk++) {
+		if ((blk == super_blk) ||
+		    (old_desc_blk && old_desc_blocks &&
+		     (blk >= old_desc_blk) &&
+		     (blk < old_desc_blk + old_desc_blocks)) ||
+		    (new_desc_blk && (blk == new_desc_blk)) ||
+		    (blk == ext2fs_block_bitmap_loc(fs, group)) ||
+		    (blk == ext2fs_inode_bitmap_loc(fs, group)) ||
+		    (blk >= ext2fs_inode_table_loc(fs, group) &&
+		     (blk < ext2fs_inode_table_loc(fs, group)
+		      + fs->inode_blocks_per_group)))
+			ext2fs_fast_mark_block_bitmap2(map, blk);
+	}
+	ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
+	ext2fs_group_desc_csum_set(fs, group);
+	ext2fs_mark_super_dirty(fs);
+	ext2fs_mark_bb_dirty(fs);
+}
+
+/*
+ * Check for uninit inode bitmaps and deal with them appropriately
+ */
+static void check_inode_uninit(ext2_filsys fs, ext2fs_inode_bitmap map,
+			  dgrp_t group)
+{
+	ext2_ino_t	i, ino;
+
+	if (!(EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) ||
+	    !(ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT)))
+		return;
+
+	ino = (group * fs->super->s_inodes_per_group) + 1;
+	for (i=0; i < fs->super->s_inodes_per_group; i++, ino++)
+		ext2fs_fast_unmark_inode_bitmap2(map, ino);
+
+	ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
+	ext2fs_group_desc_csum_set(fs, group);
+	ext2fs_mark_ib_dirty(fs);
+	ext2fs_mark_super_dirty(fs);
+	check_block_uninit(fs, fs->block_map, group);
+}
+
+/*
+ * 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	start_inode = 0;
+	ext2_ino_t	i, ino_in_group, upto, first_zero;
+	errcode_t	retval;
+	dgrp_t		group;
+
+	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) {
+		group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super);
+		start_inode = (group * EXT2_INODES_PER_GROUP(fs->super)) + 1;
+	}
+	if (start_inode < EXT2_FIRST_INODE(fs->super))
+		start_inode = EXT2_FIRST_INODE(fs->super);
+	if (start_inode > fs->super->s_inodes_count)
+		return EXT2_ET_INODE_ALLOC_FAIL;
+	i = start_inode;
+	do {
+		ino_in_group = (i - 1) % EXT2_INODES_PER_GROUP(fs->super);
+		group = (i - 1) / EXT2_INODES_PER_GROUP(fs->super);
+
+		check_inode_uninit(fs, map, group);
+		upto = i + (EXT2_INODES_PER_GROUP(fs->super) - ino_in_group);
+		if (i < start_inode && upto >= start_inode)
+			upto = start_inode - 1;
+		if (upto > fs->super->s_inodes_count)
+			upto = fs->super->s_inodes_count;
+
+		retval = ext2fs_find_first_zero_inode_bitmap2(map, i, upto,
+							      &first_zero);
+		if (retval == 0) {
+			i = first_zero;
+			break;
+		}
+		if (retval != ENOENT)
+			return EXT2_ET_INODE_ALLOC_FAIL;
+		i = upto + 1;
+		if (i > fs->super->s_inodes_count)
+			i = EXT2_FIRST_INODE(fs->super);
+	} while (i != start_inode);
+
+	if (ext2fs_test_inode_bitmap2(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_block2(ext2_filsys fs, blk64_t goal,
+			   ext2fs_block_bitmap map, blk64_t *ret)
+{
+	blk64_t	i;
+	int	c_ratio;
+
+	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 >= ext2fs_blocks_count(fs->super)))
+		goal = fs->super->s_first_data_block;
+	i = goal;
+	c_ratio = 1 << ext2fs_get_bitmap_granularity(map);
+	if (c_ratio > 1)
+		goal &= ~EXT2FS_CLUSTER_MASK(fs);
+	check_block_uninit(fs, map,
+			   (i - fs->super->s_first_data_block) /
+			   EXT2_BLOCKS_PER_GROUP(fs->super));
+	do {
+		if (((i - fs->super->s_first_data_block) %
+		     EXT2_BLOCKS_PER_GROUP(fs->super)) == 0)
+			check_block_uninit(fs, map,
+					   (i - fs->super->s_first_data_block) /
+					   EXT2_BLOCKS_PER_GROUP(fs->super));
+
+		if (!ext2fs_fast_test_block_bitmap2(map, i)) {
+			*ret = i;
+			return 0;
+		}
+		i = (i + c_ratio) & ~(c_ratio - 1);
+		if (i >= ext2fs_blocks_count(fs->super))
+			i = fs->super->s_first_data_block;
+	} while (i != goal);
+	return EXT2_ET_BLOCK_ALLOC_FAIL;
+}
+
+errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
+			   ext2fs_block_bitmap map, blk_t *ret)
+{
+	errcode_t retval;
+	blk64_t val;
+	retval = ext2fs_new_block2(fs, goal, map, &val);
+	if (!retval)
+		*ret = (blk_t) val;
+	return retval;
+}
+
+/*
+ * This function zeros out the allocated block, and updates all of the
+ * appropriate filesystem records.
+ */
+errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
+			     char *block_buf, blk64_t *ret)
+{
+	errcode_t	retval;
+	blk64_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->get_alloc_block) {
+		retval = (fs->get_alloc_block)(fs, goal, &block);
+		if (retval)
+			goto fail;
+	} else {
+		if (!fs->block_map) {
+			retval = ext2fs_read_block_bitmap(fs);
+			if (retval)
+				goto fail;
+		}
+
+		retval = ext2fs_new_block2(fs, goal, 0, &block);
+		if (retval)
+			goto fail;
+	}
+
+	retval = io_channel_write_blk64(fs->io, block, 1, block_buf);
+	if (retval)
+		goto fail;
+
+	ext2fs_block_alloc_stats2(fs, block, +1);
+	*ret = block;
+
+fail:
+	if (buf)
+		ext2fs_free_mem(&buf);
+	return retval;
+}
+
+errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
+			     char *block_buf, blk_t *ret)
+{
+	errcode_t retval;
+	blk64_t	val;
+	retval = ext2fs_alloc_block2(fs, goal, block_buf, &val);
+	if (!retval)
+		*ret = (blk_t) val;
+	return retval;
+}
+
+errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish,
+				 int num, ext2fs_block_bitmap map, blk64_t *ret)
+{
+	blk64_t	b = start;
+	int	c_ratio;
+
+	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;
+	c_ratio = 1 << ext2fs_get_bitmap_granularity(map);
+	b &= ~(c_ratio - 1);
+	finish &= ~(c_ratio -1);
+	do {
+		if (b+num-1 > ext2fs_blocks_count(fs->super))
+			b = fs->super->s_first_data_block;
+		if (ext2fs_fast_test_block_bitmap_range2(map, b, num)) {
+			*ret = b;
+			return 0;
+		}
+		b += c_ratio;
+	} while (b != finish);
+	return EXT2_ET_BLOCK_ALLOC_FAIL;
+}
+
+errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
+				 int num, ext2fs_block_bitmap map, blk_t *ret)
+{
+	errcode_t retval;
+	blk64_t val;
+	retval = ext2fs_get_free_blocks2(fs, start, finish, num, map, &val);
+	if(!retval)
+		*ret = (blk_t) val;
+	return retval;
+}
+
+void ext2fs_set_alloc_block_callback(ext2_filsys fs,
+				     errcode_t (*func)(ext2_filsys fs,
+						       blk64_t goal,
+						       blk64_t *ret),
+				     errcode_t (**old)(ext2_filsys fs,
+						       blk64_t goal,
+						       blk64_t *ret))
+{
+	if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS)
+		return;
+
+	if (old)
+		*old = fs->get_alloc_block;
+
+	fs->get_alloc_block = func;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_sb.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_sb.c
new file mode 100644
index 0000000..223ec51
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_sb.c
@@ -0,0 +1,83 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 function reserves the superblock and block group descriptors
+ * for a given block group.  It currently returns the number of free
+ * blocks assuming that inode table and allocation bitmaps will be in
+ * the group.  This is not necessarily the case when the flex_bg
+ * feature is enabled, so callers should take care!  It was only
+ * really intended for use by mke2fs, and even there it's not that
+ * useful.  In the future, when we redo this function for 64-bit block
+ * numbers, we should probably return the number of blocks used by the
+ * super block and group descriptors instead.
+ *
+ * See also the comment for ext2fs_super_and_bgd_loc()
+ */
+int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
+				 dgrp_t group,
+				 ext2fs_block_bitmap bmap)
+{
+	blk64_t	super_blk, old_desc_blk, new_desc_blk;
+	blk_t	used_blks;
+	int	old_desc_blocks, num_blocks;
+
+	ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
+				  &old_desc_blk, &new_desc_blk, &used_blks);
+
+	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_bitmap2(bmap, super_blk);
+	if ((group == 0) && (fs->blocksize == 1024) &&
+	    EXT2FS_CLUSTER_RATIO(fs) > 1)
+		ext2fs_mark_block_bitmap2(bmap, 0);
+
+	if (old_desc_blk) {
+		if (fs->super->s_reserved_gdt_blocks && fs->block_map == bmap)
+			ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
+		num_blocks = old_desc_blocks;
+		if (old_desc_blk + num_blocks >= ext2fs_blocks_count(fs->super))
+			num_blocks = ext2fs_blocks_count(fs->super) -
+				old_desc_blk;
+		ext2fs_mark_block_bitmap_range2(bmap, old_desc_blk, num_blocks);
+	}
+	if (new_desc_blk)
+		ext2fs_mark_block_bitmap2(bmap, new_desc_blk);
+
+	num_blocks = ext2fs_group_blocks_count(fs, group);
+	num_blocks -= 2 + fs->inode_blocks_per_group + used_blks;
+
+	return num_blocks  ;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_stats.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_stats.c
new file mode 100644
index 0000000..adec363
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_stats.c
@@ -0,0 +1,108 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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);
+
+#ifndef OMIT_COM_ERR
+	if (ino > fs->super->s_inodes_count) {
+		com_err("ext2fs_inode_alloc_stats2", 0,
+			"Illegal inode number: %lu", (unsigned long) ino);
+		return;
+	}
+#endif
+	if (inuse > 0)
+		ext2fs_mark_inode_bitmap2(fs->inode_map, ino);
+	else
+		ext2fs_unmark_inode_bitmap2(fs->inode_map, ino);
+	ext2fs_bg_free_inodes_count_set(fs, group, ext2fs_bg_free_inodes_count(fs, group) - inuse);
+	if (isdir)
+		ext2fs_bg_used_dirs_count_set(fs, group, ext2fs_bg_used_dirs_count(fs, group) + inuse);
+
+	/* We don't strictly need to be clearing the uninit flag if inuse < 0
+	 * (i.e. freeing inodes) but it also means something is bad. */
+	ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+		ext2_ino_t first_unused_inode =	fs->super->s_inodes_per_group -
+			ext2fs_bg_itable_unused(fs, group) +
+			group * fs->super->s_inodes_per_group + 1;
+
+		if (ino >= first_unused_inode)
+			ext2fs_bg_itable_unused_set(fs, group, group * fs->super->s_inodes_per_group + fs->super->s_inodes_per_group - ino);
+		ext2fs_group_desc_csum_set(fs, group);
+	}
+
+	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_stats2(ext2_filsys fs, blk64_t blk, int inuse)
+{
+	int	group = ext2fs_group_of_blk2(fs, blk);
+
+#ifndef OMIT_COM_ERR
+	if (blk >= ext2fs_blocks_count(fs->super)) {
+		com_err("ext2fs_block_alloc_stats", 0,
+			"Illegal block number: %lu", (unsigned long) blk);
+		return;
+	}
+#endif
+	if (inuse > 0)
+		ext2fs_mark_block_bitmap2(fs->block_map, blk);
+	else
+		ext2fs_unmark_block_bitmap2(fs->block_map, blk);
+	ext2fs_bg_free_blocks_count_set(fs, group, ext2fs_bg_free_blocks_count(fs, group) - inuse);
+	ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
+	ext2fs_group_desc_csum_set(fs, group);
+
+	ext2fs_free_blocks_count_add(fs->super,
+				     -inuse * EXT2FS_CLUSTER_RATIO(fs));
+	ext2fs_mark_super_dirty(fs);
+	ext2fs_mark_bb_dirty(fs);
+	if (fs->block_alloc_stats)
+		(fs->block_alloc_stats)(fs, (blk64_t) blk, inuse);
+}
+
+void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse)
+{
+	ext2fs_block_alloc_stats2(fs, blk, inuse);
+}
+
+void ext2fs_set_block_alloc_stats_callback(ext2_filsys fs,
+					   void (*func)(ext2_filsys fs,
+							blk64_t blk,
+							int inuse),
+					   void (**old)(ext2_filsys fs,
+							blk64_t blk,
+							int inuse))
+{
+	if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS)
+		return;
+	if (old)
+		*old = fs->block_alloc_stats;
+
+	fs->block_alloc_stats = func;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_tables.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_tables.c
new file mode 100644
index 0000000..9f3d4e0
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_tables.c
@@ -0,0 +1,245 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 "ext2fsP.h"
+
+/*
+ * This routine searches for free blocks that can allocate a full
+ * group of bitmaps or inode tables for a flexbg group.  Returns the
+ * block number with a correct offset were the bitmaps and inode
+ * tables can be allocated continously and in order.
+ */
+static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk,
+			     ext2fs_block_bitmap bmap, int rem_grp,
+			     int elem_size)
+{
+	int		flexbg, flexbg_size, size;
+	blk64_t		last_blk, first_free = 0;
+	dgrp_t	       	last_grp;
+
+	flexbg_size = 1 << fs->super->s_log_groups_per_flex;
+	flexbg = group / flexbg_size;
+	size = rem_grp * elem_size;
+
+	if (size > (int) (fs->super->s_blocks_per_group / 8))
+		size = (int) fs->super->s_blocks_per_group / 8;
+
+	/*
+	 * Don't do a long search if the previous block
+	 * search is still valid.
+	 */
+	if (start_blk && ext2fs_test_block_bitmap_range2(bmap, start_blk,
+							 elem_size))
+		return start_blk;
+
+	start_blk = ext2fs_group_first_block2(fs, flexbg_size * flexbg);
+	last_grp = group | (flexbg_size - 1);
+	if (last_grp > fs->group_desc_count-1)
+		last_grp = fs->group_desc_count-1;
+	last_blk = ext2fs_group_last_block2(fs, last_grp);
+
+	/* Find the first available block */
+	if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, size,
+				    bmap, &first_free) == 0)
+		return first_free;
+
+	if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, elem_size,
+				   bmap, &first_free) == 0)
+		return first_free;
+
+	if (ext2fs_get_free_blocks2(fs, 0, last_blk, elem_size, bmap,
+				    &first_free) == 0)
+		return first_free;
+
+	return first_free;
+}
+
+errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
+				      ext2fs_block_bitmap bmap)
+{
+	unsigned int	j;
+	errcode_t	retval;
+	blk64_t		group_blk, start_blk, last_blk, new_blk, blk;
+	dgrp_t		last_grp = 0;
+	int		rem_grps = 0, flexbg_size = 0;
+
+	group_blk = ext2fs_group_first_block2(fs, group);
+	last_blk = ext2fs_group_last_block2(fs, group);
+
+	if (!bmap)
+		bmap = fs->block_map;
+
+	if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+				      EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
+	    fs->super->s_log_groups_per_flex) {
+		flexbg_size = 1 << fs->super->s_log_groups_per_flex;
+		last_grp = group | (flexbg_size - 1);
+		if (last_grp > fs->group_desc_count-1)
+			last_grp = fs->group_desc_count-1;
+		rem_grps = last_grp - group + 1;
+	}
+
+	/*
+	 * Allocate the block and inode bitmaps, if necessary
+	 */
+	if (fs->stride) {
+		retval = ext2fs_get_free_blocks2(fs, group_blk, last_blk,
+						 1, bmap, &start_blk);
+		if (retval)
+			return retval;
+		start_blk += fs->inode_blocks_per_group;
+		start_blk += ((fs->stride * group) %
+			      (last_blk - start_blk + 1));
+		if (start_blk >= last_blk)
+			start_blk = group_blk;
+	} else
+		start_blk = group_blk;
+
+	if (flexbg_size) {
+		blk64_t prev_block = 0;
+
+		if (group % flexbg_size)
+			prev_block = ext2fs_block_bitmap_loc(fs, group - 1) + 1;
+		start_blk = flexbg_offset(fs, group, prev_block, bmap,
+					  rem_grps, 1);
+		last_blk = ext2fs_group_last_block2(fs, last_grp);
+	}
+
+	if (!ext2fs_block_bitmap_loc(fs, group)) {
+		retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
+						 1, bmap, &new_blk);
+		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
+			retval = ext2fs_get_free_blocks2(fs, group_blk,
+					last_blk, 1, bmap, &new_blk);
+		if (retval)
+			return retval;
+		ext2fs_mark_block_bitmap2(bmap, new_blk);
+		ext2fs_block_bitmap_loc_set(fs, group, new_blk);
+		if (flexbg_size) {
+			dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
+			ext2fs_bg_free_blocks_count_set(fs, gr, ext2fs_bg_free_blocks_count(fs, gr) - 1);
+			ext2fs_free_blocks_count_add(fs->super, -1);
+			ext2fs_bg_flags_clear(fs, gr, EXT2_BG_BLOCK_UNINIT);
+			ext2fs_group_desc_csum_set(fs, gr);
+		}
+	}
+
+	if (flexbg_size) {
+		blk64_t prev_block = 0;
+		if (group % flexbg_size)
+			prev_block = ext2fs_inode_bitmap_loc(fs, group - 1) + 1;
+		else
+			prev_block = ext2fs_block_bitmap_loc(fs, group) +
+				flexbg_size;
+		start_blk = flexbg_offset(fs, group, prev_block, bmap,
+					  rem_grps, 1);
+		last_blk = ext2fs_group_last_block2(fs, last_grp);
+	}
+
+	if (!ext2fs_inode_bitmap_loc(fs, group)) {
+		retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
+						 1, bmap, &new_blk);
+		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
+			retval = ext2fs_get_free_blocks2(fs, group_blk,
+					 last_blk, 1, bmap, &new_blk);
+		if (retval)
+			return retval;
+		ext2fs_mark_block_bitmap2(bmap, new_blk);
+		ext2fs_inode_bitmap_loc_set(fs, group, new_blk);
+		if (flexbg_size) {
+			dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
+			ext2fs_bg_free_blocks_count_set(fs, gr, ext2fs_bg_free_blocks_count(fs, gr) - 1);
+			ext2fs_free_blocks_count_add(fs->super, -1);
+			ext2fs_bg_flags_clear(fs, gr, EXT2_BG_BLOCK_UNINIT);
+			ext2fs_group_desc_csum_set(fs, gr);
+		}
+	}
+
+	/*
+	 * Allocate the inode table
+	 */
+	if (flexbg_size) {
+		blk64_t prev_block = 0;
+
+		if (group % flexbg_size)
+			prev_block = ext2fs_inode_table_loc(fs, group - 1) +
+				fs->inode_blocks_per_group;
+		else
+			prev_block = ext2fs_inode_bitmap_loc(fs, group) +
+				flexbg_size;
+
+		group_blk = flexbg_offset(fs, group, prev_block, bmap,
+					  rem_grps, fs->inode_blocks_per_group);
+		last_blk = ext2fs_group_last_block2(fs, last_grp);
+	}
+
+	if (!ext2fs_inode_table_loc(fs, group)) {
+		retval = ext2fs_get_free_blocks2(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_bitmap2(bmap, blk);
+			if (flexbg_size) {
+				dgrp_t gr = ext2fs_group_of_blk2(fs, blk);
+				ext2fs_bg_free_blocks_count_set(fs, gr, ext2fs_bg_free_blocks_count(fs, gr) - 1);
+				ext2fs_free_blocks_count_add(fs->super, -1);
+				ext2fs_bg_flags_clear(fs, gr,
+						     EXT2_BG_BLOCK_UNINIT);
+				ext2fs_group_desc_csum_set(fs, gr);
+			}
+		}
+		ext2fs_inode_table_loc_set(fs, group, new_blk);
+	}
+	ext2fs_group_desc_csum_set(fs, group);
+	return 0;
+}
+
+errcode_t ext2fs_allocate_tables(ext2_filsys fs)
+{
+	errcode_t	retval;
+	dgrp_t		i;
+	struct ext2fs_numeric_progress_struct progress;
+
+	ext2fs_numeric_progress_init(fs, &progress, NULL,
+				     fs->group_desc_count);
+
+	for (i = 0; i < fs->group_desc_count; i++) {
+		ext2fs_numeric_progress_update(fs, &progress, i);
+		retval = ext2fs_allocate_group_table(fs, i, fs->block_map);
+		if (retval)
+			return retval;
+	}
+	ext2fs_numeric_progress_close(fs, &progress, NULL);
+	return 0;
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/badblocks.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/badblocks.c
new file mode 100644
index 0000000..0f23983
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/badblocks.c
@@ -0,0 +1,328 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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_array(bb->size, sizeof(blk_t), &bb->list);
+	if (retval) {
+		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 = ((unsigned)low + (unsigned)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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bb_compat.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bb_compat.c
new file mode 100644
index 0000000..373792a
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bb_compat.c
@@ -0,0 +1,64 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bb_inode.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bb_inode.c
new file mode 100644
index 0000000..268eecf
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bb_inode.c
@@ -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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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;
+
+	memset(&rec, 0, sizeof(rec));
+	rec.max_ind_blocks = 10;
+	retval = ext2fs_get_array(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 = fs->now ? fs->now : time(0);
+	if (!inode.i_ctime)
+		inode.i_ctime = fs->now ? fs->now : time(0);
+	ext2fs_iblk_set(fs, &inode, rec.bad_block_count);
+	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 >= ext2fs_blocks_count(fs->super) ||
+	    *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_stats2(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_bitmap2(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_blk64(fs->io, blk, 1, rec->block_buf);
+		if (retval) {
+			rec->err = retval;
+			return BLOCK_ABORT;
+		}
+	}
+
+	/*
+	 * Update block counts
+	 */
+	ext2fs_block_alloc_stats2(fs, blk, +1);
+
+	*block_nr = blk;
+	return BLOCK_CHANGED;
+}
+
+
+
+
+
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bitmaps.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bitmaps.c
new file mode 100644
index 0000000..8402191
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bitmaps.c
@@ -0,0 +1,308 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 "ext2fsP.h"
+#include "bmap64.h"
+
+void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
+{
+	ext2fs_free_generic_bmap(bitmap);
+}
+
+void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap)
+{
+	ext2fs_free_generic_bmap(bitmap);
+}
+
+errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
+			     ext2fs_generic_bitmap *dest)
+{
+	return (ext2fs_copy_generic_bmap(src, dest));
+}
+void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map)
+{
+	ext2fs_set_generic_bmap_padding(map);
+}
+
+errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
+				       const char *descr,
+				       ext2fs_inode_bitmap *ret)
+{
+	__u64		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);
+
+	/* Are we permitted to use new-style bitmaps? */
+	if (fs->flags & EXT2_FLAG_64BITS)
+		return (ext2fs_alloc_generic_bmap(fs,
+				EXT2_ET_MAGIC_INODE_BITMAP64,
+				fs->default_bitmap_type,
+				start, end, real_end, descr, ret));
+
+	/* Otherwise, check to see if the file system is small enough
+	 * to use old-style 32-bit bitmaps */
+	if ((end > ~0U) || (real_end > ~0U))
+		return EXT2_ET_CANT_USE_LEGACY_BITMAPS;
+
+	return (ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_INODE_BITMAP, fs,
+					 start, end, real_end,
+					 descr, 0,
+					 (ext2fs_generic_bitmap *) ret));
+}
+
+errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
+				       const char *descr,
+				       ext2fs_block_bitmap *ret)
+{
+	__u64		start, end, real_end;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	fs->write_bitmaps = ext2fs_write_bitmaps;
+
+	start = EXT2FS_B2C(fs, fs->super->s_first_data_block);
+	end = EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1);
+	real_end = ((__u64) EXT2_CLUSTERS_PER_GROUP(fs->super)
+		    * (__u64) fs->group_desc_count)-1 + start;
+
+	if (fs->flags & EXT2_FLAG_64BITS)
+		return (ext2fs_alloc_generic_bmap(fs,
+				EXT2_ET_MAGIC_BLOCK_BITMAP64,
+				fs->default_bitmap_type,
+				start, end, real_end, descr, ret));
+
+	if ((end > ~0U) || (real_end > ~0U))
+		return EXT2_ET_CANT_USE_LEGACY_BITMAPS;
+
+	return (ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, fs,
+					   start, end, real_end,
+					   descr, 0,
+					   (ext2fs_generic_bitmap *) ret));
+}
+
+/*
+ * ext2fs_allocate_block_bitmap() really allocates a per-cluster
+ * bitmap for backwards compatibility.  This function allocates a
+ * block bitmap which is truly per-block, even if clusters/bigalloc
+ * are enabled.  mke2fs and e2fsck need this for tracking the
+ * allocation of the file system metadata blocks.
+ */
+errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs,
+					    const char *descr,
+					    ext2fs_block_bitmap *ret)
+{
+	__u64			start, end, real_end;
+	ext2fs_generic_bitmap	bmap;
+	errcode_t		retval;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	fs->write_bitmaps = ext2fs_write_bitmaps;
+
+	if (!fs->cluster_ratio_bits)
+		return ext2fs_allocate_block_bitmap(fs, descr, ret);
+
+	if ((fs->flags & EXT2_FLAG_64BITS) == 0)
+		return EXT2_ET_CANT_USE_LEGACY_BITMAPS;
+
+	start = fs->super->s_first_data_block;
+	end = ext2fs_blocks_count(fs->super)-1;
+	real_end = ((__u64) EXT2_BLOCKS_PER_GROUP(fs->super)
+		    * (__u64) fs->group_desc_count)-1 + start;
+
+	retval = ext2fs_alloc_generic_bmap(fs, EXT2_ET_MAGIC_BLOCK_BITMAP64,
+					   fs->default_bitmap_type, start,
+					   end, real_end, descr, &bmap);
+	if (retval)
+		return retval;
+	bmap->cluster_bits = 0;
+	*ret = bmap;
+	return 0;
+}
+
+int ext2fs_get_bitmap_granularity(ext2fs_block_bitmap bitmap)
+{
+	ext2fs_generic_bitmap bmap = bitmap;
+
+	if (!EXT2FS_IS_64_BITMAP(bmap))
+		return 0;
+
+	return bmap->cluster_bits;
+}
+
+errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
+					ext2_ino_t end, ext2_ino_t *oend)
+{
+	__u64 tmp_oend;
+	int retval;
+
+	retval = ext2fs_fudge_generic_bmap_end((ext2fs_generic_bitmap) bitmap,
+					       EXT2_ET_FUDGE_INODE_BITMAP_END,
+					       end, &tmp_oend);
+	if (oend)
+		*oend = tmp_oend;
+	return retval;
+}
+
+errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
+					blk_t end, blk_t *oend)
+{
+	return (ext2fs_fudge_generic_bitmap_end(bitmap,
+						EXT2_ET_MAGIC_BLOCK_BITMAP,
+						EXT2_ET_FUDGE_BLOCK_BITMAP_END,
+						end, oend));
+}
+
+errcode_t ext2fs_fudge_block_bitmap_end2(ext2fs_block_bitmap bitmap,
+					 blk64_t end, blk64_t *oend)
+{
+	return (ext2fs_fudge_generic_bmap_end(bitmap,
+					      EXT2_ET_FUDGE_BLOCK_BITMAP_END,
+					      end, oend));
+}
+
+void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap)
+{
+	ext2fs_clear_generic_bmap(bitmap);
+}
+
+void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap)
+{
+	ext2fs_clear_generic_bmap(bitmap);
+}
+
+errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
+				     ext2fs_inode_bitmap bmap)
+{
+	return (ext2fs_resize_generic_bitmap(EXT2_ET_MAGIC_INODE_BITMAP,
+					     new_end, new_real_end, bmap));
+}
+
+errcode_t ext2fs_resize_inode_bitmap2(__u64 new_end, __u64 new_real_end,
+				      ext2fs_inode_bitmap bmap)
+{
+	return (ext2fs_resize_generic_bmap(bmap, new_end, new_real_end));
+}
+
+errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
+				     ext2fs_block_bitmap bmap)
+{
+	return (ext2fs_resize_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP,
+					     new_end, new_real_end, bmap));
+}
+
+errcode_t ext2fs_resize_block_bitmap2(__u64 new_end, __u64 new_real_end,
+				      ext2fs_block_bitmap bmap)
+{
+	return (ext2fs_resize_generic_bmap(bmap, new_end, new_real_end));
+}
+
+errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
+				      ext2fs_block_bitmap bm2)
+{
+	return (ext2fs_compare_generic_bmap(EXT2_ET_NEQ_BLOCK_BITMAP,
+					    bm1, bm2));
+}
+
+errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
+				      ext2fs_inode_bitmap bm2)
+{
+	return (ext2fs_compare_generic_bmap(EXT2_ET_NEQ_INODE_BITMAP,
+					    bm1, bm2));
+}
+
+errcode_t ext2fs_set_inode_bitmap_range(ext2fs_inode_bitmap bmap,
+					ext2_ino_t start, unsigned int num,
+					void *in)
+{
+	return (ext2fs_set_generic_bitmap_range(bmap,
+						EXT2_ET_MAGIC_INODE_BITMAP,
+						start, num, in));
+}
+
+errcode_t ext2fs_set_inode_bitmap_range2(ext2fs_inode_bitmap bmap,
+					 __u64 start, size_t num,
+					 void *in)
+{
+	return (ext2fs_set_generic_bmap_range(bmap, start, num, in));
+}
+
+errcode_t ext2fs_get_inode_bitmap_range(ext2fs_inode_bitmap bmap,
+					ext2_ino_t start, unsigned int num,
+					void *out)
+{
+	return (ext2fs_get_generic_bitmap_range(bmap,
+						EXT2_ET_MAGIC_INODE_BITMAP,
+						start, num, out));
+}
+
+errcode_t ext2fs_get_inode_bitmap_range2(ext2fs_inode_bitmap bmap,
+					 __u64 start, size_t num,
+					 void *out)
+{
+	return (ext2fs_get_generic_bmap_range(bmap, start, num, out));
+}
+
+errcode_t ext2fs_set_block_bitmap_range(ext2fs_block_bitmap bmap,
+					blk_t start, unsigned int num,
+					void *in)
+{
+	return (ext2fs_set_generic_bitmap_range(bmap,
+						EXT2_ET_MAGIC_BLOCK_BITMAP,
+						start, num, in));
+}
+
+errcode_t ext2fs_set_block_bitmap_range2(ext2fs_block_bitmap bmap,
+					 blk64_t start, size_t num,
+					 void *in)
+{
+	return (ext2fs_set_generic_bmap_range(bmap, start, num, in));
+}
+
+errcode_t ext2fs_get_block_bitmap_range(ext2fs_block_bitmap bmap,
+					blk_t start, unsigned int num,
+					void *out)
+{
+	return (ext2fs_get_generic_bitmap_range(bmap,
+						EXT2_ET_MAGIC_BLOCK_BITMAP,
+						start, num, out));
+}
+
+errcode_t ext2fs_get_block_bitmap_range2(ext2fs_block_bitmap bmap,
+					 blk64_t start, size_t num,
+					 void *out)
+{
+	return (ext2fs_get_generic_bmap_range(bmap, start, num, out));
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bitops.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bitops.c
new file mode 100644
index 0000000..8e4c05c
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bitops.c
@@ -0,0 +1,158 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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
+}
+
+/*
+ * C-only 64 bit ops.
+ */
+
+int ext2fs_set_bit64(__u64 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_bit64(__u64 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_bit64(__u64 nr, const void * addr)
+{
+	int			mask;
+	const unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return (mask & *ADDR);
+}
+
+static unsigned int popcount8(unsigned int w)
+{
+	unsigned int res = w - ((w >> 1) & 0x55);
+	res = (res & 0x33) + ((res >> 2) & 0x33);
+	return (res + (res >> 4)) & 0x0F;
+}
+
+static unsigned int popcount32(unsigned int w)
+{
+	unsigned int res = w - ((w >> 1) & 0x55555555);
+	res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+	res = (res + (res >> 4)) & 0x0F0F0F0F;
+	res = res + (res >> 8);
+	return (res + (res >> 16)) & 0x000000FF;
+}
+
+unsigned int ext2fs_bitcount(const void *addr, unsigned int nbytes)
+{
+	const unsigned char *cp = addr;
+	const __u32 *p;
+	unsigned int res = 0;
+
+	while (((((unsigned long) cp) & 3) != 0) && (nbytes > 0)) {
+		res += popcount8(*cp++);
+		nbytes--;
+	}
+	p = (const __u32 *) cp;
+
+	while (nbytes > 4) {
+		res += popcount32(*p++);
+		nbytes -= 4;
+	}
+	cp = (const unsigned char *) p;
+
+	while (nbytes > 0) {
+		res += popcount8(*cp++);
+		nbytes--;
+	}
+	return res;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bitops.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bitops.h
new file mode 100644
index 0000000..3e8132d
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bitops.h
@@ -0,0 +1,660 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#ifdef WORDS_BIGENDIAN
+#define ext2fs_cpu_to_le64(x) ext2fs_swab64((x))
+#define ext2fs_le64_to_cpu(x) ext2fs_swab64((x))
+#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_be64(x) ((__u64)(x))
+#define ext2fs_be64_to_cpu(x) ((__u64)(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_le64(x) ((__u64)(x))
+#define ext2fs_le64_to_cpu(x) ((__u64)(x))
+#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_be64(x) ext2fs_swab64((x))
+#define ext2fs_be64_to_cpu(x) ext2fs_swab64((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);
+
+#ifdef NO_INLINE_FUNCS
+extern void ext2fs_fast_set_bit(unsigned int nr,void * addr);
+extern void ext2fs_fast_clear_bit(unsigned int nr, void * addr);
+extern void ext2fs_fast_set_bit64(__u64 nr,void * addr);
+extern void ext2fs_fast_clear_bit64(__u64 nr, void * addr);
+extern __u16 ext2fs_swab16(__u16 val);
+extern __u32 ext2fs_swab32(__u32 val);
+extern __u64 ext2fs_swab64(__u64 val);
+
+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_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);
+#endif
+
+/* These functions routines moved to gen_bitmap.c */
+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 int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
+					  ino_t inode, int num);
+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);
+extern int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+				      blk_t bitno);
+extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+					  blk_t block, int num);
+extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
+extern __u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap);
+extern __u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap);
+
+/* 64-bit versions */
+
+#ifdef NO_INLINE_FUNCS
+extern int ext2fs_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
+				     blk64_t block);
+extern int ext2fs_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
+				       blk64_t block);
+extern int ext2fs_test_block_bitmap2(ext2fs_block_bitmap bitmap,
+				     blk64_t block);
+
+extern int ext2fs_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+				     ext2_ino_t inode);
+extern int ext2fs_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+				       ext2_ino_t inode);
+extern int ext2fs_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+				     ext2_ino_t inode);
+
+extern void ext2fs_fast_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
+					   blk64_t block);
+extern void ext2fs_fast_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
+					     blk64_t block);
+extern int ext2fs_fast_test_block_bitmap2(ext2fs_block_bitmap bitmap,
+					  blk64_t block);
+
+extern void ext2fs_fast_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+					   ext2_ino_t inode);
+extern void ext2fs_fast_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+					    ext2_ino_t inode);
+extern int ext2fs_fast_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+					  ext2_ino_t inode);
+extern errcode_t ext2fs_find_first_zero_block_bitmap2(ext2fs_block_bitmap bitmap,
+						      blk64_t start,
+						      blk64_t end,
+						      blk64_t *out);
+extern errcode_t ext2fs_find_first_zero_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+						      ext2_ino_t start,
+						      ext2_ino_t end,
+						      ext2_ino_t *out);
+extern blk64_t ext2fs_get_block_bitmap_start2(ext2fs_block_bitmap bitmap);
+extern ext2_ino_t ext2fs_get_inode_bitmap_start2(ext2fs_inode_bitmap bitmap);
+extern blk64_t ext2fs_get_block_bitmap_end2(ext2fs_block_bitmap bitmap);
+extern ext2_ino_t ext2fs_get_inode_bitmap_end2(ext2fs_inode_bitmap bitmap);
+
+extern int ext2fs_fast_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
+						blk64_t block,
+						unsigned int num);
+extern void ext2fs_fast_mark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
+						 blk64_t block,
+						 unsigned int num);
+extern void ext2fs_fast_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
+						   blk64_t block,
+						   unsigned int num);
+#endif
+
+/* These routines moved to gen_bitmap64.c */
+extern void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap);
+extern errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
+					     ext2fs_generic_bitmap bm1,
+					     ext2fs_generic_bitmap bm2);
+extern void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap);
+extern int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap,
+				    blk64_t bitno);
+extern int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap,
+				      blk64_t bitno);
+extern int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap,
+				    blk64_t bitno);
+extern int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
+					   blk64_t block, unsigned int num);
+extern __u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap bitmap);
+extern __u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap bitmap);
+extern int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
+					   blk64_t block, unsigned int num);
+extern void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
+					    blk64_t block, unsigned int num);
+extern void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
+					      blk64_t block, unsigned int num);
+extern errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
+						     __u64 start, __u64 end,
+						     __u64 *out);
+
+/*
+ * 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__)))
+	/* 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
+#if (__STDC_VERSION__ >= 199901L)
+#define _INLINE_ extern inline
+#else
+#define _INLINE_ inline
+#endif
+#else /* !INCLUDE_INLINE FUNCS */
+#if (__STDC_VERSION__ >= 199901L)
+#define _INLINE_ inline
+#else /* not C99 */
+#ifdef __GNUC__
+#define _INLINE_ extern __inline__
+#else				/* For Watcom C */
+#define _INLINE_ extern inline
+#endif /* __GNUC__ */
+#endif /* __STDC_VERSION__ >= 199901L */
+#endif /* INCLUDE_INLINE_FUNCS */
+
+/*
+ * Fast bit set/clear functions that doesn't need to return the
+ * previous bit value.
+ */
+
+_INLINE_ void ext2fs_fast_set_bit(unsigned int nr,void * addr)
+{
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	*ADDR |= (unsigned char) (1 << (nr & 0x07));
+}
+
+_INLINE_ void ext2fs_fast_clear_bit(unsigned int nr, void * addr)
+{
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	*ADDR &= (unsigned char) ~(1 << (nr & 0x07));
+}
+
+
+_INLINE_ void ext2fs_fast_set_bit64(__u64 nr, void * addr)
+{
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	*ADDR |= (unsigned char) (1 << (nr & 0x07));
+}
+
+_INLINE_ void ext2fs_fast_clear_bit64(__u64 nr, void * addr)
+{
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	*ADDR &= (unsigned char) ~(1 << (nr & 0x07));
+}
+
+
+#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
+     (defined(__i386__) || defined(__i486__) || defined(__i586__)))
+
+#define _EXT2_HAVE_ASM_BITOPS_
+#define _EXT2_HAVE_ASM_SWAB_
+
+/*
+ * 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;
+
+	addr = (void *) (((unsigned char *) addr) + (nr >> 3));
+	__asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
+		:"=r" (oldbit),"+m" (EXT2FS_ADDR)
+		:"r" (nr & 7));
+	return oldbit;
+}
+
+_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
+{
+	int oldbit;
+
+	addr = (void *) (((unsigned char *) addr) + (nr >> 3));
+	__asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
+		:"=r" (oldbit),"+m" (EXT2FS_ADDR)
+		:"r" (nr & 7));
+	return oldbit;
+}
+
+_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
+{
+	int oldbit;
+
+	addr = (const void *) (((const unsigned char *) addr) + (nr >> 3));
+	__asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
+		:"=r" (oldbit)
+		:"m" (EXT2FS_CONST_ADDR),"r" (nr & 7));
+	return oldbit;
+}
+
+_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;
+}
+
+#undef EXT2FS_ADDR
+
+#endif	/* i386 */
+
+
+#if !defined(_EXT2_HAVE_ASM_SWAB_)
+
+_INLINE_ __u16 ext2fs_swab16(__u16 val)
+{
+	return (val >> 8) | (__u16) (val << 8);
+}
+
+_INLINE_ __u32 ext2fs_swab32(__u32 val)
+{
+	return ((val>>24) | ((val>>8)&0xFF00) |
+		((val<<8)&0xFF0000) | (val<<24));
+}
+
+#endif /* !_EXT2_HAVE_ASM_SWAB */
+
+_INLINE_ __u64 ext2fs_swab64(__u64 val)
+{
+	return (ext2fs_swab32((__u32) (val >> 32)) |
+		(((__u64)ext2fs_swab32(val & 0xFFFFFFFFUL)) << 32));
+}
+
+_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)
+{
+	ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+					      blk_t block)
+{
+	ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
+					    blk_t block)
+{
+	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+					  block);
+}
+
+_INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+					    ext2_ino_t inode)
+{
+	ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
+}
+
+_INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+					      ext2_ino_t inode)
+{
+	ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
+}
+
+_INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
+					   ext2_ino_t inode)
+{
+	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+					  inode);
+}
+
+_INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
+{
+	return ext2fs_get_generic_bitmap_start((ext2fs_generic_bitmap) bitmap);
+}
+
+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
+{
+	return ext2fs_get_generic_bitmap_start((ext2fs_generic_bitmap) bitmap);
+}
+
+_INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
+{
+	return ext2fs_get_generic_bitmap_end((ext2fs_generic_bitmap) bitmap);
+}
+
+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
+{
+	return ext2fs_get_generic_bitmap_end((ext2fs_generic_bitmap) bitmap);
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+						 blk_t block, int num)
+{
+	return ext2fs_test_block_bitmap_range(bitmap, block, num);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+						  blk_t block, int num)
+{
+	ext2fs_mark_block_bitmap_range(bitmap, block, num);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+						    blk_t block, int num)
+{
+	ext2fs_unmark_block_bitmap_range(bitmap, block, num);
+}
+
+/* 64-bit versions */
+
+_INLINE_ int ext2fs_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
+				       blk64_t block)
+{
+	return ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap,
+					block);
+}
+
+_INLINE_ int ext2fs_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
+					 blk64_t block)
+{
+	return ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ int ext2fs_test_block_bitmap2(ext2fs_block_bitmap bitmap,
+				       blk64_t block)
+{
+	return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
+					block);
+}
+
+_INLINE_ int ext2fs_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+				       ext2_ino_t inode)
+{
+	return ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap,
+					inode);
+}
+
+_INLINE_ int ext2fs_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+					 ext2_ino_t inode)
+{
+	return ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap,
+					  inode);
+}
+
+_INLINE_ int ext2fs_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+				       ext2_ino_t inode)
+{
+	return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
+					inode);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap2(ext2fs_block_bitmap bitmap,
+					     blk64_t block)
+{
+	ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap2(ext2fs_block_bitmap bitmap,
+					       blk64_t block)
+{
+	ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap2(ext2fs_block_bitmap bitmap,
+					    blk64_t block)
+{
+	return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
+					block);
+}
+
+_INLINE_ void ext2fs_fast_mark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+					     ext2_ino_t inode)
+{
+	ext2fs_mark_generic_bmap((ext2fs_generic_bitmap) bitmap, inode);
+}
+
+_INLINE_ void ext2fs_fast_unmark_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+					       ext2_ino_t inode)
+{
+	ext2fs_unmark_generic_bmap((ext2fs_generic_bitmap) bitmap, inode);
+}
+
+_INLINE_ int ext2fs_fast_test_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+					    ext2_ino_t inode)
+{
+	return ext2fs_test_generic_bmap((ext2fs_generic_bitmap) bitmap,
+					inode);
+}
+
+_INLINE_ errcode_t ext2fs_find_first_zero_block_bitmap2(ext2fs_block_bitmap bitmap,
+							blk64_t start,
+							blk64_t end,
+							blk64_t *out)
+{
+	__u64 o;
+	errcode_t rv;
+
+	rv = ext2fs_find_first_zero_generic_bmap((ext2fs_generic_bitmap) bitmap,
+						 start, end, &o);
+	if (!rv)
+		*out = o;
+	return rv;
+}
+
+_INLINE_ errcode_t ext2fs_find_first_zero_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+							ext2_ino_t start,
+							ext2_ino_t end,
+							ext2_ino_t *out)
+{
+	__u64 o;
+	errcode_t rv;
+
+	rv = ext2fs_find_first_zero_generic_bmap((ext2fs_generic_bitmap) bitmap,
+						 start, end, &o);
+	if (!rv)
+		*out = (ext2_ino_t) o;
+	return rv;
+}
+
+_INLINE_ blk64_t ext2fs_get_block_bitmap_start2(ext2fs_block_bitmap bitmap)
+{
+	return ext2fs_get_generic_bmap_start((ext2fs_generic_bitmap) bitmap);
+}
+
+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start2(ext2fs_inode_bitmap bitmap)
+{
+	return (ext2_ino_t) ext2fs_get_generic_bmap_start((ext2fs_generic_bitmap) bitmap);
+}
+
+_INLINE_ blk64_t ext2fs_get_block_bitmap_end2(ext2fs_block_bitmap bitmap)
+{
+	return ext2fs_get_generic_bmap_end((ext2fs_generic_bitmap) bitmap);
+}
+
+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end2(ext2fs_inode_bitmap bitmap)
+{
+	return (ext2_ino_t) ext2fs_get_generic_bmap_end((ext2fs_generic_bitmap) bitmap);
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap_range2(ext2fs_block_bitmap bitmap,
+						  blk64_t block,
+						  unsigned int num)
+{
+	return ext2fs_test_block_bitmap_range2(bitmap, block, num);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
+						   blk64_t block,
+						   unsigned int num)
+{
+	ext2fs_mark_block_bitmap_range2(bitmap, block, num);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap_range2(ext2fs_block_bitmap bitmap,
+						     blk64_t block,
+						     unsigned int num)
+{
+	ext2fs_unmark_block_bitmap_range2(bitmap, block, num);
+}
+
+#undef _INLINE_
+#endif
+
+#ifndef _EXT2_HAVE_ASM_BITOPS_
+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);
+#endif
+
+extern int ext2fs_set_bit64(__u64 nr,void * addr);
+extern int ext2fs_clear_bit64(__u64 nr, void * addr);
+extern int ext2fs_test_bit64(__u64 nr, const void * addr);
+extern unsigned int ext2fs_bitcount(const void *addr, unsigned int nbytes);
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/blkmap64_ba.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/blkmap64_ba.c
new file mode 100644
index 0000000..8eddde9
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/blkmap64_ba.c
@@ -0,0 +1,417 @@
+/*
+ * blkmap64_ba.c --- Simple bitarray implementation for bitmaps
+ *
+ * Copyright (C) 2008 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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"
+#include "bmap64.h"
+
+/*
+ * Private data for bit array implementation of bitmap ops.
+ * Currently, this is just a pointer to our big flat hunk of memory,
+ * exactly equivalent to the old-skool char * bitmap member.
+ */
+
+struct ext2fs_ba_private_struct {
+	char *bitarray;
+};
+
+typedef struct ext2fs_ba_private_struct *ext2fs_ba_private;
+
+static errcode_t ba_alloc_private_data (ext2fs_generic_bitmap bitmap)
+{
+	ext2fs_ba_private bp;
+	errcode_t	retval;
+	size_t		size;
+
+	/*
+	 * Since we only have the one pointer, we could just shove our
+	 * private data in the void *private field itself, but then
+	 * we'd have to do a fair bit of rewriting if we ever added a
+	 * field.  I'm agnostic.
+	 */
+	retval = ext2fs_get_mem(sizeof (ext2fs_ba_private), &bp);
+	if (retval)
+		return retval;
+
+	size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
+
+	retval = ext2fs_get_mem(size, &bp->bitarray);
+	if (retval) {
+		ext2fs_free_mem(&bp);
+		bp = 0;
+		return retval;
+	}
+	bitmap->private = (void *) bp;
+	return 0;
+}
+
+static errcode_t ba_new_bmap(ext2_filsys fs EXT2FS_ATTR((unused)),
+			     ext2fs_generic_bitmap bitmap)
+{
+	ext2fs_ba_private bp;
+	errcode_t	retval;
+	size_t		size;
+
+	retval = ba_alloc_private_data (bitmap);
+	if (retval)
+		return retval;
+
+	bp = (ext2fs_ba_private) bitmap->private;
+	size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
+	memset(bp->bitarray, 0, size);
+
+	return 0;
+}
+
+static void ba_free_bmap(ext2fs_generic_bitmap bitmap)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+
+	if (!bp)
+		return;
+
+	if (bp->bitarray) {
+		ext2fs_free_mem (&bp->bitarray);
+		bp->bitarray = 0;
+	}
+	ext2fs_free_mem (&bp);
+	bp = 0;
+}
+
+static errcode_t ba_copy_bmap(ext2fs_generic_bitmap src,
+			      ext2fs_generic_bitmap dest)
+{
+	ext2fs_ba_private src_bp = (ext2fs_ba_private) src->private;
+	ext2fs_ba_private dest_bp;
+	errcode_t retval;
+	size_t size;
+
+	retval = ba_alloc_private_data (dest);
+	if (retval)
+		return retval;
+
+	dest_bp = (ext2fs_ba_private) dest->private;
+
+	size = (size_t) (((src->real_end - src->start) / 8) + 1);
+	memcpy (dest_bp->bitarray, src_bp->bitarray, size);
+
+	return 0;
+}
+
+static errcode_t ba_resize_bmap(ext2fs_generic_bitmap bmap,
+				__u64 new_end, __u64 new_real_end)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bmap->private;
+	errcode_t	retval;
+	size_t		size, new_size;
+	__u64		bitno;
+
+	/*
+	 * 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_bit64(bitno - bmap->start, bp->bitarray);
+	}
+	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, &bp->bitarray);
+		if (retval)
+			return retval;
+	}
+	if (new_size > size)
+		memset(bp->bitarray + size, 0, new_size - size);
+
+	bmap->end = new_end;
+	bmap->real_end = new_real_end;
+	return 0;
+
+}
+
+static int ba_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+	blk64_t bitno = (blk64_t) arg;
+
+	return ext2fs_set_bit64(bitno - bitmap->start, bp->bitarray);
+}
+
+static int ba_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+	blk64_t bitno = (blk64_t) arg;
+
+	return ext2fs_clear_bit64(bitno - bitmap->start, bp->bitarray);
+}
+
+static int ba_test_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+	blk64_t bitno = (blk64_t) arg;
+
+	return ext2fs_test_bit64(bitno - bitmap->start, bp->bitarray);
+}
+
+static void ba_mark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+				unsigned int num)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+	blk64_t bitno = (blk64_t) arg;
+	unsigned int i;
+
+	for (i = 0; i < num; i++)
+		ext2fs_fast_set_bit64(bitno + i - bitmap->start, bp->bitarray);
+}
+
+static void ba_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+				  unsigned int num)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+	blk64_t bitno = (blk64_t) arg;
+	unsigned int i;
+
+	for (i = 0; i < num; i++)
+		ext2fs_fast_clear_bit64(bitno + i - bitmap->start, bp->bitarray);
+}
+
+static int ba_test_clear_bmap_extent(ext2fs_generic_bitmap bitmap,
+				     __u64 start, unsigned int len)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+	__u64 start_byte, len_byte = len >> 3;
+	unsigned int start_bit, len_bit = len % 8;
+	unsigned int first_bit = 0;
+	unsigned int last_bit  = 0;
+	int mark_count = 0;
+	int mark_bit = 0;
+	int i;
+	const char *ADDR;
+
+	ADDR = bp->bitarray;
+	start -= bitmap->start;
+	start_byte = start >> 3;
+	start_bit = start % 8;
+
+	if (start_bit != 0) {
+		/*
+		 * The compared start block number or start inode number
+		 * is not the first bit in a byte.
+		 */
+		mark_count = 8 - start_bit;
+		if (len < 8 - start_bit) {
+			mark_count = (int)len;
+			mark_bit = len + start_bit - 1;
+		} else
+			mark_bit = 7;
+
+		for (i = mark_count; i > 0; i--, mark_bit--)
+			first_bit |= 1 << mark_bit;
+
+		/*
+		 * Compare blocks or inodes in the first byte.
+		 * If there is any marked bit, this function returns 0.
+		 */
+		if (first_bit & ADDR[start_byte])
+			return 0;
+		else if (len <= 8 - start_bit)
+			return 1;
+
+		start_byte++;
+		len_bit = (len - mark_count) % 8;
+		len_byte = (len - mark_count) >> 3;
+	}
+
+	/*
+	 * The compared start block number or start inode number is
+	 * the first bit in a byte.
+	 */
+	if (len_bit != 0) {
+		/*
+		 * The compared end block number or end inode number is
+		 * not the last bit in a byte.
+		 */
+		for (mark_bit = len_bit - 1; mark_bit >= 0; mark_bit--)
+			last_bit |= 1 << mark_bit;
+
+		/*
+		 * Compare blocks or inodes in the last byte.
+		 * If there is any marked bit, this function returns 0.
+		 */
+		if (last_bit & ADDR[start_byte + len_byte])
+			return 0;
+		else if (len_byte == 0)
+			return 1;
+	}
+
+	/* Check whether all bytes are 0 */
+	return ext2fs_mem_is_zero(ADDR + start_byte, len_byte);
+}
+
+
+static errcode_t ba_set_bmap_range(ext2fs_generic_bitmap bitmap,
+				     __u64 start, size_t num, void *in)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+
+	memcpy (bp->bitarray + (start >> 3), in, (num + 7) >> 3);
+
+	return 0;
+}
+
+static errcode_t ba_get_bmap_range(ext2fs_generic_bitmap bitmap,
+				     __u64 start, size_t num, void *out)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+
+	memcpy (out, bp->bitarray + (start >> 3), (num + 7) >> 3);
+
+	return 0;
+}
+
+static void ba_clear_bmap(ext2fs_generic_bitmap bitmap)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private) bitmap->private;
+
+	memset(bp->bitarray, 0,
+	       (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
+}
+
+static void ba_print_stats(ext2fs_generic_bitmap bitmap)
+{
+	fprintf(stderr, "%16llu Bytes used by bitarray\n",
+		((bitmap->real_end - bitmap->start) >> 3) + 1 +
+		sizeof(struct ext2fs_ba_private_struct));
+}
+
+/* Find the first zero bit between start and end, inclusive. */
+static errcode_t ba_find_first_zero(ext2fs_generic_bitmap bitmap,
+				    __u64 start, __u64 end, __u64 *out)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private)bitmap->private;
+	unsigned long bitpos = start - bitmap->start;
+	unsigned long count = end - start + 1;
+	int byte_found = 0; /* whether a != 0xff byte has been found */
+	const unsigned char *pos;
+	unsigned long max_loop_count, i;
+
+	if (start < bitmap->start || end > bitmap->end || start > end)
+		return EINVAL;
+
+	if (bitmap->cluster_bits)
+		return EINVAL;
+
+	/* scan bits until we hit a byte boundary */
+	while ((bitpos & 0x7) != 0 && count > 0) {
+		if (!ext2fs_test_bit64(bitpos, bp->bitarray)) {
+			*out = bitpos + bitmap->start;
+			return 0;
+		}
+		bitpos++;
+		count--;
+	}
+
+	if (!count)
+		return ENOENT;
+
+	pos = ((unsigned char *)bp->bitarray) + (bitpos >> 3);
+	/* scan bytes until 8-byte (64-bit) aligned */
+	while (count >= 8 && (((unsigned long)pos) & 0x07)) {
+		if (*pos != 0xff) {
+			byte_found = 1;
+			break;
+		}
+		pos++;
+		count -= 8;
+		bitpos += 8;
+	}
+
+	if (!byte_found) {
+		max_loop_count = count >> 6; /* 8-byte blocks */
+		i = max_loop_count;
+		while (i) {
+			if (*((const __u64 *)pos) != ((__u64)-1))
+				break;
+			pos += 8;
+			i--;
+		}
+		count -= 64 * (max_loop_count - i);
+		bitpos += 64 * (max_loop_count - i);
+
+		max_loop_count = count >> 3;
+		i = max_loop_count;
+		while (i) {
+			if (*pos != 0xff) {
+				byte_found = 1;
+				break;
+			}
+			pos++;
+			i--;
+		}
+		count -= 8 * (max_loop_count - i);
+		bitpos += 8 * (max_loop_count - i);
+	}
+
+	/* Here either count < 8 or byte_found == 1. */
+	while (count-- > 0) {
+		if (!ext2fs_test_bit64(bitpos, bp->bitarray)) {
+			*out = bitpos + bitmap->start;
+			return 0;
+		}
+		bitpos++;
+	}
+
+	return ENOENT;
+}
+
+struct ext2_bitmap_ops ext2fs_blkmap64_bitarray = {
+	.type = EXT2FS_BMAP64_BITARRAY,
+	.new_bmap = ba_new_bmap,
+	.free_bmap = ba_free_bmap,
+	.copy_bmap = ba_copy_bmap,
+	.resize_bmap = ba_resize_bmap,
+	.mark_bmap = ba_mark_bmap,
+	.unmark_bmap = ba_unmark_bmap,
+	.test_bmap = ba_test_bmap,
+	.test_clear_bmap_extent = ba_test_clear_bmap_extent,
+	.mark_bmap_extent = ba_mark_bmap_extent,
+	.unmark_bmap_extent = ba_unmark_bmap_extent,
+	.set_bmap_range = ba_set_bmap_range,
+	.get_bmap_range = ba_get_bmap_range,
+	.clear_bmap = ba_clear_bmap,
+	.print_stats = ba_print_stats,
+	.find_first_zero = ba_find_first_zero
+};
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/blkmap64_rb.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/blkmap64_rb.c
new file mode 100644
index 0000000..a22682e
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/blkmap64_rb.c
@@ -0,0 +1,886 @@
+/*
+ * blkmap64_rb.c --- Simple rb-tree implementation for bitmaps
+ *
+ * (C)2010 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>
+ *
+ * %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"
+#include "bmap64.h"
+#include "rbtree.h"
+
+#include <limits.h>
+
+struct bmap_rb_extent {
+	struct rb_node node;
+	__u64 start;
+	__u64 count;
+};
+
+struct ext2fs_rb_private {
+	struct rb_root root;
+	struct bmap_rb_extent *wcursor;
+	struct bmap_rb_extent *rcursor;
+	struct bmap_rb_extent *rcursor_next;
+#ifdef BMAP_STATS_OPS
+	__u64 mark_hit;
+	__u64 test_hit;
+#endif
+};
+
+inline static struct bmap_rb_extent *node_to_extent(struct rb_node *node)
+{
+	/*
+	 * This depends on the fact the struct rb_node is at the
+	 * beginning of the bmap_rb_extent structure.  We use this
+	 * instead of the ext2fs_rb_entry macro because it causes gcc
+	 * -Wall to generate a huge amount of noise.
+	 */
+	return (struct bmap_rb_extent *) node;
+}
+
+static int rb_insert_extent(__u64 start, __u64 count,
+			    struct ext2fs_rb_private *);
+static void rb_get_new_extent(struct bmap_rb_extent **, __u64, __u64);
+
+/* #define DEBUG_RB */
+
+#ifdef DEBUG_RB
+static void print_tree(struct rb_root *root)
+{
+	struct rb_node *node = NULL;
+	struct bmap_rb_extent *ext;
+
+	printf("\t\t\t=================================\n");
+	node = ext2fs_rb_first(root);
+	for (node = ext2fs_rb_first(root); node != NULL; 
+	     node = ext2fs_rb_next(node)) {
+		ext = node_to_extent(node);
+		printf("\t\t\t--> (%llu -> %llu)\n",
+			ext->start, ext->start + ext->count);
+	}
+	printf("\t\t\t=================================\n");
+}
+
+static void check_tree(struct rb_root *root, const char *msg)
+{
+	struct rb_node *new_node, *node, *next;
+	struct bmap_rb_extent *ext, *old = NULL;
+
+	for (node = ext2fs_rb_first(root); node;
+	     node = ext2fs_rb_next(node)) {
+		ext = node_to_extent(node);
+		if (ext->count <= 0) {
+			printf("Tree Error: count is crazy\n");
+			printf("extent: %llu -> %llu (%u)\n", ext->start,
+				ext->start + ext->count, ext->count);
+			goto err_out;
+		}
+		if (ext->start < 0) {
+			printf("Tree Error: start is crazy\n");
+			printf("extent: %llu -> %llu (%u)\n", ext->start,
+				ext->start + ext->count, ext->count);
+			goto err_out;
+		}
+
+		if (old) {
+			if (old->start > ext->start) {
+				printf("Tree Error: start is crazy\n");
+				printf("extent: %llu -> %llu (%u)\n",
+					old->start, old->start + old->count,
+					old->count);
+				printf("extent next: %llu -> %llu (%u)\n",
+					ext->start, ext->start + ext->count,
+					ext->count);
+				goto err_out;
+			}
+			if ((old->start + old->count) >= ext->start) {
+				printf("Tree Error: extent is crazy\n");
+				printf("extent: %llu -> %llu (%u)\n",
+					old->start, old->start + old->count,
+					old->count);
+				printf("extent next: %llu -> %llu (%u)\n",
+					ext->start, ext->start + ext->count,
+					ext->count);
+				goto err_out;
+			}
+		}
+		old = ext;
+	}
+	return;
+
+err_out:
+	printf("%s\n", msg);
+	print_tree(root);
+	exit(1);
+}
+#else
+#define check_tree(root, msg) do {} while (0)
+#define print_tree(root, msg) do {} while (0)
+#endif
+
+static void rb_get_new_extent(struct bmap_rb_extent **ext, __u64 start,
+			     __u64 count)
+{
+	struct bmap_rb_extent *new_ext;
+	int retval;
+
+	retval = ext2fs_get_mem(sizeof (struct bmap_rb_extent),
+				&new_ext);
+	if (retval) {
+		perror("ext2fs_get_mem");
+		exit(1);
+	}
+
+	new_ext->start = start;
+	new_ext->count = count;
+	*ext = new_ext;
+}
+
+inline
+static void rb_free_extent(struct ext2fs_rb_private *bp,
+			   struct bmap_rb_extent *ext)
+{
+	if (bp->wcursor == ext)
+		bp->wcursor = NULL;
+	if (bp->rcursor == ext)
+		bp->rcursor = NULL;
+	if (bp->rcursor_next == ext)
+		bp->rcursor_next = NULL;
+	ext2fs_free_mem(&ext);
+}
+
+static errcode_t rb_alloc_private_data (ext2fs_generic_bitmap bitmap)
+{
+	struct ext2fs_rb_private *bp;
+	errcode_t	retval;
+
+	retval = ext2fs_get_mem(sizeof (struct ext2fs_rb_private), &bp);
+	if (retval)
+		return retval;
+
+	bp->root = RB_ROOT;
+	bp->rcursor = NULL;
+	bp->rcursor_next = NULL;
+	bp->wcursor = NULL;
+
+#ifdef BMAP_STATS_OPS
+	bp->test_hit = 0;
+	bp->mark_hit = 0;
+#endif
+
+	bitmap->private = (void *) bp;
+	return 0;
+}
+
+static errcode_t rb_new_bmap(ext2_filsys fs EXT2FS_ATTR((unused)),
+			     ext2fs_generic_bitmap bitmap)
+{
+	errcode_t	retval;
+
+	retval = rb_alloc_private_data (bitmap);
+	if (retval)
+		return retval;
+
+	return 0;
+}
+
+static void rb_free_tree(struct rb_root *root)
+{
+	struct bmap_rb_extent *ext;
+	struct rb_node *node, *next;
+
+	for (node = ext2fs_rb_first(root); node; node = next) {
+		next = ext2fs_rb_next(node);
+		ext = node_to_extent(node);
+		ext2fs_rb_erase(node, root);
+		ext2fs_free_mem(&ext);
+	}
+}
+
+static void rb_free_bmap(ext2fs_generic_bitmap bitmap)
+{
+	struct ext2fs_rb_private *bp;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+
+	rb_free_tree(&bp->root);
+	ext2fs_free_mem(&bp);
+	bp = 0;
+}
+
+static errcode_t rb_copy_bmap(ext2fs_generic_bitmap src,
+			      ext2fs_generic_bitmap dest)
+{
+	struct ext2fs_rb_private *src_bp, *dest_bp;
+	struct bmap_rb_extent *src_ext, *dest_ext;
+	struct rb_node *dest_node, *src_node, *dest_last, **n;
+	errcode_t retval = 0;
+
+	retval = rb_alloc_private_data (dest);
+	if (retval)
+		return retval;
+
+	src_bp = (struct ext2fs_rb_private *) src->private;
+	dest_bp = (struct ext2fs_rb_private *) dest->private;
+	src_bp->rcursor = NULL;
+	dest_bp->rcursor = NULL;
+
+	src_node = ext2fs_rb_first(&src_bp->root);
+	while (src_node) {
+		src_ext = node_to_extent(src_node);
+		retval = ext2fs_get_mem(sizeof (struct bmap_rb_extent),
+					&dest_ext);
+		if (retval)
+			break;
+
+		memcpy(dest_ext, src_ext, sizeof(struct bmap_rb_extent));
+
+		dest_node = &dest_ext->node;
+		n = &dest_bp->root.rb_node;
+
+		dest_last = NULL;
+		if (*n) {
+			dest_last = ext2fs_rb_last(&dest_bp->root);
+			n = &(dest_last)->rb_right;
+		}
+
+		ext2fs_rb_link_node(dest_node, dest_last, n);
+		ext2fs_rb_insert_color(dest_node, &dest_bp->root);
+
+		src_node = ext2fs_rb_next(src_node);
+	}
+
+	return retval;
+}
+
+static void rb_truncate(__u64 new_max, struct rb_root *root)
+{
+	struct bmap_rb_extent *ext;
+	struct rb_node *node;
+
+	node = ext2fs_rb_last(root);
+	while (node) {
+		ext = node_to_extent(node);
+
+		if ((ext->start + ext->count - 1) <= new_max)
+			break;
+		else if (ext->start > new_max) {
+			ext2fs_rb_erase(node, root);
+			ext2fs_free_mem(&ext);
+			node = ext2fs_rb_last(root);
+			continue;
+		} else
+			ext->count = new_max - ext->start + 1;
+	}
+}
+
+static errcode_t rb_resize_bmap(ext2fs_generic_bitmap bmap,
+				__u64 new_end, __u64 new_real_end)
+{
+	struct ext2fs_rb_private *bp;
+
+	if (new_real_end >= bmap->real_end) {
+		bmap->end = new_end;
+		bmap->real_end = new_real_end;
+		return 0;
+	}
+
+	bp = (struct ext2fs_rb_private *) bmap->private;
+	bp->rcursor = NULL;
+	bp->wcursor = NULL;
+
+	/* truncate tree to new_real_end size */
+	rb_truncate(new_real_end, &bp->root);
+
+	bmap->end = new_end;
+	bmap->real_end = new_real_end;
+	return 0;
+
+}
+
+inline static int
+rb_test_bit(struct ext2fs_rb_private *bp, __u64 bit)
+{
+	struct bmap_rb_extent *rcursor, *next_ext = NULL;
+	struct rb_node *parent = NULL, *next;
+	struct rb_node **n = &bp->root.rb_node;
+	struct bmap_rb_extent *ext;
+
+	rcursor = bp->rcursor;
+	if (!rcursor)
+		goto search_tree;
+
+	if (bit >= rcursor->start && bit < rcursor->start + rcursor->count) {
+#ifdef BMAP_STATS_OPS
+		bp->test_hit++;
+#endif
+		return 1;
+	}
+
+	next_ext = bp->rcursor_next;
+	if (!next_ext) {
+		next = ext2fs_rb_next(&rcursor->node);
+		if (next)
+			next_ext = node_to_extent(next);
+		bp->rcursor_next = next_ext;
+	}
+	if (next_ext) {
+		if ((bit >= rcursor->start + rcursor->count) &&
+		    (bit < next_ext->start)) {
+#ifdef BMAP_STATS_OPS
+			bp->test_hit++;
+#endif
+			return 0;
+		}
+	}
+	bp->rcursor = NULL;
+	bp->rcursor_next = NULL;
+
+	rcursor = bp->wcursor;
+	if (!rcursor)
+		goto search_tree;
+
+	if (bit >= rcursor->start && bit < rcursor->start + rcursor->count)
+		return 1;
+
+search_tree:
+
+	while (*n) {
+		parent = *n;
+		ext = node_to_extent(parent);
+		if (bit < ext->start)
+			n = &(*n)->rb_left;
+		else if (bit >= (ext->start + ext->count))
+			n = &(*n)->rb_right;
+		else {
+			bp->rcursor = ext;
+			bp->rcursor_next = NULL;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static int rb_insert_extent(__u64 start, __u64 count,
+			    struct ext2fs_rb_private *bp)
+{
+	struct rb_root *root = &bp->root;
+	struct rb_node *parent = NULL, **n = &root->rb_node;
+	struct rb_node *new_node, *node, *next;
+	struct bmap_rb_extent *new_ext;
+	struct bmap_rb_extent *ext;
+	int retval = 0;
+
+	bp->rcursor_next = NULL;
+	ext = bp->wcursor;
+	if (ext) {
+		if (start >= ext->start &&
+		    start <= (ext->start + ext->count)) {
+#ifdef BMAP_STATS_OPS
+			bp->mark_hit++;
+#endif
+			goto got_extent;
+		}
+	}
+
+	while (*n) {
+		parent = *n;
+		ext = node_to_extent(parent);
+
+		if (start < ext->start) {
+			n = &(*n)->rb_left;
+		} else if (start > (ext->start + ext->count)) {
+			n = &(*n)->rb_right;
+		} else {
+got_extent:
+			if ((start + count) <= (ext->start + ext->count))
+				return 1;
+
+			if ((ext->start + ext->count) == start)
+				retval = 0;
+			else
+				retval = 1;
+
+			count += (start - ext->start);
+			start = ext->start;
+			new_ext = ext;
+			new_node = &ext->node;
+
+			goto skip_insert;
+		}
+	}
+
+	rb_get_new_extent(&new_ext, start, count);
+
+	new_node = &new_ext->node;
+	ext2fs_rb_link_node(new_node, parent, n);
+	ext2fs_rb_insert_color(new_node, root);
+	bp->wcursor = new_ext;
+
+	node = ext2fs_rb_prev(new_node);
+	if (node) {
+		ext = node_to_extent(node);
+		if ((ext->start + ext->count) == start) {
+			start = ext->start;
+			count += ext->count;
+			ext2fs_rb_erase(node, root);
+			rb_free_extent(bp, ext);
+		}
+	}
+
+skip_insert:
+	/* See if we can merge extent to the right */
+	for (node = ext2fs_rb_next(new_node); node != NULL; node = next) {
+		next = ext2fs_rb_next(node);
+		ext = node_to_extent(node);
+
+		if ((ext->start + ext->count) <= start)
+			continue;
+
+		/* No more merging */
+		if ((start + count) < ext->start)
+			break;
+
+		/* ext is embedded in new_ext interval */
+		if ((start + count) >= (ext->start + ext->count)) {
+			ext2fs_rb_erase(node, root);
+			rb_free_extent(bp, ext);
+			continue;
+		} else {
+		/* merge ext with new_ext */
+			count += ((ext->start + ext->count) -
+				  (start + count));
+			ext2fs_rb_erase(node, root);
+			rb_free_extent(bp, ext);
+			break;
+		}
+	}
+
+	new_ext->start = start;
+	new_ext->count = count;
+
+	return retval;
+}
+
+static int rb_remove_extent(__u64 start, __u64 count,
+			    struct ext2fs_rb_private *bp)
+{
+	struct rb_root *root = &bp->root;
+	struct rb_node *parent = NULL, **n = &root->rb_node;
+	struct rb_node *node;
+	struct bmap_rb_extent *ext;
+	__u64 new_start, new_count;
+	int retval = 0;
+
+	if (EXT2FS_RB_EMPTY_ROOT(root))
+		return 0;
+
+	while (*n) {
+		parent = *n;
+		ext = node_to_extent(parent);
+		if (start < ext->start) {
+			n = &(*n)->rb_left;
+			continue;
+		} else if (start >= (ext->start + ext->count)) {
+			n = &(*n)->rb_right;
+			continue;
+		}
+
+		if ((start > ext->start) &&
+		    (start + count) < (ext->start + ext->count)) {
+			/* We have to split extent into two */
+			new_start = start + count;
+			new_count = (ext->start + ext->count) - new_start;
+
+			ext->count = start - ext->start;
+
+			rb_insert_extent(new_start, new_count, bp);
+			return 1;
+		}
+
+		if ((start + count) >= (ext->start + ext->count)) {
+			ext->count = start - ext->start;
+			retval = 1;
+		}
+
+		if (0 == ext->count) {
+			parent = ext2fs_rb_next(&ext->node);
+			ext2fs_rb_erase(&ext->node, root);
+			rb_free_extent(bp, ext);
+			break;
+		}
+
+		if (start == ext->start) {
+			ext->start += count;
+			ext->count -= count;
+			return 1;
+		}
+	}
+
+	/* See if we should delete or truncate extent on the right */
+	for (; parent != NULL; parent = node) {
+		node = ext2fs_rb_next(parent);
+		ext = node_to_extent(parent);
+		if ((ext->start + ext->count) <= start)
+			continue;
+
+		/* No more extents to be removed/truncated */
+		if ((start + count) < ext->start)
+			break;
+
+		/* The entire extent is within the region to be removed */
+		if ((start + count) >= (ext->start + ext->count)) {
+			ext2fs_rb_erase(parent, root);
+			rb_free_extent(bp, ext);
+			retval = 1;
+			continue;
+		} else {
+			/* modify the last extent in reigon to be removed */
+			ext->count -= ((start + count) - ext->start);
+			ext->start = start + count;
+			retval = 1;
+			break;
+		}
+	}
+
+	return retval;
+}
+
+static int rb_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+{
+	struct ext2fs_rb_private *bp;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+	arg -= bitmap->start;
+
+	return rb_insert_extent(arg, 1, bp);
+}
+
+static int rb_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+{
+	struct ext2fs_rb_private *bp;
+	int retval;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+	arg -= bitmap->start;
+
+	retval = rb_remove_extent(arg, 1, bp);
+	check_tree(&bp->root, __func__);
+
+	return retval;
+}
+
+inline
+static int rb_test_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
+{
+	struct ext2fs_rb_private *bp;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+	arg -= bitmap->start;
+
+	return rb_test_bit(bp, arg);
+}
+
+static void rb_mark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+				unsigned int num)
+{
+	struct ext2fs_rb_private *bp;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+	arg -= bitmap->start;
+
+	rb_insert_extent(arg, num, bp);
+}
+
+static void rb_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
+				  unsigned int num)
+{
+	struct ext2fs_rb_private *bp;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+	arg -= bitmap->start;
+
+	rb_remove_extent(arg, num, bp);
+	check_tree(&bp->root, __func__);
+}
+
+static int rb_test_clear_bmap_extent(ext2fs_generic_bitmap bitmap,
+				     __u64 start, unsigned int len)
+{
+	struct rb_node *parent = NULL, **n;
+	struct rb_node *node, *next;
+	struct ext2fs_rb_private *bp;
+	struct bmap_rb_extent *ext;
+	int retval = 1;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+	n = &bp->root.rb_node;
+	start -= bitmap->start;
+
+	if ((len == 0) || EXT2FS_RB_EMPTY_ROOT(&bp->root))
+		return 1;
+
+	/*
+	 * If we find nothing, we should examine whole extent, but
+	 * when we find match, the extent is not clean, thus be return
+	 * false.
+	 */
+	while (*n) {
+		parent = *n;
+		ext = node_to_extent(parent);
+		if (start < ext->start) {
+			n = &(*n)->rb_left;
+		} else if (start >= (ext->start + ext->count)) {
+			n = &(*n)->rb_right;
+		} else {
+			/*
+			 * We found extent int the tree -> extent is not
+			 * clean
+			 */
+			return 0;
+		}
+	}
+
+	node = parent;
+	while (node) {
+		next = ext2fs_rb_next(node);
+		ext = node_to_extent(node);
+		node = next;
+
+		if ((ext->start + ext->count) <= start)
+			continue;
+
+		/* No more merging */
+		if ((start + len) <= ext->start)
+			break;
+
+		retval = 0;
+		break;
+	}
+	return retval;
+}
+
+static errcode_t rb_set_bmap_range(ext2fs_generic_bitmap bitmap,
+				     __u64 start, size_t num, void *in)
+{
+	struct ext2fs_rb_private *bp;
+	unsigned char *cp = in;
+	size_t i;
+	int first_set = -1;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+
+	for (i = 0; i < num; i++) {
+		if ((i & 7) == 0) {
+			unsigned char c = cp[i/8];
+			if (c == 0xFF) {
+				if (first_set == -1)
+					first_set = i;
+				i += 7;
+				continue;
+			}
+			if ((c == 0x00) && (first_set == -1)) {
+				i += 7;
+				continue;
+			}
+		}
+		if (ext2fs_test_bit(i, in)) {
+			if (first_set == -1)
+				first_set = i;
+			continue;
+		}
+		if (first_set == -1)
+			continue;
+
+		rb_insert_extent(start + first_set - bitmap->start,
+				 i - first_set, bp);
+		first_set = -1;
+	}
+	if (first_set != -1)
+		rb_insert_extent(start + first_set - bitmap->start,
+				 num - first_set, bp);
+
+	return 0;
+}
+
+static errcode_t rb_get_bmap_range(ext2fs_generic_bitmap bitmap,
+				     __u64 start, size_t num, void *out)
+{
+
+	struct rb_node *parent = NULL, *next, **n;
+	struct ext2fs_rb_private *bp;
+	struct bmap_rb_extent *ext;
+	int count;
+	__u64 pos;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+	n = &bp->root.rb_node;
+	start -= bitmap->start;
+
+	if (EXT2FS_RB_EMPTY_ROOT(&bp->root))
+		return 0;
+
+	while (*n) {
+		parent = *n;
+		ext = node_to_extent(parent);
+		if (start < ext->start) {
+			n = &(*n)->rb_left;
+		} else if (start >= (ext->start + ext->count)) {
+			n = &(*n)->rb_right;
+		} else
+			break;
+	}
+
+	memset(out, 0, (num + 7) >> 3);
+
+	for (; parent != NULL; parent = next) {
+		next = ext2fs_rb_next(parent);
+		ext = node_to_extent(parent);
+
+		pos = ext->start;
+		count = ext->count;
+		if (pos >= start + num)
+			break;
+		if (pos < start) {
+			count -= start - pos;
+			if (count < 0)
+				continue;
+			pos = start;
+		}
+		if (pos + count > start + num)
+			count = start + num - pos;
+
+		while (count > 0) {
+			if ((count >= 8) &&
+			    ((pos - start) % 8) == 0) {
+				int nbytes = count >> 3;
+				int offset = (pos - start) >> 3;
+
+				memset(((char *) out) + offset, 0xFF, nbytes);
+				pos += nbytes << 3;
+				count -= nbytes << 3;
+				continue;
+			}
+			ext2fs_fast_set_bit64((pos - start), out);
+			pos++;
+			count--;
+		}
+	}
+	return 0;
+}
+
+static void rb_clear_bmap(ext2fs_generic_bitmap bitmap)
+{
+	struct ext2fs_rb_private *bp;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+
+	rb_free_tree(&bp->root);
+	bp->rcursor = NULL;
+	bp->rcursor_next = NULL;
+	bp->wcursor = NULL;
+}
+
+#ifdef BMAP_STATS
+static void rb_print_stats(ext2fs_generic_bitmap bitmap)
+{
+	struct ext2fs_rb_private *bp;
+	struct rb_node *node = NULL;
+	struct bmap_rb_extent *ext;
+	__u64 count = 0;
+	__u64 max_size = 0;
+	__u64 min_size = ULONG_MAX;
+	__u64 size = 0, avg_size = 0;
+	double eff;
+#ifdef BMAP_STATS_OPS
+	__u64 mark_all, test_all;
+	double m_hit = 0.0, t_hit = 0.0;
+#endif
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+
+	node = ext2fs_rb_first(&bp->root);
+	for (node = ext2fs_rb_first(&bp->root); node != NULL;
+	     node = ext2fs_rb_next(node)) {
+		ext = node_to_extent(node);
+		count++;
+		if (ext->count > max_size)
+			max_size = ext->count;
+		if (ext->count < min_size)
+			min_size = ext->count;
+		size += ext->count;
+	}
+
+	if (count)
+		avg_size = size / count;
+	if (min_size == ULONG_MAX)
+		min_size = 0;
+	eff = (double)((count * sizeof(struct bmap_rb_extent)) << 3) /
+	      (bitmap->real_end - bitmap->start);
+#ifdef BMAP_STATS_OPS
+	mark_all = bitmap->stats.mark_count + bitmap->stats.mark_ext_count;
+	test_all = bitmap->stats.test_count + bitmap->stats.test_ext_count;
+	if (mark_all)
+		m_hit = ((double)bp->mark_hit / mark_all) * 100;
+	if (test_all)
+		t_hit = ((double)bp->test_hit / test_all) * 100;
+
+	fprintf(stderr, "%16llu cache hits on test (%.2f%%)\n"
+		"%16llu cache hits on mark (%.2f%%)\n",
+		bp->test_hit, t_hit, bp->mark_hit, m_hit);
+#endif
+	fprintf(stderr, "%16llu extents (%llu bytes)\n",
+		count, ((count * sizeof(struct bmap_rb_extent)) +
+			sizeof(struct ext2fs_rb_private)));
+ 	fprintf(stderr, "%16llu bits minimum size\n",
+		min_size);
+	fprintf(stderr, "%16llu bits maximum size\n"
+		"%16llu bits average size\n",
+		max_size, avg_size);
+	fprintf(stderr, "%16llu bits set in bitmap (out of %llu)\n", size,
+		bitmap->real_end - bitmap->start);
+	fprintf(stderr,
+		"%16.4lf memory / bitmap bit memory ratio (bitarray = 1)\n",
+		eff);
+}
+#else
+static void rb_print_stats(ext2fs_generic_bitmap bitmap){}
+#endif
+
+struct ext2_bitmap_ops ext2fs_blkmap64_rbtree = {
+	.type = EXT2FS_BMAP64_RBTREE,
+	.new_bmap = rb_new_bmap,
+	.free_bmap = rb_free_bmap,
+	.copy_bmap = rb_copy_bmap,
+	.resize_bmap = rb_resize_bmap,
+	.mark_bmap = rb_mark_bmap,
+	.unmark_bmap = rb_unmark_bmap,
+	.test_bmap = rb_test_bmap,
+	.test_clear_bmap_extent = rb_test_clear_bmap_extent,
+	.mark_bmap_extent = rb_mark_bmap_extent,
+	.unmark_bmap_extent = rb_unmark_bmap_extent,
+	.set_bmap_range = rb_set_bmap_range,
+	.get_bmap_range = rb_get_bmap_range,
+	.clear_bmap = rb_clear_bmap,
+	.print_stats = rb_print_stats,
+};
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/blknum.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/blknum.c
new file mode 100644
index 0000000..8ced1ee
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/blknum.c
@@ -0,0 +1,495 @@
+/*
+ * blknum.c --- Functions to handle blk64_t and high/low 64-bit block
+ * number.
+ *
+ * Copyright IBM Corporation, 2007
+ * Author Jose R. Santos <jrs@us.ibm.com>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include "ext2fs.h"
+
+/*
+ * Return the group # of a block
+ */
+dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t blk)
+{
+	return (blk - fs->super->s_first_data_block) /
+		fs->super->s_blocks_per_group;
+}
+
+/*
+ * Return the first block (inclusive) in a group
+ */
+blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group)
+{
+	return fs->super->s_first_data_block +
+		((blk64_t)group * fs->super->s_blocks_per_group);
+}
+
+/*
+ * Return the last block (inclusive) in a group
+ */
+blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group)
+{
+	return (group == fs->group_desc_count - 1 ?
+		ext2fs_blocks_count(fs->super) - 1 :
+		ext2fs_group_first_block2(fs, group) +
+			(fs->super->s_blocks_per_group - 1));
+}
+
+/*
+ * Return the number of blocks in a group
+ */
+int ext2fs_group_blocks_count(ext2_filsys fs, dgrp_t group)
+{
+	int num_blocks;
+
+	if (group == fs->group_desc_count - 1) {
+		num_blocks = (ext2fs_blocks_count(fs->super) -
+				fs->super->s_first_data_block) %
+			      fs->super->s_blocks_per_group;
+		if (!num_blocks)
+			num_blocks = fs->super->s_blocks_per_group;
+	} else
+		num_blocks = fs->super->s_blocks_per_group;
+
+	return num_blocks;
+}
+
+/*
+ * Return the inode data block count
+ */
+blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs,
+					struct ext2_inode *inode)
+{
+	return (inode->i_blocks |
+		((fs->super->s_feature_ro_compat &
+		  EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ?
+		 (__u64) inode->osd2.linux2.l_i_blocks_hi << 32 : 0)) -
+		(inode->i_file_acl ? fs->blocksize >> 9 : 0);
+}
+
+/*
+ * Return the inode i_blocks count
+ */
+blk64_t ext2fs_inode_i_blocks(ext2_filsys fs,
+					struct ext2_inode *inode)
+{
+	return (inode->i_blocks |
+		((fs->super->s_feature_ro_compat &
+		  EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ?
+		 (__u64)inode->osd2.linux2.l_i_blocks_hi << 32 : 0));
+}
+
+/*
+ * Return the fs block count
+ */
+blk64_t ext2fs_blocks_count(struct ext2_super_block *super)
+{
+	return super->s_blocks_count |
+		(super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
+		(__u64) super->s_blocks_count_hi << 32 : 0);
+}
+
+/*
+ * Set the fs block count
+ */
+void ext2fs_blocks_count_set(struct ext2_super_block *super, blk64_t blk)
+{
+	super->s_blocks_count = blk;
+	if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		super->s_blocks_count_hi = (__u64) blk >> 32;
+}
+
+/*
+ * Add to the current fs block count
+ */
+void ext2fs_blocks_count_add(struct ext2_super_block *super, blk64_t blk)
+{
+	blk64_t tmp;
+	tmp = ext2fs_blocks_count(super) + blk;
+	ext2fs_blocks_count_set(super, tmp);
+}
+
+/*
+ * Return the fs reserved block count
+ */
+blk64_t ext2fs_r_blocks_count(struct ext2_super_block *super)
+{
+	return super->s_r_blocks_count |
+		(super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
+		(__u64) super->s_r_blocks_count_hi << 32 : 0);
+}
+
+/*
+ * Set the fs reserved block count
+ */
+void ext2fs_r_blocks_count_set(struct ext2_super_block *super, blk64_t blk)
+{
+	super->s_r_blocks_count = blk;
+	if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		super->s_r_blocks_count_hi = (__u64) blk >> 32;
+}
+
+/*
+ * Add to the current reserved fs block count
+ */
+void ext2fs_r_blocks_count_add(struct ext2_super_block *super, blk64_t blk)
+{
+	blk64_t tmp;
+	tmp = ext2fs_r_blocks_count(super) + blk;
+	ext2fs_r_blocks_count_set(super, tmp);
+}
+
+/*
+ * Return the fs free block count
+ */
+blk64_t ext2fs_free_blocks_count(struct ext2_super_block *super)
+{
+	return super->s_free_blocks_count |
+		(super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
+		(__u64) super->s_free_blocks_hi << 32 : 0);
+}
+
+/*
+ * Set the fs free block count
+ */
+void ext2fs_free_blocks_count_set(struct ext2_super_block *super, blk64_t blk)
+{
+	super->s_free_blocks_count = blk;
+	if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		super->s_free_blocks_hi = (__u64) blk >> 32;
+}
+
+/*
+ * Add to the current free fs block count
+ */
+void ext2fs_free_blocks_count_add(struct ext2_super_block *super, blk64_t blk)
+{
+	blk64_t tmp;
+	tmp = ext2fs_free_blocks_count(super) + blk;
+	ext2fs_free_blocks_count_set(super, tmp);
+}
+
+/*
+ * Get a pointer to a block group descriptor.  We need the explicit
+ * pointer to the group desc for code that swaps block group
+ * descriptors before writing them out, as it wants to make a copy and
+ * do the swap there.
+ */
+struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
+					  struct opaque_ext2_group_desc *gdp,
+					  dgrp_t group)
+{
+	return (struct ext2_group_desc *)((char *)gdp +
+					  group * EXT2_DESC_SIZE(fs->super));
+}
+
+/* Do the same but as an ext4 group desc for internal use here */
+static struct ext4_group_desc *ext4fs_group_desc(ext2_filsys fs,
+					  struct opaque_ext2_group_desc *gdp,
+					  dgrp_t group)
+{
+	return (struct ext4_group_desc *)ext2fs_group_desc(fs, gdp, group);
+}
+
+/*
+ * Return the block bitmap block of a group
+ */
+blk64_t ext2fs_block_bitmap_loc(ext2_filsys fs, dgrp_t group)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	return gdp->bg_block_bitmap |
+		(fs->super->s_feature_incompat
+		 & EXT4_FEATURE_INCOMPAT_64BIT ?
+		 (__u64)gdp->bg_block_bitmap_hi << 32 : 0);
+}
+
+/*
+ * Set the block bitmap block of a group
+ */
+void ext2fs_block_bitmap_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_block_bitmap = blk;
+	if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		gdp->bg_block_bitmap_hi = (__u64) blk >> 32;
+}
+
+/*
+ * Return the inode bitmap block of a group
+ */
+blk64_t ext2fs_inode_bitmap_loc(ext2_filsys fs, dgrp_t group)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	return gdp->bg_inode_bitmap |
+		(fs->super->s_feature_incompat
+		 & EXT4_FEATURE_INCOMPAT_64BIT ?
+		 (__u64) gdp->bg_inode_bitmap_hi << 32 : 0);
+}
+
+/*
+ * Set the inode bitmap block of a group
+ */
+void ext2fs_inode_bitmap_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_inode_bitmap = blk;
+	if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		gdp->bg_inode_bitmap_hi = (__u64) blk >> 32;
+}
+
+/*
+ * Return the inode table block of a group
+ */
+blk64_t ext2fs_inode_table_loc(ext2_filsys fs, dgrp_t group)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	return gdp->bg_inode_table |
+		(fs->super->s_feature_incompat
+		 & EXT4_FEATURE_INCOMPAT_64BIT ?
+		 (__u64) gdp->bg_inode_table_hi << 32 : 0);
+}
+
+/*
+ * Set the inode table block of a group
+ */
+void ext2fs_inode_table_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_inode_table = blk;
+	if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		gdp->bg_inode_table_hi = (__u64) blk >> 32;
+}
+
+/*
+ * Return the free blocks count of a group
+ */
+__u32 ext2fs_bg_free_blocks_count(ext2_filsys fs, dgrp_t group)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	return gdp->bg_free_blocks_count |
+		(fs->super->s_feature_incompat
+		 & EXT4_FEATURE_INCOMPAT_64BIT ?
+		 (__u32) gdp->bg_free_blocks_count_hi << 16 : 0);
+}
+
+/*
+ * Set the free blocks count of a group
+ */
+void ext2fs_bg_free_blocks_count_set(ext2_filsys fs, dgrp_t group, __u32 n)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_free_blocks_count = n;
+
+	if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		gdp->bg_free_blocks_count_hi = (__u32) n >> 16;
+}
+
+/*
+ * Return the free inodes count of a group
+ */
+__u32 ext2fs_bg_free_inodes_count(ext2_filsys fs, dgrp_t group)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	return gdp->bg_free_inodes_count |
+		(fs->super->s_feature_incompat
+		 & EXT4_FEATURE_INCOMPAT_64BIT ?
+		 (__u32) gdp->bg_free_inodes_count_hi << 16 : 0);
+}
+
+/*
+ * Set the free inodes count of a group
+ */
+void ext2fs_bg_free_inodes_count_set(ext2_filsys fs, dgrp_t group, __u32 n)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_free_inodes_count = n;
+	if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		gdp->bg_free_inodes_count_hi = (__u32) n >> 16;
+}
+
+/*
+ * Return the used dirs count of a group
+ */
+__u32 ext2fs_bg_used_dirs_count(ext2_filsys fs, dgrp_t group)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	return gdp->bg_used_dirs_count |
+		(fs->super->s_feature_incompat
+		 & EXT4_FEATURE_INCOMPAT_64BIT ?
+		 (__u32) gdp->bg_used_dirs_count_hi << 16 : 0);
+}
+
+/*
+ * Set the used dirs count of a group
+ */
+void ext2fs_bg_used_dirs_count_set(ext2_filsys fs, dgrp_t group, __u32 n)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_used_dirs_count = n;
+	if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		gdp->bg_used_dirs_count_hi = (__u32) n >> 16;
+}
+
+/*
+ * Return the unused inodes count of a group
+ */
+__u32 ext2fs_bg_itable_unused(ext2_filsys fs, dgrp_t group)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	return gdp->bg_itable_unused |
+		(fs->super->s_feature_incompat
+		 & EXT4_FEATURE_INCOMPAT_64BIT ?
+		 (__u32) gdp->bg_itable_unused_hi << 16 : 0);
+}
+
+/*
+ * Set the unused inodes count of a group
+ */
+void ext2fs_bg_itable_unused_set(ext2_filsys fs, dgrp_t group, __u32 n)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_itable_unused = n;
+	if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		gdp->bg_itable_unused_hi = (__u32) n >> 16;
+}
+
+/*
+ * Get the flags for this block group
+ */
+__u16 ext2fs_bg_flags(ext2_filsys fs, dgrp_t group)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	return gdp->bg_flags;
+}
+
+/*
+ * Zero out the flags for this block group
+ */
+void ext2fs_bg_flags_zap(ext2_filsys fs, dgrp_t group)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_flags = 0;
+	return;
+}
+
+/*
+ * Get the value of a particular flag for this block group
+ */
+int ext2fs_bg_flags_test(ext2_filsys fs, dgrp_t group, __u16 bg_flag)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	return gdp->bg_flags & bg_flag;
+}
+
+/*
+ * Set a flag or set of flags for this block group
+ */
+void ext2fs_bg_flags_set(ext2_filsys fs, dgrp_t group, __u16 bg_flags)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_flags |= bg_flags;
+	return;
+}
+
+/*
+ * Clear a flag or set of flags for this block group
+ */
+void ext2fs_bg_flags_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flags)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_flags &= ~bg_flags;
+	return;
+}
+
+/*
+ * Get the checksum for this block group
+ */
+__u16 ext2fs_bg_checksum(ext2_filsys fs, dgrp_t group)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	return gdp->bg_checksum;
+}
+
+/*
+ * Set the checksum for this block group to a previously calculated value
+ */
+void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum)
+{
+	struct ext4_group_desc *gdp;
+
+	gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+	gdp->bg_checksum = checksum;
+	return;
+}
+
+/*
+ * Get the acl block of a file
+ */
+blk64_t ext2fs_file_acl_block(ext2_filsys fs, const struct ext2_inode *inode)
+{
+	blk64_t	blk = inode->i_file_acl;
+
+	if (fs && fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		blk |= ((__u64) inode->osd2.linux2.l_i_file_acl_high) << 32;
+	return blk;
+}
+
+/*
+ * Set the acl block of a file
+ */
+void ext2fs_file_acl_block_set(ext2_filsys fs, struct ext2_inode *inode,
+			       blk64_t blk)
+{
+	inode->i_file_acl = blk;
+	if (fs && fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		inode->osd2.linux2.l_i_file_acl_high = (__u64) blk >> 32;
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/block.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/block.c
new file mode 100644
index 0000000..b8c6879
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/block.c
@@ -0,0 +1,652 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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,
+		    blk64_t	*blocknr,
+		    e2_blkcnt_t	bcount,
+		    blk64_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;
+};
+
+#define check_for_ro_violation_return(ctx, ret)				\
+	do {								\
+		if (((ctx)->flags & BLOCK_FLAG_READ_ONLY) &&		\
+		    ((ret) & BLOCK_CHANGED)) {				\
+			(ctx)->errcode = EXT2_ET_RO_BLOCK_ITERATE;	\
+			ret |= BLOCK_ABORT | BLOCK_ERROR;		\
+			return ret;					\
+		}							\
+	} while (0)
+
+#define check_for_ro_violation_goto(ctx, ret, label)			\
+	do {								\
+		if (((ctx)->flags & BLOCK_FLAG_READ_ONLY) &&		\
+		    ((ret) & BLOCK_CHANGED)) {				\
+			(ctx)->errcode = EXT2_ET_RO_BLOCK_ITERATE;	\
+			ret |= BLOCK_ABORT | BLOCK_ERROR;		\
+			goto label;					\
+		}							\
+	} while (0)
+
+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;
+	blk64_t	blk64;
+
+	limit = ctx->fs->blocksize >> 2;
+	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY)) {
+		blk64 = *ind_block;
+		ret = (*ctx->func)(ctx->fs, &blk64,
+				   BLOCK_COUNT_IND, ref_block,
+				   ref_offset, ctx->priv_data);
+		*ind_block = blk64;
+	}
+	check_for_ro_violation_return(ctx, ret);
+	if (!*ind_block || (ret & BLOCK_ABORT)) {
+		ctx->bcount += limit;
+		return ret;
+	}
+	if (*ind_block >= ext2fs_blocks_count(ctx->fs->super) ||
+	    *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++) {
+			blk64 = *block_nr;
+			flags = (*ctx->func)(ctx->fs, &blk64, ctx->bcount,
+					     *ind_block, offset,
+					     ctx->priv_data);
+			*block_nr = blk64;
+			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)
+				goto skip_sparse;
+			blk64 = *block_nr;
+			flags = (*ctx->func)(ctx->fs, &blk64, ctx->bcount,
+					     *ind_block, offset,
+					     ctx->priv_data);
+			*block_nr = blk64;
+			changed	|= flags;
+			if (flags & BLOCK_ABORT) {
+				ret |= BLOCK_ABORT;
+				break;
+			}
+		skip_sparse:
+			offset += sizeof(blk_t);
+		}
+	}
+	check_for_ro_violation_return(ctx, changed);
+	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)) {
+		blk64 = *ind_block;
+		ret |= (*ctx->func)(ctx->fs, &blk64,
+				    BLOCK_COUNT_IND, ref_block,
+				    ref_offset, ctx->priv_data);
+		*ind_block = blk64;
+	}
+	check_for_ro_violation_return(ctx, ret);
+	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;
+	blk64_t	blk64;
+
+	limit = ctx->fs->blocksize >> 2;
+	if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
+			    BLOCK_FLAG_DATA_ONLY))) {
+		blk64 = *dind_block;
+		ret = (*ctx->func)(ctx->fs, &blk64,
+				   BLOCK_COUNT_DIND, ref_block,
+				   ref_offset, ctx->priv_data);
+		*dind_block = blk64;
+	}
+	check_for_ro_violation_return(ctx, ret);
+	if (!*dind_block || (ret & BLOCK_ABORT)) {
+		ctx->bcount += limit*limit;
+		return ret;
+	}
+	if (*dind_block >= ext2fs_blocks_count(ctx->fs->super) ||
+	    *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);
+		}
+	}
+	check_for_ro_violation_return(ctx, changed);
+	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)) {
+		blk64 = *dind_block;
+		ret |= (*ctx->func)(ctx->fs, &blk64,
+				    BLOCK_COUNT_DIND, ref_block,
+				    ref_offset, ctx->priv_data);
+		*dind_block = blk64;
+	}
+	check_for_ro_violation_return(ctx, ret);
+	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;
+	blk64_t	blk64;
+
+	limit = ctx->fs->blocksize >> 2;
+	if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
+			    BLOCK_FLAG_DATA_ONLY))) {
+		blk64 = *tind_block;
+		ret = (*ctx->func)(ctx->fs, &blk64,
+				   BLOCK_COUNT_TIND, ref_block,
+				   ref_offset, ctx->priv_data);
+		*tind_block = blk64;
+	}
+	check_for_ro_violation_return(ctx, ret);
+	if (!*tind_block || (ret & BLOCK_ABORT)) {
+		ctx->bcount += limit*limit*limit;
+		return ret;
+	}
+	if (*tind_block >= ext2fs_blocks_count(ctx->fs->super) ||
+	    *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);
+		}
+	}
+	check_for_ro_violation_return(ctx, changed);
+	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)) {
+		blk64 = *tind_block;
+		ret |= (*ctx->func)(ctx->fs, &blk64,
+				    BLOCK_COUNT_TIND, ref_block,
+				    ref_offset, ctx->priv_data);
+		*tind_block = blk64;
+	}
+	check_for_ro_violation_return(ctx, ret);
+	return ret;
+}
+
+errcode_t ext2fs_block_iterate3(ext2_filsys fs,
+				ext2_ino_t ino,
+				int	flags,
+				char *block_buf,
+				int (*func)(ext2_filsys fs,
+					    blk64_t	*blocknr,
+					    e2_blkcnt_t	blockcnt,
+					    blk64_t	ref_blk,
+					    int		ref_offset,
+					    void	*priv_data),
+				void *priv_data)
+{
+	int	i;
+	int	r, ret = 0;
+	struct ext2_inode inode;
+	errcode_t	retval;
+	struct block_context ctx;
+	int	limit;
+	blk64_t	blk64;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
+	if (ctx.errcode)
+		return ctx.errcode;
+
+	/*
+	 * Check to see if we need to limit large files
+	 */
+	if (flags & BLOCK_FLAG_NO_LARGE) {
+		if (!LINUX_S_ISDIR(inode.i_mode) &&
+		    (inode.i_size_high != 0))
+			return EXT2_ET_FILE_TOO_BIG;
+	}
+
+	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_array(3, fs->blocksize, &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)) {
+		if (inode.osd1.hurd1.h_i_translator) {
+			blk64 = inode.osd1.hurd1.h_i_translator;
+			ret |= (*ctx.func)(fs, &blk64,
+					   BLOCK_COUNT_TRANSLATOR,
+					   0, 0, priv_data);
+			inode.osd1.hurd1.h_i_translator = (blk_t) blk64;
+			if (ret & BLOCK_ABORT)
+				goto abort_exit;
+			check_for_ro_violation_goto(&ctx, ret, abort_exit);
+		}
+	}
+
+	if (inode.i_flags & EXT4_EXTENTS_FL) {
+		ext2_extent_handle_t	handle;
+		struct ext2fs_extent	extent, next;
+		e2_blkcnt_t		blockcnt = 0;
+		blk64_t			blk, new_blk;
+		int			op = EXT2_EXTENT_ROOT;
+		int			uninit;
+		unsigned int		j;
+
+		ctx.errcode = ext2fs_extent_open2(fs, ino, &inode, &handle);
+		if (ctx.errcode)
+			goto abort_exit;
+
+		while (1) {
+			if (op == EXT2_EXTENT_CURRENT)
+				ctx.errcode = 0;
+			else
+				ctx.errcode = ext2fs_extent_get(handle, op,
+								&extent);
+			if (ctx.errcode) {
+				if (ctx.errcode != EXT2_ET_EXTENT_NO_NEXT)
+					break;
+				ctx.errcode = 0;
+				if (!(flags & BLOCK_FLAG_APPEND))
+					break;
+			next_block_set:
+				blk = 0;
+				r = (*ctx.func)(fs, &blk, blockcnt,
+						0, 0, priv_data);
+				ret |= r;
+				check_for_ro_violation_goto(&ctx, ret,
+							    extent_done);
+				if (r & BLOCK_CHANGED) {
+					ctx.errcode =
+						ext2fs_extent_set_bmap(handle,
+						       (blk64_t) blockcnt++,
+						       (blk64_t) blk, 0);
+					if (ctx.errcode || (ret & BLOCK_ABORT))
+						break;
+					if (blk)
+						goto next_block_set;
+				}
+				break;
+			}
+
+			op = EXT2_EXTENT_NEXT;
+			blk = extent.e_pblk;
+			if (!(extent.e_flags & EXT2_EXTENT_FLAGS_LEAF)) {
+				if (ctx.flags & BLOCK_FLAG_DATA_ONLY)
+					continue;
+				if ((!(extent.e_flags &
+				       EXT2_EXTENT_FLAGS_SECOND_VISIT) &&
+				     !(ctx.flags & BLOCK_FLAG_DEPTH_TRAVERSE)) ||
+				    ((extent.e_flags &
+				      EXT2_EXTENT_FLAGS_SECOND_VISIT) &&
+				     (ctx.flags & BLOCK_FLAG_DEPTH_TRAVERSE))) {
+					ret |= (*ctx.func)(fs, &blk,
+							   -1, 0, 0, priv_data);
+					if (ret & BLOCK_CHANGED) {
+						extent.e_pblk = blk;
+						ctx.errcode =
+				ext2fs_extent_replace(handle, 0, &extent);
+						if (ctx.errcode)
+							break;
+					}
+					if (ret & BLOCK_ABORT)
+						break;
+				}
+				continue;
+			}
+			uninit = 0;
+			if (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
+				uninit = EXT2_EXTENT_SET_BMAP_UNINIT;
+
+			/* 
+			 * Get the next extent before we start messing
+			 * with the current extent
+			 */
+			retval = ext2fs_extent_get(handle, op, &next);
+
+#if 0
+			printf("lblk %llu pblk %llu len %d blockcnt %llu\n",
+			       extent.e_lblk, extent.e_pblk,
+			       extent.e_len, blockcnt);
+#endif
+			if (extent.e_lblk + extent.e_len <= (blk64_t) blockcnt)
+				continue;
+			if (extent.e_lblk > (blk64_t) blockcnt)
+				blockcnt = extent.e_lblk;
+			j = blockcnt - extent.e_lblk;
+			blk += j;
+			for (blockcnt = extent.e_lblk, j = 0;
+			     j < extent.e_len;
+			     blk++, blockcnt++, j++) {
+				new_blk = blk;
+				r = (*ctx.func)(fs, &new_blk, blockcnt,
+						0, 0, priv_data);
+				ret |= r;
+				check_for_ro_violation_goto(&ctx, ret,
+							    extent_done);
+				if (r & BLOCK_CHANGED) {
+					ctx.errcode =
+						ext2fs_extent_set_bmap(handle,
+						       (blk64_t) blockcnt,
+						       new_blk, uninit);
+					if (ctx.errcode)
+						goto extent_done;
+				}
+				if (ret & BLOCK_ABORT)
+					goto extent_done;
+			}
+			if (retval == 0) {
+				extent = next;
+				op = EXT2_EXTENT_CURRENT;
+			}
+		}
+
+	extent_done:
+		ext2fs_extent_free(handle);
+		ret |= BLOCK_ERROR; /* ctx.errcode is always valid here */
+		goto errout;
+	}
+
+	/*
+	 * Iterate over normal data blocks
+	 */
+	for (i = 0; i < EXT2_NDIR_BLOCKS ; i++, ctx.bcount++) {
+		if (inode.i_block[i] || (flags & BLOCK_FLAG_APPEND)) {
+			blk64 = inode.i_block[i];
+			ret |= (*ctx.func)(fs, &blk64, ctx.bcount, 0, i, 
+					   priv_data);
+			inode.i_block[i] = (blk_t) blk64;
+			if (ret & BLOCK_ABORT)
+				goto abort_exit;
+		}
+	}
+	check_for_ro_violation_goto(&ctx, ret, abort_exit);
+	if (inode.i_block[EXT2_IND_BLOCK] || (flags & BLOCK_FLAG_APPEND)) {
+		ret |= block_iterate_ind(&inode.i_block[EXT2_IND_BLOCK], 
+					 0, EXT2_IND_BLOCK, &ctx);
+		if (ret & BLOCK_ABORT)
+			goto abort_exit;
+	} else
+		ctx.bcount += limit;
+	if (inode.i_block[EXT2_DIND_BLOCK] || (flags & BLOCK_FLAG_APPEND)) {
+		ret |= block_iterate_dind(&inode.i_block[EXT2_DIND_BLOCK],
+					  0, EXT2_DIND_BLOCK, &ctx);
+		if (ret & BLOCK_ABORT)
+			goto abort_exit;
+	} else
+		ctx.bcount += limit * limit;
+	if (inode.i_block[EXT2_TIND_BLOCK] || (flags & BLOCK_FLAG_APPEND)) {
+		ret |= block_iterate_tind(&inode.i_block[EXT2_TIND_BLOCK],
+					  0, EXT2_TIND_BLOCK, &ctx);
+		if (ret & BLOCK_ABORT)
+			goto abort_exit;
+	}
+
+abort_exit:
+	if (ret & BLOCK_CHANGED) {
+		retval = ext2fs_write_inode(fs, ino, &inode);
+		if (retval) {
+			ret |= BLOCK_ERROR;
+			ctx.errcode = retval;
+		}
+	}
+errout:
+	if (!block_buf)
+		ext2fs_free_mem(&ctx.ind_buf);
+
+	return (ret & BLOCK_ERROR) ? ctx.errcode : 0;
+}
+
+/*
+ * Emulate the old ext2fs_block_iterate function!
+ */
+
+struct xlate64 {
+	int (*func)(ext2_filsys fs,
+		    blk_t	*blocknr,
+		    e2_blkcnt_t	blockcnt,
+		    blk_t	ref_blk,
+		    int		ref_offset,
+		    void	*priv_data);
+	void *real_private;
+};
+
+static int xlate64_func(ext2_filsys fs, blk64_t	*blocknr,
+			e2_blkcnt_t blockcnt, blk64_t ref_blk,
+			int ref_offset, void *priv_data)
+{
+	struct xlate64 *xl = (struct xlate64 *) priv_data;
+	int		ret;
+	blk_t		block32 = *blocknr;
+	
+	ret = (*xl->func)(fs, &block32, blockcnt, (blk_t) ref_blk, ref_offset,
+			     xl->real_private);
+	*blocknr = block32;
+	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)
+{
+	struct xlate64 xl;
+
+	xl.real_private = priv_data;
+	xl.func = func;
+
+	return ext2fs_block_iterate3(fs, ino, flags, block_buf, 
+				     xlate64_func, &xl);
+}
+
+
+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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bmap.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bmap.c
new file mode 100644
index 0000000..b944c27
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bmap.c
@@ -0,0 +1,460 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+#include "ext2_fs.h"
+#include "ext2fsP.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 WORDS_BIGENDIAN
+		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 WORDS_BIGENDIAN
+	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 WORDS_BIGENDIAN
+		((blk_t *) block_buf)[nr] = ext2fs_swab32(b);
+#else
+		((blk_t *) block_buf)[nr] = b;
+#endif
+
+		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 = 0;
+	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 = 0;
+	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;
+}
+
+static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino,
+			     struct ext2_inode *inode,
+			     ext2_extent_handle_t handle,
+			     char *block_buf, int bmap_flags, blk64_t block,
+			     int *ret_flags, int *blocks_alloc,
+			     blk64_t *phys_blk);
+
+static errcode_t implied_cluster_alloc(ext2_filsys fs, ext2_ino_t ino,
+				       struct ext2_inode *inode,
+				       ext2_extent_handle_t handle,
+				       blk64_t lblk, blk64_t *phys_blk)
+{
+	blk64_t	base_block, pblock = 0;
+	int i;
+
+	if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					EXT4_FEATURE_RO_COMPAT_BIGALLOC))
+		return 0;
+
+	base_block = lblk & ~EXT2FS_CLUSTER_MASK(fs);
+	/*
+	 * Except for the logical block (lblk) that was passed in, search all
+	 * blocks in this logical cluster for a mapping to a physical cluster.
+	 * If any such map exists, calculate the physical block that maps to
+	 * the logical block and return that.
+	 *
+	 * The old code wouldn't even look if (block % cluster_ratio) == 0;
+	 * this is incorrect if we're allocating blocks in reverse order.
+	 */
+	for (i = 0; i < EXT2FS_CLUSTER_RATIO(fs); i++) {
+		if (base_block + i == lblk)
+			continue;
+		extent_bmap(fs, ino, inode, handle, 0, 0,
+			    base_block + i, 0, 0, &pblock);
+		if (pblock)
+			break;
+	}
+	if (pblock == 0)
+		return 0;
+	*phys_blk = pblock - i + (lblk - base_block);
+	return 0;
+}
+
+/* Try to map a logical block to an already-allocated physical cluster. */
+errcode_t ext2fs_map_cluster_block(ext2_filsys fs, ext2_ino_t ino,
+				   struct ext2_inode *inode, blk64_t lblk,
+				   blk64_t *pblk)
+{
+	ext2_extent_handle_t handle;
+	errcode_t retval;
+
+	/* Need bigalloc and extents to be enabled */
+	*pblk = 0;
+	if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					EXT4_FEATURE_RO_COMPAT_BIGALLOC) ||
+	    !(inode->i_flags & EXT4_EXTENTS_FL))
+		return 0;
+
+	retval = ext2fs_extent_open2(fs, ino, inode, &handle);
+	if (retval)
+		goto out;
+
+	retval = implied_cluster_alloc(fs, ino, inode, handle, lblk, pblk);
+	if (retval)
+		goto out2;
+
+out2:
+	ext2fs_extent_free(handle);
+out:
+	return retval;
+}
+
+static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino,
+			     struct ext2_inode *inode,
+			     ext2_extent_handle_t handle,
+			     char *block_buf, int bmap_flags, blk64_t block,
+			     int *ret_flags, int *blocks_alloc,
+			     blk64_t *phys_blk)
+{
+	struct ext2fs_extent	extent;
+	unsigned int		offset;
+	errcode_t		retval = 0;
+	blk64_t			blk64 = 0;
+	int			alloc = 0;
+
+	if (bmap_flags & BMAP_SET) {
+		retval = ext2fs_extent_set_bmap(handle, block,
+						*phys_blk, 0);
+		return retval;
+	}
+	retval = ext2fs_extent_goto(handle, block);
+	if (retval) {
+		/* If the extent is not found, return phys_blk = 0 */
+		if (retval == EXT2_ET_EXTENT_NOT_FOUND)
+			goto got_block;
+		return retval;
+	}
+	retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
+	if (retval)
+		return retval;
+	offset = block - extent.e_lblk;
+	if (block >= extent.e_lblk && (offset <= extent.e_len)) {
+		*phys_blk = extent.e_pblk + offset;
+		if (ret_flags && extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
+			*ret_flags |= BMAP_RET_UNINIT;
+	}
+got_block:
+	if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) {
+		implied_cluster_alloc(fs, ino, inode, handle, block, &blk64);
+		if (blk64)
+			goto set_extent;
+		retval = extent_bmap(fs, ino, inode, handle, block_buf,
+				     0, block-1, 0, blocks_alloc, &blk64);
+		if (retval)
+			blk64 = 0;
+		retval = ext2fs_alloc_block2(fs, blk64, block_buf,
+					     &blk64);
+		if (retval)
+			return retval;
+		blk64 &= ~EXT2FS_CLUSTER_MASK(fs);
+		blk64 += EXT2FS_CLUSTER_MASK(fs) & block;
+		alloc++;
+	set_extent:
+		retval = ext2fs_extent_set_bmap(handle, block,
+						blk64, 0);
+		if (retval)
+			return retval;
+		/* Update inode after setting extent */
+		retval = ext2fs_read_inode(fs, ino, inode);
+		if (retval)
+			return retval;
+		*blocks_alloc += alloc;
+		*phys_blk = blk64;
+	}
+	return 0;
+}
+
+int ext2fs_file_block_offset_too_big(ext2_filsys fs,
+				     struct ext2_inode *inode,
+				     blk64_t offset)
+{
+	blk64_t addr_per_block, max_map_block;
+
+	/* Kernel seems to cut us off at 4294967294 blocks */
+	if (offset >= (1ULL << 32) - 1)
+		return 1;
+
+	if (inode->i_flags & EXT4_EXTENTS_FL)
+		return 0;
+
+	addr_per_block = fs->blocksize >> 2;
+	max_map_block = addr_per_block;
+	max_map_block += addr_per_block * addr_per_block;
+	max_map_block += addr_per_block * addr_per_block * addr_per_block;
+	max_map_block += 12;
+
+	return offset >= max_map_block;
+}
+
+errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
+		       char *block_buf, int bmap_flags, blk64_t block,
+		       int *ret_flags, blk64_t *phys_blk)
+{
+	struct ext2_inode inode_buf;
+	ext2_extent_handle_t handle = 0;
+	blk_t addr_per_block;
+	blk_t	b, blk32;
+	char	*buf = 0;
+	errcode_t	retval = 0;
+	int		blocks_alloc = 0, inode_dirty = 0;
+
+	if (!(bmap_flags & BMAP_SET))
+		*phys_blk = 0;
+
+	if (ret_flags)
+		*ret_flags = 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 (ext2fs_file_block_offset_too_big(fs, inode, block))
+		return EXT2_ET_FILE_TOO_BIG;
+
+	if (!block_buf) {
+		retval = ext2fs_get_array(2, fs->blocksize, &buf);
+		if (retval)
+			return retval;
+		block_buf = buf;
+	}
+
+	if (inode->i_flags & EXT4_EXTENTS_FL) {
+		retval = ext2fs_extent_open2(fs, ino, inode, &handle);
+		if (retval)
+			goto done;
+		retval = extent_bmap(fs, ino, inode, handle, block_buf,
+				     bmap_flags, block, ret_flags,
+				     &blocks_alloc, phys_blk);
+		goto done;
+	}
+
+	if (block < EXT2_NDIR_BLOCKS) {
+		if (bmap_flags & BMAP_SET) {
+			b = *phys_blk;
+			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;
+	blk32 = *phys_blk;
+	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, &blk32);
+		if (retval == 0)
+			*phys_blk = blk32;
+		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, &blk32);
+		if (retval == 0)
+			*phys_blk = blk32;
+		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, &blk32);
+	if (retval == 0)
+		*phys_blk = blk32;
+done:
+	if (buf)
+		ext2fs_free_mem(&buf);
+	if (handle)
+		ext2fs_extent_free(handle);
+	if ((retval == 0) && (blocks_alloc || inode_dirty)) {
+		ext2fs_iblk_add_blocks(fs, inode, blocks_alloc);
+		retval = ext2fs_write_inode(fs, ino, inode);
+	}
+	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)
+{
+	errcode_t ret;
+	blk64_t	ret_blk = *phys_blk;
+
+	ret = ext2fs_bmap2(fs, ino, inode, block_buf, bmap_flags, block,
+			    0, &ret_blk);
+	if (ret)
+		return ret;
+	if (ret_blk >= ((long long) 1 << 32))
+		return EOVERFLOW;
+	*phys_blk = ret_blk;
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bmap64.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bmap64.h
new file mode 100644
index 0000000..f44d379
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bmap64.h
@@ -0,0 +1,100 @@
+/*
+ * bmap64.h --- 64-bit bitmap structure
+ *
+ * Copyright (C) 2007, 2008 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+struct ext2_bmap_statistics {
+	int		type;
+	struct timeval	created;
+
+#ifdef BMAP_STATS_OPS
+	unsigned long	copy_count;
+	unsigned long	resize_count;
+	unsigned long	mark_count;
+	unsigned long	unmark_count;
+	unsigned long	test_count;
+	unsigned long	mark_ext_count;
+	unsigned long	unmark_ext_count;
+	unsigned long	test_ext_count;
+	unsigned long	set_range_count;
+	unsigned long	get_range_count;
+	unsigned long	clear_count;
+
+	blk64_t		last_marked;
+	blk64_t		last_tested;
+	blk64_t		mark_back;
+	blk64_t		test_back;
+
+	unsigned long	mark_seq;
+	unsigned long	test_seq;
+#endif /* BMAP_STATS_OPS */
+};
+
+
+struct ext2fs_struct_generic_bitmap {
+	errcode_t		magic;
+	ext2_filsys 		fs;
+	struct ext2_bitmap_ops	*bitmap_ops;
+	int			flags;
+	__u64			start, end;
+	__u64			real_end;
+	int			cluster_bits;
+	char			*description;
+	void			*private;
+	errcode_t		base_error_code;
+#ifdef BMAP_STATS
+	struct ext2_bmap_statistics	stats;
+#endif
+};
+
+#define EXT2FS_IS_32_BITMAP(bmap) \
+	(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \
+	 ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \
+	 ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP))
+
+#define EXT2FS_IS_64_BITMAP(bmap) \
+	(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP64) || \
+	 ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP64) || \
+	 ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP64))
+
+struct ext2_bitmap_ops {
+	int	type;
+	/* Generic bmap operators */
+	errcode_t (*new_bmap)(ext2_filsys fs, ext2fs_generic_bitmap bmap);
+	void	(*free_bmap)(ext2fs_generic_bitmap bitmap);
+	errcode_t (*copy_bmap)(ext2fs_generic_bitmap src,
+			     ext2fs_generic_bitmap dest);
+	errcode_t (*resize_bmap)(ext2fs_generic_bitmap bitmap,
+			       __u64 new_end,
+			       __u64 new_real_end);
+	/* bit set/test operators */
+	int	(*mark_bmap)(ext2fs_generic_bitmap bitmap, __u64 arg);
+	int	(*unmark_bmap)(ext2fs_generic_bitmap bitmap, __u64 arg);
+	int	(*test_bmap)(ext2fs_generic_bitmap bitmap, __u64 arg);
+	void	(*mark_bmap_extent)(ext2fs_generic_bitmap bitmap, __u64 arg,
+				    unsigned int num);
+	void	(*unmark_bmap_extent)(ext2fs_generic_bitmap bitmap, __u64 arg,
+				      unsigned int num);
+	int	(*test_clear_bmap_extent)(ext2fs_generic_bitmap bitmap,
+					  __u64 arg, unsigned int num);
+	errcode_t (*set_bmap_range)(ext2fs_generic_bitmap bitmap,
+				    __u64 start, size_t num, void *in);
+	errcode_t (*get_bmap_range)(ext2fs_generic_bitmap bitmap,
+				    __u64 start, size_t num, void *out);
+	void (*clear_bmap)(ext2fs_generic_bitmap bitmap);
+	void (*print_stats)(ext2fs_generic_bitmap);
+
+	/* Find the first zero bit between start and end, inclusive.
+	 * May be NULL, in which case a generic function is used. */
+	errcode_t (*find_first_zero)(ext2fs_generic_bitmap bitmap,
+				     __u64 start, __u64 end, __u64 *out);
+};
+
+extern struct ext2_bitmap_ops ext2fs_blkmap64_bitarray;
+extern struct ext2_bitmap_ops ext2fs_blkmap64_rbtree;
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bmove.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bmove.c
new file mode 100644
index 0000000..e2ea405
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/bmove.c
@@ -0,0 +1,167 @@
+/*
+ * bmove.c --- Move blocks around to make way for a particular
+ * 	filesystem structure.
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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, blk64_t *block_nr,
+			 e2_blkcnt_t blockcnt, blk64_t ref_block,
+			 int ref_offset, void *priv_data)
+{
+	struct process_block_struct *pb;
+	errcode_t	retval;
+	int		ret;
+	blk64_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_bitmap2(pb->reserve, block)) {
+		do {
+			if (++block >= ext2fs_blocks_count(fs->super))
+				block = fs->super->s_first_data_block;
+			if (block == orig) {
+				pb->error = EXT2_ET_BLOCK_ALLOC_FAIL;
+				return BLOCK_ABORT;
+			}
+		} while (ext2fs_test_block_bitmap2(pb->reserve, block) ||
+			 ext2fs_test_block_bitmap2(pb->alloc_map, block));
+
+		retval = io_channel_read_blk64(fs->io, orig, 1, pb->buf);
+		if (retval) {
+			pb->error = retval;
+			return BLOCK_ABORT;
+		}
+		retval = io_channel_write_blk64(fs->io, block, 1, pb->buf);
+		if (retval) {
+			pb->error = retval;
+			return BLOCK_ABORT;
+		}
+		*block_nr = block;
+		ext2fs_mark_block_bitmap2(pb->alloc_map, block);
+		ret = BLOCK_CHANGED;
+		if (pb->flags & EXT2_BMOVE_DEBUG)
+			printf("ino=%u, blockcnt=%lld, %llu->%llu\n",
+			       (unsigned) pb->ino, blockcnt, 
+			       (unsigned long long) orig,
+			       (unsigned long long) block);
+	}
+	if (pb->add_dir) {
+		retval = ext2fs_add_dir_block2(fs->dblist, pb->ino,
+					       block, 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_array(4, fs->blocksize, &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_blocks2(fs, &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_iterate3(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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/brel.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/brel.h
new file mode 100644
index 0000000..9fdddd4
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/brel.h
@@ -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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+struct ext2_block_relocate_entry {
+	blk64_t	new;
+	__s16	offset;
+	__u16	flags;
+	union {
+		blk64_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;
+	blk64_t	current;
+	void	*priv_data;
+
+	/*
+	 * Add a block relocation entry.
+	 */
+	errcode_t (*put)(ext2_brel brel, blk64_t old,
+			      struct ext2_block_relocate_entry *ent);
+
+	/*
+	 * Get a block relocation entry.
+	 */
+	errcode_t (*get)(ext2_brel brel, blk64_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, blk64_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, blk64_t old, blk_t new);
+
+	/*
+	 * Remove a block relocation entry.
+	 */
+	errcode_t (*delete)(ext2_brel brel, blk64_t old);
+
+
+	/*
+	 * Free the block relocation table.
+	 */
+	errcode_t (*free)(ext2_brel brel);
+};
+
+errcode_t ext2fs_brel_memarray_create(char *name, blk64_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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/brel_ma.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/brel_ma.c
new file mode 100644
index 0000000..a12afae
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/brel_ma.c
@@ -0,0 +1,199 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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, blk64_t old,
+			struct ext2_block_relocate_entry *ent);
+static errcode_t bma_get(ext2_brel brel, blk64_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, blk64_t *old,
+			 struct ext2_block_relocate_entry *ent);
+static errcode_t bma_move(ext2_brel brel, blk64_t old, blk64_t new);
+static errcode_t bma_delete(ext2_brel brel, blk64_t old);
+static errcode_t bma_free(ext2_brel brel);
+
+struct brel_ma {
+	__u32 magic;
+	blk64_t max_block;
+	struct ext2_block_relocate_entry *entries;
+};
+
+errcode_t ext2fs_brel_memarray_create(char *name, blk64_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_array(max_block+1,
+		sizeof(struct ext2_block_relocate_entry), &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, blk64_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, blk64_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, blk64_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, blk64_t old, blk64_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, blk64_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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/check_desc.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/check_desc.c
new file mode 100644
index 0000000..1a768f9
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/check_desc.c
@@ -0,0 +1,105 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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)
+{
+	ext2fs_block_bitmap bmap;
+	errcode_t retval;
+	dgrp_t i;
+	blk64_t first_block = fs->super->s_first_data_block;
+	blk64_t last_block = ext2fs_blocks_count(fs->super)-1;
+	blk64_t blk, b;
+	unsigned int j;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	if (EXT2_DESC_SIZE(fs->super) & (EXT2_DESC_SIZE(fs->super) - 1))
+		return EXT2_ET_BAD_DESC_SIZE;
+
+	retval = ext2fs_allocate_subcluster_bitmap(fs, "check_desc map", &bmap);
+	if (retval)
+		return retval;
+
+	for (i = 0; i < fs->group_desc_count; i++)
+		ext2fs_reserve_super_and_bgd(fs, i, bmap);
+
+	for (i = 0; i < fs->group_desc_count; i++) {
+		if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+					       EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
+			first_block = ext2fs_group_first_block2(fs, i);
+			last_block = ext2fs_group_last_block2(fs, i);
+		}
+
+		/*
+		 * Check to make sure the block bitmap for group is sane
+		 */
+		blk = ext2fs_block_bitmap_loc(fs, i);
+		if (blk < first_block || blk > last_block ||
+		    ext2fs_test_block_bitmap2(bmap, blk)) {
+			retval = EXT2_ET_GDESC_BAD_BLOCK_MAP;
+			goto errout;
+		}
+		ext2fs_mark_block_bitmap2(bmap, blk);
+
+		/*
+		 * Check to make sure the inode bitmap for group is sane
+		 */
+		blk = ext2fs_inode_bitmap_loc(fs, i);
+		if (blk < first_block || blk > last_block ||
+		    ext2fs_test_block_bitmap2(bmap, blk)) {
+			retval = EXT2_ET_GDESC_BAD_INODE_MAP;
+			goto errout;
+		}
+		ext2fs_mark_block_bitmap2(bmap, blk);
+
+		/*
+		 * Check to make sure the inode table for group is sane
+		 */
+		blk = ext2fs_inode_table_loc(fs, i);
+		if (blk < first_block ||
+		    ((blk + fs->inode_blocks_per_group - 1) > last_block)) {
+			retval = EXT2_ET_GDESC_BAD_INODE_TABLE;
+			goto errout;
+		}
+		for (j = 0, b = blk; j < fs->inode_blocks_per_group;
+		     j++, b++) {
+			if (ext2fs_test_block_bitmap2(bmap, b)) {
+				retval = EXT2_ET_GDESC_BAD_INODE_TABLE;
+				goto errout;
+			}
+			ext2fs_mark_block_bitmap2(bmap, b);
+		}
+	}
+errout:
+	ext2fs_free_block_bitmap(bmap);
+	return retval;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/closefs.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/closefs.c
new file mode 100644
index 0000000..3e4af7f
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/closefs.c
@@ -0,0 +1,475 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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(unsigned int a, unsigned int b)
+{
+	while (1) {
+		if (a < b)
+			return 0;
+		if (a == b)
+			return 1;
+		if (a % b)
+			return 0;
+		a = a / b;
+	}
+}
+
+int ext2fs_bg_has_super(ext2_filsys fs, dgrp_t group)
+{
+	if (!(fs->super->s_feature_ro_compat &
+	      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) || group <= 1)
+		return 1;
+	if (!(group & 1))
+		return 0;
+	if (test_root(group, 3) || (test_root(group, 5)) ||
+	    test_root(group, 7))
+		return 1;
+
+	return 0;
+}
+
+/*
+ * ext2fs_super_and_bgd_loc2()
+ * @fs:			ext2 fs pointer
+ * @group		given block group
+ * @ret_super_blk:	if !NULL, returns super block location
+ * @ret_old_desc_blk:	if !NULL, returns location of the old block
+ *			group descriptor
+ * @ret_new_desc_blk:	if !NULL, returns location of meta_bg block
+ *			group descriptor
+ * @ret_used_blks:	if !NULL, returns number of blocks used by
+ *			super block and group_descriptors.
+ *
+ * Returns errcode_t of 0
+ */
+errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs,
+					   dgrp_t group,
+					   blk64_t *ret_super_blk,
+					   blk64_t *ret_old_desc_blk,
+					   blk64_t *ret_new_desc_blk,
+					   blk_t *ret_used_blks)
+{
+	blk64_t	group_block, super_blk = 0, old_desc_blk = 0, new_desc_blk = 0;
+	unsigned int meta_bg, meta_bg_size;
+	blk_t	numblocks = 0;
+	blk64_t old_desc_blocks;
+	int	has_super;
+
+	group_block = ext2fs_group_first_block2(fs, group);
+	if (group_block == 0 && fs->blocksize == 1024)
+		group_block = 1; /* Deal with 1024 blocksize && bigalloc */
+
+	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;
+
+	has_super = ext2fs_bg_has_super(fs, group);
+
+	if (has_super) {
+		super_blk = group_block;
+		numblocks++;
+	}
+	meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
+	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++;
+		}
+	}
+
+	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_used_blks)
+		*ret_used_blks = numblocks;
+
+	return 0;
+}
+
+/*
+ * This function returns the location of the superblock, block group
+ * descriptors for a given block group.  It currently returns the
+ * number of free blocks assuming that inode table and allocation
+ * bitmaps will be in the group.  This is not necessarily the case
+ * when the flex_bg feature is enabled, so callers should take care!
+ * It was only really intended for use by mke2fs, and even there it's
+ * not that useful.
+ *
+ * The ext2fs_super_and_bgd_loc2() function is 64-bit block number
+ * capable and returns the number of blocks used by super block and
+ * group descriptors.
+ */
+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)
+{
+	blk64_t ret_super_blk2;
+	blk64_t ret_old_desc_blk2;
+	blk64_t ret_new_desc_blk2;
+	blk_t ret_used_blks;
+	blk_t numblocks;
+	unsigned int meta_bg_size;
+
+	ext2fs_super_and_bgd_loc2(fs, group, &ret_super_blk2,
+					&ret_old_desc_blk2,
+					&ret_new_desc_blk2,
+					&ret_used_blks);
+
+	numblocks = ext2fs_group_blocks_count(fs, group);
+
+	if (ret_super_blk)
+		*ret_super_blk = (blk_t)ret_super_blk2;
+	if (ret_old_desc_blk)
+		*ret_old_desc_blk = (blk_t)ret_old_desc_blk2;
+	if (ret_new_desc_blk)
+		*ret_new_desc_blk = (blk_t)ret_new_desc_blk2;
+	if (ret_meta_bg) {
+		meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
+		*ret_meta_bg = group / meta_bg_size;
+	}
+
+	numblocks -= 2 + fs->inode_blocks_per_group + ret_used_blks;
+
+	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) {
+	fallback:
+		io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET);
+		retval = io_channel_write_blk64(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 == EXT2_ET_UNIMPLEMENTED)
+			goto fallback;
+		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,
+				    blk64_t group_block,
+				    struct ext2_super_block *super_shadow)
+{
+	dgrp_t	sgrp = group;
+
+	if (sgrp > ((1 << 16) - 1))
+		sgrp = (1 << 16) - 1;
+#ifdef WORDS_BIGENDIAN
+	super_shadow->s_block_group_nr = ext2fs_swab16(sgrp);
+#else
+	fs->super->s_block_group_nr = sgrp;
+#endif
+
+	return io_channel_write_blk64(fs->io, group_block, -SUPERBLOCK_SIZE,
+				    super_shadow);
+}
+
+errcode_t ext2fs_flush(ext2_filsys fs)
+{
+	return ext2fs_flush2(fs, 0);
+}
+
+errcode_t ext2fs_flush2(ext2_filsys fs, int flags)
+{
+	dgrp_t		i;
+	errcode_t	retval;
+	unsigned long	fs_state;
+	__u32		feature_incompat;
+	struct ext2_super_block *super_shadow = 0;
+	struct ext2_group_desc *group_shadow = 0;
+#ifdef WORDS_BIGENDIAN
+	struct ext2_group_desc *gdp;
+	dgrp_t		j;
+#endif
+	char	*group_ptr;
+	int	old_desc_blocks;
+	struct ext2fs_numeric_progress_struct progress;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	fs_state = fs->super->s_state;
+	feature_incompat = fs->super->s_feature_incompat;
+
+	fs->super->s_wtime = fs->now ? fs->now : time(NULL);
+	fs->super->s_block_group_nr = 0;
+#ifdef WORDS_BIGENDIAN
+	retval = EXT2_ET_NO_MEMORY;
+	retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super_shadow);
+	if (retval)
+		goto errout;
+	retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize,
+				  &group_shadow);
+	if (retval)
+		goto errout;
+	memcpy(group_shadow, fs->group_desc, (size_t) fs->blocksize *
+	       fs->desc_blocks);
+
+	/* swap the group descriptors */
+	for (j = 0; j < fs->group_desc_count; j++) {
+		gdp = ext2fs_group_desc(fs, group_shadow, j);
+		ext2fs_swap_group_desc2(fs, gdp);
+	}
+#else
+	super_shadow = fs->super;
+	group_shadow = ext2fs_group_desc(fs, fs->group_desc, 0);
+#endif
+
+	/*
+	 * 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;
+	fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
+#ifdef WORDS_BIGENDIAN
+	*super_shadow = *fs->super;
+	ext2fs_swap_super(super_shadow);
+#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;
+
+	/*
+	 * Write out the master group descriptors, and the backup
+	 * superblocks and group descriptors.
+	 */
+	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;
+
+	ext2fs_numeric_progress_init(fs, &progress, NULL,
+				     fs->group_desc_count);
+
+
+	for (i = 0; i < fs->group_desc_count; i++) {
+		blk64_t	super_blk, old_desc_blk, new_desc_blk;
+
+		ext2fs_numeric_progress_update(fs, &progress, i);
+		ext2fs_super_and_bgd_loc2(fs, i, &super_blk, &old_desc_blk,
+					 &new_desc_blk, 0);
+
+		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_blk64(fs->io,
+			      old_desc_blk, old_desc_blocks, group_ptr);
+			if (retval)
+				goto errout;
+		}
+		if (new_desc_blk) {
+			int meta_bg = i / EXT2_DESC_PER_BLOCK(fs->super);
+
+			retval = io_channel_write_blk64(fs->io, new_desc_blk,
+				1, group_ptr + (meta_bg*fs->blocksize));
+			if (retval)
+				goto errout;
+		}
+	}
+
+	ext2fs_numeric_progress_close(fs, &progress, NULL);
+
+	/*
+	 * 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....
+	 */
+
+	fs->super->s_block_group_nr = 0;
+	fs->super->s_state = fs_state;
+	fs->super->s_feature_incompat = feature_incompat;
+#ifdef WORDS_BIGENDIAN
+	*super_shadow = *fs->super;
+	ext2fs_swap_super(super_shadow);
+#endif
+
+	if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC))
+		retval = io_channel_flush(fs->io);
+	retval = write_primary_superblock(fs, super_shadow);
+	if (retval)
+		goto errout;
+
+	fs->flags &= ~EXT2_FLAG_DIRTY;
+
+	if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC))
+		retval = io_channel_flush(fs->io);
+errout:
+	fs->super->s_state = fs_state;
+#ifdef WORDS_BIGENDIAN
+	if (super_shadow)
+		ext2fs_free_mem(&super_shadow);
+	if (group_shadow)
+		ext2fs_free_mem(&group_shadow);
+#endif
+	return retval;
+}
+
+errcode_t ext2fs_close(ext2_filsys fs)
+{
+	return ext2fs_close2(fs, 0);
+}
+
+errcode_t ext2fs_close2(ext2_filsys fs, int flags)
+{
+	errcode_t	retval;
+	int		meta_blks;
+	io_stats stats = 0;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	if (fs->write_bitmaps) {
+		retval = fs->write_bitmaps(fs);
+		if (retval)
+			return retval;
+	}
+	if (fs->super->s_kbytes_written &&
+	    fs->io->manager->get_stats)
+		fs->io->manager->get_stats(fs->io, &stats);
+	if (stats && stats->bytes_written && (fs->flags & EXT2_FLAG_RW)) {
+		fs->super->s_kbytes_written += stats->bytes_written >> 10;
+		meta_blks = fs->desc_blocks + 1;
+		if (!(fs->flags & EXT2_FLAG_SUPER_ONLY))
+			fs->super->s_kbytes_written += meta_blks /
+				(fs->blocksize / 1024);
+		if ((fs->flags & EXT2_FLAG_DIRTY) == 0)
+			fs->flags |= EXT2_FLAG_SUPER_ONLY | EXT2_FLAG_DIRTY;
+	}
+	if (fs->flags & EXT2_FLAG_DIRTY) {
+		retval = ext2fs_flush2(fs, flags);
+		if (retval)
+			return retval;
+	}
+
+	retval = ext2fs_mmp_stop(fs);
+	if (retval)
+		return retval;
+
+	ext2fs_free(fs);
+	return 0;
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc16.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc16.c
new file mode 100644
index 0000000..2fdeb24
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc16.c
@@ -0,0 +1,74 @@
+/*
+ *      crc16.c
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include "config.h"
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <ext2fs/ext2_types.h>
+
+#include "crc16.h"
+
+/** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */
+static __u16 const crc16_table[256] = {
+	0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+	0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+	0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+	0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+	0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+	0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+	0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+	0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+	0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+	0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+	0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+	0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+	0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+	0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+	0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+	0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+	0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+	0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+	0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+	0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+	0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+	0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+	0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+	0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+	0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+	0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+	0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+	0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+	0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+	0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+	0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+	0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+
+/**
+ * Compute the CRC-16 for the data buffer
+ *
+ * @param crc     previous CRC value
+ * @param buffer  data pointer
+ * @param len     number of bytes in the buffer
+ * @return        the updated CRC value
+ */
+crc16_t ext2fs_crc16(crc16_t crc, const void *buffer, unsigned int len)
+{
+	const unsigned char *cp = buffer;
+
+	while (len--)
+		/*
+		 * for an unknown reason, PPC treats __u16 as signed
+		 * and keeps doing sign extension on the value.
+		 * Instead, use only the low 16 bits of an unsigned
+		 * int for holding the CRC value to avoid this.
+		 */
+		crc = (((crc >> 8) & 0xffU) ^
+		       crc16_table[(crc ^ *cp++) & 0xffU]) & 0x0000ffffU;
+	return crc;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc16.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc16.h
new file mode 100644
index 0000000..322e68d
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc16.h
@@ -0,0 +1,26 @@
+/*
+ *	crc16.h - CRC-16 routine
+ *
+ * Implements the standard CRC-16:
+ *   Width 16
+ *   Poly  0x8005 (x16 + x15 + x2 + 1)
+ *   Init  0
+ *
+ * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#ifndef __CRC16_H
+#define __CRC16_H
+
+/* for an unknown reason, PPC treats __u16 as signed and keeps doing sign
+ * extension on the value.  Instead, use only the low 16 bits of an
+ * unsigned int for holding the CRC value to avoid this.
+ */
+typedef unsigned int crc16_t;
+
+extern crc16_t ext2fs_crc16(crc16_t crc, const void *buffer, unsigned int len);
+
+#endif /* __CRC16_H */
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc32c.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc32c.c
new file mode 100644
index 0000000..2512528
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc32c.c
@@ -0,0 +1,1144 @@
+/*
+ * crc32c.c
+ *
+ * August 26, 2011 Darrick J. Wong <djwong at us.ibm.com>
+ * Reuse Bob Pearson's slice-by-8 implementation for e2fsprogs.
+ *
+ * July 20, 2011 Bob Pearson <rpearson at systemfabricworks.com>
+ * added slice by 8 algorithm to the existing conventional and
+ * slice by 4 algorithms.
+ *
+ * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com>
+ * Nicer crc32 functions/docs submitted by linux@horizon.com.  Thanks!
+ * Code was from the public domain, copyright abandoned.  Code was
+ * subsequently included in the kernel, thus was re-licensed under the
+ * GNU GPL v2.
+ *
+ * Oct 12, 2000 Matt Domsch <Matt_Domsch@dell.com>
+ * Same crc32 function was used in 5 other places in the kernel.
+ * I made one version, and deleted the others.
+ * There are various incantations of crc32().  Some use a seed of 0 or ~0.
+ * Some xor at the end with ~0.  The generic crc32() function takes
+ * seed as an argument, and doesn't xor at the end.  Then individual
+ * users can do whatever they need.
+ *   drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0.
+ *   fs/jffs2 uses seed 0, doesn't xor with ~0.
+ *   fs/partitions/efi.c uses seed ~0, xor's with ~0.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+#include "config.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define __force
+#define min(x, y)		((x) > (y) ? (y) : (x))
+#define __ALIGN_KERNEL_MASK(x, mask)	(((x) + (mask)) & ~(mask))
+#define __ALIGN_KERNEL(x, a)	__ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1)
+#define ALIGN(x, a)		__ALIGN_KERNEL((x), (a))
+#define PTR_ALIGN(p, a)		((__typeof__(p))ALIGN((unsigned long)(p), (a)))
+#include "crc32c_defs.h"
+
+#include "ext2fs.h"
+#ifdef WORDS_BIGENDIAN
+#define __constant_cpu_to_le32(x) ___constant_swab32((x))
+#define __constant_cpu_to_be32(x) (x)
+#define __be32_to_cpu(x) (x)
+#define __cpu_to_be32(x) (x)
+#define __cpu_to_le32(x) (ext2fs_cpu_to_le32((x)))
+#define __le32_to_cpu(x) (ext2fs_le32_to_cpu((x)))
+#else
+#define __constant_cpu_to_le32(x) (x)
+#define __constant_cpu_to_be32(x) ___constant_swab32((x))
+#define __be32_to_cpu(x) (ext2fs_be32_to_cpu((x)))
+#define __cpu_to_be32(x) (ext2fs_cpu_to_be32((x)))
+#define __cpu_to_le32(x) (x)
+#define __le32_to_cpu(x) (x)
+#endif
+
+#if CRC_LE_BITS > 8
+# define tole(x) (__force uint32_t) __constant_cpu_to_le32(x)
+#else
+# define tole(x) (x)
+#endif
+
+#if CRC_BE_BITS > 8
+# define tobe(x) (__force uint32_t) __constant_cpu_to_be32(x)
+#else
+# define tobe(x) (x)
+#endif
+
+#include "crc32c_table.h"
+
+#if CRC_LE_BITS == 32
+/* slice by 4 algorithm */
+static uint32_t crc32c_le_body(uint32_t crc, uint8_t const *buf, size_t len)
+{
+	const uint8_t *p8;
+	const uint32_t *p32;
+	size_t init_bytes;
+	size_t words;
+	size_t end_bytes;
+	size_t i;
+	uint32_t q;
+	uint8_t i0, i1, i2, i3;
+
+	crc = (__force uint32_t) __cpu_to_le32(crc);
+
+	/* unroll loop into 'init_bytes' odd bytes followed by
+	 * 'words' aligned 4 byte words followed by
+	 * 'end_bytes' odd bytes at the end */
+	p8 = buf;
+	p32 = (uint32_t *)PTR_ALIGN(p8, 4);
+	init_bytes = min((uintptr_t)p32 - (uintptr_t)p8, len);
+	words = (len - init_bytes) >> 2;
+	end_bytes = (len - init_bytes) & 3;
+
+	for (i = 0; i < init_bytes; i++) {
+#ifndef WORDS_BIGENDIAN
+		i0 = *p8++ ^ crc;
+		crc = t0_le[i0] ^ (crc >> 8);
+#else
+		i0 = *p8++ ^ (crc >> 24);
+		crc = t0_le[i0] ^ (crc << 8);
+#endif
+	}
+
+	/* using pre-increment below slightly faster */
+	p32--;
+
+	for (i = 0; i < words; i++) {
+#ifndef WORDS_BIGENDIAN
+		q = *++p32 ^ crc;
+		i3 = q;
+		i2 = q >> 8;
+		i1 = q >> 16;
+		i0 = q >> 24;
+		crc = t3_le[i3] ^ t2_le[i2] ^ t1_le[i1] ^ t0_le[i0];
+#else
+		q = *++p32 ^ crc;
+		i3 = q >> 24;
+		i2 = q >> 16;
+		i1 = q >> 8;
+		i0 = q;
+		crc = t3_le[i3] ^ t2_le[i2] ^ t1_le[i1] ^ t0_le[i0];
+#endif
+	}
+
+	p8 = (uint8_t *)(++p32);
+
+	for (i = 0; i < end_bytes; i++) {
+#ifndef WORDS_BIGENDIAN
+		i0 = *p8++ ^ crc;
+		crc = t0_le[i0] ^ (crc >> 8);
+#else
+		i0 = *p8++ ^ (crc >> 24);
+		crc = t0_le[i0] ^ (crc << 8);
+#endif
+	}
+
+	return __le32_to_cpu((__force __le32)crc);
+}
+#endif
+
+#if CRC_BE_BITS == 32
+static uint32_t crc32c_be_body(uint32_t crc, uint8_t const *buf, size_t len)
+{
+	const uint8_t *p8;
+	const uint32_t *p32;
+	size_t init_bytes;
+	size_t words;
+	size_t end_bytes;
+	size_t i;
+	uint32_t q;
+	uint8_t i0, i1, i2, i3;
+
+	crc = (__force uint32_t) __cpu_to_be32(crc);
+
+	p8 = buf;
+	p32 = (uint32_t *)PTR_ALIGN(p8, 4);
+	init_bytes = min((uintptr_t)p32 - (uintptr_t)p8, len);
+	words = (len - init_bytes) >> 2;
+	end_bytes = (len - init_bytes) & 3;
+
+	for (i = 0; i < init_bytes; i++) {
+#ifndef WORDS_BIGENDIAN
+		i0 = *p8++ ^ crc;
+		crc = t0_be[i0] ^ (crc >> 8);
+#else
+		i0 = *p8++ ^ (crc >> 24);
+		crc = t0_be[i0] ^ (crc << 8);
+#endif
+	}
+
+	p32--;
+
+	for (i = 0; i < words; i++) {
+#ifndef WORDS_BIGENDIAN
+		q = *++p32 ^ crc;
+		i3 = q;
+		i2 = q >> 8;
+		i1 = q >> 16;
+		i0 = q >> 24;
+		crc = t3_be[i3] ^ t2_be[i2] ^ t1_be[i1] ^ t0_be[i0];
+#else
+		q = *++p32 ^ crc;
+		i3 = q >> 24;
+		i2 = q >> 16;
+		i1 = q >> 8;
+		i0 = q;
+		crc = t3_be[i3] ^ t2_be[i2] ^ t1_be[i1] ^ t0_be[i0];
+#endif
+	}
+
+	p8 = (uint8_t *)(++p32);
+
+	for (i = 0; i < end_bytes; i++) {
+#ifndef WORDS_BIGENDIAN
+		i0 = *p8++ ^ crc;
+		crc = t0_be[i0] ^ (crc >> 8);
+#else
+		i0 = *p8++ ^ (crc >> 24);
+		crc = t0_be[i0] ^ (crc << 8);
+#endif
+	}
+
+	return __be32_to_cpu((__force __be32)crc);
+}
+#endif
+
+#if CRC_LE_BITS == 64
+/* slice by 8 algorithm */
+static uint32_t crc32c_le_body(uint32_t crc, uint8_t const *buf, size_t len)
+{
+	const uint8_t *p8;
+	const uint32_t *p32;
+	size_t init_bytes;
+	size_t words;
+	size_t end_bytes;
+	size_t i;
+	uint32_t q;
+	uint8_t i0, i1, i2, i3;
+
+	crc = (__force uint32_t) __cpu_to_le32(crc);
+
+	p8 = buf;
+	p32 = (const uint32_t *)PTR_ALIGN(p8, 8);
+	init_bytes = min((uintptr_t)p32 - (uintptr_t)p8, len);
+	words = (len - init_bytes) >> 3;
+	end_bytes = (len - init_bytes) & 7;
+
+	for (i = 0; i < init_bytes; i++) {
+#ifndef WORDS_BIGENDIAN
+		i0 = *p8++ ^ crc;
+		crc = t0_le[i0] ^ (crc >> 8);
+#else
+		i0 = *p8++ ^ (crc >> 24);
+		crc = t0_le[i0] ^ (crc << 8);
+#endif
+	}
+
+	p32--;
+
+	for (i = 0; i < words; i++) {
+#ifndef WORDS_BIGENDIAN
+		q = *++p32 ^ crc;
+		i3 = q;
+		i2 = q >> 8;
+		i1 = q >> 16;
+		i0 = q >> 24;
+		crc = t7_le[i3] ^ t6_le[i2] ^ t5_le[i1] ^ t4_le[i0];
+
+		q = *++p32;
+		i3 = q;
+		i2 = q >> 8;
+		i1 = q >> 16;
+		i0 = q >> 24;
+		crc ^= t3_le[i3] ^ t2_le[i2] ^ t1_le[i1] ^ t0_le[i0];
+#else
+		q = *++p32 ^ crc;
+		i3 = q >> 24;
+		i2 = q >> 16;
+		i1 = q >> 8;
+		i0 = q;
+		crc = t7_le[i3] ^ t6_le[i2] ^ t5_le[i1] ^ t4_le[i0];
+
+		q = *++p32;
+		i3 = q >> 24;
+		i2 = q >> 16;
+		i1 = q >> 8;
+		i0 = q;
+		crc ^= t3_le[i3] ^ t2_le[i2] ^ t1_le[i1] ^ t0_le[i0];
+#endif
+	}
+
+	p8 = (const uint8_t *)(++p32);
+
+	for (i = 0; i < end_bytes; i++) {
+#ifndef WORDS_BIGENDIAN
+		i0 = *p8++ ^ crc;
+		crc = t0_le[i0] ^ (crc >> 8);
+#else
+		i0 = *p8++ ^ (crc >> 24);
+		crc = t0_le[i0] ^ (crc << 8);
+#endif
+	}
+
+	return __le32_to_cpu(crc);
+}
+#endif
+
+#if CRC_BE_BITS == 64
+static uint32_t crc32c_be_body(uint32_t crc, uint8_t const *buf, size_t len)
+{
+	const uint8_t *p8;
+	const uint32_t *p32;
+	size_t init_bytes;
+	size_t words;
+	size_t end_bytes;
+	size_t i;
+	uint32_t q;
+	uint8_t i0, i1, i2, i3;
+
+	crc = (__force uint32_t) __cpu_to_be32(crc);
+
+	p8 = buf;
+	p32 = (const uint32_t *)PTR_ALIGN(p8, 8);
+	init_bytes = min((uintptr_t)p32 - (uintptr_t)p8, len);
+	words = (len - init_bytes) >> 3;
+	end_bytes = (len - init_bytes) & 7;
+
+	for (i = 0; i < init_bytes; i++) {
+#ifndef WORDS_BIGENDIAN
+		i0 = *p8++ ^ crc;
+		crc = t0_be[i0] ^ (crc >> 8);
+#else
+		i0 = *p8++ ^ (crc >> 24);
+		crc = t0_be[i0] ^ (crc << 8);
+#endif
+	}
+
+	p32--;
+
+	for (i = 0; i < words; i++) {
+#ifndef WORDS_BIGENDIAN
+		q = *++p32 ^ crc;
+		i3 = q;
+		i2 = q >> 8;
+		i1 = q >> 16;
+		i0 = q >> 24;
+		crc = t7_be[i3] ^ t6_be[i2] ^ t5_be[i1] ^ t4_be[i0];
+
+		q = *++p32;
+		i3 = q;
+		i2 = q >> 8;
+		i1 = q >> 16;
+		i0 = q >> 24;
+		crc ^= t3_be[i3] ^ t2_be[i2] ^ t1_be[i1] ^ t0_be[i0];
+#else
+		q = *++p32 ^ crc;
+		i3 = q >> 24;
+		i2 = q >> 16;
+		i1 = q >> 8;
+		i0 = q;
+		crc = t7_be[i3] ^ t6_be[i2] ^ t5_be[i1] ^ t4_be[i0];
+
+		q = *++p32;
+		i3 = q >> 24;
+		i2 = q >> 16;
+		i1 = q >> 8;
+		i0 = q;
+		crc ^= t3_be[i3] ^ t2_be[i2] ^ t1_be[i1] ^ t0_be[i0];
+#endif
+	}
+
+	p8 = (const uint8_t *)(++p32);
+
+	for (i = 0; i < end_bytes; i++) {
+#ifndef WORDS_BIGENDIAN
+		i0 = *p8++ ^ crc;
+		crc = t0_be[i0] ^ (crc >> 8);
+#else
+		i0 = *p8++ ^ (crc >> 24);
+		crc = t0_be[i0] ^ (crc << 8);
+#endif
+	}
+
+	return __be32_to_cpu(crc);
+}
+#endif
+
+/**
+ * crc32c_le() - Calculate bitwise little-endian CRC32c.
+ * @crc: seed value for computation.  ~0 for ext4, sometimes 0 for
+ *	other uses, or the previous crc32c value if computing incrementally.
+ * @p: pointer to buffer over which CRC is run
+ * @len: length of buffer @p
+ */
+uint32_t ext2fs_crc32c_le(uint32_t crc, unsigned char const *p, size_t len)
+{
+#if CRC_LE_BITS == 1
+	int i;
+	while (len--) {
+		crc ^= *p++;
+		for (i = 0; i < 8; i++)
+			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+	}
+# elif CRC_LE_BITS == 2
+	while (len--) {
+		crc ^= *p++;
+		crc = (crc >> 2) ^ t0_le[crc & 0x03];
+		crc = (crc >> 2) ^ t0_le[crc & 0x03];
+		crc = (crc >> 2) ^ t0_le[crc & 0x03];
+		crc = (crc >> 2) ^ t0_le[crc & 0x03];
+	}
+# elif CRC_LE_BITS == 4
+	while (len--) {
+		crc ^= *p++;
+		crc = (crc >> 4) ^ t0_le[crc & 0x0f];
+		crc = (crc >> 4) ^ t0_le[crc & 0x0f];
+	}
+# elif CRC_LE_BITS == 8
+	while (len--) {
+		crc ^= *p++;
+		crc = (crc >> 8) ^ t0_le[crc & 0xff];
+	}
+# else
+	crc = crc32c_le_body(crc, p, len);
+# endif
+	return crc;
+}
+
+/**
+ * crc32c_be() - Calculate bitwise big-endian CRC32c.
+ * @crc: seed value for computation.  ~0 for ext4, sometimes 0 for
+ *	other uses, or the previous crc32c value if computing incrementally.
+ * @p: pointer to buffer over which CRC is run
+ * @len: length of buffer @p
+ */
+uint32_t ext2fs_crc32c_be(uint32_t crc, unsigned char const *p, size_t len)
+{
+#if CRC_BE_BITS == 1
+	int i;
+	while (len--) {
+		crc ^= *p++ << 24;
+		for (i = 0; i < 8; i++)
+			crc = (crc << 1) ^
+			      ((crc & 0x80000000) ? CRCPOLY_BE : 0);
+	}
+# elif CRC_BE_BITS == 2
+	while (len--) {
+		crc ^= *p++ << 24;
+		crc = (crc << 2) ^ t0_be[crc >> 30];
+		crc = (crc << 2) ^ t0_be[crc >> 30];
+		crc = (crc << 2) ^ t0_be[crc >> 30];
+		crc = (crc << 2) ^ t0_be[crc >> 30];
+	}
+# elif CRC_BE_BITS == 4
+	while (len--) {
+		crc ^= *p++ << 24;
+		crc = (crc << 4) ^ t0_be[crc >> 28];
+		crc = (crc << 4) ^ t0_be[crc >> 28];
+	}
+# elif CRC_BE_BITS == 8
+	while (len--) {
+		crc ^= *p++ << 24;
+		crc = (crc << 8) ^ t0_be[crc >> 24];
+	}
+# else
+	crc = crc32c_be_body(crc, p, len);
+# endif
+	return crc;
+}
+
+#ifdef UNITTEST
+static uint8_t test_buf[] = {
+	0xd9, 0xd7, 0x6a, 0x13, 0x3a, 0xb1, 0x05, 0x48,
+	0xda, 0xad, 0x14, 0xbd, 0x03, 0x3a, 0x58, 0x5e,
+	0x6e, 0xd1, 0x56, 0xc9, 0x2e, 0xc4, 0xcb, 0x6b,
+	0xe8, 0x77, 0x52, 0x37, 0x4e, 0x0f, 0x55, 0xd2,
+	0x12, 0x65, 0x90, 0xc2, 0x41, 0x49, 0x81, 0x01,
+	0xf5, 0x01, 0xeb, 0x2d, 0x78, 0x74, 0x23, 0x5d,
+	0x84, 0x5c, 0x81, 0x92, 0x21, 0xe9, 0x8d, 0x1d,
+	0x89, 0xf2, 0x4a, 0xac, 0xdd, 0xf9, 0xaf, 0xee,
+	0x44, 0xe7, 0x6e, 0xed, 0xfb, 0xd8, 0x89, 0x0e,
+	0x96, 0x62, 0xcd, 0xa4, 0x4b, 0xa9, 0xe5, 0x45,
+	0xb1, 0x29, 0x9b, 0x0f, 0xfc, 0xbd, 0x83, 0xab,
+	0xa8, 0x54, 0x96, 0x44, 0x2c, 0x7f, 0xbb, 0xe7,
+	0x52, 0x29, 0x08, 0xee, 0x14, 0xc5, 0xc2, 0xec,
+	0x5a, 0xeb, 0x40, 0x40, 0xea, 0xd1, 0x3d, 0x15,
+	0x73, 0xaa, 0x8c, 0x73, 0xfc, 0xf2, 0x2b, 0x49,
+	0x0b, 0x13, 0x96, 0xd9, 0x8e, 0x4b, 0xbc, 0xe0,
+	0xf4, 0xd2, 0xe0, 0x2e, 0x7a, 0xf0, 0x5d, 0x1f,
+	0xd2, 0x92, 0x97, 0xe0, 0xaa, 0x59, 0xab, 0xc9,
+	0x5c, 0xa6, 0x51, 0x1a, 0xe3, 0xd6, 0x06, 0xb9,
+	0xae, 0xb8, 0x76, 0x36, 0x79, 0x37, 0x52, 0xf6,
+	0x34, 0xaf, 0x27, 0x19, 0xe1, 0xc0, 0x2b, 0xdd,
+	0x01, 0x15, 0xcd, 0xce, 0x44, 0xf6, 0x4c, 0x18,
+	0x92, 0x69, 0xbe, 0x8a, 0x76, 0x23, 0x52, 0x13,
+	0x3f, 0xf9, 0xe0, 0xf5, 0x06, 0x28, 0x7c, 0xc7,
+	0xf3, 0x42, 0x0f, 0xdd, 0x40, 0x33, 0xf7, 0x99,
+	0xe2, 0xad, 0x26, 0xd9, 0x53, 0x10, 0x72, 0x0c,
+	0x4e, 0x43, 0x4c, 0x61, 0xfe, 0xd9, 0xc1, 0x16,
+	0xa1, 0x93, 0xca, 0x3c, 0x75, 0x7f, 0x07, 0x7a,
+	0x65, 0xb3, 0x53, 0x2a, 0x52, 0x00, 0xa0, 0x62,
+	0xe0, 0xa3, 0x1f, 0xad, 0xd7, 0xbb, 0xc0, 0x83,
+	0x5d, 0x54, 0x87, 0x5f, 0xc8, 0x2f, 0xc8, 0xbf,
+	0x69, 0x04, 0x91, 0xc8, 0xa6, 0x1d, 0x4d, 0x46,
+	0x91, 0xfc, 0x26, 0xf4, 0x16, 0xd1, 0xa4, 0xbf,
+	0x5c, 0xa2, 0x6c, 0xdd, 0xb4, 0x40, 0xf2, 0x2e,
+	0xa2, 0xad, 0xf7, 0xf4, 0xa5, 0x8a, 0x3e, 0x23,
+	0x64, 0x08, 0xc8, 0xa1, 0xa0, 0xf0, 0x5d, 0x70,
+	0xd2, 0x77, 0xfd, 0xc8, 0x50, 0x83, 0x0f, 0xd6,
+	0x2b, 0xe4, 0x1f, 0x52, 0x34, 0x33, 0x68, 0xfd,
+	0x92, 0xbe, 0x9f, 0x97, 0x6b, 0x8d, 0x81, 0x91,
+	0x0f, 0xef, 0x65, 0xc8, 0x0d, 0x15, 0x01, 0x77,
+	0x58, 0xb2, 0xf4, 0x1b, 0x06, 0x7e, 0xf5, 0xca,
+	0x15, 0x2e, 0x38, 0xd8, 0x81, 0x1c, 0x1c, 0xa0,
+	0xb6, 0x13, 0x6a, 0x2b, 0x71, 0x34, 0x52, 0xd7,
+	0x1d, 0xbd, 0x37, 0x59, 0xbc, 0x86, 0x25, 0x2b,
+	0xa8, 0x93, 0xce, 0x1a, 0x03, 0x16, 0xfe, 0x01,
+	0x57, 0x99, 0x24, 0x25, 0x2c, 0xb3, 0xab, 0x1e,
+	0x2d, 0x65, 0x20, 0x89, 0x17, 0x02, 0x0e, 0x0a,
+	0xf5, 0x1e, 0xc7, 0xff, 0x1f, 0x61, 0xa9, 0x54,
+	0x18, 0xd4, 0xba, 0x50, 0x57, 0x02, 0xa1, 0xab,
+	0x22, 0x2e, 0x07, 0xea, 0xa9, 0xa3, 0x83, 0x4f,
+	0x27, 0xf5, 0xc5, 0xee, 0x3c, 0x3b, 0x10, 0xad,
+	0x32, 0x2b, 0x1c, 0x03, 0xcb, 0xaf, 0x98, 0x83,
+	0x54, 0xc3, 0x68, 0x63, 0xd4, 0xe0, 0x0e, 0x3c,
+	0x1a, 0x4e, 0xc0, 0x81, 0xd0, 0xe8, 0x6a, 0x62,
+	0x6b, 0x3e, 0x6f, 0xc4, 0xc6, 0x33, 0x4e, 0x26,
+	0x21, 0xf5, 0x04, 0xdf, 0xfa, 0xce, 0x45, 0xaf,
+	0xdc, 0x5e, 0x1b, 0xad, 0x93, 0xca, 0xf5, 0xcf,
+	0xd7, 0xee, 0x0c, 0x5c, 0x5e, 0xb4, 0xf0, 0x92,
+	0xd2, 0xf2, 0xf0, 0xa9, 0x1e, 0xab, 0x80, 0x68,
+	0x46, 0xef, 0xcc, 0x26, 0x0c, 0x5c, 0xdd, 0x4e,
+	0x83, 0xb8, 0xb9, 0x53, 0x6e, 0xf8, 0x93, 0x38,
+	0x67, 0xa4, 0x41, 0x87, 0x72, 0xe7, 0x7e, 0x86,
+	0xc9, 0x49, 0x00, 0x33, 0xb1, 0x38, 0x6c, 0x71,
+	0xd7, 0x1d, 0x8e, 0x61, 0x01, 0xb6, 0x57, 0xa9,
+	0xf1, 0xac, 0x15, 0xc2, 0x83, 0x77, 0xca, 0x64,
+	0xca, 0x7b, 0x6c, 0xa1, 0x10, 0x1b, 0x13, 0xd0,
+	0xd3, 0x9e, 0x9e, 0x10, 0x70, 0xc8, 0x1a, 0xbb,
+	0x3f, 0x19, 0x86, 0xab, 0x01, 0x0e, 0xea, 0x34,
+	0x22, 0xea, 0xe2, 0x15, 0xb7, 0xed, 0x21, 0x21,
+	0x75, 0xa5, 0xe7, 0x08, 0xa1, 0x38, 0xe0, 0x91,
+	0x05, 0x60, 0xea, 0xa7, 0x50, 0x27, 0x18, 0x07,
+	0x9d, 0xe0, 0x18, 0x2b, 0xd4, 0x07, 0x59, 0x00,
+	0xe6, 0x45, 0x18, 0x2a, 0x30, 0x6e, 0xf3, 0xb4,
+	0xd0, 0xef, 0xa6, 0x5b, 0x71, 0xa2, 0x5a, 0x3b,
+	0x89, 0x4c, 0xaf, 0x3f, 0xcb, 0x9f, 0x03, 0xfb,
+	0x43, 0x7c, 0x6b, 0xd3, 0x6a, 0xea, 0xce, 0x4a,
+	0x5f, 0x64, 0xb5, 0x62, 0xda, 0x5d, 0x27, 0xb7,
+	0xb8, 0x11, 0xca, 0x33, 0x30, 0xec, 0x70, 0xf0,
+	0x1b, 0x03, 0x50, 0xff, 0x5e, 0xa6, 0x08, 0xde,
+	0x37, 0x70, 0xc0, 0x81, 0x55, 0x60, 0x17, 0xa1,
+	0x85, 0xae, 0x26, 0x44, 0xe4, 0x67, 0x3c, 0x91,
+	0xfd, 0xc4, 0x3d, 0x97, 0x72, 0x23, 0xf3, 0x3c,
+	0x8f, 0xe0, 0xe2, 0xf2, 0x09, 0x96, 0x10, 0x67,
+	0xb5, 0xfe, 0xff, 0x3d, 0x4a, 0xc8, 0x62, 0x11,
+	0xa5, 0x98, 0xc1, 0x2d, 0x40, 0x82, 0x88, 0x8b,
+	0xe5, 0xb0, 0x75, 0xbf, 0x2f, 0xa8, 0x6a, 0x55,
+	0x49, 0x2e, 0x9c, 0x29, 0xd2, 0x7c, 0xbf, 0xf3,
+	0xaa, 0x3a, 0x16, 0x4a, 0xa4, 0x15, 0xf3, 0x48,
+	0xde, 0x38, 0x13, 0x44, 0x26, 0x02, 0xe6, 0xe9,
+	0xa8, 0x24, 0x89, 0xb5, 0x43, 0x95, 0xe4, 0x4c,
+	0xc3, 0xa0, 0xdf, 0xcc, 0x42, 0xf8, 0x8d, 0xb0,
+	0x3b, 0xea, 0x10, 0xb7, 0xe1, 0x40, 0x54, 0xb9,
+	0xa3, 0x2d, 0xfb, 0xb4, 0x91, 0xc0, 0x3e, 0x94,
+	0xf1, 0xa1, 0x3c, 0xbe, 0xef, 0xb8, 0x70, 0x55,
+	0x0a, 0x26, 0x93, 0xbf, 0xe6, 0x21, 0x92, 0x32,
+	0x3c, 0x39, 0x27, 0x6a, 0x23, 0x48, 0x02, 0x35,
+	0x3c, 0xd4, 0xcc, 0x04, 0xc0, 0x4e, 0xa7, 0x02,
+	0x63, 0x37, 0xc2, 0xb8, 0x56, 0x1d, 0x57, 0x57,
+	0x42, 0x04, 0x8d, 0xee, 0xcf, 0x8b, 0xc9, 0xc3,
+	0xba, 0x3b, 0x15, 0xd7, 0xaf, 0xbf, 0x9e, 0xcd,
+	0x44, 0xcf, 0xf0, 0x00, 0xb7, 0x3a, 0xfc, 0xa8,
+	0x12, 0xab, 0x3a, 0x62, 0x01, 0x21, 0x46, 0xe9,
+	0x1e, 0x48, 0x37, 0xfc, 0x13, 0x4d, 0xf6, 0x2a,
+	0x72, 0x40, 0x75, 0x38, 0x71, 0xf2, 0x17, 0x20,
+	0x2c, 0xdd, 0xc0, 0x49, 0xbc, 0x63, 0x33, 0xea,
+	0x06, 0x75, 0x41, 0xe7, 0x5c, 0x1f, 0xfb, 0xf9,
+	0x68, 0x83, 0xc2, 0x5a, 0x4a, 0x1e, 0x61, 0x08,
+	0x57, 0xf3, 0x00, 0xba, 0x77, 0x92, 0x63, 0xa5,
+	0xb7, 0xfe, 0x97, 0x22, 0xda, 0x5e, 0xd3, 0xaf,
+	0xbc, 0x89, 0x0d, 0x4c, 0x37, 0xa9, 0x27, 0x4a,
+	0x7f, 0xdb, 0x81, 0x39, 0x11, 0x86, 0x12, 0xf9,
+	0x10, 0x50, 0xe4, 0xdb, 0x72, 0xf9, 0xae, 0x10,
+	0x7c, 0xed, 0x50, 0x5c, 0x61, 0xeb, 0x42, 0x1e,
+	0xa4, 0xf4, 0xf0, 0xfa, 0x45, 0x4d, 0x95, 0x2b,
+	0xd4, 0x67, 0x4a, 0xe3, 0x8a, 0x15, 0x55, 0x92,
+	0x77, 0x64, 0x8c, 0x51, 0x38, 0xf9, 0x26, 0x3e,
+	0x68, 0xe2, 0xac, 0xbb, 0x64, 0x77, 0xe2, 0x82,
+	0xa4, 0x42, 0x41, 0x38, 0xa0, 0xf0, 0xc9, 0xd8,
+	0x6c, 0xe0, 0xef, 0x4c, 0xda, 0xb4, 0x92, 0xef,
+	0x1b, 0xe3, 0x9b, 0xc1, 0x44, 0x3c, 0xb9, 0xb7,
+	0x39, 0xac, 0x5c, 0x32, 0x39, 0xb4, 0x21, 0x85,
+	0x93, 0xbc, 0xf2, 0x51, 0x43, 0xb7, 0xae, 0x1e,
+	0x61, 0x9c, 0x38, 0x9c, 0xaa, 0xff, 0xde, 0xfc,
+	0xbf, 0x85, 0xef, 0x17, 0x34, 0x36, 0x71, 0x5f,
+	0x04, 0x16, 0xa6, 0x9e, 0xfd, 0x3a, 0x03, 0xd8,
+	0xbf, 0x71, 0x70, 0x20, 0x8f, 0x7c, 0xfb, 0xff,
+	0x61, 0xe0, 0xe2, 0x60, 0xa7, 0xb1, 0xc0, 0xe0,
+	0xd9, 0x3f, 0xdc, 0x8d, 0x4a, 0xa4, 0x52, 0x61,
+	0xaf, 0x9d, 0xdf, 0x8a, 0x0d, 0x41, 0xc0, 0x25,
+	0x68, 0x12, 0x7b, 0xd5, 0xc7, 0xdb, 0x68, 0x70,
+	0x2d, 0x7d, 0x95, 0x12, 0x03, 0x23, 0x0c, 0xe8,
+	0x14, 0x41, 0x11, 0x28, 0xec, 0x9d, 0xd3, 0x28,
+	0x77, 0x7a, 0x3c, 0x93, 0x8e, 0x5c, 0x7e, 0xb3,
+	0x42, 0x9a, 0x18, 0x25, 0x93, 0xc8, 0xea, 0x43,
+	0x1b, 0xbe, 0xd5, 0x27, 0xf1, 0xd4, 0xe0, 0x1e,
+	0xce, 0xc7, 0xc7, 0x2c, 0x25, 0x35, 0x58, 0xb8,
+	0x6c, 0xf3, 0xa2, 0xad, 0xe7, 0x58, 0x49, 0x47,
+	0xf7, 0xca, 0xde, 0x8b, 0x81, 0xb7, 0x75, 0xf4,
+	0x95, 0xa7, 0x5c, 0xc3, 0x2c, 0x0e, 0x1c, 0x52,
+	0x9a, 0xc3, 0x2a, 0x00, 0x21, 0xa7, 0x51, 0x6b,
+	0xf0, 0x05, 0x87, 0x8c, 0x42, 0x1b, 0xc3, 0x2e,
+	0xa3, 0x76, 0x22, 0xd5, 0x7f, 0x56, 0x10, 0xef,
+	0x98, 0x85, 0x65, 0x86, 0x71, 0x87, 0xd2, 0x8c,
+	0xc0, 0x47, 0x20, 0xe8, 0xb5, 0x1c, 0xe3, 0xdd,
+	0x3c, 0x5c, 0x03, 0xbb, 0x0e, 0x97, 0x3b, 0xe1,
+	0x56, 0x9a, 0xd5, 0x0a, 0x63, 0xd5, 0x33, 0xaf,
+	0x36, 0xca, 0xcf, 0x8f, 0x00, 0x28, 0xa3, 0x45,
+	0xb8, 0xcd, 0xde, 0x73, 0xd4, 0xfa, 0x2d, 0x6f,
+	0xdb, 0x93, 0xaa, 0xdd, 0x7f, 0xd2, 0x22, 0x9c,
+	0x96, 0x48, 0x1e, 0xa8, 0x63, 0xbe, 0xbc, 0x0d,
+	0x14, 0x3c, 0x2e, 0x11, 0x1f, 0xd2, 0xf4, 0x57,
+	0xb3, 0x47, 0xf8, 0xa6, 0x1b, 0xc3, 0xa7, 0x95,
+	0x2d, 0xd4, 0xca, 0xb8, 0x0d, 0xfb, 0x06, 0x85,
+	0xda, 0x63, 0xf0, 0x3e, 0x9d, 0x5e, 0xee, 0xce,
+	0xed, 0x74, 0x1d, 0x2c, 0x97, 0x3f, 0x71, 0x95,
+	0x12, 0x03, 0xc5, 0x92, 0x46, 0x84, 0x1b, 0x07,
+	0xe6, 0xb4, 0x1d, 0x3a, 0xf1, 0x89, 0x90, 0x50,
+	0x10, 0x29, 0x34, 0xc0, 0x90, 0xbe, 0x4a, 0xa9,
+	0x0d, 0xb0, 0x7b, 0xfb, 0x35, 0xee, 0x4e, 0x34,
+	0xec, 0x5a, 0x58, 0xbc, 0xb8, 0xda, 0x38, 0x88,
+	0x8c, 0x74, 0x1e, 0xc9, 0xab, 0x78, 0x2e, 0x2a,
+	0x17, 0x8a, 0x43, 0x3d, 0xa1, 0x2a, 0x41, 0xb5,
+	0xd6, 0xe8, 0x5b, 0xc5, 0x4a, 0x1c, 0x3c, 0x9f,
+	0x8d, 0x3a, 0x69, 0x88, 0xf8, 0x80, 0xd2, 0x11,
+	0xfc, 0x7e, 0x80, 0x8e, 0x7f, 0x85, 0x64, 0x9c,
+	0x46, 0x58, 0xc8, 0x48, 0x98, 0x4b, 0xf5, 0x73,
+	0x3f, 0x49, 0xce, 0x53, 0x2c, 0xd5, 0xfc, 0x33,
+	0xf1, 0x6f, 0xd8, 0xe9, 0x2e, 0x70, 0x2e, 0xdc,
+	0xe5, 0x43, 0x80, 0x38, 0xf2, 0x87, 0xed, 0x85,
+	0xe4, 0x3e, 0x45, 0x14, 0x20, 0xcf, 0xa0, 0x61,
+	0x4f, 0xe8, 0xd7, 0x5b, 0xb3, 0x0d, 0x0e, 0x4e,
+	0x4d, 0xce, 0xbe, 0xba, 0xaa, 0x90, 0x09, 0xcb,
+	0x4b, 0x5d, 0x08, 0xff, 0x52, 0xd5, 0x23, 0xbc,
+	0xad, 0x8d, 0xd3, 0x06, 0x4a, 0xa0, 0x51, 0x56,
+	0xa7, 0xd8, 0x33, 0xab, 0xbc, 0xd0, 0xdf, 0x92,
+	0x87, 0x20, 0x2d, 0x7b, 0x5e, 0xfa, 0x30, 0xa7,
+	0x06, 0x06, 0xe5, 0x4f, 0x2c, 0xb5, 0x61, 0xd7,
+	0x54, 0xd3, 0xdf, 0xd0, 0x0a, 0xb0, 0x06, 0xce,
+	0xf6, 0x86, 0xb7, 0x8e, 0xaa, 0x7b, 0x78, 0xd5,
+	0xb9, 0xeb, 0x07, 0xac, 0x5f, 0xc5, 0xd2, 0x8c,
+	0x40, 0xe0, 0x7f, 0x98, 0xd4, 0xe5, 0x4b, 0xca,
+	0xfb, 0x47, 0xef, 0xef, 0xb9, 0x4d, 0x6d, 0x8f,
+	0x82, 0x68, 0x74, 0x84, 0xe0, 0x0a, 0x93, 0x0f,
+	0xb2, 0x01, 0xa9, 0x9f, 0x68, 0x6a, 0xe8, 0xf7,
+	0xfb, 0x0b, 0xde, 0x17, 0xe0, 0x30, 0x38, 0x51,
+	0xbc, 0x07, 0xb8, 0x2c, 0x91, 0x0f, 0xc1, 0x0e,
+	0xa6, 0xf9, 0xf0, 0xd5, 0x48, 0x76, 0x8a, 0xde,
+	0x74, 0xe3, 0x30, 0x65, 0x56, 0xb3, 0x5c, 0xe2,
+	0x89, 0x8d, 0xda, 0x80, 0xad, 0x0f, 0x22, 0xfb,
+	0x24, 0x1d, 0x16, 0xdd, 0x34, 0x4b, 0x90, 0x58,
+	0x4e, 0x0c, 0x13, 0x28, 0xcf, 0x1d, 0xa4, 0xaa,
+	0xb7, 0xf3, 0xb1, 0x66, 0xad, 0x3b, 0xcf, 0x79,
+	0x12, 0x04, 0xd7, 0x79, 0xd9, 0x5f, 0xdf, 0x89,
+	0xb2, 0x5b, 0xa7, 0x9a, 0x26, 0x1e, 0x67, 0x46,
+	0x7c, 0x66, 0x95, 0x67, 0xe6, 0x45, 0x8b, 0x1f,
+	0x65, 0x79, 0x9f, 0x6d, 0x11, 0x81, 0x17, 0x0d,
+	0x11, 0xb0, 0x5c, 0xb4, 0xc7, 0x27, 0x87, 0xab,
+	0x5d, 0x0a, 0x18, 0xae, 0x4e, 0x06, 0xa3, 0x3d,
+	0xc7, 0xb0, 0x22, 0xba, 0x03, 0xa4, 0x0f, 0xe5,
+	0x1c, 0x72, 0x2a, 0x04, 0xce, 0x83, 0xe9, 0xf3,
+	0xd7, 0xc9, 0x67, 0x6c, 0x1e, 0x6b, 0x3c, 0x9b,
+	0x0b, 0x5e, 0x6a, 0xa6, 0x79, 0x0a, 0xf1, 0xbe,
+	0xd7, 0xb4, 0x6f, 0x45, 0x1e, 0xfb, 0x78, 0x97,
+	0xaf, 0x34, 0x76, 0x95, 0x52, 0xf7, 0x3d, 0x5d,
+	0x07, 0x28, 0x57, 0x9c, 0x4a, 0x0f, 0xcf, 0x0b,
+	0x1b, 0xc4, 0xc2, 0x72, 0xd7, 0x72, 0x38, 0x9b,
+	0xea, 0xeb, 0xee, 0xae, 0x34, 0xc8, 0x01, 0xd7,
+	0xa5, 0xe3, 0xce, 0x41, 0xad, 0x02, 0x60, 0x23,
+	0x18, 0x36, 0xba, 0x17, 0xfa, 0xcf, 0xe4, 0xda,
+	0xdc, 0xfc, 0x82, 0xdc, 0x7c, 0x11, 0xf4, 0xb8,
+	0x52, 0x5d, 0xf7, 0x2f, 0xc8, 0xfe, 0x4a, 0xe6,
+	0xb9, 0xaf, 0x4b, 0x17, 0x18, 0x91, 0xc2, 0xfe,
+	0xd7, 0x3a, 0x77, 0x0c, 0xa0, 0x43, 0x9c, 0x6f,
+	0x13, 0x06, 0xbe, 0x6e, 0xe0, 0x1a, 0x3c, 0xf3,
+	0xf5, 0xcc, 0x78, 0xfb, 0x5d, 0xd5, 0xda, 0xb7,
+	0x58, 0xea, 0x86, 0x42, 0x6b, 0x32, 0xff, 0xb2,
+	0xe2, 0xee, 0x03, 0x1f, 0xf4, 0xef, 0xdb, 0x53,
+	0x79, 0xd5, 0x4e, 0xaf, 0x60, 0x8e, 0x02, 0xc2,
+	0xcc, 0x39, 0x97, 0x7b, 0xfd, 0xa1, 0xf8, 0x7a,
+	0x26, 0xe8, 0x55, 0xd6, 0xa4, 0x8b, 0xa0, 0x1b,
+	0x2d, 0x63, 0xaa, 0x73, 0x71, 0x6e, 0xbf, 0x8b,
+	0x3b, 0xe3, 0x1b, 0x0d, 0xbb, 0x2e, 0x44, 0x09,
+	0x64, 0xac, 0xc7, 0x9e, 0xb5, 0xc6, 0x77, 0xb0,
+	0x79, 0xb3, 0xaa, 0xfc, 0x67, 0x57, 0x9a, 0x50,
+	0x81, 0x37, 0x14, 0x7c, 0xd7, 0xa0, 0xd4, 0x6a,
+	0x79, 0x84, 0x51, 0x0e, 0x95, 0x0a, 0x30, 0xa3,
+	0x60, 0x55, 0x48, 0x05, 0x16, 0xae, 0x43, 0x90,
+	0xdc, 0x8e, 0x09, 0xbe, 0x79, 0xf6, 0x90, 0x74,
+	0xf8, 0x20, 0x96, 0x4d, 0xa7, 0xf5, 0x1a, 0x2b,
+	0xc7, 0x15, 0x9d, 0x18, 0xf7, 0x94, 0x87, 0xf7,
+	0xf4, 0xfb, 0x0d, 0x61, 0xb6, 0xd7, 0xbe, 0x10,
+	0x8e, 0x47, 0x3c, 0x10, 0x44, 0x90, 0x52, 0x21,
+	0x83, 0xc0, 0xf5, 0x99, 0xaa, 0xbc, 0xf6, 0x55,
+	0xae, 0xf5, 0xb2, 0xa4, 0xcd, 0x4d, 0xb9, 0x38,
+	0x6c, 0xbc, 0x80, 0xc3, 0xad, 0xf4, 0x46, 0x31,
+	0x01, 0x58, 0x2d, 0x88, 0x57, 0xc3, 0x23, 0xd1,
+	0x64, 0xc9, 0xa3, 0x21, 0x6b, 0x8b, 0x8a, 0x23,
+	0x2c, 0x4f, 0xa9, 0xcd, 0x67, 0xfa, 0x77, 0xad,
+	0xa3, 0x16, 0xa2, 0xe5, 0x19, 0x14, 0x70, 0x41,
+	0x5b, 0xda, 0x14, 0xde, 0xe3, 0xe5, 0xc1, 0x15,
+	0xb4, 0x77, 0xa4, 0x9b, 0xb8, 0xb1, 0x28, 0x51,
+	0x30, 0xb4, 0xf1, 0xf3, 0xf8, 0x6d, 0xd0, 0xc3,
+	0x8c, 0x4c, 0x76, 0xb0, 0x9a, 0xdf, 0xc8, 0xbe,
+	0xf8, 0x4a, 0x61, 0x6e, 0x3e, 0xd6, 0x3c, 0xe8,
+	0xde, 0x56, 0xa0, 0x9c, 0x25, 0xbe, 0xce, 0x93,
+	0x1f, 0x88, 0xfb, 0x9a, 0x1a, 0xe2, 0xff, 0x88,
+	0xad, 0x10, 0xcb, 0x6c, 0xd6, 0xe7, 0x39, 0x0b,
+	0xe5, 0x1a, 0x06, 0x05, 0x64, 0x5b, 0x0a, 0xdf,
+	0x22, 0x58, 0xd7, 0xfb, 0x88, 0x12, 0xdd, 0xb7,
+	0x52, 0x3a, 0xc9, 0xbf, 0x49, 0xdf, 0x8c, 0x87,
+	0x9f, 0x84, 0xb5, 0x0a, 0xf6, 0x00, 0x52, 0xae,
+	0x67, 0x12, 0x1a, 0x8c, 0x71, 0x15, 0xf5, 0xa1,
+	0x13, 0x39, 0xf0, 0x91, 0x7e, 0x88, 0x7c, 0xb3,
+	0x95, 0x50, 0x02, 0xa6, 0x63, 0xb5, 0x64, 0xfb,
+	0x90, 0x87, 0x61, 0xe2, 0x27, 0xaf, 0x11, 0x0c,
+	0x73, 0x83, 0xef, 0xa9, 0x28, 0xfe, 0xc8, 0x85,
+	0x1a, 0x3a, 0xde, 0xf2, 0xe5, 0x25, 0x64, 0x6d,
+	0xaa, 0x41, 0x4c, 0x80, 0x2e, 0x84, 0xff, 0xc1,
+	0xc0, 0x54, 0x0c, 0x29, 0x1b, 0xa3, 0x07, 0x7c,
+	0x33, 0x4c, 0x10, 0xf6, 0x6f, 0x79, 0xdf, 0xd3,
+	0xf0, 0x24, 0x57, 0xf1, 0x60, 0xe1, 0xf0, 0xbd,
+	0xc4, 0x1f, 0xf4, 0x67, 0xd2, 0xd3, 0xcc, 0x6a,
+	0x07, 0x72, 0x44, 0x16, 0x85, 0x46, 0xd0, 0x73,
+	0x87, 0xa9, 0xc7, 0x2f, 0xd1, 0xf5, 0xec, 0xe3,
+	0x28, 0xa3, 0x93, 0x4f, 0xd7, 0x76, 0xc1, 0x3c,
+	0x0d, 0x13, 0x33, 0xcf, 0x5b, 0xbd, 0x6a, 0x52,
+	0x4e, 0xee, 0xc8, 0x5e, 0xa1, 0x58, 0x4a, 0x08,
+	0x81, 0xd9, 0x23, 0xcc, 0xfb, 0x1c, 0xb2, 0xd8,
+	0xa3, 0xe4, 0x53, 0xfe, 0xf4, 0x4b, 0x48, 0xc1,
+	0x20, 0xa4, 0x97, 0xf8, 0x38, 0xa3, 0x69, 0xc1,
+	0x11, 0xf0, 0xa1, 0x3b, 0xa9, 0x9a, 0x12, 0x61,
+	0xe8, 0x8d, 0x99, 0x44, 0x3f, 0x94, 0x72, 0x82,
+	0x19, 0x96, 0x62, 0xb0, 0xa6, 0x64, 0x05, 0x19,
+	0x8f, 0xd6, 0x5d, 0x05, 0xbf, 0x79, 0x9e, 0x9d,
+	0xe4, 0x93, 0x4c, 0xad, 0x61, 0x8c, 0x18, 0xda,
+	0xb6, 0x2e, 0xb3, 0xca, 0x14, 0x4d, 0x53, 0xa4,
+	0x97, 0x27, 0x10, 0x56, 0xa2, 0x67, 0x5a, 0x5a,
+	0x5e, 0x13, 0xc0, 0xdb, 0xa7, 0x9f, 0x45, 0x5b,
+	0xeb, 0x1a, 0x14, 0x0c, 0x8c, 0x38, 0x5e, 0x77,
+	0x9a, 0xec, 0x75, 0x68, 0x93, 0x65, 0x02, 0x9c,
+	0xfb, 0x62, 0x60, 0x49, 0xdd, 0xb2, 0x2a, 0x67,
+	0x86, 0xe3, 0x8a, 0x7d, 0x8c, 0x46, 0x78, 0x81,
+	0x60, 0x69, 0xf2, 0x3f, 0x74, 0x11, 0x35, 0xff,
+	0x77, 0xa3, 0x66, 0x20, 0xfc, 0x98, 0x4a, 0x35,
+	0x7a, 0x52, 0xe4, 0x90, 0x13, 0x80, 0xb9, 0xa6,
+	0x73, 0x7a, 0x7d, 0x66, 0x6e, 0x6b, 0xb6, 0x43,
+	0x10, 0xd5, 0x91, 0x2b, 0x66, 0xdd, 0x89, 0x87,
+	0xe3, 0x8c, 0x58, 0x53, 0x2f, 0x40, 0x74, 0x45,
+	0x1b, 0x77, 0x7a, 0xa4, 0x44, 0x19, 0x78, 0xba,
+	0x87, 0x10, 0x41, 0x31, 0x32, 0x5f, 0x87, 0x68,
+	0xde, 0x43, 0x4a, 0xef, 0x33, 0xb3, 0x11, 0x83,
+	0xa9, 0xc2, 0x6f, 0x8d, 0x34, 0xe2, 0x95, 0x84,
+	0x3a, 0x4f, 0x6f, 0x8c, 0x31, 0x1d, 0xb6, 0xf5,
+	0x95, 0x0d, 0x01, 0x11, 0x20, 0xdf, 0x72, 0xf3,
+	0x3f, 0x9a, 0x33, 0xaa, 0xb1, 0x06, 0x6a, 0x63,
+	0x47, 0x91, 0x01, 0xdf, 0xb3, 0x54, 0x36, 0xfd,
+	0x06, 0x2d, 0xb8, 0x08, 0xe3, 0xd3, 0x65, 0xac,
+	0x66, 0x03, 0xee, 0xa4, 0x63, 0xbd, 0xd4, 0xce,
+	0xbd, 0x79, 0xa7, 0x48, 0x38, 0xc5, 0x7d, 0xb5,
+	0x71, 0x9a, 0x3c, 0x11, 0x7c, 0x6c, 0xe2, 0x54,
+	0x02, 0x5d, 0x42, 0xab, 0x25, 0x93, 0x66, 0x01,
+	0x37, 0x78, 0x35, 0x4a, 0x8c, 0x19, 0x4d, 0x00,
+	0x75, 0x4f, 0xcc, 0xc0, 0x26, 0x82, 0xc1, 0x35,
+	0x8c, 0xc7, 0xc2, 0x59, 0x01, 0x3e, 0x98, 0x22,
+	0x88, 0x9c, 0x90, 0x75, 0x05, 0x33, 0x07, 0xb9,
+	0x39, 0x81, 0x38, 0x58, 0x10, 0x29, 0xcf, 0xc8,
+	0x98, 0xb2, 0x03, 0xd7, 0x5b, 0xb3, 0x18, 0xba,
+	0x34, 0x0c, 0x9f, 0xab, 0xd7, 0xed, 0x29, 0x82,
+	0x41, 0xe0, 0x20, 0x97, 0x57, 0x92, 0xb2, 0xb8,
+	0x10, 0x2d, 0x0b, 0xa2, 0xc5, 0x8f, 0x90, 0x6f,
+	0xed, 0x12, 0x56, 0x25, 0xbe, 0xfd, 0x75, 0xf7,
+	0xb6, 0xf8, 0x40, 0x67, 0x39, 0x11, 0xfa, 0x15,
+	0xae, 0x6a, 0x54, 0x5f, 0x32, 0x2b, 0xf8, 0x48,
+	0x55, 0xbe, 0x86, 0x2f, 0x69, 0x48, 0x5b, 0x5d,
+	0x4d, 0xb7, 0x35, 0xaa, 0xb6, 0x91, 0x88, 0x19,
+	0x96, 0x1c, 0x68, 0xf6, 0x85, 0x9e, 0xb3, 0xb2,
+	0xa3, 0x32, 0xd4, 0x52, 0x70, 0xb7, 0x62, 0xe3,
+	0x14, 0xb6, 0x78, 0x5f, 0x1b, 0x1d, 0x04, 0x9c,
+	0x26, 0x0c, 0x33, 0x94, 0xb1, 0x97, 0x08, 0xdb,
+	0x0b, 0x39, 0x29, 0xd4, 0xbc, 0x6d, 0xdf, 0x02,
+	0xc6, 0x99, 0xab, 0x99, 0x32, 0xe5, 0xce, 0x51,
+	0x4f, 0xae, 0xb8, 0x8b, 0xe0, 0xaf, 0x07, 0xc4,
+	0xf9, 0x41, 0x7c, 0x59, 0xa0, 0xac, 0x74, 0x4d,
+	0x7e, 0x43, 0x77, 0x9c, 0x06, 0x49, 0x79, 0x8a,
+	0x14, 0x73, 0x93, 0xa8, 0x5b, 0x1b, 0x34, 0x29,
+	0x78, 0x04, 0x2f, 0xd7, 0x1f, 0x13, 0x90, 0xe0,
+	0xdd, 0x3b, 0x42, 0x6b, 0x79, 0x6e, 0x52, 0xc7,
+	0x0f, 0x38, 0xda, 0x01, 0x2c, 0x8d, 0xe6, 0x94,
+	0x5d, 0x59, 0x27, 0x1d, 0x10, 0x4e, 0x11, 0x36,
+	0xfb, 0x53, 0x16, 0x05, 0x25, 0xf2, 0x64, 0xd8,
+	0xf9, 0xcd, 0x5c, 0xfe, 0xb4, 0x18, 0x44, 0x80,
+	0x10, 0xbc, 0x3d, 0xf3, 0x1d, 0x5a, 0xf0, 0xc1,
+	0xc3, 0x55, 0xff, 0x41, 0x3e, 0xe3, 0xef, 0x44,
+	0xb2, 0xc0, 0x01, 0x18, 0xa2, 0x49, 0x88, 0x78,
+	0x0d, 0x4c, 0xc8, 0x73, 0xcf, 0x30, 0x85, 0x3a,
+	0x88, 0x90, 0x01, 0xcf, 0x69, 0x53, 0xa3, 0x18,
+	0x3f, 0xd6, 0xe7, 0x94, 0x14, 0xa7, 0xae, 0xcd,
+	0x6f, 0x11, 0x72, 0xfe, 0x2b, 0xb0, 0x81, 0x53,
+	0xea, 0x67, 0xd6, 0xe4, 0xca, 0x42, 0xa0, 0xf9,
+	0xb1, 0xd4, 0xb5, 0x3b, 0xc9, 0xf0, 0x36, 0xc1,
+	0x1c, 0xf4, 0xb1, 0xf6, 0x84, 0xd0, 0x86, 0x6c,
+	0x76, 0x9a, 0x03, 0xc2, 0xb6, 0x2e, 0x9a, 0x46,
+	0xf5, 0x5f, 0x2c, 0x38, 0xac, 0xad, 0x6f, 0x2e,
+	0x7a, 0x18, 0x2d, 0x22, 0x95, 0x5e, 0x5e, 0xc9,
+	0x7a, 0x0a, 0x56, 0xe1, 0xc7, 0x15, 0xfd, 0xbf,
+	0xff, 0xf7, 0x7e, 0x85, 0x20, 0xa9, 0x8a, 0x9c,
+	0xa9, 0x7d, 0xe8, 0xed, 0xfc, 0x7f, 0xbb, 0xf0,
+	0x05, 0x3f, 0xce, 0x4f, 0x4c, 0xee, 0xa4, 0xa0,
+	0xcc, 0x9c, 0x62, 0x1e, 0xd6, 0xd0, 0x30, 0x37,
+	0xb8, 0x98, 0x56, 0x1d, 0xaa, 0xd6, 0x5e, 0x73,
+	0x12, 0xe4, 0x88, 0x82, 0x48, 0x64, 0x06, 0xd7,
+	0x2a, 0x31, 0x50, 0x7b, 0x10, 0x17, 0xb8, 0x4c,
+	0x5a, 0x8d, 0xf1, 0xfc, 0xf1, 0x33, 0x3b, 0x98,
+	0x42, 0x18, 0x5b, 0x35, 0x78, 0xca, 0x8e, 0x41,
+	0x52, 0xae, 0x6d, 0xe1, 0xa2, 0x9d, 0x5b, 0xbd,
+	0xf3, 0x5f, 0x49, 0xc1, 0x27, 0x06, 0xc1, 0xaf,
+	0xc0, 0xa3, 0x9d, 0xf3, 0x1c, 0x8e, 0x90, 0x8a,
+	0xb0, 0x69, 0xb0, 0xc5, 0x11, 0x0c, 0x91, 0x14,
+	0x1f, 0x5e, 0x10, 0xe1, 0x1d, 0x14, 0x30, 0x54,
+	0x1e, 0x17, 0x3d, 0x31, 0x7b, 0xbf, 0x2f, 0x9d,
+	0x6d, 0x63, 0x32, 0xf0, 0x9d, 0x9f, 0x95, 0x3d,
+	0x0b, 0xd2, 0x4d, 0x10, 0xe2, 0x3f, 0x67, 0x69,
+	0x43, 0x9a, 0x4a, 0x2c, 0x54, 0x71, 0xa8, 0xa0,
+	0x9e, 0x9f, 0x10, 0xaf, 0x1b, 0xce, 0x99, 0xe3,
+	0x25, 0x32, 0x10, 0x54, 0x80, 0xfe, 0xda, 0x57,
+	0xd0, 0xb2, 0x92, 0x7f, 0xbb, 0x5f, 0xe7, 0x4d,
+	0x1b, 0x3d, 0x46, 0x4d, 0xe4, 0x4c, 0xd6, 0xaf,
+	0x1a, 0x32, 0x12, 0x40, 0xb8, 0x84, 0x8e, 0xe4,
+	0x80, 0xce, 0x7e, 0xc1, 0x13, 0x8b, 0xb0, 0xb7,
+	0x6f, 0x24, 0xba, 0x85, 0x50, 0x83, 0xc3, 0xcf,
+	0x19, 0xb3, 0xf0, 0xc7, 0xee, 0x68, 0xbe, 0x9e,
+	0x6d, 0xb9, 0xfb, 0xd5, 0x29, 0xce, 0x82, 0xcd,
+	0x69, 0x16, 0x68, 0x6b, 0x6a, 0xf4, 0x02, 0x32,
+	0xce, 0x60, 0x37, 0x0c, 0xb9, 0x38, 0x92, 0x9c,
+	0x42, 0xa9, 0x0b, 0x53, 0x96, 0xfe, 0x39, 0xc1,
+	0x24, 0x65, 0x9b, 0xcd, 0xe7, 0x8d, 0x36, 0x07,
+	0x9f, 0x1d, 0x35, 0x8e, 0xdc, 0x4c, 0xb5, 0x68,
+	0xc5, 0xfd, 0x44, 0x19, 0xf2, 0x6c, 0x59, 0x1c,
+	0xb1, 0x0b, 0x35, 0x48, 0x86, 0x1a, 0x05, 0x22,
+	0x03, 0x0c, 0x0c, 0xa2, 0x92, 0x90, 0x35, 0xfb,
+	0x37, 0x94, 0xc7, 0x15, 0x84, 0xae, 0xe8, 0x05,
+	0xa0, 0xf7, 0x30, 0x11, 0x5c, 0xe4, 0x5d, 0x3e,
+	0x12, 0x54, 0x80, 0x54, 0x6b, 0x09, 0x8c, 0xce,
+	0x80, 0x5e, 0xa7, 0xc8, 0x6a, 0x0c, 0x56, 0xe1,
+	0x18, 0x7d, 0xc9, 0x39, 0xc1, 0xef, 0xe3, 0x25,
+	0xa0, 0x8b, 0x2f, 0x60, 0x3a, 0x43, 0x39, 0xa6,
+	0x28, 0x28, 0x7b, 0x4c, 0x77, 0xd4, 0x49, 0x61,
+	0x46, 0xe9, 0x1b, 0x45, 0xd6, 0xb1, 0x56, 0xe1,
+	0x7d, 0x34, 0xcd, 0x06, 0xb6, 0x67, 0x8d, 0x7d,
+	0x7a, 0xe2, 0xbe, 0x68, 0x35, 0xa6, 0x78, 0xe5,
+	0x47, 0x48, 0xb7, 0xc7, 0xde, 0xcd, 0xc9, 0x05,
+	0xb4, 0xe7, 0x50, 0x48, 0xe1, 0x4b, 0xfe, 0x76,
+	0x77, 0xc6, 0xf7, 0x5f, 0xcb, 0xc2, 0xa8, 0xd7,
+	0xd6, 0x8a, 0xe5, 0x49, 0xd9, 0xca, 0x45, 0xf4,
+	0xda, 0xcd, 0x33, 0xd1, 0x59, 0x2d, 0x9e, 0xc1,
+	0x5c, 0xe6, 0x01, 0x18, 0xb8, 0xf0, 0x5e, 0xb1,
+	0x69, 0x95, 0x2f, 0x02, 0x2a, 0xe7, 0x4a, 0xd7,
+	0xd1, 0xc3, 0xd5, 0x6f, 0x15, 0xc8, 0xdc, 0x29,
+	0xde, 0xb9, 0x3f, 0x8b, 0xa6, 0xbc, 0xdd, 0x25,
+	0x84, 0x35, 0x3c, 0x90, 0x2d, 0xc2, 0x1e, 0x98,
+	0x8a, 0x50, 0x09, 0x77, 0x42, 0xe9, 0x35, 0x8a,
+	0x7c, 0x97, 0xbf, 0xe8, 0xbf, 0x56, 0xd0, 0x8b,
+	0x65, 0xd3, 0xaf, 0x1e, 0x05, 0x94, 0xfa, 0xac,
+	0xa8, 0x2b, 0x28, 0xcb, 0x37, 0x3e, 0xe8, 0xbb,
+	0x66, 0x3a, 0xed, 0xb2, 0x48, 0x10, 0x0f, 0x3a,
+	0x5a, 0xc5, 0xdb, 0x26, 0x0e, 0xaa, 0x5e, 0x69,
+	0x15, 0xd6, 0x81, 0xae, 0xbd, 0xe6, 0x03, 0xf1,
+	0xf6, 0x37, 0xc8, 0xde, 0x70, 0x1f, 0x64, 0xb9,
+	0x5e, 0xbf, 0x2e, 0x4f, 0xb1, 0xea, 0xa0, 0x17,
+	0xe6, 0x7c, 0xf9, 0x2f, 0x1e, 0xd8, 0x58, 0xde,
+	0xa7, 0xf0, 0x46, 0x52, 0x95, 0xdf, 0xa4, 0x96,
+	0xd0, 0xc4, 0x97, 0x2b, 0x95, 0xcd, 0x5e, 0x40,
+	0x23, 0x5c, 0x10, 0xee, 0xba, 0x72, 0x9b, 0xcf,
+	0x0b, 0xe8, 0x18, 0x3a, 0x70, 0xd2, 0x5e, 0x07,
+	0x68, 0x93, 0xef, 0x4a, 0x5b, 0x8d, 0x72, 0x41,
+	0x4e, 0xea, 0x33, 0x6a, 0x0a, 0x5e, 0xfb, 0x02,
+	0x3f, 0xd4, 0xed, 0x5b, 0xe0, 0x42, 0x84, 0xd4,
+	0xaa, 0x85, 0xdc, 0x5b, 0x67, 0xee, 0x71, 0x67,
+	0xba, 0x8e, 0xd2, 0xbe, 0x61, 0xdf, 0x5a, 0x26,
+	0xb9, 0xf0, 0x77, 0x81, 0x53, 0x24, 0x16, 0xcb,
+	0x8c, 0xb8, 0x06, 0x6e, 0x68, 0xda, 0xc8, 0x2d,
+	0x17, 0x54, 0xdb, 0x46, 0xcb, 0xfd, 0x1f, 0x3d,
+	0x94, 0x81, 0x09, 0x4b, 0xfa, 0xb1, 0x46, 0xd9,
+	0x11, 0xa3, 0xb7, 0x31, 0x9c, 0xd2, 0x38, 0xd6,
+	0xba, 0x3d, 0xa3, 0x74, 0xd8, 0xf1, 0x24, 0xe8,
+	0x9c, 0xcb, 0x1d, 0xf9, 0x4a, 0xf7, 0xc8, 0x4b,
+	0xfe, 0x97, 0x7c, 0xa1, 0x02, 0xeb, 0x40, 0xc3,
+	0x89, 0x71, 0x01, 0xcd, 0x33, 0x2a, 0xc2, 0x82,
+	0xce, 0x62, 0x8d, 0x53, 0x7c, 0xdf, 0xce, 0xd7,
+	0xf5, 0xa8, 0x4f, 0xf2, 0xf2, 0x2e, 0xc1, 0xeb,
+	0x97, 0x99, 0x37, 0x3c, 0x53, 0xa6, 0xb4, 0x46,
+	0x05, 0x64, 0x92, 0x87, 0x08, 0x3c, 0x23, 0x4b,
+	0x9d, 0x67, 0x18, 0xf9, 0xe2, 0x0b, 0x1c, 0x39,
+	0xd3, 0x87, 0x70, 0xc0, 0xb9, 0x1e, 0x52, 0x0a,
+	0x0f, 0x48, 0xe2, 0xe7, 0x51, 0x72, 0x94, 0xf7,
+	0xa3, 0xdc, 0xe5, 0x66, 0x33, 0x39, 0x54, 0x06,
+	0x55, 0x93, 0x30, 0xf9, 0x5e, 0x76, 0x8f, 0xe0,
+	0x59, 0x4d, 0x0d, 0xa7, 0xf5, 0xbe, 0xdb, 0x20,
+	0xad, 0x0d, 0x76, 0x88, 0x5f, 0x9c, 0x7c, 0x75,
+	0x2f, 0x2a, 0x0b, 0x79, 0x6e, 0xd3, 0xe2, 0x66,
+	0xf5, 0x4a, 0x2d, 0x87, 0x87, 0x49, 0x84, 0x17,
+	0xa2, 0x62, 0x4c, 0xbb, 0xe4, 0x6e, 0x98, 0x10,
+	0xc9, 0xfb, 0x8a, 0x04, 0x68, 0x8d, 0x22, 0x66,
+	0xad, 0xea, 0x2a, 0xc9, 0x97, 0x2d, 0x3c, 0xbc,
+	0xd0, 0x77, 0x5f, 0xe6, 0xb8, 0x7f, 0xe6, 0xf6,
+	0x39, 0xbf, 0x56, 0x0e, 0x26, 0x6d, 0xc5, 0x3e,
+	0x53, 0x19, 0xd6, 0xb4, 0x57, 0x36, 0xa3, 0xc6,
+	0xd3, 0x3d, 0x66, 0x79, 0x30, 0x5c, 0x14, 0x0c,
+	0x0f, 0x3e, 0x96, 0xae, 0x90, 0x97, 0xab, 0x0d,
+	0x9f, 0xc3, 0xe7, 0x66, 0x3e, 0xe0, 0x31, 0x43,
+	0x4b, 0x01, 0xb3, 0x0e, 0x9e, 0x8c, 0x82, 0x4a,
+	0x8c, 0xc7, 0x79, 0x85, 0xdf, 0x75, 0x0d, 0xb4,
+	0x2b, 0x03, 0x14, 0xef, 0x72, 0x58, 0xfd, 0x64,
+	0xc8, 0xe3, 0x0d, 0x9a, 0x14, 0x6f, 0x76, 0xf9,
+	0x46, 0xd1, 0xd2, 0x81, 0xb3, 0x16, 0x6e, 0xc7,
+	0x76, 0x82, 0xce, 0xf4, 0xee, 0x33, 0x00, 0xe6,
+	0x77, 0xc4, 0xad, 0x4f, 0x06, 0xa7, 0x48, 0x80,
+	0x9e, 0x21, 0x66, 0xca, 0x75, 0x69, 0x57, 0xcb,
+	0xf0, 0x67, 0x6a, 0xaa, 0x8f, 0x88, 0x14, 0xbd,
+	0x65, 0x62, 0xe2, 0xad, 0xcc, 0x22, 0x88, 0x7b,
+	0x94, 0xbd, 0x0e, 0xcd, 0xb6, 0x69, 0xa2, 0xcb,
+	0x7d, 0x57, 0x5c, 0xb4, 0x92, 0x80, 0x13, 0x99,
+	0x84, 0xf3, 0x79, 0x0a, 0x2d, 0x70, 0xa4, 0xe0,
+	0xde, 0xc6, 0x32, 0xb0, 0x8a, 0x62, 0xb5, 0xcf,
+	0xfa, 0x5e, 0x5a, 0x92, 0x32, 0x7d, 0x34, 0x07,
+	0xb5, 0x52, 0x3a, 0xb5, 0x7d, 0x0f, 0xa1, 0xba,
+	0x56, 0xd0, 0x07, 0x76, 0x11, 0xf2, 0xc3, 0x33,
+	0x9d, 0xbd, 0x12, 0x35, 0x5e, 0xf7, 0x05, 0x88,
+	0x76, 0x94, 0xa6, 0xbf, 0xed, 0xb8, 0xa4, 0xa2,
+	0x0c, 0xbe, 0x0f, 0x6a, 0xaf, 0xf3, 0x1b, 0x33,
+	0x4a, 0xb7, 0x68, 0x3f, 0xbe, 0x95, 0x13, 0x97,
+	0x0f, 0x15, 0x17, 0x1b, 0x23, 0xaa, 0x08, 0x78,
+	0xa6, 0x5b, 0x08, 0xa2, 0x9d, 0x03, 0xa8, 0xa7,
+	0x39, 0xdc, 0xbc, 0x9a, 0x85, 0xf5, 0xe5, 0x55,
+	0x59, 0x3c, 0xef, 0xf9, 0x3f, 0x22, 0x8e, 0xf8,
+	0xd8, 0x3e, 0x02, 0x0b, 0xd8, 0x78, 0x4b, 0x15,
+	0x7f, 0xaa, 0x2c, 0xff, 0xbe, 0x77, 0x33, 0xc7,
+	0x6a, 0x12, 0xaa, 0xa4, 0xbe, 0xc0, 0x3b, 0xcb,
+	0x13, 0x9d, 0x9c, 0x5a, 0x9f, 0x8a, 0x57, 0x36,
+	0x4f, 0x02, 0x5a, 0xf8, 0x1d, 0x97, 0x77, 0x43,
+	0xc8, 0xa5, 0xb7, 0x9b, 0x10, 0x98, 0xfd, 0x58,
+	0xbf, 0x42, 0xf6, 0xbf, 0xff, 0x6c, 0x40, 0x18,
+	0x18, 0xdf, 0xac, 0x57, 0x71, 0xea, 0xcc, 0x8e,
+	0xfd, 0xfe, 0x10, 0xfb, 0xb9, 0xfe, 0xbc, 0x9a,
+	0x9c, 0x27, 0xe4, 0x10, 0x15, 0x94, 0x41, 0xa1,
+	0xcc, 0xf6, 0x25, 0x49, 0x4f, 0x96, 0xc1, 0x8c,
+	0x9e, 0x3e, 0x18, 0x29, 0x49, 0x92, 0xe7, 0xfe,
+	0x22, 0xff, 0xed, 0x02, 0x16, 0x90, 0xef, 0xac,
+	0xec, 0x95, 0x1d, 0x5b, 0x94, 0x9c, 0xf6, 0x7c,
+	0x1b, 0x5a, 0x9d, 0xb0, 0x9b, 0x05, 0x36, 0xbf,
+	0xef, 0xec, 0x63, 0x35, 0x40, 0x24, 0x45, 0x40,
+	0x30, 0x1a, 0x9b, 0x90, 0xc3, 0xc2, 0xf7, 0x37,
+	0xfb, 0x08, 0x8e, 0x48, 0x19, 0x48, 0xed, 0xa8,
+	0xa8, 0x04, 0x6f, 0xd0, 0x33, 0xe9, 0xb8, 0x8d,
+	0xe7, 0x1e, 0x5c, 0x47, 0x74, 0xc0, 0x66, 0x30,
+	0x4e, 0xa7, 0x86, 0x73, 0xf1, 0xe5, 0x78, 0xa6,
+	0xe0, 0xc1, 0xda, 0x13, 0x72, 0x07, 0x85, 0x34,
+	0x63, 0x95, 0x49, 0x30, 0x4b, 0x9d, 0x03, 0xf1,
+	0x7a, 0x6b, 0x91, 0xa2, 0x85, 0x41, 0xf9, 0x4a,
+	0xd6, 0xff, 0xff, 0x86, 0xf7, 0xf0, 0xce, 0xb9,
+	0x07, 0xf1, 0x88, 0x04, 0x33, 0xaa, 0xeb, 0x54,
+	0xb2, 0x1c, 0x8e, 0x2e, 0x7b, 0x04, 0xa8, 0xcc,
+	0x2c, 0x7a, 0xb3, 0xad, 0x1a, 0x89, 0x38, 0x89,
+	0xd7, 0x11, 0x3a, 0x8c, 0xcf, 0xe3, 0xc5, 0xba,
+	0xb0, 0xcc, 0xc4, 0xe3, 0x33, 0xf3, 0x18, 0xba,
+	0xec, 0x56, 0xd9, 0x1c, 0x40, 0x70, 0x0d, 0x4e,
+	0x97, 0x01, 0x23, 0xf3, 0x5a, 0xdc, 0xbf, 0x68,
+	0x93, 0xc2, 0x1d, 0x8a, 0x96, 0xb7, 0xac, 0x18,
+	0x6f, 0xf7, 0x84, 0x71, 0x0d, 0x3d, 0xf8, 0xba,
+	0xdf, 0xb6, 0x89, 0x1d, 0x78, 0x19, 0xf2, 0x59,
+	0xe9, 0x15, 0x55, 0x29, 0x73, 0x50, 0x59, 0x14,
+	0x02, 0x21, 0x16, 0x8f, 0x0f, 0xdf, 0xa5, 0xf0,
+};
+
+static struct crc_test {
+	uint32_t crc;		/* random starting crc */
+	uint32_t start;		/* random offset in buf */
+	uint32_t length;	/* random length of test */
+	uint32_t crc_le;	/* expected crc32_le result */
+	uint32_t crc_be;	/* expected crc32_be result */
+} test[] = {
+	{0xffffffff, 0x00000000, 0x00001000, 0x13934bef, 0x14f3b75f},
+	{0xfe7328ea, 0x00000763, 0x00000717, 0xed2c0d70, 0x57531214},
+	{0x4c40684e, 0x00000721, 0x0000011e, 0xd7f46ccc, 0xedf12ec3},
+	{0x6b487f90, 0x00000264, 0x000007bc, 0x759e9939, 0x9af8e387},
+	{0x9f5810db, 0x00000afa, 0x00000255, 0x2685197f, 0x716de6ed},
+	{0xb15c4755, 0x00000d5b, 0x000002a4, 0xd8fadcb5, 0xfc34ae3f},
+	{0x06518253, 0x00000ffb, 0x00000004, 0xabee2433, 0xfa30ac9e},
+	{0xd9e71c55, 0x00000a2a, 0x00000259, 0x96682af2, 0xe5907ea3},
+	{0x0c1ae843, 0x00000ce4, 0x0000031b, 0x7b637c43, 0xe7f71b04},
+	{0xec3cd517, 0x000002ff, 0x00000566, 0x5d719a77, 0xed16e045},
+	{0x77828e95, 0x0000067f, 0x0000038f, 0x43ee5b6c, 0x35999927},
+	{0xec87b4e3, 0x00000d1c, 0x000002e3, 0x2ddd2eee, 0x9452d3f8},
+	{0x412158bb, 0x00000eee, 0x00000111, 0x67b38ba2, 0x177976d0},
+	{0x2e52de3e, 0x00000c4a, 0x000003b5, 0xbcc5d61d, 0xf60fee71},
+	{0x6ddaae8b, 0x00000d99, 0x00000266, 0x8b535544, 0x1dab8596},
+	{0x049b6cb1, 0x000009c5, 0x000000b0, 0xfc22cabc, 0x47ebc954},
+	{0x77d4b954, 0x0000028a, 0x000007fa, 0x71d00923, 0x905585ef},
+	{0x5e192355, 0x00000ac1, 0x000001fa, 0xb966b81a, 0x33c12903},
+	{0x7d80b71d, 0x00000213, 0x000001e0, 0x2bba371a, 0x5f4bd8d9},
+	{0x01f6f1e4, 0x000001d6, 0x00000395, 0xb7e8a647, 0x2a7943a1},
+	{0x1dfabb13, 0x00000e14, 0x000001eb, 0x53917fba, 0x8dee1e5d},
+	{0xb00a4449, 0x00000bf6, 0x00000409, 0xedecb577, 0x628e087d},
+	{0x7ecd3981, 0x0000083f, 0x0000016b, 0xefef62b9, 0xda4f94e6},
+	{0xf8f330d2, 0x000004be, 0x00000757, 0x9357c9f3, 0x8e2d5c2f},
+	{0x03c38af2, 0x00000d23, 0x000002dc, 0x360fa8c0, 0x6294c0d6},
+	{0x687bb79b, 0x00000f3d, 0x000000c2, 0x448d3be2, 0x08f48f3a},
+	{0x6710f550, 0x000009e9, 0x00000603, 0xdbfd1998, 0xc950ac29},
+	{0x873171d1, 0x00000787, 0x000004d5, 0xab7f1b62, 0xe66896ab},
+	{0x373b1314, 0x00000f0f, 0x000000f0, 0x184098ab, 0x4038e674},
+	{0x90fad9cd, 0x00000ead, 0x00000152, 0x23ce52ff, 0x9eff3974},
+	{0x19676fe7, 0x0000007d, 0x0000070d, 0xf8a76f1e, 0xfbc5c8a9},
+	{0x89facd45, 0x000005f3, 0x00000473, 0x4331a006, 0xb8f0f0cc},
+	{0x6f173747, 0x00000fc3, 0x0000003c, 0xb012f08e, 0x5126e378},
+	{0x4b44a106, 0x0000075a, 0x0000008b, 0xf6f7ac38, 0xf9b1781b},
+	{0xb620ad06, 0x00000774, 0x0000017e, 0xd34558e6, 0xb175edd3},
+	{0x976f21e9, 0x000008d7, 0x0000034a, 0xe533aa3a, 0x1e4367b9},
+	{0x687628c0, 0x000006c5, 0x0000061b, 0x3a840b15, 0xfb5989a0},
+	{0xe24ac108, 0x00000cd0, 0x0000032f, 0x51010ae8, 0xcdd8f182},
+	{0x361c44a3, 0x00000304, 0x00000719, 0xfd7bd481, 0x12de540f},
+	{0xd93ff95e, 0x00000db7, 0x0000008e, 0xcfbbc304, 0x42eecd5a},
+	{0xed752d12, 0x00000883, 0x00000091, 0x65a6c868, 0x9ebfa578},
+	{0xb4ff4b54, 0x000003d3, 0x000001c1, 0xf82597e7, 0xa8ad2b19},
+	{0x111b520f, 0x00000708, 0x000000eb, 0xc3e109f3, 0x323ace17},
+	{0x62c806f2, 0x00000ba3, 0x0000045c, 0x874d3a72, 0xaf1a1360},
+	{0x40d97470, 0x000005e1, 0x0000058d, 0x87a9684f, 0x524244a8},
+	{0x4312179c, 0x00000056, 0x0000070e, 0x809a00f5, 0xf9e940b0},
+	{0x13d5f84c, 0x00000a2d, 0x00000104, 0xf3d27578, 0x5d33341c},
+	{0x1f302cb2, 0x00000151, 0x00000014, 0x1e162693, 0x53c3cfc3},
+	{0xe491db24, 0x00000600, 0x000006f6, 0x7ff09615, 0xa300ecf7},
+	{0xf9a98069, 0x000002ba, 0x000002ad, 0x01af7387, 0x31c0911e},
+	{0xe9c477ad, 0x0000015f, 0x00000778, 0x6facf9a0, 0x1993b688},
+	{0x353f32b2, 0x0000087c, 0x00000783, 0x6cc964ea, 0x418db561},
+	{0x78e1b24f, 0x00000650, 0x000006a8, 0xb3bb7c27, 0xf2aad006},
+	{0x61aa400e, 0x00000049, 0x00000254, 0xb8cd1681, 0x79150b15},
+	{0xb84b10b0, 0x00000f73, 0x0000008c, 0x406a6450, 0x0c705222},
+	{0x9fa99c9c, 0x00000a7c, 0x000004d7, 0xfb3d21b4, 0xe4e789df},
+	{0x3fc9ebe3, 0x00000cd9, 0x000000d6, 0x43803f9c, 0x5a152be5},
+	{0x529879cd, 0x000002f2, 0x00000595, 0x78b4c6a6, 0xf7236ec4},
+	{0x3a933019, 0x00000516, 0x00000266, 0xdcb45436, 0x2c7935f5},
+	{0x887b4977, 0x00000227, 0x0000038d, 0xc5f7c3d9, 0x0d6d7df6},
+	{0x770745de, 0x000008c6, 0x00000739, 0xf69145e8, 0x47d5efc9},
+	{0x28be3b47, 0x00000c46, 0x0000032b, 0x764c028f, 0x1eb70d64},
+	{0x5013a050, 0x00000cf6, 0x00000309, 0xea8fe164, 0x186affa4},
+	{0x2ec4c9ba, 0x000006e8, 0x0000078d, 0xa35557a9, 0xb41f49ec},
+	{0xa9f950c9, 0x00000d33, 0x000002cc, 0x41ea8618, 0xab8dfae3},
+	{0x5b520229, 0x000007b2, 0x00000484, 0x44569f1f, 0x607a8052},
+	{0xd8dcbbfc, 0x0000002f, 0x0000048c, 0xdb88ab8b, 0xf1c411f1},
+	{0x25529792, 0x00000d1d, 0x000002e2, 0x20cda404, 0x32683a2d},
+	{0x9f3f6d71, 0x00000238, 0x0000079a, 0x0720443e, 0x4b8ba2ff},
+	{0x64121215, 0x000007ff, 0x0000038f, 0x6aacff2c, 0x3b84233b},
+	{0xfb6cdde0, 0x00000ef8, 0x00000107, 0xbd43a0f1, 0x926624d0},
+	{0x221c9d6f, 0x000007b6, 0x0000014f, 0xb67f834b, 0x2bdedda4},
+	{0x030e1de4, 0x00000836, 0x000004b4, 0x0d67d26a, 0x75a73b73},
+	{0xb56fa6cf, 0x00000c07, 0x000003f8, 0x60601ac1, 0x10a43f35},
+	{0xb55c89f5, 0x0000098e, 0x000001d4, 0x2400efbe, 0x006e28eb},
+	{0x5e90b6d5, 0x0000070b, 0x000003ea, 0x3bb5d6ea, 0xb175fa6b},
+	{0x2a7045ae, 0x00000961, 0x00000633, 0xfca89e4b, 0x962cd6d2},
+	{0x8b374ea9, 0x000006ba, 0x00000780, 0xbce036ed, 0x4dc8279b},
+	{0x8bd90bc9, 0x00000562, 0x00000369, 0xcb26a24b, 0x50dee743},
+	{0x5b1b1762, 0x000000fd, 0x0000051a, 0x33cdda07, 0xee75ff7b},
+	{0xa4153555, 0x0000058f, 0x000005c7, 0xbe50eeca, 0xe73fffcc},
+	{0x0be1f931, 0x00000651, 0x00000672, 0x95a25753, 0x4ad6270f},
+	{0xb7e78618, 0x00000a7f, 0x000002bb, 0xe06bcc1c, 0x1a35ee59},
+	{0x4a9bc41b, 0x00000e51, 0x000001ae, 0x709e8d2c, 0x75080ca8},
+	{0xfc359d13, 0x00000440, 0x000002f8, 0x0a58451f, 0x6fa3cfbf},
+	{0x5aa48619, 0x000006d1, 0x00000284, 0x928ead83, 0xbd600efc},
+	{0xa609afa8, 0x0000053e, 0x00000272, 0xb048c141, 0x184f80bb},
+	{0x3f108afb, 0x00000949, 0x00000150, 0x9a6bb5bc, 0x0ea02be1},
+	{0x79bec2d3, 0x000008ed, 0x00000712, 0x32692d57, 0x2eb13289},
+	{0x9429e067, 0x00000bc3, 0x0000043c, 0x5295ceff, 0x8a9014a7},
+	{0xae58b96a, 0x0000082d, 0x000007d2, 0xc2a681ba, 0x6af94089},
+	{0x95df24be, 0x00000985, 0x000004c1, 0x3a287765, 0x379fcb42},
+	{0x5e94976f, 0x00000596, 0x000004ed, 0xff00c489, 0x991fc1f5},
+	{0xf5e5f1de, 0x00000d31, 0x000002ce, 0x35f28e91, 0x543def1a},
+	{0xa2c219cf, 0x00000a3c, 0x00000374, 0x707d21eb, 0xa6d28bc1},
+	{0xf21b6ceb, 0x00000919, 0x00000135, 0x0847fb8b, 0x224468c2},
+	{0xaa988728, 0x00000787, 0x00000771, 0x885aeaa4, 0x814db00b},
+	{0xaa5dfaac, 0x000003e5, 0x0000051b, 0x52c48ab7, 0x725bef8a},
+	{0x0a053968, 0x00000d2a, 0x000002d5, 0x7a90256d, 0xc53b9402},
+	{0x1421dc20, 0x00000eef, 0x00000110, 0x97d6da24, 0x10846935},
+	{0xb47c2166, 0x00000a6a, 0x00000209, 0xcfd6cc52, 0x46e2797e},
+	{0x77dd1955, 0x000000de, 0x00000266, 0xba74bcaa, 0x4fa3fe9c},
+	{0x68a03cc2, 0x0000082f, 0x000007b0, 0x752bd5d8, 0x4f760c63},
+	{0x0226b0a3, 0x00000a5f, 0x000005a0, 0x82de4970, 0x8ee1310e},
+	{0x637bf3b1, 0x00000d93, 0x0000026c, 0x5c7115cb, 0x9f6a0ced},
+	{0x3b120edf, 0x00000c13, 0x000003ec, 0x80d7d20f, 0x241657d5},
+	{0xe2456780, 0x000002eb, 0x00000641, 0xc0a5d289, 0x74df96b4},
+	{0x9b2e7125, 0x00000c0c, 0x000003f3, 0xcc15f57e, 0x03e290bf},
+	{0x153033ef, 0x00000787, 0x000006b6, 0x3cde443b, 0x7bf1d121},
+	{0x18458b3f, 0x0000066c, 0x00000561, 0x9a2bd8c6, 0x9d564bef},
+	{0x4ff9d4b9, 0x00000c8f, 0x0000033a, 0xd0ee6d6d, 0xee00aa0b},
+	{0xdf84b5d9, 0x00000802, 0x0000029a, 0xdab0d74a, 0xd0cb63dc},
+	{0x81ee15df, 0x000003ce, 0x00000725, 0x9942e2de, 0xe48fb26b},
+	{0x5c768e04, 0x00000afd, 0x00000160, 0x36110831, 0x8dc74483},
+	{0xe5e18094, 0x00000b4b, 0x000000a0, 0xffa3e4a7, 0xc0145e1b},
+	{0xed7263b6, 0x00000d0d, 0x000002f2, 0xb0006a35, 0x5468ae3a},
+	{0x5bfde7d7, 0x000006fb, 0x00000554, 0xa4193b76, 0xb73d34b2},
+	{0x67f4a743, 0x00000b85, 0x0000047a, 0xf05c8d8f, 0x4f843e49},
+	{0xf13bdf22, 0x00000ff7, 0x00000008, 0x816351eb, 0x41f537f6},
+	{0x08ecc608, 0x00000d5d, 0x00000098, 0x90492772, 0xf5172204},
+	{0x296f52ba, 0x000004f9, 0x00000788, 0x5e5a4896, 0xe01d5b46},
+	{0xbe4624c2, 0x00000427, 0x000004ef, 0xcd267b94, 0x7b9069f4},
+	{0x906f7c7c, 0x00000a05, 0x0000003f, 0x03fcfc33, 0x7b6ff563},
+	{0x8f7b323e, 0x00000458, 0x000004c7, 0xcd4969c8, 0xd4c22ada},
+	{0x88d6593d, 0x00000597, 0x000005b5, 0xf199cd3b, 0x5c3e8ca2},
+	{0x978a7768, 0x00000268, 0x000001d3, 0xb28c95bd, 0x49a2cc67},
+	{0x857a621e, 0x000007a7, 0x000003a8, 0xf4bf84ab, 0xde26f369},
+	{0xb0e121ef, 0x000005be, 0x00000644, 0x28747c14, 0x61d4dc6b},
+	{0, 0, 0, 0, 0},
+};
+
+static int test_crc32c(void)
+{
+	struct crc_test *t = test;
+	int failures = 0;
+
+	while (t->length) {
+		uint32_t be, le;
+		le = ext2fs_crc32c_le(t->crc, test_buf + t->start, t->length);
+		be = ext2fs_crc32c_be(t->crc, test_buf + t->start, t->length);
+		if (le != t->crc_le) {
+			printf("Test %d LE fails, %x != %x\n",
+			       (int) (t - test), le, t->crc_le);
+			failures++;
+		}
+		if (be != t->crc_be) {
+			printf("Test %d BE fails, %x != %x\n",
+			       (int) (t - test), be, t->crc_be);
+			failures++;
+		}
+		t++;
+	}
+
+	return failures;
+}
+
+int main(int argc, char *argv[])
+{
+	int ret;
+
+	ret = test_crc32c();
+	if (!ret)
+		printf("No failures.\n");
+
+	return ret;
+}
+#endif /* UNITTEST */
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc32c_defs.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc32c_defs.h
new file mode 100644
index 0000000..023f2c0
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/crc32c_defs.h
@@ -0,0 +1,51 @@
+/*
+ * This is the CRC32c polynomial, as outlined by Castagnoli.
+ * x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+
+ * x^8+x^6+x^0
+ */
+#define CRCPOLY_LE 0x82F63B78
+#define CRCPOLY_BE 0x1EDC6F41
+
+/* How many bits at a time to use.  Valid values are 1, 2, 4, 8, 32 and 64. */
+/* For less performance-sensitive, use 4 */
+#ifndef CRC_LE_BITS
+# define CRC_LE_BITS 64
+#endif
+#ifndef CRC_BE_BITS
+# define CRC_BE_BITS 64
+#endif
+
+/*
+ * Little-endian CRC computation.  Used with serial bit streams sent
+ * lsbit-first.  Be sure to use cpu_to_le32() to append the computed CRC.
+ */
+#if CRC_LE_BITS > 64 || CRC_LE_BITS < 1 || CRC_LE_BITS == 16 || \
+	CRC_LE_BITS & CRC_LE_BITS-1
+# error "CRC_LE_BITS must be one of {1, 2, 4, 8, 32, 64}"
+#endif
+
+/*
+ * Big-endian CRC computation.  Used with serial bit streams sent
+ * msbit-first.  Be sure to use cpu_to_be32() to append the computed CRC.
+ */
+#if CRC_BE_BITS > 64 || CRC_BE_BITS < 1 || CRC_BE_BITS == 16 || \
+	CRC_BE_BITS & CRC_BE_BITS-1
+# error "CRC_BE_BITS must be one of {1, 2, 4, 8, 32, 64}"
+#endif
+
+
+#define ___constant_swab32(x) \
+	((uint32_t)( \
+		(((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
+		(((uint32_t)(x) & (uint32_t)0x0000ff00UL) <<  8) | \
+		(((uint32_t)(x) & (uint32_t)0x00ff0000UL) >>  8) | \
+		(((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
+
+
+#if (__GNUC__ >= 3)
+#define likely(x)	__builtin_expect(!!(x), 1)
+#define unlikely(x)	__builtin_expect(!!(x), 0)
+#else
+#define likely(x)	(x)
+#define unlikely(x)	(x)
+#endif
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/csum.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/csum.c
new file mode 100644
index 0000000..b681d34
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/csum.c
@@ -0,0 +1,308 @@
+/*
+ * csum.c --- checksumming of ext3 structures
+ *
+ * Copyright (C) 2006 Cluster File Systems, Inc.
+ * Copyright (C) 2006, 2007 by Andreas Dilger <adilger@clusterfs.com>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+#include "crc16.h"
+#include <assert.h>
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#ifdef DEBUG
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+__u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group)
+{
+	struct ext2_group_desc *desc = ext2fs_group_desc(fs, fs->group_desc,
+							 group);
+	size_t size = EXT2_DESC_SIZE(fs->super);
+	size_t offset;
+	__u16 crc;
+
+	if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
+		size_t offset = offsetof(struct ext2_group_desc, bg_checksum);
+
+#ifdef WORDS_BIGENDIAN
+		struct ext4_group_desc swabdesc;
+		size_t save_size = size;
+		const size_t ext4_bg_size = sizeof(struct ext4_group_desc);
+		struct ext2_group_desc *save_desc = desc;
+
+		/* Have to swab back to little-endian to do the checksum */
+		if (size > ext4_bg_size)
+			size = ext4_bg_size;
+		memcpy(&swabdesc, desc, size);
+		ext2fs_swap_group_desc2(fs,
+					(struct ext2_group_desc *) &swabdesc);
+		desc = (struct ext2_group_desc *) &swabdesc;
+
+		group = ext2fs_swab32(group);
+#endif
+		crc = ext2fs_crc16(~0, fs->super->s_uuid,
+				   sizeof(fs->super->s_uuid));
+		crc = ext2fs_crc16(crc, &group, sizeof(group));
+		crc = ext2fs_crc16(crc, desc, offset);
+		offset += sizeof(desc->bg_checksum); /* skip checksum */
+		/* for checksum of struct ext4_group_desc do the rest...*/
+		if (offset < size) {
+			crc = ext2fs_crc16(crc, (char *)desc + offset,
+					   size - offset);
+		}
+#ifdef WORDS_BIGENDIAN
+		/*
+		 * If the size of the bg descriptor is greater than 64
+		 * bytes, which is the size of the traditional ext4 bg
+		 * descriptor, checksum the rest of the descriptor here
+		 */
+		if (save_size > ext4_bg_size)
+			crc = ext2fs_crc16(crc,
+					   (char *)save_desc + ext4_bg_size,
+					   save_size - ext4_bg_size);
+#endif
+	}
+
+	return crc;
+}
+
+int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group)
+{
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_GDT_CSUM) &&
+	    (ext2fs_bg_checksum(fs, group) !=
+	     ext2fs_group_desc_csum(fs, group)))
+		return 0;
+
+	return 1;
+}
+
+void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group)
+{
+	if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
+		return;
+
+	/* ext2fs_bg_checksum_set() sets the actual checksum field but
+	 * does not calculate the checksum itself. */
+	ext2fs_bg_checksum_set(fs, group, ext2fs_group_desc_csum(fs, group));
+}
+
+static __u32 find_last_inode_ingrp(ext2fs_inode_bitmap bitmap,
+				   __u32 inodes_per_grp, dgrp_t grp_no)
+{
+	ext2_ino_t i, start_ino, end_ino;
+
+	start_ino = grp_no * inodes_per_grp + 1;
+	end_ino = start_ino + inodes_per_grp - 1;
+
+	for (i = end_ino; i >= start_ino; i--) {
+		if (ext2fs_fast_test_inode_bitmap2(bitmap, i))
+			return i - start_ino + 1;
+	}
+	return inodes_per_grp;
+}
+
+/* update the bitmap flags, set the itable high watermark, and calculate
+ * checksums for the group descriptors */
+errcode_t ext2fs_set_gdt_csum(ext2_filsys fs)
+{
+	struct ext2_super_block *sb = fs->super;
+	int dirty = 0;
+	dgrp_t i;
+
+	if (!fs->inode_map)
+		return EXT2_ET_NO_INODE_BITMAP;
+
+	if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
+		return 0;
+
+	for (i = 0; i < fs->group_desc_count; i++) {
+		__u32 old_csum = ext2fs_bg_checksum(fs, i);
+		__u32 old_unused = ext2fs_bg_itable_unused(fs, i);
+		__u32 old_flags = ext2fs_bg_flags(fs, i);
+		__u32 old_free_inodes_count = ext2fs_bg_free_inodes_count(fs, i);
+
+		if (old_free_inodes_count == sb->s_inodes_per_group) {
+			ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT);
+			ext2fs_bg_itable_unused_set(fs, i, sb->s_inodes_per_group);
+		} else {
+			int unused =
+				sb->s_inodes_per_group -
+				find_last_inode_ingrp(fs->inode_map,
+						      sb->s_inodes_per_group, i);
+
+			ext2fs_bg_flags_clear(fs, i, EXT2_BG_INODE_UNINIT);
+			ext2fs_bg_itable_unused_set(fs, i, unused);
+		}
+
+		ext2fs_group_desc_csum_set(fs, i);
+		if (old_flags != ext2fs_bg_flags(fs, i))
+			dirty = 1;
+		if (old_unused != ext2fs_bg_itable_unused(fs, i))
+			dirty = 1;
+		if (old_csum != ext2fs_bg_checksum(fs, i))
+			dirty = 1;
+	}
+	if (dirty)
+		ext2fs_mark_super_dirty(fs);
+	return 0;
+}
+
+#ifdef DEBUG
+#include "e2p/e2p.h"
+
+void print_csum(const char *msg, ext2_filsys fs, dgrp_t group)
+{
+	__u16 crc1, crc2, crc3;
+	dgrp_t swabgroup;
+	struct ext2_group_desc *desc = ext2fs_group_desc(fs, fs->group_desc,
+							 group);
+	size_t size = EXT2_DESC_SIZE(fs->super);
+	struct ext2_super_block *sb = fs->super;
+	int offset = offsetof(struct ext2_group_desc, bg_checksum);
+#ifdef WORDS_BIGENDIAN
+	struct ext4_group_desc swabdesc;
+	struct ext2_group_desc *save_desc = desc;
+	const size_t ext4_bg_size = sizeof(struct ext4_group_desc);
+	size_t save_size = size;
+#endif
+
+#ifdef WORDS_BIGENDIAN
+	/* Have to swab back to little-endian to do the checksum */
+	if (size > ext4_bg_size)
+		size = ext4_bg_size;
+	memcpy(&swabdesc, desc, size);
+	ext2fs_swap_group_desc2(fs, (struct ext2_group_desc *) &swabdesc);
+	desc = (struct ext2_group_desc *) &swabdesc;
+
+	swabgroup = ext2fs_swab32(group);
+#else
+	swabgroup = group;
+#endif
+
+	crc1 = ext2fs_crc16(~0, sb->s_uuid, sizeof(fs->super->s_uuid));
+	crc2 = ext2fs_crc16(crc1, &swabgroup, sizeof(swabgroup));
+	crc3 = ext2fs_crc16(crc2, desc, offset);
+	offset += sizeof(desc->bg_checksum); /* skip checksum */
+	/* for checksum of struct ext4_group_desc do the rest...*/
+	if (offset < size)
+		crc3 = ext2fs_crc16(crc3, (char *)desc + offset, size - offset);
+#ifdef WORDS_BIGENDIAN
+	if (save_size > ext4_bg_size)
+		crc3 = ext2fs_crc16(crc3, (char *)save_desc + ext4_bg_size,
+				    save_size - ext4_bg_size);
+#endif
+
+	printf("%s UUID %s=%04x, grp %u=%04x: %04x=%04x\n",
+	       msg, e2p_uuid2str(sb->s_uuid), crc1, group, crc2, crc3,
+	       ext2fs_group_desc_csum(fs, group));
+}
+
+unsigned char sb_uuid[16] = { 0x4f, 0x25, 0xe8, 0xcf, 0xe7, 0x97, 0x48, 0x23,
+			      0xbe, 0xfa, 0xa7, 0x88, 0x4b, 0xae, 0xec, 0xdb };
+
+int main(int argc, char **argv)
+{
+	struct ext2_super_block param;
+	errcode_t		retval;
+	ext2_filsys		fs;
+	int			i;
+	__u16 csum1, csum2, csum_known = 0xd3a4;
+
+	memset(&param, 0, sizeof(param));
+	ext2fs_blocks_count_set(&param, 32768);
+#if 0
+	param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_64BIT;
+	param.s_desc_size = 128;
+	csum_known = 0x5b6e;
+#endif
+
+	retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, &param,
+				   test_io_manager, &fs);
+	if (retval) {
+		com_err("setup", retval,
+			"While initializing filesystem");
+		exit(1);
+	}
+	memcpy(fs->super->s_uuid, sb_uuid, 16);
+	fs->super->s_feature_ro_compat = EXT4_FEATURE_RO_COMPAT_GDT_CSUM;
+
+	for (i=0; i < fs->group_desc_count; i++) {
+		ext2fs_block_bitmap_loc_set(fs, i, 124);
+		ext2fs_inode_bitmap_loc_set(fs, i, 125);
+		ext2fs_inode_table_loc_set(fs, i, 126);
+		ext2fs_bg_free_blocks_count_set(fs, i, 31119);
+		ext2fs_bg_free_inodes_count_set(fs, i, 15701);
+		ext2fs_bg_used_dirs_count_set(fs, i, 2);
+		ext2fs_bg_flags_zap(fs, i);
+	};
+
+	csum1 = ext2fs_group_desc_csum(fs, 0);
+	print_csum("csum0000", fs, 0);
+
+	if (csum1 != csum_known) {
+		printf("checksum for group 0 should be %04x\n", csum_known);
+		exit(1);
+	}
+	csum2 = ext2fs_group_desc_csum(fs, 1);
+	print_csum("csum0001", fs, 1);
+	if (csum1 == csum2) {
+		printf("checksums for different groups shouldn't match\n");
+		exit(1);
+	}
+	csum2 = ext2fs_group_desc_csum(fs, 2);
+	print_csum("csumffff", fs, 2);
+	if (csum1 == csum2) {
+		printf("checksums for different groups shouldn't match\n");
+		exit(1);
+	}
+	ext2fs_bg_checksum_set(fs, 0, csum1);
+	csum2 = ext2fs_group_desc_csum(fs, 0);
+	print_csum("csum_set", fs, 0);
+	if (csum1 != csum2) {
+		printf("checksums should not depend on checksum field\n");
+		exit(1);
+	}
+	if (!ext2fs_group_desc_csum_verify(fs, 0)) {
+		printf("checksums should verify against gd_checksum\n");
+		exit(1);
+	}
+	memset(fs->super->s_uuid, 0x30, sizeof(fs->super->s_uuid));
+	print_csum("new_uuid", fs, 0);
+	if (ext2fs_group_desc_csum_verify(fs, 0) != 0) {
+		printf("checksums for different filesystems shouldn't match\n");
+		exit(1);
+	}
+	csum1 = ext2fs_group_desc_csum(fs, 0);
+	ext2fs_bg_checksum_set(fs, 0, csum1);
+	print_csum("csum_new", fs, 0);
+	ext2fs_bg_free_blocks_count_set(fs, 0, 1);
+	csum2 = ext2fs_group_desc_csum(fs, 0);
+	print_csum("csum_blk", fs, 0);
+	if (csum1 == csum2) {
+		printf("checksums for different data shouldn't match\n");
+		exit(1);
+	}
+
+	return 0;
+}
+#endif
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dblist.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dblist.c
new file mode 100644
index 0000000..3f6ea50
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dblist.c
@@ -0,0 +1,416 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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);
+static EXT2_QSORT_TYPE dir_block_cmp2(const void *a, const void *b);
+static EXT2_QSORT_TYPE (*sortfunc32)(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 (ext2fs_bg_used_dirs_count(fs, i) > max_dirs)
+			num_dirs += max_dirs / 8;
+		else
+			num_dirs += ext2fs_bg_used_dirs_count(fs, i);
+	}
+	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_entry2 *list,
+			     ext2_dblist *ret_dblist)
+{
+	ext2_dblist	dblist = NULL;
+	errcode_t	retval;
+	ext2_ino_t	num_dirs;
+	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)
+		goto cleanup;
+	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, &num_dirs);
+		if (retval)
+			goto cleanup;
+		dblist->size = (num_dirs * 2) + 12;
+	}
+	len = (size_t) sizeof(struct ext2_db_entry2) * dblist->size;
+	dblist->count = count;
+	retval = ext2fs_get_array(dblist->size, sizeof(struct ext2_db_entry2),
+		&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_block2(ext2_dblist dblist, ext2_ino_t ino,
+				blk64_t blk, e2_blkcnt_t blockcnt)
+{
+	struct ext2_db_entry2 	*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_entry2);
+		dblist->size += dblist->size > 200 ? dblist->size / 2 : 100;
+		retval = ext2fs_resize_mem(old_size, (size_t) dblist->size *
+					   sizeof(struct ext2_db_entry2),
+					   &dblist->list);
+		if (retval) {
+			dblist->size = old_size / sizeof(struct ext2_db_entry2);
+			return retval;
+		}
+	}
+	new_entry = dblist->list + ( 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_block2(ext2_dblist dblist, ext2_ino_t ino,
+				blk64_t blk, e2_blkcnt_t 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_sort2(ext2_dblist dblist,
+			 EXT2_QSORT_TYPE (*sortfunc)(const void *,
+						     const void *))
+{
+	if (!sortfunc)
+		sortfunc = dir_block_cmp2;
+	qsort(dblist->list, (size_t) dblist->count,
+	      sizeof(struct ext2_db_entry2), sortfunc);
+	dblist->sorted = 1;
+}
+
+/*
+ * This function iterates over the directory block list
+ */
+errcode_t ext2fs_dblist_iterate2(ext2_dblist dblist,
+				 int (*func)(ext2_filsys fs,
+					     struct ext2_db_entry2 *db_info,
+					     void	*priv_data),
+				 void *priv_data)
+{
+	unsigned long long	i;
+	int		ret;
+
+	EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+
+	if (!dblist->sorted)
+		ext2fs_dblist_sort2(dblist, 0);
+	for (i=0; i < dblist->count; i++) {
+		ret = (*func)(dblist->fs, &dblist->list[i], priv_data);
+		if (ret & DBLIST_ABORT)
+			return 0;
+	}
+	return 0;
+}
+
+static EXT2_QSORT_TYPE dir_block_cmp2(const void *a, const void *b)
+{
+	const struct ext2_db_entry2 *db_a =
+		(const struct ext2_db_entry2 *) a;
+	const struct ext2_db_entry2 *db_b =
+		(const struct ext2_db_entry2 *) 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 (db_a->blockcnt - db_b->blockcnt);
+}
+
+blk64_t ext2fs_dblist_count2(ext2_dblist dblist)
+{
+	return dblist->count;
+}
+
+errcode_t ext2fs_dblist_get_last2(ext2_dblist dblist,
+				  struct ext2_db_entry2 **entry)
+{
+	EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+
+	if (dblist->count == 0)
+		return EXT2_ET_DBLIST_EMPTY;
+
+	if (entry)
+		*entry = dblist->list + ( dblist->count-1);
+	return 0;
+}
+
+errcode_t ext2fs_dblist_drop_last(ext2_dblist dblist)
+{
+	EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+
+	if (dblist->count == 0)
+		return EXT2_ET_DBLIST_EMPTY;
+
+	dblist->count--;
+	return 0;
+}
+
+/*
+ * Legacy 32-bit versions
+ */
+
+/*
+ * 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)
+{
+	return ext2fs_add_dir_block2(dblist, ino, blk, blockcnt);
+}
+
+/*
+ * 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)
+{
+	return ext2fs_set_dir_block2(dblist, ino, blk, blockcnt);
+}
+
+void ext2fs_dblist_sort(ext2_dblist dblist,
+			EXT2_QSORT_TYPE (*sortfunc)(const void *,
+						    const void *))
+{
+	if (sortfunc) {
+		sortfunc32 = sortfunc;
+		sortfunc = dir_block_cmp;
+	} else
+		sortfunc = dir_block_cmp2;
+	qsort(dblist->list, (size_t) dblist->count,
+	      sizeof(struct ext2_db_entry2), sortfunc);
+	dblist->sorted = 1;
+}
+
+/*
+ * This function iterates over the directory block list
+ */
+struct iterate_passthrough {
+	int (*func)(ext2_filsys fs,
+		    struct ext2_db_entry *db_info,
+		    void	*priv_data);
+	void *priv_data;
+};
+
+static int passthrough_func(ext2_filsys fs,
+			    struct ext2_db_entry2 *db_info,
+			    void	*priv_data)
+{
+	struct iterate_passthrough *p = priv_data;
+	struct ext2_db_entry db;
+	int ret;
+
+	db.ino = db_info->ino;
+	db.blk = (blk_t) db_info->blk;
+	db.blockcnt = (int) db_info->blockcnt;
+	ret = (p->func)(fs, &db, p->priv_data);
+	db_info->ino = db.ino;
+	db_info->blk = db.blk;
+	db_info->blockcnt = db.blockcnt;
+	return ret;
+}
+
+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)
+{
+	struct iterate_passthrough pass;
+
+	EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+	pass.func = func;
+	pass.priv_data = priv_data;
+
+	return ext2fs_dblist_iterate2(dblist, passthrough_func, &pass);
+}
+
+static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b)
+{
+	const struct ext2_db_entry2 *db_a =
+		(const struct ext2_db_entry2 *) a;
+	const struct ext2_db_entry2 *db_b =
+		(const struct ext2_db_entry2 *) b;
+
+	struct ext2_db_entry a32, b32;
+
+	a32.ino = db_a->ino;  a32.blk = db_a->blk;
+	a32.blockcnt = db_a->blockcnt;
+
+	b32.ino = db_b->ino;  b32.blk = db_b->blk;
+	b32.blockcnt = db_b->blockcnt;
+
+	return sortfunc32(&a32, &b32);
+}
+
+int ext2fs_dblist_count(ext2_dblist dblist)
+{
+	return dblist->count;
+}
+
+errcode_t ext2fs_dblist_get_last(ext2_dblist dblist,
+				 struct ext2_db_entry **entry)
+{
+	static struct ext2_db_entry ret_entry;
+	struct ext2_db_entry2 *last;
+
+	EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+
+	if (dblist->count == 0)
+		return EXT2_ET_DBLIST_EMPTY;
+
+	if (!entry)
+		return 0;
+
+	last = dblist->list + dblist->count -1;
+
+	ret_entry.ino = last->ino;
+	ret_entry.blk = last->blk;
+	ret_entry.blockcnt = last->blockcnt;
+	*entry = &ret_entry;
+
+	return 0;
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dblist_dir.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dblist_dir.c
new file mode 100644
index 0000000..d4d5111
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dblist_dir.c
@@ -0,0 +1,80 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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_entry2 *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_iterate2(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_entry2 *db_info,
+		       void *priv_data)
+{
+	struct dir_context	*ctx;
+	int			ret;
+
+	ctx = (struct dir_context *) priv_data;
+	ctx->dir = db_info->ino;
+	ctx->errcode = 0;
+
+	ret = ext2fs_process_dir_block(fs, &db_info->blk,
+				       db_info->blockcnt, 0, 0, priv_data);
+	if ((ret & BLOCK_ABORT) && !ctx->errcode)
+		return DBLIST_ABORT;
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dir_iterate.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dir_iterate.c
new file mode 100644
index 0000000..589af69
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dir_iterate.c
@@ -0,0 +1,271 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.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 "ext2fsP.h"
+
+#define EXT4_MAX_REC_LEN		((1<<16)-1)
+
+errcode_t ext2fs_get_rec_len(ext2_filsys fs,
+			     struct ext2_dir_entry *dirent,
+			     unsigned int *rec_len)
+{
+	unsigned int len = dirent->rec_len;
+
+	if (fs->blocksize < 65536)
+		*rec_len = len;
+	else if (len == EXT4_MAX_REC_LEN || len == 0)
+		*rec_len = fs->blocksize;
+	else 
+		*rec_len = (len & 65532) | ((len & 3) << 16);
+	return 0;
+}
+
+errcode_t ext2fs_set_rec_len(ext2_filsys fs,
+			     unsigned int len,
+			     struct ext2_dir_entry *dirent)
+{
+	if ((len > fs->blocksize) || (fs->blocksize > (1 << 18)) || (len & 3))
+		return EINVAL;
+	if (len < 65536) {
+		dirent->rec_len = len;
+		return 0;
+	}
+	if (len == fs->blocksize) {
+		if (fs->blocksize == 65536)
+			dirent->rec_len = EXT4_MAX_REC_LEN;
+		else 
+			dirent->rec_len = 0;
+	} else
+		dirent->rec_len = (len & 65532) | ((len >> 16) & 3);
+	return 0;
+}
+
+/*
+ * 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(ext2_filsys fs, char *buf,
+				 unsigned int offset,
+				 unsigned int final_offset)
+{
+	struct ext2_dir_entry *dirent;
+	unsigned int rec_len;
+#define DIRENT_MIN_LENGTH 12
+
+	while ((offset < final_offset) &&
+	       (offset <= fs->blocksize - DIRENT_MIN_LENGTH)) {
+		dirent = (struct ext2_dir_entry *)(buf + offset);
+		if (ext2fs_get_rec_len(fs, dirent, &rec_len))
+			return 0;
+		offset += rec_len;
+		if ((rec_len < 8) ||
+		    ((rec_len % 4) != 0) ||
+		    ((((unsigned) dirent->name_len & 0xFF)+8) > 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_iterate3(fs, dir, BLOCK_FLAG_READ_ONLY, 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);
+}
+
+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,
+			     blk64_t	*blocknr,
+			     e2_blkcnt_t blockcnt,
+			     blk64_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;
+	unsigned int	rec_len, size;
+	int		entry;
+	struct ext2_dir_entry *dirent;
+
+	if (blockcnt < 0)
+		return 0;
+
+	entry = blockcnt ? DIRENT_OTHER_FILE : DIRENT_DOT_FILE;
+
+	ctx->errcode = ext2fs_read_dir_block3(fs, *blocknr, ctx->buf, 0);
+	if (ctx->errcode)
+		return BLOCK_ABORT;
+
+	while (offset < fs->blocksize) {
+		dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
+		if (ext2fs_get_rec_len(fs, dirent, &rec_len))
+			return BLOCK_ABORT;
+		if (((offset + rec_len) > fs->blocksize) ||
+		    (rec_len < 8) ||
+		    ((rec_len % 4) != 0) ||
+		    ((((unsigned) dirent->name_len & 0xFF)+8) > 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) {
+			if (ext2fs_get_rec_len(fs, dirent, &rec_len))
+				return BLOCK_ABORT;
+			changed++;
+		}
+		if (ret & DIRENT_ABORT) {
+			do_abort++;
+			break;
+		}
+next:
+ 		if (next_real_entry == offset)
+			next_real_entry += rec_len;
+
+ 		if (ctx->flags & DIRENT_FLAG_INCLUDE_REMOVED) {
+			size = ((dirent->name_len & 0xFF) + 11) & ~3;
+
+			if (rec_len != size)  {
+				unsigned int final_offset;
+
+				final_offset = offset + rec_len;
+				offset += size;
+				while (offset < final_offset &&
+				       !ext2fs_validate_entry(fs, ctx->buf,
+							      offset,
+							      final_offset))
+					offset += 4;
+				continue;
+			}
+		}
+		offset += rec_len;
+	}
+
+	if (changed) {
+		ctx->errcode = ext2fs_write_dir_block3(fs, *blocknr, ctx->buf,
+						       0);
+		if (ctx->errcode)
+			return BLOCK_ABORT;
+	}
+	if (do_abort)
+		return BLOCK_ABORT;
+	return 0;
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dirblock.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dirblock.c
new file mode 100644
index 0000000..cb3a104
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dirblock.c
@@ -0,0 +1,127 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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_block3(ext2_filsys fs, blk64_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;
+
+
+	retval = io_channel_read_blk64(fs->io, block, 1, buf);
+	if (retval)
+		return retval;
+
+	p = (char *) buf;
+	end = (char *) buf + fs->blocksize;
+	while (p < end-8) {
+		dirent = (struct ext2_dir_entry *) p;
+#ifdef WORDS_BIGENDIAN
+		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
+		if ((retval = ext2fs_get_rec_len(fs, dirent, &rec_len)) != 0)
+			return retval;
+		if ((rec_len < 8) || (rec_len % 4)) {
+			rec_len = 8;
+			retval = EXT2_ET_DIR_CORRUPTED;
+		} else if (((name_len & 0xFF) + 8) > rec_len)
+			retval = EXT2_ET_DIR_CORRUPTED;
+		p += rec_len;
+	}
+	return retval;
+}
+
+errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
+				 void *buf, int flags EXT2FS_ATTR((unused)))
+{
+	return ext2fs_read_dir_block3(fs, block, buf, flags);
+}
+
+errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
+				 void *buf)
+{
+	return ext2fs_read_dir_block3(fs, block, buf, 0);
+}
+
+
+errcode_t ext2fs_write_dir_block3(ext2_filsys fs, blk64_t block,
+				  void *inbuf, int flags EXT2FS_ATTR((unused)))
+{
+#ifdef WORDS_BIGENDIAN
+	errcode_t	retval;
+	char		*p, *end;
+	char		*buf = 0;
+	unsigned int	rec_len;
+	struct ext2_dir_entry *dirent;
+
+	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 ((retval = ext2fs_get_rec_len(fs, dirent, &rec_len)) != 0)
+			return retval;
+		if ((rec_len < 8) ||
+		    (rec_len % 4)) {
+			ext2fs_free_mem(&buf);
+			return (EXT2_ET_DIR_CORRUPTED);
+		}
+		p += rec_len;
+		dirent->inode = ext2fs_swab32(dirent->inode);
+		dirent->rec_len = ext2fs_swab16(dirent->rec_len);
+		dirent->name_len = ext2fs_swab16(dirent->name_len);
+
+		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
+			dirent->name_len = ext2fs_swab16(dirent->name_len);
+	}
+	retval = io_channel_write_blk64(fs->io, block, 1, buf);
+	ext2fs_free_mem(&buf);
+	return retval;
+#else
+	return io_channel_write_blk64(fs->io, block, 1, (char *) inbuf);
+#endif
+}
+
+errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
+				 void *inbuf, int flags EXT2FS_ATTR((unused)))
+{
+	return ext2fs_write_dir_block3(fs, block, inbuf, flags);
+}
+
+errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
+				 void *inbuf)
+{
+	return ext2fs_write_dir_block3(fs, block, inbuf, 0);
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dirhash.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dirhash.c
new file mode 100644
index 0000000..c4ac94e
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dirhash.c
@@ -0,0 +1,261 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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,
+				    int unsigned_flag)
+{
+	__u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
+	const unsigned char *ucp = (const unsigned char *) name;
+	const signed char *scp = (const signed char *) name;
+	int c;
+
+	while (len--) {
+		if (unsigned_flag)
+			c = (int) *ucp++;
+		else
+			c = (int) *scp++;
+		hash = hash1 + (hash0 ^ (c * 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,
+			int unsigned_flag)
+{
+	__u32	pad, val;
+	int	i, c;
+	const unsigned char *ucp = (const unsigned char *) msg;
+	const signed char *scp = (const signed char *) msg;
+
+	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;
+		if (unsigned_flag)
+			c = (int) ucp[i];
+		else
+			c = (int) scp[i];
+
+		val = c + (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];
+	int		unsigned_flag = 0;
+
+	/* 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_UNSIGNED:
+		unsigned_flag++;
+		/* fallthrough */
+	case EXT2_HASH_LEGACY:
+		hash = dx_hack_hash(name, len, unsigned_flag);
+		break;
+	case EXT2_HASH_HALF_MD4_UNSIGNED:
+		unsigned_flag++;
+		/* fallthrough */
+	case EXT2_HASH_HALF_MD4:
+		p = name;
+		while (len > 0) {
+			str2hashbuf(p, len, in, 8, unsigned_flag);
+			halfMD4Transform(buf, in);
+			len -= 32;
+			p += 32;
+		}
+		minor_hash = buf[2];
+		hash = buf[1];
+		break;
+	case EXT2_HASH_TEA_UNSIGNED:
+		unsigned_flag++;
+		/* fallthrough */
+	case EXT2_HASH_TEA:
+		p = name;
+		while (len > 0) {
+			str2hashbuf(p, len, in, 4, unsigned_flag);
+			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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dosio.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dosio.c
new file mode 100644
index 0000000..0defff8
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dosio.c
@@ -0,0 +1,458 @@
+/*
+ * dosio.c -- Disk I/O module for the ext2fs/DOS library.
+ *
+ * Copyright (c) 1997 by Theodore Ts'o.
+ *
+ * Copyright (c) 1997 Mark Habersack
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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;
+    free(part->dev);
+    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;
+    free(part->dev);
+    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;
+    free(part->dev);
+    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)
+{
+	free(channel->name);
+	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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dosio.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dosio.h
new file mode 100644
index 0000000..d2a8f03
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dosio.h
@@ -0,0 +1,157 @@
+/*
+ * v1.0
+ *
+ * Disk I/O include file for the ext2fs/DOS library.
+ *
+ * Copyright (c) 1997 Mark Habersack
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dupfs.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dupfs.c
new file mode 100644
index 0000000..02721e1
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/dupfs.c
@@ -0,0 +1,122 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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;
+	fs->mmp_buf = 0;
+	fs->mmp_cmp = 0;
+	fs->mmp_fd = -1;
+
+	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_array(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;
+	}
+	if (src->mmp_buf) {
+		retval = ext2fs_get_mem(src->blocksize, &fs->mmp_buf);
+		if (retval)
+			goto errout;
+		memcpy(fs->mmp_buf, src->mmp_buf, src->blocksize);
+	}
+	if (src->mmp_fd >= 0) {
+		fs->mmp_fd = dup(src->mmp_fd);
+		if (fs->mmp_fd < 0) {
+			retval = EXT2_ET_MMP_OPEN_DIRECT;
+			goto errout;
+		}
+	}
+	if (src->mmp_cmp) {
+		int align = ext2fs_get_dio_alignment(src->mmp_fd);
+
+		retval = ext2fs_get_memalign(src->blocksize, align,
+					     &fs->mmp_cmp);
+		if (retval)
+			goto errout;
+		memcpy(fs->mmp_cmp, src->mmp_cmp, src->blocksize);
+	}
+	*dest = fs;
+	return 0;
+errout:
+	ext2fs_free(fs);
+	return retval;
+
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/e2image.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/e2image.h
new file mode 100644
index 0000000..53b20cc
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/e2image.h
@@ -0,0 +1,37 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/expanddir.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/expanddir.c
new file mode 100644
index 0000000..153b838
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/expanddir.c
@@ -0,0 +1,137 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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;
+	blk64_t		goal;
+	errcode_t	err;
+};
+
+static int expand_dir_proc(ext2_filsys	fs,
+			   blk64_t	*blocknr,
+			   e2_blkcnt_t	blockcnt,
+			   blk64_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;
+	blk64_t	new_blk;
+	char		*block;
+	errcode_t	retval;
+
+	if (*blocknr) {
+		if (blockcnt >= 0)
+			es->goal = *blocknr;
+		return 0;
+	}
+	if (blockcnt &&
+	    (EXT2FS_B2C(fs, es->goal) == EXT2FS_B2C(fs, es->goal+1)))
+		new_blk = es->goal+1;
+	else {
+		es->goal &= ~EXT2FS_CLUSTER_MASK(fs);
+		retval = ext2fs_new_block2(fs, es->goal, 0, &new_blk);
+		if (retval) {
+			es->err = retval;
+			return BLOCK_ABORT;
+		}
+		es->newblocks++;
+		ext2fs_block_alloc_stats2(fs, new_blk, +1);
+	}
+	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_blk64(fs->io, new_blk, 1, block);
+	}
+	if (blockcnt >= 0)
+		es->goal = new_blk;
+	if (retval) {
+		es->err = retval;
+		return BLOCK_ABORT;
+	}
+	ext2fs_free_mem(&block);
+	*blocknr = new_blk;
+
+	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.goal = 0;
+	es.newblocks = 0;
+
+	retval = ext2fs_block_iterate3(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;
+	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
+
+	retval = ext2fs_write_inode(fs, dir, &inode);
+	if (retval)
+		return retval;
+
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_err.et.in b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_err.et.in
new file mode 100644
index 0000000..87812ab
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_err.et.in
@@ -0,0 +1,479 @@
+#
+# 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%
+#
+	error_table ext2
+
+ec	EXT2_ET_BASE,
+	"EXT2FS Library version @E2FSPROGS_VERSION@"
+
+ec	EXT2_ET_MAGIC_EXT2FS_FILSYS,
+	"Wrong magic number for ext2_filsys structure"
+
+ec	EXT2_ET_MAGIC_BADBLOCKS_LIST,
+	"Wrong magic number for badblocks_list structure"
+
+ec	EXT2_ET_MAGIC_BADBLOCKS_ITERATE,
+	"Wrong magic number for badblocks_iterate structure"
+
+ec	EXT2_ET_MAGIC_INODE_SCAN,
+	"Wrong magic number for inode_scan structure"
+
+ec	EXT2_ET_MAGIC_IO_CHANNEL,
+	"Wrong magic number for io_channel structure"
+
+ec	EXT2_ET_MAGIC_UNIX_IO_CHANNEL,
+	"Wrong magic number for unix io_channel structure"
+
+ec	EXT2_ET_MAGIC_IO_MANAGER,
+	"Wrong magic number for io_manager structure"
+
+ec	EXT2_ET_MAGIC_BLOCK_BITMAP,
+	"Wrong magic number for block_bitmap structure"
+
+ec	EXT2_ET_MAGIC_INODE_BITMAP,
+	"Wrong magic number for inode_bitmap structure"
+
+ec	EXT2_ET_MAGIC_GENERIC_BITMAP,
+	"Wrong magic number for generic_bitmap structure"
+
+ec	EXT2_ET_MAGIC_TEST_IO_CHANNEL,
+	"Wrong magic number for test io_channel structure"
+
+ec	EXT2_ET_MAGIC_DBLIST,
+	"Wrong magic number for directory block list structure"
+
+ec	EXT2_ET_MAGIC_ICOUNT,
+	"Wrong magic number for icount structure"
+
+ec	EXT2_ET_MAGIC_PQ_IO_CHANNEL,
+	"Wrong magic number for Powerquest io_channel structure"
+
+ec	EXT2_ET_MAGIC_EXT2_FILE,
+	"Wrong magic number for ext2 file structure"
+
+ec	EXT2_ET_MAGIC_E2IMAGE,
+	"Wrong magic number for Ext2 Image Header"
+
+ec	EXT2_ET_MAGIC_INODE_IO_CHANNEL,
+	"Wrong magic number for inode io_channel structure"
+
+ec	EXT2_ET_MAGIC_EXTENT_HANDLE,
+	"Wrong magic number for ext4 extent handle"
+
+ec	EXT2_ET_BAD_MAGIC,
+	"Bad magic number in super-block"
+
+ec	EXT2_ET_REV_TOO_HIGH,
+	"Filesystem revision too high"
+
+ec	EXT2_ET_RO_FILSYS,
+	"Attempt to write to filesystem opened read-only"
+
+ec	EXT2_ET_GDESC_READ,
+	"Can't read group descriptors"
+
+ec	EXT2_ET_GDESC_WRITE,
+	"Can't write group descriptors"
+
+ec	EXT2_ET_GDESC_BAD_BLOCK_MAP,
+	"Corrupt group descriptor: bad block for block bitmap"
+
+ec	EXT2_ET_GDESC_BAD_INODE_MAP,
+	"Corrupt group descriptor: bad block for inode bitmap"
+
+ec	EXT2_ET_GDESC_BAD_INODE_TABLE,
+	"Corrupt group descriptor: bad block for inode table"
+
+ec	EXT2_ET_INODE_BITMAP_WRITE,
+	"Can't write an inode bitmap"
+
+ec	EXT2_ET_INODE_BITMAP_READ,
+	"Can't read an inode bitmap"
+
+ec	EXT2_ET_BLOCK_BITMAP_WRITE,
+	"Can't write a block bitmap"
+
+ec	EXT2_ET_BLOCK_BITMAP_READ,
+	"Can't read a block bitmap"
+
+ec	EXT2_ET_INODE_TABLE_WRITE,
+	"Can't write an inode table"
+
+ec	EXT2_ET_INODE_TABLE_READ,
+	"Can't read an inode table"
+
+ec	EXT2_ET_NEXT_INODE_READ,
+	"Can't read next inode"
+
+ec	EXT2_ET_UNEXPECTED_BLOCK_SIZE,
+	"Filesystem has unexpected block size"
+
+ec	EXT2_ET_DIR_CORRUPTED,
+	"EXT2 directory corrupted"
+
+ec	EXT2_ET_SHORT_READ,
+	"Attempt to read block from filesystem resulted in short read"
+
+ec	EXT2_ET_SHORT_WRITE,
+	"Attempt to write block to filesystem resulted in short write"
+
+ec	EXT2_ET_DIR_NO_SPACE,
+	"No free space in the directory"
+
+ec	EXT2_ET_NO_INODE_BITMAP,
+	"Inode bitmap not loaded"
+
+ec	EXT2_ET_NO_BLOCK_BITMAP,
+	"Block bitmap not loaded"
+
+ec	EXT2_ET_BAD_INODE_NUM,
+	"Illegal inode number"
+
+ec	EXT2_ET_BAD_BLOCK_NUM,
+	"Illegal block number"
+
+ec	EXT2_ET_EXPAND_DIR_ERR,
+	"Internal error in ext2fs_expand_dir"
+
+ec	EXT2_ET_TOOSMALL,
+	"Not enough space to build proposed filesystem"
+
+ec	EXT2_ET_BAD_BLOCK_MARK,
+	"Illegal block number passed to ext2fs_mark_block_bitmap"
+
+ec	EXT2_ET_BAD_BLOCK_UNMARK,
+	"Illegal block number passed to ext2fs_unmark_block_bitmap"
+
+ec	EXT2_ET_BAD_BLOCK_TEST,
+	"Illegal block number passed to ext2fs_test_block_bitmap"
+
+ec	EXT2_ET_BAD_INODE_MARK,
+	"Illegal inode number passed to ext2fs_mark_inode_bitmap"
+
+ec	EXT2_ET_BAD_INODE_UNMARK,
+	"Illegal inode number passed to ext2fs_unmark_inode_bitmap"
+
+ec	EXT2_ET_BAD_INODE_TEST,
+	"Illegal inode number passed to ext2fs_test_inode_bitmap"
+
+ec	EXT2_ET_FUDGE_BLOCK_BITMAP_END,
+	"Attempt to fudge end of block bitmap past the real end"
+
+ec	EXT2_ET_FUDGE_INODE_BITMAP_END,
+	"Attempt to fudge end of inode bitmap past the real end"
+
+ec	EXT2_ET_BAD_IND_BLOCK,
+	"Illegal indirect block found" 
+
+ec	EXT2_ET_BAD_DIND_BLOCK,
+	"Illegal doubly indirect block found" 
+
+ec	EXT2_ET_BAD_TIND_BLOCK,
+	"Illegal triply indirect block found" 
+
+ec	EXT2_ET_NEQ_BLOCK_BITMAP,
+	"Block bitmaps are not the same"
+
+ec	EXT2_ET_NEQ_INODE_BITMAP,
+	"Inode bitmaps are not the same"
+
+ec	EXT2_ET_BAD_DEVICE_NAME,
+	"Illegal or malformed device name"
+
+ec	EXT2_ET_MISSING_INODE_TABLE,
+	"A block group is missing an inode table"
+
+ec	EXT2_ET_CORRUPT_SUPERBLOCK,
+	"The ext2 superblock is corrupt"
+
+ec	EXT2_ET_BAD_GENERIC_MARK,
+	"Illegal generic bit number passed to ext2fs_mark_generic_bitmap"
+
+ec	EXT2_ET_BAD_GENERIC_UNMARK,
+	"Illegal generic bit number passed to ext2fs_unmark_generic_bitmap"
+
+ec	EXT2_ET_BAD_GENERIC_TEST,
+	"Illegal generic bit number passed to ext2fs_test_generic_bitmap"
+
+ec	EXT2_ET_SYMLINK_LOOP,
+	"Too many symbolic links encountered."
+
+ec	EXT2_ET_CALLBACK_NOTHANDLED,
+	"The callback function will not handle this case"
+
+ec	EXT2_ET_BAD_BLOCK_IN_INODE_TABLE,
+	"The inode is from a bad block in the inode table"
+
+ec	EXT2_ET_UNSUPP_FEATURE,
+	"Filesystem has unsupported feature(s)"
+
+ec	EXT2_ET_RO_UNSUPP_FEATURE,
+	"Filesystem has unsupported read-only feature(s)"
+
+ec	EXT2_ET_LLSEEK_FAILED,
+	"IO Channel failed to seek on read or write"
+
+ec	EXT2_ET_NO_MEMORY,
+	"Memory allocation failed"
+
+ec	EXT2_ET_INVALID_ARGUMENT,
+	"Invalid argument passed to ext2 library"
+
+ec	EXT2_ET_BLOCK_ALLOC_FAIL,
+	"Could not allocate block in ext2 filesystem"
+
+ec	EXT2_ET_INODE_ALLOC_FAIL,
+	"Could not allocate inode in ext2 filesystem"
+
+ec	EXT2_ET_NO_DIRECTORY,
+	"Ext2 inode is not a directory"
+
+ec	EXT2_ET_TOO_MANY_REFS,
+	"Too many references in table"
+
+ec	EXT2_ET_FILE_NOT_FOUND,
+	"File not found by ext2_lookup"
+
+ec	EXT2_ET_FILE_RO,
+	"File open read-only"
+
+ec	EXT2_ET_DB_NOT_FOUND,
+	"Ext2 directory block not found"
+
+ec	EXT2_ET_DIR_EXISTS,
+	"Ext2 directory already exists"
+
+ec	EXT2_ET_UNIMPLEMENTED,
+	"Unimplemented ext2 library function"
+
+ec	EXT2_ET_CANCEL_REQUESTED,
+	"User cancel requested"
+
+ec	EXT2_ET_FILE_TOO_BIG,
+	"Ext2 file too big"
+
+ec	EXT2_ET_JOURNAL_NOT_BLOCK,
+	"Supplied journal device not a block device"
+
+ec	EXT2_ET_NO_JOURNAL_SB,
+	"Journal superblock not found"
+
+ec	EXT2_ET_JOURNAL_TOO_SMALL,
+	"Journal must be at least 1024 blocks"
+
+ec	EXT2_ET_JOURNAL_UNSUPP_VERSION,
+	"Unsupported journal version"
+
+ec	EXT2_ET_LOAD_EXT_JOURNAL,
+	"Error loading external journal"
+
+ec	EXT2_ET_NO_JOURNAL,
+	"Journal not found"
+
+ec	EXT2_ET_DIRHASH_UNSUPP,
+	"Directory hash unsupported"
+
+ec	EXT2_ET_BAD_EA_BLOCK_NUM,
+	"Illegal extended attribute block number"
+
+ec	EXT2_ET_TOO_MANY_INODES,
+	"Cannot create filesystem with requested number of inodes"
+
+ec	EXT2_ET_NOT_IMAGE_FILE,
+	"E2image snapshot not in use"
+
+ec	EXT2_ET_RES_GDT_BLOCKS,
+	"Too many reserved group descriptor blocks"
+
+ec	EXT2_ET_RESIZE_INODE_CORRUPT,
+	"Resize inode is corrupt"
+
+ec	EXT2_ET_SET_BMAP_NO_IND,
+	"Tried to set block bmap with missing indirect block"
+
+ec	EXT2_ET_TDB_SUCCESS,
+	"TDB: Success"
+
+ec	EXT2_ET_TDB_ERR_CORRUPT,
+	"TDB: Corrupt database"
+
+ec	EXT2_ET_TDB_ERR_IO,
+	"TDB: IO Error"
+
+ec	EXT2_ET_TDB_ERR_LOCK,
+	"TDB: Locking error"
+
+ec	EXT2_ET_TDB_ERR_OOM,
+	"TDB: Out of memory"
+
+ec	EXT2_ET_TDB_ERR_EXISTS,
+	"TDB: Record exists"
+
+ec	EXT2_ET_TDB_ERR_NOLOCK,
+	"TDB: Lock exists on other keys"
+
+ec	EXT2_ET_TDB_ERR_EINVAL,
+	"TDB: Invalid parameter"
+
+ec	EXT2_ET_TDB_ERR_NOEXIST,
+	"TDB: Record does not exist"
+
+ec	EXT2_ET_TDB_ERR_RDONLY,
+	"TDB: Write not permitted"
+
+ec	EXT2_ET_DBLIST_EMPTY,
+	"Ext2fs directory block list is empty"
+
+ec	EXT2_ET_RO_BLOCK_ITERATE,
+	"Attempt to modify a block mapping via a read-only block iterator"
+
+ec	EXT2_ET_MAGIC_EXTENT_PATH,
+	"Wrong magic number for ext4 extent saved path"
+
+ec	EXT2_ET_MAGIC_GENERIC_BITMAP64,
+	"Wrong magic number for 64-bit generic bitmap"
+
+ec	EXT2_ET_MAGIC_BLOCK_BITMAP64,
+	"Wrong magic number for 64-bit block bitmap"
+
+ec	EXT2_ET_MAGIC_INODE_BITMAP64,
+	"Wrong magic number for 64-bit inode bitmap"
+
+ec	EXT2_ET_MAGIC_RESERVED_13,
+	"Wrong magic number --- RESERVED_13"
+
+ec	EXT2_ET_MAGIC_RESERVED_14,
+	"Wrong magic number --- RESERVED_14"
+
+ec	EXT2_ET_MAGIC_RESERVED_15,
+	"Wrong magic number --- RESERVED_15"
+
+ec	EXT2_ET_MAGIC_RESERVED_16,
+	"Wrong magic number --- RESERVED_16"
+
+ec	EXT2_ET_MAGIC_RESERVED_17,
+	"Wrong magic number --- RESERVED_17"
+
+ec	EXT2_ET_MAGIC_RESERVED_18,
+	"Wrong magic number --- RESERVED_18"
+
+ec	EXT2_ET_MAGIC_RESERVED_19,
+	"Wrong magic number --- RESERVED_19"
+
+ec	EXT2_ET_EXTENT_HEADER_BAD,
+	"Corrupt extent header"
+
+ec	EXT2_ET_EXTENT_INDEX_BAD,
+	"Corrupt extent index"
+
+ec	EXT2_ET_EXTENT_LEAF_BAD,
+	"Corrupt extent"
+
+ec	EXT2_ET_EXTENT_NO_SPACE,
+	"No free space in extent map"
+
+ec	EXT2_ET_INODE_NOT_EXTENT,
+	"Inode does not use extents"
+
+ec	EXT2_ET_EXTENT_NO_NEXT,
+	"No 'next' extent"
+
+ec	EXT2_ET_EXTENT_NO_PREV,
+	"No 'previous' extent"
+
+ec	EXT2_ET_EXTENT_NO_UP,
+	"No 'up' extent"
+
+ec	EXT2_ET_EXTENT_NO_DOWN,
+	"No 'down' extent"
+
+ec	EXT2_ET_NO_CURRENT_NODE,
+	"No current node"
+
+ec	EXT2_ET_OP_NOT_SUPPORTED,
+	"Ext2fs operation not supported"
+
+ec	EXT2_ET_CANT_INSERT_EXTENT,
+	"No room to insert extent in node"
+
+ec	EXT2_ET_CANT_SPLIT_EXTENT,
+	"Splitting would result in empty node"
+
+ec	EXT2_ET_EXTENT_NOT_FOUND,
+	"Extent not found"
+
+ec	EXT2_ET_EXTENT_NOT_SUPPORTED,
+	"Operation not supported for inodes containing extents"
+
+ec	EXT2_ET_EXTENT_INVALID_LENGTH,
+	"Extent length is invalid"
+
+ec	EXT2_ET_IO_CHANNEL_NO_SUPPORT_64,
+	"I/O Channel does not support 64-bit block numbers"
+
+ec	EXT2_ET_NO_MTAB_FILE,
+	"Can't check if filesystem is mounted due to missing mtab file"
+
+ec	EXT2_ET_CANT_USE_LEGACY_BITMAPS,
+	"Filesystem too large to use legacy bitmaps"
+
+ec	EXT2_ET_MMP_MAGIC_INVALID,
+	"MMP: invalid magic number"
+
+ec	EXT2_ET_MMP_FAILED,
+	"MMP: device currently active"
+
+ec	EXT2_ET_MMP_FSCK_ON,
+	"MMP: fsck being run"
+
+ec	EXT2_ET_MMP_BAD_BLOCK,
+	"MMP: block number beyond filesystem range"
+
+ec	EXT2_ET_MMP_UNKNOWN_SEQ,
+	"MMP: undergoing an unknown operation"
+
+ec	EXT2_ET_MMP_CHANGE_ABORT,
+	"MMP: filesystem still in use"
+
+ec	EXT2_ET_MMP_OPEN_DIRECT,
+	"MMP: open with O_DIRECT failed"
+
+ec	EXT2_ET_BAD_DESC_SIZE,
+	"Block group descriptor size incorrect"
+
+ec	EXT2_ET_INODE_CSUM_INVALID,
+	"Inode checksum does not match inode"
+
+ec	EXT2_ET_INODE_BITMAP_CSUM_INVALID,
+	"Inode bitmap checksum does not match bitmap"
+
+ec	EXT2_ET_EXTENT_CSUM_INVALID,
+	"Extent block checksum does not match extent block"
+
+ec	EXT2_ET_DIR_NO_SPACE_FOR_CSUM,
+	"Directory block does not have space for checksum"
+
+ec	EXT2_ET_DIR_CSUM_INVALID,
+	"Directory block checksum does not match directory block"
+
+ec	EXT2_ET_EXT_ATTR_CSUM_INVALID,
+	"Extended attribute block checksum does not match block"
+
+ec	EXT2_ET_SB_CSUM_INVALID,
+	"Superblock checksum does not match superblock"
+
+ec	EXT2_ET_UNKNOWN_CSUM,
+	"Unknown checksum algorithm"
+
+ec	EXT2_ET_MMP_CSUM_INVALID,
+	"MMP block checksum does not match MMP block"
+
+ec	EXT2_ET_FILE_EXISTS,
+	"Ext2 file already exists"
+
+	end
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_ext_attr.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_ext_attr.h
new file mode 100644
index 0000000..ed548d1
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_ext_attr.h
@@ -0,0 +1,71 @@
+/*
+  File: linux/ext2_ext_attr.h
+
+  On-disk format of extended attributes for the ext2 filesystem.
+
+  (C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+#ifndef _EXT2_EXT_ATTR_H
+#define _EXT2_EXT_ATTR_H
+/* 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		((unsigned) 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__ */
+#endif  /* _EXT2_EXT_ATTR_H */
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_fs.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_fs.h
new file mode 100644
index 0000000..930c2a3
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_fs.h
@@ -0,0 +1,860 @@
+/*
+ *  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 EXT4_USR_QUOTA_INO	 3	/* User quota inode */
+#define EXT4_GRP_QUOTA_INO	 4	/* Group quota 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 */
+#define EXT2_EXCLUDE_INO	 9	/* The "exclude" inode, for snapshots */
+#define EXT4_REPLICA_INO	10	/* Used by non-upstream feature */
+
+/* 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		65000
+
+/*
+ * 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 allocation clusters
+ */
+#define EXT2_MIN_CLUSTER_LOG_SIZE	EXT2_MIN_BLOCK_LOG_SIZE
+#define EXT2_MAX_CLUSTER_LOG_SIZE	29	/* 512MB  */
+#define EXT2_MIN_CLUSTER_SIZE		EXT2_MIN_BLOCK_SIZE
+#define EXT2_MAX_CLUSTER_SIZE		(1 << EXT2_MAX_CLUSTER_LOG_SIZE)
+#define EXT2_CLUSTER_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << \
+						(s)->s_log_cluster_size)
+#define EXT2_CLUSTER_SIZE_BITS(s)	((s)->s_log_cluster_size + 10)
+
+/*
+ * Macro-instructions used to manage fragments
+ *
+ * Note: for backwards compatibility only, for the dump program.
+ * Ext2/3/4 will never support 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
+#define EXT2_FRAG_SIZE(s)		EXT2_BLOCK_SIZE(s)
+#define EXT2_FRAGS_PER_BLOCK(s)		1
+
+/*
+ * 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_flags;
+	__u32	bg_exclude_bitmap_lo;	/* Exclude bitmap for snapshots */
+	__u16	bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
+	__u16	bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
+	__u16	bg_itable_unused;	/* Unused inodes count */
+	__u16	bg_checksum;		/* crc16(s_uuid+group_num+group_desc)*/
+};
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext4_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_flags;		/* EXT4_BG_flags (INODE_UNINIT, etc) */
+	__u32	bg_exclude_bitmap_lo;	/* Exclude bitmap for snapshots */
+	__u16	bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
+	__u16	bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bitmap) LSB */
+	__u16	bg_itable_unused;	/* Unused inodes count */
+	__u16	bg_checksum;		/* crc16(sb_uuid+group+desc) */
+	__u32	bg_block_bitmap_hi;	/* Blocks bitmap block MSB */
+	__u32	bg_inode_bitmap_hi;	/* Inodes bitmap block MSB */
+	__u32	bg_inode_table_hi;	/* Inodes table block MSB */
+	__u16	bg_free_blocks_count_hi;/* Free blocks count MSB */
+	__u16	bg_free_inodes_count_hi;/* Free inodes count MSB */
+	__u16	bg_used_dirs_count_hi;	/* Directories count MSB */
+	__u16	bg_itable_unused_hi;	/* Unused inodes count MSB */
+	__u32	bg_exclude_bitmap_hi;	/* Exclude bitmap block MSB */
+	__u16	bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bitmap) MSB */
+	__u16	bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bitmap) MSB */
+	__u32	bg_reserved;
+};
+
+#define EXT2_BG_INODE_UNINIT	0x0001 /* Inode table/bitmap not initialized */
+#define EXT2_BG_BLOCK_UNINIT	0x0002 /* Block bitmap not initialized */
+#define EXT2_BG_INODE_ZEROED	0x0004 /* On-disk itable initialized to zero */
+
+/*
+ * 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_LEGACY_UNSIGNED	3 /* reserved for userspace lib */
+#define EXT2_HASH_HALF_MD4_UNSIGNED	4 /* reserved for userspace lib */
+#define EXT2_HASH_TEA_UNSIGNED		5 /* reserved for userspace lib */
+
+#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_MIN_DESC_SIZE             32
+#define EXT2_MIN_DESC_SIZE_64BIT       64
+#define EXT2_MAX_DESC_SIZE             EXT2_MIN_BLOCK_SIZE
+#define EXT2_DESC_SIZE(s)                                                \
+       ((EXT2_SB(s)->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) ? \
+	(s)->s_desc_size : EXT2_MIN_DESC_SIZE)
+
+#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_CLUSTERS_PER_GROUP(s)	(EXT2_SB(s)->s_clusters_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)	((((unsigned) 1 << 16) - 8) *	\
+					 (EXT2_CLUSTER_SIZE(s) / \
+					  EXT2_BLOCK_SIZE(s)))
+#define EXT2_MAX_CLUSTERS_PER_GROUP(s)	(((unsigned) 1 << 16) - 8)
+#define EXT2_MAX_INODES_PER_GROUP(s)	(((unsigned) 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) / EXT2_DESC_SIZE(s))
+#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 EXT4_HUGE_FILE_FL               0x00040000 /* Set to each huge file */
+#define EXT4_EXTENTS_FL 		0x00080000 /* Inode uses extents */
+#define EXT4_EA_INODE_FL	        0x00200000 /* Inode used for large EA */
+/* EXT4_EOFBLOCKS_FL 0x00400000 was here */
+#define FS_NOCOW_FL			0x00800000 /* Do not cow file */
+#define EXT4_SNAPFILE_FL		0x01000000  /* Inode is a snapshot */
+#define EXT4_SNAPFILE_DELETED_FL	0x04000000  /* Snapshot is being deleted */
+#define EXT4_SNAPFILE_SHRUNK_FL		0x08000000  /* Snapshot shrink has completed */
+#define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
+
+#define EXT2_FL_USER_VISIBLE		0x004BDFFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE		0x004B80FF /* User modifiable flags */
+
+/*
+ * ioctl commands
+ */
+
+/* Used for online resize */
+struct ext2_new_group_input {
+	__u32 group;		/* Group number for this data */
+	__u32 block_bitmap;	/* Absolute block number of block bitmap */
+	__u32 inode_bitmap;	/* Absolute block number of inode bitmap */
+	__u32 inode_table;	/* Absolute block number of inode table start */
+	__u32 blocks_count;	/* Total number of blocks in this group */
+	__u16 reserved_blocks;	/* Number of reserved blocks in this group */
+	__u16 unused;		/* Number of reserved GDT blocks in group */
+};
+
+struct ext4_new_group_input {
+	__u32 group;		/* Group number for this data */
+	__u64 block_bitmap;	/* Absolute block number of block bitmap */
+	__u64 inode_bitmap;	/* Absolute block number of inode bitmap */
+	__u64 inode_table;	/* Absolute block number of inode table start */
+	__u32 blocks_count;	/* Total number of blocks in this group */
+	__u16 reserved_blocks;	/* Number of reserved blocks in this group */
+	__u16 unused;
+};
+
+#ifdef __GNU__			/* Needed for the Hurd */
+#define _IOT_ext2_new_group_input _IOT (_IOTS(__u32), 5, _IOTS(__u16), 2, 0, 0)
+#endif
+
+#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)
+#define EXT2_IOC_GETVERSION_NEW		_IOR('f', 3, long)
+#define EXT2_IOC_SETVERSION_NEW		_IOW('f', 4, long)
+#define EXT2_IOC_GROUP_EXTEND		_IOW('f', 7, unsigned long)
+#define EXT2_IOC_GROUP_ADD		_IOW('f', 8,struct ext2_new_group_input)
+#define EXT4_IOC_GROUP_ADD		_IOW('f', 8,struct ext4_new_group_input)
+#define EXT4_IOC_RESIZE_FS		_IOW('f', 16, __u64)
+
+/*
+ * 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;	/* Inode change 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_version; /* was l_i_reserved1 */
+		} linux1;
+		struct {
+			__u32  h_i_translator;
+		} hurd1;
+	} 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_size_high;	/* Formerly i_dir_acl, directory ACL */
+	__u32	i_faddr;	/* Fragment address */
+	union {
+		struct {
+			__u16	l_i_blocks_hi;
+			__u16	l_i_file_acl_high;
+			__u16	l_i_uid_high;	/* these 2 fields    */
+			__u16	l_i_gid_high;	/* were reserved2[0] */
+			__u16	l_i_checksum_lo; /* crc32c(uuid+inum+inode) */
+			__u16	l_i_reserved;
+		} 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;
+	} 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;	/* Inode Change 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_version; /* was l_i_reserved1 */
+		} linux1;
+		struct {
+			__u32  h_i_translator;
+		} hurd1;
+	} 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_size_high;	/* Formerly i_dir_acl, directory ACL */
+	__u32	i_faddr;	/* Fragment address */
+	union {
+		struct {
+			__u16	l_i_blocks_hi;
+			__u16	l_i_file_acl_high;
+			__u16	l_i_uid_high;	/* these 2 fields    */
+			__u16	l_i_gid_high;	/* were reserved2[0] */
+			__u16	l_i_checksum_lo; /* crc32c(uuid+inum+inode) */
+			__u16	l_i_reserved;
+		} 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;
+	} osd2;				/* OS dependent 2 */
+	__u16	i_extra_isize;
+	__u16	i_checksum_hi;	/* crc32c(uuid+inum+inode) */
+	__u32	i_ctime_extra;	/* extra Change time (nsec << 2 | epoch) */
+	__u32	i_mtime_extra;	/* extra Modification time (nsec << 2 | epoch) */
+	__u32	i_atime_extra;	/* extra Access time (nsec << 2 | epoch) */
+	__u32	i_crtime;	/* File creation time */
+	__u32	i_crtime_extra;	/* extra File creation time (nsec << 2 | epoch)*/
+	__u32	i_version_hi;	/* high 32 bits for 64-bit version */
+};
+
+#define i_dir_acl	i_size_high
+
+#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
+#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
+
+#endif  /* __GNU__ */
+#endif	/* defined(__KERNEL__) || defined(__linux__) */
+
+#define inode_uid(inode)	((inode).i_uid | (inode).osd2.linux2.l_i_uid_high << 16)
+#define inode_gid(inode)	((inode).i_gid | (inode).osd2.linux2.l_i_gid_high << 16)
+#define ext2fs_set_i_uid_high(inode,x) ((inode).osd2.linux2.l_i_uid_high = (x))
+#define ext2fs_set_i_gid_high(inode,x) ((inode).osd2.linux2.l_i_gid_high = (x))
+
+/*
+ * File system states
+ */
+#define EXT2_VALID_FS			0x0001	/* Unmounted cleanly */
+#define EXT2_ERROR_FS			0x0002	/* Errors detected */
+#define EXT3_ORPHAN_FS			0x0004	/* Orphans being recovered */
+
+/*
+ * Misc. filesystem flags
+ */
+#define EXT2_FLAGS_SIGNED_HASH		0x0001  /* Signed dirhash in use */
+#define EXT2_FLAGS_UNSIGNED_HASH	0x0002  /* Unsigned dirhash in use */
+#define EXT2_FLAGS_TEST_FILESYS		0x0004	/* OK for use on development code */
+#define EXT2_FLAGS_IS_SNAPSHOT		0x0010	/* This is a snapshot image */
+#define EXT2_FLAGS_FIX_SNAPSHOT		0x0020	/* Snapshot inodes corrupted */
+#define EXT2_FLAGS_FIX_EXCLUDE		0x0040	/* Exclude bitmaps corrupted */
+
+/*
+ * 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
+
+#if (__GNUC__ >= 4)
+#define ext4_offsetof(TYPE,MEMBER) __builtin_offsetof(TYPE,MEMBER)
+#else
+#define ext4_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+/*
+ * 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 */
+	__u32	s_log_cluster_size;	/* Allocation cluster size */
+	__u32	s_blocks_per_group;	/* # Blocks per group */
+	__u32	s_clusters_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_desc_size;		/* Group desc. size: INCOMPAT_64BIT */
+	__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_blocks_count_hi;	/* Blocks count high 32bits */
+	__u32	s_r_blocks_count_hi;	/* Reserved blocks count high 32 bits*/
+	__u32	s_free_blocks_hi; 	/* Free blocks count */
+	__u16	s_min_extra_isize;	/* All inodes have at least # bytes */
+	__u16	s_want_extra_isize; 	/* New inodes should reserve # bytes */
+	__u32	s_flags;		/* Miscellaneous flags */
+	__u16   s_raid_stride;		/* RAID stride */
+	__u16   s_mmp_update_interval;  /* # seconds to wait in MMP checking */
+	__u64   s_mmp_block;            /* Block for multi-mount protection */
+	__u32   s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
+	__u8	s_log_groups_per_flex;	/* FLEX_BG group size */
+	__u8    s_reserved_char_pad;
+	__u16	s_reserved_pad;		/* Padding to next 32bits */
+	__u64	s_kbytes_written;	/* nr of lifetime kilobytes written */
+	__u32	s_snapshot_inum;	/* Inode number of active snapshot */
+	__u32	s_snapshot_id;		/* sequential ID of active snapshot */
+	__u64	s_snapshot_r_blocks_count; /* reserved blocks for active
+					      snapshot's future use */
+	__u32	s_snapshot_list;	/* inode number of the head of the on-disk snapshot list */
+#define EXT4_S_ERR_START ext4_offsetof(struct ext2_super_block, s_error_count)
+	__u32	s_error_count;		/* number of fs errors */
+	__u32	s_first_error_time;	/* first time an error happened */
+	__u32	s_first_error_ino;	/* inode involved in first error */
+	__u64	s_first_error_block;	/* block involved of first error */
+	__u8	s_first_error_func[32];	/* function where the error happened */
+	__u32	s_first_error_line;	/* line number where error happened */
+	__u32	s_last_error_time;	/* most recent time of an error */
+	__u32	s_last_error_ino;	/* inode involved in last error */
+	__u32	s_last_error_line;	/* line number where error happened */
+	__u64	s_last_error_block;	/* block involved of last error */
+	__u8	s_last_error_func[32];	/* function where the error happened */
+#define EXT4_S_ERR_END ext4_offsetof(struct ext2_super_block, s_mount_opts)
+	__u8	s_mount_opts[64];
+	__u32	s_usr_quota_inum;	/* inode number of user quota file */
+	__u32	s_grp_quota_inum;	/* inode number of group quota file */
+	__u32	s_overhead_blocks;	/* overhead blocks/clusters in fs */
+	__u32   s_reserved[108];        /* Padding to the end of the block */
+	__u32	s_checksum;		/* crc32c(superblock) */
+};
+
+#define EXT4_S_ERR_LEN (EXT4_S_ERR_END - EXT4_S_ERR_START)
+
+/*
+ * Codes for operating systems
+ */
+#define EXT2_OS_LINUX		0
+#define EXT2_OS_HURD		1
+#define EXT2_OBSO_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_COMPAT_LAZY_BG		0x0040
+/* #define EXT2_FEATURE_COMPAT_EXCLUDE_INODE	0x0080 not used, legacy */
+#define EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP	0x0100
+
+
+#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 EXT4_FEATURE_RO_COMPAT_HUGE_FILE	0x0008
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM		0x0010
+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK	0x0020
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE	0x0040
+#define EXT4_FEATURE_RO_COMPAT_HAS_SNAPSHOT	0x0080
+#define EXT4_FEATURE_RO_COMPAT_QUOTA		0x0100
+#define EXT4_FEATURE_RO_COMPAT_BIGALLOC		0x0200
+#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM	0x0400
+#define EXT4_FEATURE_RO_COMPAT_REPLICA		0x0800
+
+#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 EXT4_FEATURE_INCOMPAT_64BIT		0x0080
+#define EXT4_FEATURE_INCOMPAT_MMP		0x0100
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG		0x0200
+#define EXT4_FEATURE_INCOMPAT_EA_INODE		0x0400
+#define EXT4_FEATURE_INCOMPAT_DIRDATA		0x1000
+/* 0x2000 was EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM but this was never used */
+#define EXT4_FEATURE_INCOMPAT_LARGEDIR		0x4000 /* >2GB or 3-lvl htree */
+#define EXT4_FEATURE_INCOMPAT_INLINEDATA	0x8000 /* data in inode */
+
+#define EXT2_FEATURE_COMPAT_SUPP	0
+#define EXT2_FEATURE_INCOMPAT_SUPP    (EXT2_FEATURE_INCOMPAT_FILETYPE| \
+				       EXT4_FEATURE_INCOMPAT_MMP)
+#define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+					 EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
+					 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
+#define EXT4_DEFM_NOBARRIER	0x0100
+#define EXT4_DEFM_BLOCK_VALIDITY 0x0200
+#define EXT4_DEFM_DISCARD	0x0400
+#define EXT4_DEFM_NODELALLOC	0x0800
+
+/*
+ * 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)
+
+/*
+ * This structure is used for multiple mount protection. It is written
+ * into the block number saved in the s_mmp_block field in the superblock.
+ * Programs that check MMP should assume that if SEQ_FSCK (or any unknown
+ * code above SEQ_MAX) is present then it is NOT safe to use the filesystem,
+ * regardless of how old the timestamp is.
+ *
+ * The timestamp in the MMP structure will be updated by e2fsck at some
+ * arbitary intervals (start of passes, after every few groups of inodes
+ * in pass1 and pass1b).  There is no guarantee that e2fsck is updating
+ * the MMP block in a timely manner, and the updates it does are purely
+ * for the convenience of the sysadmin and not for automatic validation.
+ *
+ * Note: Only the mmp_seq value is used to determine whether the MMP block
+ *	is being updated.  The mmp_time, mmp_nodename, and mmp_bdevname
+ *	fields are only for informational purposes for the administrator,
+ *	due to clock skew between nodes and hostname HA service takeover.
+ */
+#define EXT4_MMP_MAGIC     0x004D4D50U /* ASCII for MMP */
+#define EXT4_MMP_SEQ_CLEAN 0xFF4D4D50U /* mmp_seq value for clean unmount */
+#define EXT4_MMP_SEQ_FSCK  0xE24D4D50U /* mmp_seq value when being fscked */
+#define EXT4_MMP_SEQ_MAX   0xE24D4D4FU /* maximum valid mmp_seq value */
+
+struct mmp_struct {
+	__u32	mmp_magic;		/* Magic number for MMP */
+	__u32	mmp_seq;		/* Sequence no. updated periodically */
+	__u64	mmp_time;		/* Time last updated */
+	char	mmp_nodename[64];	/* Node which last updated MMP block */
+	char	mmp_bdevname[32];	/* Bdev which last updated MMP block */
+	__u16	mmp_check_interval;	/* Changed mmp_check_interval */
+	__u16	mmp_pad1;
+	__u32	mmp_pad2[227];
+};
+
+/*
+ * Default interval for MMP update in seconds.
+ */
+#define EXT4_MMP_UPDATE_INTERVAL	5
+
+/*
+ * Maximum interval for MMP update in seconds.
+ */
+#define EXT4_MMP_MAX_UPDATE_INTERVAL	300
+
+/*
+ * Minimum interval for MMP checking in seconds.
+ */
+#define EXT4_MMP_MIN_CHECK_INTERVAL     5
+
+#endif	/* _LINUX_EXT2_FS_H */
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_io.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_io.h
new file mode 100644
index 0000000..1894fb8
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_io.h
@@ -0,0 +1,150 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %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;
+typedef struct struct_io_stats *io_stats;
+
+#define CHANNEL_FLAGS_WRITETHROUGH	0x01
+#define CHANNEL_FLAGS_DISCARD_ZEROES	0x02
+#define CHANNEL_FLAGS_BLOCK_DEVICE	0x04
+
+#define io_channel_discard_zeroes_data(i) (i->flags & CHANNEL_FLAGS_DISCARD_ZEROES)
+
+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;
+	long		reserved[14];
+	void		*private_data;
+	void		*app_data;
+	int		align;
+};
+
+struct struct_io_stats {
+	int			num_fields;
+	int			reserved;
+	unsigned long long	bytes_read;
+	unsigned long long	bytes_written;
+};
+
+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);
+	errcode_t (*get_stats)(io_channel channel, io_stats *io_stats);
+	errcode_t (*read_blk64)(io_channel channel, unsigned long long block,
+					int count, void *data);
+	errcode_t (*write_blk64)(io_channel channel, unsigned long long block,
+					int count, const void *data);
+	errcode_t (*discard)(io_channel channel, unsigned long long block,
+			     unsigned long long count);
+	long	reserved[16];
+};
+
+#define IO_FLAG_RW		0x0001
+#define IO_FLAG_EXCLUSIVE	0x0002
+#define IO_FLAG_DIRECT_IO	0x0004
+
+/*
+ * 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);
+extern errcode_t io_channel_read_blk64(io_channel channel,
+				       unsigned long long block,
+				       int count, void *data);
+extern errcode_t io_channel_write_blk64(io_channel channel,
+					unsigned long long block,
+					int count, const void *data);
+extern errcode_t io_channel_discard(io_channel channel,
+				    unsigned long long block,
+				    unsigned long long count);
+extern errcode_t io_channel_alloc_buf(io_channel channel,
+				      int count, void *ptr);
+
+/* unix_io.c */
+extern io_manager unix_io_manager;
+
+/* undo_io.c */
+extern io_manager undo_io_manager;
+extern errcode_t set_undo_io_backing_manager(io_manager manager);
+extern errcode_t set_undo_io_backup_file(char *file_name);
+
+/* 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_read_blk64)
+	(unsigned long long block, int count, errcode_t err);
+extern void (*test_io_cb_write_blk64)
+	(unsigned long 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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_types.h.in b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_types.h.in
new file mode 100644
index 0000000..5b98f71
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2_types.h.in
@@ -0,0 +1,136 @@
+/* 
+ * If linux/types.h is already been included, assume it has defined
+ * everything we need.  (cross fingers)  Other header files may have 
+ * also defined the types that we need.
+ */
+#if (!defined(_LINUX_TYPES_H) && !defined(_BLKID_TYPES_H) && \
+	!defined(_EXT2_TYPES_H))
+#define _EXT2_TYPES_H
+
+@ASM_TYPES_HEADER@
+
+#ifdef __U8_TYPEDEF
+typedef __U8_TYPEDEF __u8;
+#else
+typedef unsigned char __u8;
+#endif
+
+#ifdef __S8_TYPEDEF
+typedef __S8_TYPEDEF __s8;
+#else
+typedef signed char __s8;
+#endif
+
+#ifdef __U16_TYPEDEF
+typedef __U16_TYPEDEF __u16;
+#else
+#if (@SIZEOF_INT@ == 2)
+typedef	unsigned int	__u16;
+#else
+#if (@SIZEOF_SHORT@ == 2)
+typedef	unsigned short	__u16;
+#else
+  ?==error: undefined 16 bit type
+#endif /* SIZEOF_SHORT == 2 */
+#endif /* SIZEOF_INT == 2 */
+#endif /* __U16_TYPEDEF */
+
+#ifdef __S16_TYPEDEF
+typedef __S16_TYPEDEF __s16;
+#else
+#if (@SIZEOF_INT@ == 2)
+typedef	int		__s16;
+#else
+#if (@SIZEOF_SHORT@ == 2)
+typedef	short		__s16;
+#else
+  ?==error: undefined 16 bit type
+#endif /* SIZEOF_SHORT == 2 */
+#endif /* SIZEOF_INT == 2 */
+#endif /* __S16_TYPEDEF */
+
+
+#ifdef __U32_TYPEDEF
+typedef __U32_TYPEDEF __u32;
+#else
+#if (@SIZEOF_INT@ == 4)
+typedef	unsigned int	__u32;
+#else
+#if (@SIZEOF_LONG@ == 4)
+typedef	unsigned long	__u32;
+#else
+#if (@SIZEOF_SHORT@ == 4)
+typedef	unsigned short	__u32;
+#else
+ ?== error: undefined 32 bit type
+#endif /* SIZEOF_SHORT == 4 */
+#endif /* SIZEOF_LONG == 4 */
+#endif /* SIZEOF_INT == 4 */
+#endif /* __U32_TYPEDEF */
+
+#ifdef __S32_TYPEDEF
+typedef __S32_TYPEDEF __s32;
+#else
+#if (@SIZEOF_INT@ == 4)
+typedef	int		__s32;
+#else
+#if (@SIZEOF_LONG@ == 4)
+typedef	long		__s32;
+#else
+#if (@SIZEOF_SHORT@ == 4)
+typedef	short		__s32;
+#else
+ ?== error: undefined 32 bit type
+#endif /* SIZEOF_SHORT == 4 */
+#endif /* SIZEOF_LONG == 4 */
+#endif /* SIZEOF_INT == 4 */
+#endif /* __S32_TYPEDEF */
+
+#ifdef __U64_TYPEDEF
+typedef __U64_TYPEDEF __u64;
+#else
+#if (@SIZEOF_INT@ == 8)
+typedef unsigned int	__u64;
+#else
+#if (@SIZEOF_LONG_LONG@ == 8)
+typedef unsigned long long	__u64;
+#else
+#if (@SIZEOF_LONG@ == 8)
+typedef unsigned long	__u64;
+#endif /* SIZEOF_LONG_LONG == 8 */
+#endif /* SIZEOF_LONG == 8 */
+#endif /* SIZEOF_INT == 8 */
+#endif /* __U64_TYPEDEF */
+
+#ifdef __S64_TYPEDEF
+typedef __S64_TYPEDEF __s64;
+#else
+#if (@SIZEOF_INT@ == 8)
+typedef int		__s64;
+#else
+#if (@SIZEOF_LONG_LONG@ == 8)
+#if defined(__GNUC__)
+typedef __signed__ long long	__s64;
+#else
+typedef signed long long	__s64;
+#endif /* __GNUC__ */
+#else
+#if (@SIZEOF_LONG@ == 8)
+typedef long		__s64;
+#endif /* SIZEOF_LONG_LONG == 8 */
+#endif /* SIZEOF_LONG == 8 */
+#endif /* SIZEOF_INT == 8 */
+#endif /* __S64_TYPEDEF */
+
+#undef __S8_TYPEDEF
+#undef __U8_TYPEDEF
+#undef __S16_TYPEDEF
+#undef __U16_TYPEDEF
+#undef __S32_TYPEDEF
+#undef __U32_TYPEDEF
+#undef __S64_TYPEDEF
+#undef __U64_TYPEDEF
+
+#endif /* _*_TYPES_H */
+
+@PUBLIC_CONFIG_HEADER@
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2fs.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2fs.h
new file mode 100644
index 0000000..fb6b0b4
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2fs.h
@@ -0,0 +1,1743 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %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
+
+/*
+ * 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>
+#include <string.h>
+#include <errno.h>
+
+#if EXT2_FLAT_INCLUDES
+#include "e2_types.h"
+#include "ext2_fs.h"
+#include "ext3_extents.h"
+#else
+#include <ext2fs/ext2_types.h>
+#include <ext2fs/ext2_fs.h>
+#include <ext2fs/ext3_extents.h>
+#endif /* EXT2_FLAT_INCLUDES */
+
+#ifdef __CHECK_ENDIAN__
+#define __bitwise __attribute__((bitwise))
+#else
+#define __bitwise
+#endif
+
+typedef __u32 __bitwise		ext2_ino_t;
+typedef __u32 __bitwise		blk_t;
+typedef __u64 __bitwise		blk64_t;
+typedef __u32 __bitwise		dgrp_t;
+typedef __u32 __bitwise		ext2_off_t;
+typedef __u64 __bitwise		ext2_off64_t;
+typedef __s64 __bitwise		e2_blkcnt_t;
+typedef __u32 __bitwise		ext2_dirhash_t;
+
+#if EXT2_FLAT_INCLUDES
+#include "com_err.h"
+#include "ext2_io.h"
+#include "ext2_err.h"
+#include "ext2_ext_attr.h"
+#else
+#include <et/com_err.h>
+#include <ext2fs/ext2_io.h>
+#include <ext2fs/ext2_err.h>
+#include <ext2fs/ext2_ext_attr.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;
+
+#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;
+
+#define EXT2_FIRST_INODE(s)	EXT2_FIRST_INO(s)
+
+
+/*
+ * 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_entry2 {
+	ext2_ino_t	ino;
+	blk64_t	blk;
+	e2_blkcnt_t	blockcnt;
+};
+
+/* Ye Olde 32-bit version */
+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
+#define EXT2_FLAG_EXCLUSIVE		0x4000
+#define EXT2_FLAG_SOFTSUPP_FEATURES	0x8000
+#define EXT2_FLAG_NOFREE_ON_ERROR	0x10000
+#define EXT2_FLAG_64BITS		0x20000
+#define EXT2_FLAG_PRINT_PROGRESS	0x40000
+#define EXT2_FLAG_DIRECT_IO		0x80000
+#define EXT2_FLAG_SKIP_MMP		0x100000
+
+/*
+ * 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
+ */
+#define EXT2_MKJOURNAL_V1_SUPER	0x0000001 /* create V1 superblock (deprecated) */
+#define EXT2_MKJOURNAL_LAZYINIT	0x0000002 /* don't zero journal inode before use*/
+#define EXT2_MKJOURNAL_NO_MNT_CHECK 0x0000004 /* don't check mount status */
+
+struct opaque_ext2_group_desc;
+
+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 opaque_ext2_group_desc *	group_desc;
+	unsigned int			inode_blocks_per_group;
+	ext2fs_inode_bitmap		inode_map;
+	ext2fs_block_bitmap		block_map;
+	/* XXX FIXME-64: not 64-bit safe, but not used? */
+	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;
+	time_t				now;
+	int				cluster_ratio_bits;
+	__u16				default_bitmap_type;
+	__u16				pad;
+	/*
+	 * Reserved for future expansion
+	 */
+	__u32				reserved[5];
+
+	/*
+	 * Reserved for the use of the calling application.
+	 */
+	void *				priv_data;
+
+	/*
+	 * Inode cache
+	 */
+	struct ext2_inode_cache		*icache;
+	io_channel			image_io;
+
+	/*
+	 * More callback functions
+	 */
+	errcode_t (*get_alloc_block)(ext2_filsys fs, blk64_t goal,
+				     blk64_t *ret);
+	void (*block_alloc_stats)(ext2_filsys fs, blk64_t blk, int inuse);
+
+	/*
+	 * Buffers for Multiple mount protection(MMP) block.
+	 */
+	void *mmp_buf;
+	void *mmp_cmp;
+	int mmp_fd;
+
+	/*
+	 * Time at which e2fsck last updated the MMP block.
+	 */
+	long mmp_last_written;
+};
+
+#if EXT2_FLAT_INCLUDES
+#include "e2_bitops.h"
+#else
+#include <ext2fs/bitops.h>
+#endif
+
+/*
+ * 64-bit bitmap backend types
+ */
+#define EXT2FS_BMAP64_BITARRAY	1
+#define EXT2FS_BMAP64_RBTREE	2
+#define EXT2FS_BMAP64_AUTODIR	3
+
+/*
+ * 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_DEPTH_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_READ_ONLY is a promise by the caller that it will not
+ * modify returned block number.
+ *
+ * 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_READ_ONLY	8
+
+#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
+
+/*
+ * Generic (non-filesystem layout specific) extents structure
+ */
+
+#define EXT2_EXTENT_FLAGS_LEAF		0x0001
+#define EXT2_EXTENT_FLAGS_UNINIT	0x0002
+#define EXT2_EXTENT_FLAGS_SECOND_VISIT	0x0004
+
+struct ext2fs_extent {
+	blk64_t	e_pblk;		/* first physical block */
+	blk64_t	e_lblk;		/* first logical block extent covers */
+	__u32	e_len;		/* number of blocks covered by extent */
+	__u32	e_flags;	/* extent flags */
+};
+
+typedef struct ext2_extent_handle *ext2_extent_handle_t;
+typedef struct ext2_extent_path *ext2_extent_path_t;
+
+/*
+ * Flags used by ext2fs_extent_get()
+ */
+#define EXT2_EXTENT_CURRENT	0x0000
+#define EXT2_EXTENT_MOVE_MASK	0x000F
+#define EXT2_EXTENT_ROOT	0x0001
+#define EXT2_EXTENT_LAST_LEAF	0x0002
+#define EXT2_EXTENT_FIRST_SIB	0x0003
+#define EXT2_EXTENT_LAST_SIB	0x0004
+#define EXT2_EXTENT_NEXT_SIB	0x0005
+#define EXT2_EXTENT_PREV_SIB	0x0006
+#define EXT2_EXTENT_NEXT_LEAF	0x0007
+#define EXT2_EXTENT_PREV_LEAF	0x0008
+#define EXT2_EXTENT_NEXT	0x0009
+#define EXT2_EXTENT_PREV	0x000A
+#define EXT2_EXTENT_UP		0x000B
+#define EXT2_EXTENT_DOWN	0x000C
+#define EXT2_EXTENT_DOWN_AND_LAST 0x000D
+
+/*
+ * Flags used by ext2fs_extent_insert()
+ */
+#define EXT2_EXTENT_INSERT_AFTER	0x0001 /* insert after handle loc'n */
+#define EXT2_EXTENT_INSERT_NOSPLIT	0x0002 /* insert may not cause split */
+
+/*
+ * Flags used by ext2fs_extent_delete()
+ */
+#define EXT2_EXTENT_DELETE_KEEP_EMPTY	0x001 /* keep node if last extnt gone */
+
+/*
+ * Flags used by ext2fs_extent_set_bmap()
+ */
+#define EXT2_EXTENT_SET_BMAP_UNINIT	0x0001
+
+/*
+ * Data structure returned by ext2fs_extent_get_info()
+ */
+struct ext2_extent_info {
+	int		curr_entry;
+	int		curr_level;
+	int		num_entries;
+	int		max_entries;
+	int		max_depth;
+	int		bytes_avail;
+	blk64_t		max_lblk;
+	blk64_t		max_pblk;
+	__u32		max_len;
+	__u32		max_uninit_len;
+};
+
+/*
+ * 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
+#define EXT2_SF_DO_LAZY		0x0010
+
+/*
+ * 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
+
+/*
+ * Returned flags from ext2fs_bmap
+ */
+#define BMAP_RET_UNINIT	0x0001
+
+/*
+ * 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) -1)
+#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|\
+					 EXT3_FEATURE_INCOMPAT_EXTENTS|\
+					 EXT4_FEATURE_INCOMPAT_FLEX_BG|\
+					 EXT4_FEATURE_INCOMPAT_MMP|\
+					 EXT4_FEATURE_INCOMPAT_64BIT)
+#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|\
+					 EXT3_FEATURE_INCOMPAT_EXTENTS|\
+					 EXT4_FEATURE_INCOMPAT_FLEX_BG|\
+					 EXT4_FEATURE_INCOMPAT_MMP|\
+					 EXT4_FEATURE_INCOMPAT_64BIT)
+#endif
+#ifdef CONFIG_QUOTA
+#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
+					 EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
+					 EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
+					 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\
+					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
+					 EXT4_FEATURE_RO_COMPAT_BIGALLOC|\
+					 EXT4_FEATURE_RO_COMPAT_QUOTA)
+#else
+#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
+					 EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
+					 EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
+					 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\
+					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
+					 EXT4_FEATURE_RO_COMPAT_BIGALLOC)
+#endif
+
+/*
+ * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
+ * to ext2fs_openfs()
+ */
+#define EXT2_LIB_SOFTSUPP_INCOMPAT	(0)
+#define EXT2_LIB_SOFTSUPP_RO_COMPAT	(EXT4_FEATURE_RO_COMPAT_REPLICA)
+
+
+/* Translate a block number to a cluster number */
+#define EXT2FS_CLUSTER_RATIO(fs)	(1 << (fs)->cluster_ratio_bits)
+#define EXT2FS_CLUSTER_MASK(fs)		(EXT2FS_CLUSTER_RATIO(fs) - 1)
+#define EXT2FS_B2C(fs, blk)		((blk) >> (fs)->cluster_ratio_bits)
+/* Translate a cluster number to a block number */
+#define EXT2FS_C2B(fs, cluster)		((cluster) << (fs)->cluster_ratio_bits)
+/* Translate # of blks to # of clusters */
+#define EXT2FS_NUM_B2C(fs, blks)	(((blks) + EXT2FS_CLUSTER_MASK(fs)) >> \
+					 (fs)->cluster_ratio_bits)
+
+#if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
+typedef struct stat64 ext2fs_struct_stat;
+#else
+typedef struct stat ext2fs_struct_stat;
+#endif
+
+/*
+ * For ext2fs_close2() and ext2fs_flush2(), this flag allows you to
+ * avoid the fsync call.
+ */
+#define EXT2_FLAG_FLUSH_NO_SYNC          1
+
+/*
+ * function prototypes
+ */
+
+/* The LARGE_FILE feature should be set if we have stored files 2GB+ in size */
+static inline int ext2fs_needs_large_file_feature(unsigned long long file_size)
+{
+	return file_size >= 0x80000000ULL;
+}
+
+/* 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_new_block2(ext2_filsys fs, blk64_t goal,
+				   ext2fs_block_bitmap map, blk64_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_get_free_blocks2(ext2_filsys fs, blk64_t start,
+					 blk64_t finish, int num,
+					 ext2fs_block_bitmap map,
+					 blk64_t *ret);
+extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
+				    char *block_buf, blk_t *ret);
+extern errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
+				     char *block_buf, blk64_t *ret);
+extern void ext2fs_set_alloc_block_callback(ext2_filsys fs,
+					    errcode_t (*func)(ext2_filsys fs,
+							      blk64_t goal,
+							      blk64_t *ret),
+					    errcode_t (**old)(ext2_filsys fs,
+							      blk64_t goal,
+							      blk64_t *ret));
+
+/* alloc_sb.c */
+extern int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
+					dgrp_t group,
+					ext2fs_block_bitmap bmap);
+extern void ext2fs_set_block_alloc_stats_callback(ext2_filsys fs,
+						  void (*func)(ext2_filsys fs,
+							       blk64_t blk,
+							       int inuse),
+						  void (**old)(ext2_filsys fs,
+							       blk64_t blk,
+							       int inuse));
+
+/* 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);
+void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_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 void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
+extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
+extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
+				    ext2fs_generic_bitmap *dest);
+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_block_bitmap(ext2_filsys fs,
+					      const char *descr,
+					      ext2fs_block_bitmap *ret);
+extern errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs,
+						   const char *descr,
+						   ext2fs_block_bitmap *ret);
+extern int ext2fs_get_bitmap_granularity(ext2fs_block_bitmap bitmap);
+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 errcode_t ext2fs_fudge_block_bitmap_end2(ext2fs_block_bitmap bitmap,
+					 blk64_t end, blk64_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);
+extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
+					    ext2fs_inode_bitmap bmap);
+extern errcode_t ext2fs_resize_inode_bitmap2(__u64 new_end,
+					     __u64 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_resize_block_bitmap2(__u64 new_end,
+					     __u64 new_real_end,
+					     ext2fs_block_bitmap bmap);
+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);
+extern errcode_t ext2fs_set_inode_bitmap_range(ext2fs_inode_bitmap bmap,
+					ext2_ino_t start, unsigned int num,
+					void *in);
+extern errcode_t ext2fs_set_inode_bitmap_range2(ext2fs_inode_bitmap bmap,
+					 __u64 start, size_t num,
+					 void *in);
+extern errcode_t ext2fs_get_inode_bitmap_range(ext2fs_inode_bitmap bmap,
+					ext2_ino_t start, unsigned int num,
+					void *out);
+extern errcode_t ext2fs_get_inode_bitmap_range2(ext2fs_inode_bitmap bmap,
+					 __u64 start, size_t num,
+					 void *out);
+extern errcode_t ext2fs_set_block_bitmap_range(ext2fs_block_bitmap bmap,
+					blk_t start, unsigned int num,
+					void *in);
+extern errcode_t ext2fs_set_block_bitmap_range2(ext2fs_block_bitmap bmap,
+					 blk64_t start, size_t num,
+					 void *in);
+extern errcode_t ext2fs_get_block_bitmap_range(ext2fs_block_bitmap bmap,
+					blk_t start, unsigned int num,
+					void *out);
+extern errcode_t ext2fs_get_block_bitmap_range2(ext2fs_block_bitmap bmap,
+					 blk64_t start, size_t num,
+					 void *out);
+
+/* blknum.c */
+extern dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t);
+extern blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group);
+extern blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group);
+extern int ext2fs_group_blocks_count(ext2_filsys fs, dgrp_t group);
+extern blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs,
+					 struct ext2_inode *inode);
+extern blk64_t ext2fs_inode_i_blocks(ext2_filsys fs,
+					 struct ext2_inode *inode);
+extern blk64_t ext2fs_blocks_count(struct ext2_super_block *super);
+extern void ext2fs_blocks_count_set(struct ext2_super_block *super,
+				    blk64_t blk);
+extern void ext2fs_blocks_count_add(struct ext2_super_block *super,
+				    blk64_t blk);
+extern blk64_t ext2fs_r_blocks_count(struct ext2_super_block *super);
+extern void ext2fs_r_blocks_count_set(struct ext2_super_block *super,
+				      blk64_t blk);
+extern void ext2fs_r_blocks_count_add(struct ext2_super_block *super,
+				      blk64_t blk);
+extern blk64_t ext2fs_free_blocks_count(struct ext2_super_block *super);
+extern void ext2fs_free_blocks_count_set(struct ext2_super_block *super,
+					 blk64_t blk);
+extern void ext2fs_free_blocks_count_add(struct ext2_super_block *super,
+					 blk64_t blk);
+/* Block group descriptor accessor functions */
+extern struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
+					  struct opaque_ext2_group_desc *gdp,
+					  dgrp_t group);
+extern blk64_t ext2fs_block_bitmap_loc(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_block_bitmap_loc_set(ext2_filsys fs, dgrp_t group,
+					blk64_t blk);
+extern blk64_t ext2fs_inode_bitmap_loc(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_inode_bitmap_loc_set(ext2_filsys fs, dgrp_t group,
+					blk64_t blk);
+extern blk64_t ext2fs_inode_table_loc(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_inode_table_loc_set(ext2_filsys fs, dgrp_t group,
+				       blk64_t blk);
+extern __u32 ext2fs_bg_free_blocks_count(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_bg_free_blocks_count_set(ext2_filsys fs, dgrp_t group,
+					 __u32 n);
+extern __u32 ext2fs_bg_free_inodes_count(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_bg_free_inodes_count_set(ext2_filsys fs, dgrp_t group,
+					 __u32 n);
+extern __u32 ext2fs_bg_used_dirs_count(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_bg_used_dirs_count_set(ext2_filsys fs, dgrp_t group,
+				       __u32 n);
+extern __u32 ext2fs_bg_itable_unused(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_bg_itable_unused_set(ext2_filsys fs, dgrp_t group,
+				     __u32 n);
+extern __u16 ext2fs_bg_flags(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_bg_flags_zap(ext2_filsys fs, dgrp_t group);
+extern int ext2fs_bg_flags_test(ext2_filsys fs, dgrp_t group, __u16 bg_flag);
+extern void ext2fs_bg_flags_set(ext2_filsys fs, dgrp_t group, __u16 bg_flags);
+extern void ext2fs_bg_flags_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flags);
+extern __u16 ext2fs_bg_checksum(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum);
+extern blk64_t ext2fs_file_acl_block(ext2_filsys fs,
+				     const struct ext2_inode *inode);
+extern void ext2fs_file_acl_block_set(ext2_filsys fs,
+				      struct ext2_inode *inode, blk64_t blk);
+
+/* 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);
+errcode_t ext2fs_block_iterate3(ext2_filsys fs,
+				ext2_ino_t ino,
+				int	flags,
+				char *block_buf,
+				int (*func)(ext2_filsys fs,
+					    blk64_t	*blocknr,
+					    e2_blkcnt_t	blockcnt,
+					    blk64_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);
+extern errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino,
+			      struct ext2_inode *inode,
+			      char *block_buf, int bmap_flags, blk64_t block,
+			      int *ret_flags, blk64_t *phys_blk);
+errcode_t ext2fs_map_cluster_block(ext2_filsys fs, ext2_ino_t ino,
+				   struct ext2_inode *inode, blk64_t lblk,
+				   blk64_t *pblk);
+
+#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_close2(ext2_filsys fs, int flags);
+extern errcode_t ext2fs_flush(ext2_filsys fs);
+extern errcode_t ext2fs_flush2(ext2_filsys fs, int flags);
+extern int ext2fs_bg_has_super(ext2_filsys fs, dgrp_t group_block);
+extern errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs,
+				    dgrp_t group,
+				    blk64_t *ret_super_blk,
+				    blk64_t *ret_old_desc_blk,
+				    blk64_t *ret_new_desc_blk,
+				    blk_t *ret_used_blks);
+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);
+
+/* crc32c.c */
+extern __u32 ext2fs_crc32c_be(__u32 crc, unsigned char const *p, size_t len);
+extern __u32 ext2fs_crc32c_le(__u32 crc, unsigned char const *p, size_t len);
+
+/* csum.c */
+extern void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group);
+extern int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group);
+extern errcode_t ext2fs_set_gdt_csum(ext2_filsys fs);
+extern __u16 ext2fs_group_desc_csum(ext2_filsys fs, dgrp_t group);
+
+/* 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 errcode_t ext2fs_add_dir_block2(ext2_dblist dblist, ext2_ino_t ino,
+				       blk64_t blk, e2_blkcnt_t blockcnt);
+extern void ext2fs_dblist_sort(ext2_dblist dblist,
+			       EXT2_QSORT_TYPE (*sortfunc)(const void *,
+							   const void *));
+extern void ext2fs_dblist_sort2(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_dblist_iterate2(ext2_dblist dblist,
+	int (*func)(ext2_filsys fs, struct ext2_db_entry2 *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_set_dir_block2(ext2_dblist dblist, ext2_ino_t ino,
+				       blk64_t blk, e2_blkcnt_t blockcnt);
+extern errcode_t ext2fs_copy_dblist(ext2_dblist src,
+				    ext2_dblist *dest);
+extern int ext2fs_dblist_count(ext2_dblist dblist);
+extern blk64_t ext2fs_dblist_count2(ext2_dblist dblist);
+extern errcode_t ext2fs_dblist_get_last(ext2_dblist dblist,
+					struct ext2_db_entry **entry);
+extern errcode_t ext2fs_dblist_get_last2(ext2_dblist dblist,
+					struct ext2_db_entry2 **entry);
+extern errcode_t ext2fs_dblist_drop_last(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_read_dir_block3(ext2_filsys fs, blk64_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);
+extern errcode_t ext2fs_write_dir_block3(ext2_filsys fs, blk64_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_get_rec_len(ext2_filsys fs,
+				    struct ext2_dir_entry *dirent,
+				    unsigned int *rec_len);
+extern errcode_t ext2fs_set_rec_len(ext2_filsys fs,
+				    unsigned int len,
+				    struct ext2_dir_entry *dirent);
+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 __u32 ext2fs_ext_attr_hash_entry(struct ext2_ext_attr_entry *entry,
+					void *data);
+extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
+extern errcode_t ext2fs_read_ext_attr2(ext2_filsys fs, blk64_t block,
+				       void *buf);
+extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block,
+				       void *buf);
+extern errcode_t ext2fs_write_ext_attr2(ext2_filsys fs, blk64_t block,
+				       void *buf);
+extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
+					   char *block_buf,
+					   int adjust, __u32 *newcount);
+extern errcode_t ext2fs_adjust_ea_refcount2(ext2_filsys fs, blk64_t blk,
+					   char *block_buf,
+					   int adjust, __u32 *newcount);
+
+/* extent.c */
+extern errcode_t ext2fs_extent_header_verify(void *ptr, int size);
+extern errcode_t ext2fs_extent_open(ext2_filsys fs, ext2_ino_t ino,
+				    ext2_extent_handle_t *handle);
+extern errcode_t ext2fs_extent_open2(ext2_filsys fs, ext2_ino_t ino,
+					struct ext2_inode *inode,
+					ext2_extent_handle_t *ret_handle);
+extern void ext2fs_extent_free(ext2_extent_handle_t handle);
+extern errcode_t ext2fs_extent_get(ext2_extent_handle_t handle,
+				   int flags, struct ext2fs_extent *extent);
+extern errcode_t ext2fs_extent_node_split(ext2_extent_handle_t handle);
+extern errcode_t ext2fs_extent_replace(ext2_extent_handle_t handle, int flags,
+				       struct ext2fs_extent *extent);
+extern errcode_t ext2fs_extent_insert(ext2_extent_handle_t handle, int flags,
+				      struct ext2fs_extent *extent);
+extern errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
+					blk64_t logical, blk64_t physical,
+					int flags);
+extern errcode_t ext2fs_extent_delete(ext2_extent_handle_t handle, int flags);
+extern errcode_t ext2fs_extent_get_info(ext2_extent_handle_t handle,
+					struct ext2_extent_info *info);
+extern errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle,
+				    blk64_t blk);
+extern errcode_t ext2fs_extent_goto2(ext2_extent_handle_t handle,
+				     int leaf_level, blk64_t blk);
+extern errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle);
+
+/* 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);
+struct ext2_inode *ext2fs_file_get_inode(ext2_file_t file);
+extern ext2_ino_t ext2fs_file_get_inode_num(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);
+extern errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_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_dblist(ext2_dblist dblist);
+extern void ext2fs_badblocks_list_free(ext2_badblocks_list bb);
+extern void ext2fs_u32_list_free(ext2_u32_list bb);
+
+/* gen_bitmap.c */
+extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
+extern errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
+					    __u32 start, __u32 end,
+					    __u32 real_end,
+					    const char *descr, char *init_map,
+					    ext2fs_generic_bitmap *ret);
+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_copy_generic_bitmap(ext2fs_generic_bitmap src,
+					    ext2fs_generic_bitmap *dest);
+extern void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap);
+extern errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,
+						 errcode_t magic,
+						 errcode_t neq,
+						 ext2_ino_t end,
+						 ext2_ino_t *oend);
+extern void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map);
+extern errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
+					      __u32 new_end,
+					      __u32 new_real_end,
+					      ext2fs_generic_bitmap bmap);
+extern errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq,
+					       ext2fs_generic_bitmap bm1,
+					       ext2fs_generic_bitmap bm2);
+extern errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,
+						 errcode_t magic,
+						 __u32 start, __u32 num,
+						 void *out);
+extern errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap,
+						 errcode_t magic,
+						 __u32 start, __u32 num,
+						 void *in);
+extern errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap,
+						       __u32 start, __u32 end,
+						       __u32 *out);
+
+/* gen_bitmap64.c */
+
+/* Generate and print bitmap usage statistics */
+#define BMAP_STATS
+
+void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap);
+errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
+				    int type, __u64 start, __u64 end,
+				    __u64 real_end,
+				    const char *descr,
+				    ext2fs_generic_bitmap *ret);
+errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
+				   ext2fs_generic_bitmap *dest);
+void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap);
+errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
+					errcode_t neq,
+					__u64 end, __u64 *oend);
+void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap);
+errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
+				     __u64 new_end,
+				     __u64 new_real_end);
+errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
+				      ext2fs_generic_bitmap bm1,
+				      ext2fs_generic_bitmap bm2);
+errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
+					__u64 start, unsigned int num,
+					void *out);
+errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
+					__u64 start, unsigned int num,
+					void *in);
+errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
+					   ext2fs_block_bitmap *bitmap);
+
+/* getsize.c */
+extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
+					blk_t *retblocks);
+extern errcode_t ext2fs_get_device_size2(const char *file, int blocksize,
+					blk64_t *retblocks);
+
+/* getsectsize.c */
+extern int ext2fs_get_dio_alignment(int fd);
+errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize);
+errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize);
+
+/* i_block.c */
+errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks);
+errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks);
+errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b);
+
+/* 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_icount_tdb(ext2_filsys fs, char *tdb_dir,
+					  int flags, ext2_icount_t *ret);
+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 *);
+
+/* inline.c */
+
+extern errcode_t ext2fs_get_memalign(unsigned long size,
+				     unsigned long align, void *ptr);
+
+/* 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);
+
+/* punch.c */
+/*
+ * NOTE: This function removes from an inode the blocks "start", "end", and
+ * every block in between.
+ */
+extern errcode_t ext2fs_punch(ext2_filsys fs, ext2_ino_t ino,
+			      struct ext2_inode *inode,
+			      char *block_buf, blk64_t start,
+			      blk64_t end);
+
+/* 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_zero_blocks(ext2_filsys fs, blk_t blk, int num,
+				    blk_t *ret_blk, int *ret_count);
+extern errcode_t ext2fs_zero_blocks2(ext2_filsys fs, blk64_t blk, int num,
+				     blk64_t *ret_blk, int *ret_count);
+extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
+						  __u32 num_blocks, 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 num_blocks,
+					  int flags);
+extern int ext2fs_default_journal_size(__u64 num_blocks);
+
+/* 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 blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs,
+					blk64_t group_block, dgrp_t i);
+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);
+
+/* symlink.c */
+errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino,
+			 const char *name, char *target);
+
+/* mmp.c */
+errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf);
+errcode_t ext2fs_mmp_write(ext2_filsys fs, blk64_t mmp_blk, void *buf);
+errcode_t ext2fs_mmp_clear(ext2_filsys fs);
+errcode_t ext2fs_mmp_init(ext2_filsys fs);
+errcode_t ext2fs_mmp_start(ext2_filsys fs);
+errcode_t ext2fs_mmp_update(ext2_filsys fs);
+errcode_t ext2fs_mmp_stop(ext2_filsys fs);
+unsigned ext2fs_mmp_new_seq(void);
+
+/* 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);
+
+/* swapfs.c */
+extern void ext2fs_swap_ext_attr(char *to, char *from, int bufsize,
+				 int has_header);
+extern void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header,
+					struct ext2_ext_attr_header *from_hdr);
+extern void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry,
+				       struct ext2_ext_attr_entry *from_entry);
+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_group_desc2(ext2_filsys, 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);
+extern void ext2fs_swap_mmp(struct mmp_struct *mmp);
+
+/* unix_io.c */
+extern int ext2fs_open_file(const char *pathname, int flags, mode_t mode);
+extern int ext2fs_stat(const char *path, ext2fs_struct_stat *buf);
+extern int ext2fs_fstat(int fd, ext2fs_struct_stat *buf);
+
+/* valid_blk.c */
+extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
+extern int ext2fs_inode_has_valid_blocks2(ext2_filsys fs,
+					  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 */
+#ifdef NO_INLINE_FUNCS
+extern errcode_t ext2fs_get_mem(unsigned long size, void *ptr);
+extern errcode_t ext2fs_get_memzero(unsigned long size, void *ptr);
+extern errcode_t ext2fs_get_array(unsigned long count,
+				  unsigned long size, void *ptr);
+extern errcode_t ext2fs_get_arrayzero(unsigned long count,
+				      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 dgrp_t ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
+extern dgrp_t ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino);
+extern blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group);
+extern blk_t ext2fs_group_last_block(ext2_filsys fs, dgrp_t group);
+extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
+				      struct ext2_inode *inode);
+extern unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b);
+extern __u64 ext2fs_div64_ceil(__u64 a, __u64 b);
+#endif
+
+/*
+ * 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
+#if (__STDC_VERSION__ >= 199901L)
+#define _INLINE_ inline
+#else
+#ifdef __GNUC__
+#define _INLINE_ extern __inline__
+#else				/* For Watcom C */
+#define _INLINE_ extern inline
+#endif /* __GNUC__ */
+#endif /* __STDC_VERSION__ >= 199901L */
+#endif
+
+#ifndef EXT2_CUSTOM_MEMORY_ROUTINES
+#include <string.h>
+/*
+ *  Allocate memory.  The 'ptr' arg must point to a pointer.
+ */
+_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
+{
+	void *pp;
+
+	pp = malloc(size);
+	if (!pp)
+		return EXT2_ET_NO_MEMORY;
+	memcpy(ptr, &pp, sizeof (pp));
+	return 0;
+}
+
+_INLINE_ errcode_t ext2fs_get_memzero(unsigned long size, void *ptr)
+{
+	void *pp;
+
+	pp = malloc(size);
+	if (!pp)
+		return EXT2_ET_NO_MEMORY;
+	memset(pp, 0, size);
+	memcpy(ptr, &pp, sizeof(pp));
+	return 0;
+}
+
+_INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size, void *ptr)
+{
+	if (count && (-1UL)/count<size)
+		return EXT2_ET_NO_MEMORY;
+	return ext2fs_get_mem(count*size, ptr);
+}
+
+_INLINE_ errcode_t ext2fs_get_arrayzero(unsigned long count,
+					unsigned long size, void *ptr)
+{
+	void *pp;
+
+	if (count && (-1UL)/count<size)
+		return EXT2_ET_NO_MEMORY;
+	pp = calloc(count, size);
+	if (!pp)
+		return EXT2_ET_NO_MEMORY;
+	memcpy(ptr, &pp, sizeof(pp));
+	return 0;
+}
+
+/*
+ * Free memory.  The 'ptr' arg must point to a pointer.
+ */
+_INLINE_ errcode_t ext2fs_free_mem(void *ptr)
+{
+	void *p;
+
+	memcpy(&p, ptr, sizeof(p));
+	free(p);
+	p = 0;
+	memcpy(ptr, &p, sizeof(p));
+	return 0;
+}
+
+/*
+ *  Resize memory.  The 'ptr' arg must point to a pointer.
+ */
+_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_ dgrp_t ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
+{
+	return ext2fs_group_of_blk2(fs, blk);
+}
+/*
+ * Return the group # of an inode number
+ */
+_INLINE_ dgrp_t ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
+{
+	return (ino - 1) / fs->super->s_inodes_per_group;
+}
+
+/*
+ * Return the first block (inclusive) in a group
+ */
+_INLINE_ blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group)
+{
+	return (blk_t) ext2fs_group_first_block2(fs, group);
+}
+
+/*
+ * Return the last block (inclusive) in a group
+ */
+_INLINE_ blk_t ext2fs_group_last_block(ext2_filsys fs, dgrp_t group)
+{
+	return (blk_t) ext2fs_group_last_block2(fs, group);
+}
+
+_INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
+					struct ext2_inode *inode)
+{
+	return (blk_t) ext2fs_inode_data_blocks2(fs, inode);
+}
+
+/*
+ * This is an efficient, overflow safe way of calculating ceil((1.0 * a) / b)
+ */
+_INLINE_ unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b)
+{
+	if (!a)
+		return 0;
+	return ((a - 1) / b) + 1;
+}
+
+_INLINE_ __u64 ext2fs_div64_ceil(__u64 a, __u64 b)
+{
+	if (!a)
+		return 0;
+	return ((a - 1) / b) + 1;
+}
+
+#undef _INLINE_
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EXT2FS_EXT2FS_H */
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2fs.pc.in b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2fs.pc.in
new file mode 100644
index 0000000..efac85e
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2fs.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ext2fs
+Description: Ext2fs library
+Version: @E2FSPROGS_VERSION@
+Requires.private: com_err
+Cflags: -I${includedir}/ext2fs -I${includedir}
+Libs: -L${libdir} -lext2fs
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2fsP.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2fsP.h
new file mode 100644
index 0000000..a88db93
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext2fsP.h
@@ -0,0 +1,147 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "ext2fs.h"
+
+#define EXT2FS_MAX_NESTED_LINKS  8
+
+/*
+ * 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;
+	unsigned long long	size;
+	unsigned long long	count;
+	int			sorted;
+	struct ext2_db_entry2 *	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;
+	blk64_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,
+				    blk64_t		*blocknr,
+				    e2_blkcnt_t		blockcnt,
+				    blk64_t		ref_block,
+				    int			ref_offset,
+				    void		*priv_data);
+
+/* Generic numeric progress meter */
+
+struct ext2fs_numeric_progress_struct {
+	__u64		max;
+	int		log_max;
+	int		skip_progress;
+};
+
+extern void ext2fs_numeric_progress_init(ext2_filsys fs,
+					 struct ext2fs_numeric_progress_struct * progress,
+					 const char *label, __u64 max);
+extern void ext2fs_numeric_progress_update(ext2_filsys fs,
+					   struct ext2fs_numeric_progress_struct * progress,
+					   __u64 val);
+extern void ext2fs_numeric_progress_close(ext2_filsys fs,
+					  struct ext2fs_numeric_progress_struct * progress,
+					  const char *message);
+
+/*
+ * 64-bit bitmap support
+ */
+
+extern errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
+					   int type, __u64 start, __u64 end,
+					   __u64 real_end,
+					   const char * description,
+					   ext2fs_generic_bitmap *bmap);
+
+extern void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap);
+
+extern errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
+					  ext2fs_generic_bitmap *dest);
+
+extern errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
+					    __u64 new_end,
+					    __u64 new_real_end);
+extern errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
+					       errcode_t neq,
+					       __u64 end, __u64 *oend);
+extern int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap,
+				    __u64 arg);
+extern int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap,
+				      __u64 arg);
+extern int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap,
+				    __u64 arg);
+extern errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bitmap,
+					       __u64 start, unsigned int num,
+					       void *in);
+extern errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bitmap,
+					       __u64 start, unsigned int num,
+					       void *out);
+extern void ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap,const char *func);
+
+extern int ext2fs_mem_is_zero(const char *mem, size_t len);
+
+extern int ext2fs_file_block_offset_too_big(ext2_filsys fs,
+					    struct ext2_inode *inode,
+					    blk64_t offset);
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext3_extents.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext3_extents.h
new file mode 100644
index 0000000..88fabc9
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext3_extents.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2003,2004 Cluster File Systems, Inc, info@clusterfs.com
+ * Written by Alex Tomas <alex@clusterfs.com>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#ifndef _LINUX_EXT3_EXTENTS
+#define _LINUX_EXT3_EXTENTS
+
+/*
+ * ext3_inode has i_block array (total 60 bytes)
+ * first 4 bytes are used to store:
+ *  - tree depth (0 mean there is no tree yet. all extents in the inode)
+ *  - number of alive extents in the inode
+ */
+
+/*
+ * this is extent on-disk structure
+ * it's used at the bottom of the tree
+ */
+struct ext3_extent {
+	__u32	ee_block;	/* first logical block extent covers */
+	__u16	ee_len;		/* number of blocks covered by extent */
+	__u16	ee_start_hi;	/* high 16 bits of physical block */
+	__u32	ee_start;	/* low 32 bigs of physical block */
+};
+
+/*
+ * this is index on-disk structure
+ * it's used at all the levels, but the bottom
+ */
+struct ext3_extent_idx {
+	__u32	ei_block;	/* index covers logical blocks from 'block' */
+	__u32	ei_leaf;	/* pointer to the physical block of the next *
+				 * level. leaf or next index could bet here */
+	__u16	ei_leaf_hi;	/* high 16 bits of physical block */
+	__u16	ei_unused;
+};
+
+/*
+ * each block (leaves and indexes), even inode-stored has header
+ */
+struct ext3_extent_header {
+	__u16	eh_magic;	/* probably will support different formats */
+	__u16	eh_entries;	/* number of valid entries */
+	__u16	eh_max;		/* capacity of store in entries */
+	__u16	eh_depth;	/* has tree real underlaying blocks? */
+	__u32	eh_generation;	/* generation of the tree */
+};
+
+#define EXT3_EXT_MAGIC		0xf30a
+
+/*
+ * array of ext3_ext_path contains path to some extent
+ * creation/lookup routines use it for traversal/splitting/etc
+ * truncate uses it to simulate recursive walking
+ */
+struct ext3_ext_path {
+	__u32				p_block;
+	__u16				p_depth;
+	struct ext3_extent		*p_ext;
+	struct ext3_extent_idx		*p_idx;
+	struct ext3_extent_header	*p_hdr;
+	struct buffer_head		*p_bh;
+};
+
+/*
+ * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
+ * initialized extent. This is 2^15 and not (2^16 - 1), since we use the
+ * MSB of ee_len field in the extent datastructure to signify if this
+ * particular extent is an initialized extent or an uninitialized (i.e.
+ * preallocated).
+ * EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an
+ * uninitialized extent.
+ * If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an
+ * uninitialized one. In other words, if MSB of ee_len is set, it is an
+ * uninitialized extent with only one special scenario when ee_len = 0x8000.
+ * In this case we can not have an uninitialized extent of zero length and
+ * thus we make it as a special case of initialized extent with 0x8000 length.
+ * This way we get better extent-to-group alignment for initialized extents.
+ * Hence, the maximum number of blocks we can have in an *initialized*
+ * extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767).
+ */
+#define EXT_INIT_MAX_LEN	(1UL << 15)
+#define EXT_UNINIT_MAX_LEN	(EXT_INIT_MAX_LEN - 1)
+
+#define EXT_FIRST_EXTENT(__hdr__) \
+	((struct ext3_extent *) (((char *) (__hdr__)) +		\
+				 sizeof(struct ext3_extent_header)))
+#define EXT_FIRST_INDEX(__hdr__) \
+	((struct ext3_extent_idx *) (((char *) (__hdr__)) +	\
+				     sizeof(struct ext3_extent_header)))
+#define EXT_HAS_FREE_INDEX(__path__) \
+	((__path__)->p_hdr->eh_entries < (__path__)->p_hdr->eh_max)
+#define EXT_LAST_EXTENT(__hdr__) \
+	(EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_entries - 1)
+#define EXT_LAST_INDEX(__hdr__) \
+	(EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_entries - 1)
+#define EXT_MAX_EXTENT(__hdr__) \
+	(EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_max - 1)
+#define EXT_MAX_INDEX(__hdr__) \
+	(EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_max - 1)
+
+#endif /* _LINUX_EXT3_EXTENTS */
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext_attr.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext_attr.c
new file mode 100644
index 0000000..1889824
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ext_attr.c
@@ -0,0 +1,157 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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"
+
+#define NAME_HASH_SHIFT 5
+#define VALUE_HASH_SHIFT 16
+
+/*
+ * ext2_xattr_hash_entry()
+ *
+ * Compute the hash of an extended attribute.
+ */
+__u32 ext2fs_ext_attr_hash_entry(struct ext2_ext_attr_entry *entry, void *data)
+{
+	__u32 hash = 0;
+	char *name = ((char *) entry) + sizeof(struct ext2_ext_attr_entry);
+	int n;
+
+	for (n = 0; n < entry->e_name_len; n++) {
+		hash = (hash << NAME_HASH_SHIFT) ^
+		       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
+		       *name++;
+	}
+
+	/* The hash needs to be calculated on the data in little-endian. */
+	if (entry->e_value_block == 0 && entry->e_value_size != 0) {
+		__u32 *value = (__u32 *)data;
+		for (n = (entry->e_value_size + EXT2_EXT_ATTR_ROUND) >>
+			 EXT2_EXT_ATTR_PAD_BITS; n; n--) {
+			hash = (hash << VALUE_HASH_SHIFT) ^
+			       (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
+			       ext2fs_le32_to_cpu(*value++);
+		}
+	}
+
+	return hash;
+}
+
+#undef NAME_HASH_SHIFT
+#undef VALUE_HASH_SHIFT
+
+errcode_t ext2fs_read_ext_attr2(ext2_filsys fs, blk64_t block, void *buf)
+{
+	errcode_t	retval;
+
+	retval = io_channel_read_blk64(fs->io, block, 1, buf);
+	if (retval)
+		return retval;
+#ifdef WORDS_BIGENDIAN
+	ext2fs_swap_ext_attr(buf, buf, fs->blocksize, 1);
+#endif
+	return 0;
+}
+
+errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf)
+{
+	return ext2fs_read_ext_attr2(fs, block, buf);
+}
+
+errcode_t ext2fs_write_ext_attr2(ext2_filsys fs, blk64_t block, void *inbuf)
+{
+	errcode_t	retval;
+	char		*write_buf;
+#ifdef WORDS_BIGENDIAN
+	char		*buf = NULL;
+
+	retval = ext2fs_get_mem(fs->blocksize, &buf);
+	if (retval)
+		return retval;
+	write_buf = buf;
+	ext2fs_swap_ext_attr(buf, inbuf, fs->blocksize, 1);
+#else
+	write_buf = (char *) inbuf;
+#endif
+	retval = io_channel_write_blk64(fs->io, block, 1, write_buf);
+#ifdef WORDS_BIGENDIAN
+	ext2fs_free_mem(&buf);
+#endif
+	if (!retval)
+		ext2fs_mark_changed(fs);
+	return retval;
+}
+
+errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *inbuf)
+{
+	return ext2fs_write_ext_attr2(fs, block, inbuf);
+}
+
+/*
+ * This function adjusts the reference count of the EA block.
+ */
+errcode_t ext2fs_adjust_ea_refcount2(ext2_filsys fs, blk64_t blk,
+				    char *block_buf, int adjust,
+				    __u32 *newcount)
+{
+	errcode_t	retval;
+	struct ext2_ext_attr_header *header;
+	char	*buf = 0;
+
+	if ((blk >= ext2fs_blocks_count(fs->super)) ||
+	    (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_attr2(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_attr2(fs, blk, block_buf);
+	if (retval)
+		goto errout;
+
+errout:
+	if (buf)
+		ext2fs_free_mem(&buf);
+	return retval;
+}
+
+errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
+					char *block_buf, int adjust,
+					__u32 *newcount)
+{
+	return ext2fs_adjust_ea_refcount(fs, blk, block_buf, adjust, newcount);
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/extent.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/extent.c
new file mode 100644
index 0000000..5cdc2e4
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/extent.c
@@ -0,0 +1,1573 @@
+/*
+ * extent.c --- routines to implement extents support
+ *
+ * Copyright (C) 2007 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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"
+
+/*
+ * Definitions to be dropped in lib/ext2fs/ext2fs.h
+ */
+
+/*
+ * Private definitions
+ */
+
+struct extent_path {
+	char		*buf;
+	int		entries;
+	int		max_entries;
+	int		left;
+	int		visit_num;
+	int		flags;
+	blk64_t		end_blk;
+	void		*curr;
+};
+
+
+struct ext2_extent_handle {
+	errcode_t		magic;
+	ext2_filsys		fs;
+	ext2_ino_t 		ino;
+	struct ext2_inode	*inode;
+	struct ext2_inode	inodebuf;
+	int			type;
+	int			level;
+	int			max_depth;
+	struct extent_path	*path;
+};
+
+struct ext2_extent_path {
+	errcode_t		magic;
+	int			leaf_height;
+	blk64_t			lblk;
+};
+
+/*
+ *  Useful Debugging stuff
+ */
+
+#ifdef DEBUG
+static void dbg_show_header(struct ext3_extent_header *eh)
+{
+	printf("header: magic=%x entries=%u max=%u depth=%u generation=%u\n",
+			ext2fs_le16_to_cpu(eh->eh_magic),
+			ext2fs_le16_to_cpu(eh->eh_entries),
+			ext2fs_le16_to_cpu(eh->eh_max),
+			ext2fs_le16_to_cpu(eh->eh_depth),
+			ext2fs_le32_to_cpu(eh->eh_generation));
+}
+
+static void dbg_show_index(struct ext3_extent_idx *ix)
+{
+	printf("index: block=%u leaf=%u leaf_hi=%u unused=%u\n",
+			ext2fs_le32_to_cpu(ix->ei_block),
+			ext2fs_le32_to_cpu(ix->ei_leaf),
+			ext2fs_le16_to_cpu(ix->ei_leaf_hi),
+			ext2fs_le16_to_cpu(ix->ei_unused));
+}
+
+static void dbg_show_extent(struct ext3_extent *ex)
+{
+	printf("extent: block=%u-%u len=%u start=%u start_hi=%u\n",
+			ext2fs_le32_to_cpu(ex->ee_block),
+			ext2fs_le32_to_cpu(ex->ee_block) +
+			ext2fs_le16_to_cpu(ex->ee_len) - 1,
+			ext2fs_le16_to_cpu(ex->ee_len),
+			ext2fs_le32_to_cpu(ex->ee_start),
+			ext2fs_le16_to_cpu(ex->ee_start_hi));
+}
+
+static void dbg_print_extent(char *desc, struct ext2fs_extent *extent)
+{
+	if (desc)
+		printf("%s: ", desc);
+	printf("extent: lblk %llu--%llu, len %u, pblk %llu, flags: ",
+	       extent->e_lblk, extent->e_lblk + extent->e_len - 1,
+	       extent->e_len, extent->e_pblk);
+	if (extent->e_flags & EXT2_EXTENT_FLAGS_LEAF)
+		fputs("LEAF ", stdout);
+	if (extent->e_flags & EXT2_EXTENT_FLAGS_UNINIT)
+		fputs("UNINIT ", stdout);
+	if (extent->e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)
+		fputs("2ND_VISIT ", stdout);
+	if (!extent->e_flags)
+		fputs("(none)", stdout);
+	fputc('\n', stdout);
+
+}
+
+#else
+#define dbg_show_header(eh) do { } while (0)
+#define dbg_show_index(ix) do { } while (0)
+#define dbg_show_extent(ex) do { } while (0)
+#define dbg_print_extent(desc, ex) do { } while (0)
+#endif
+
+/*
+ * Verify the extent header as being sane
+ */
+errcode_t ext2fs_extent_header_verify(void *ptr, int size)
+{
+	int eh_max, entry_size;
+	struct ext3_extent_header *eh = ptr;
+
+	dbg_show_header(eh);
+	if (ext2fs_le16_to_cpu(eh->eh_magic) != EXT3_EXT_MAGIC)
+		return EXT2_ET_EXTENT_HEADER_BAD;
+	if (ext2fs_le16_to_cpu(eh->eh_entries) > ext2fs_le16_to_cpu(eh->eh_max))
+		return EXT2_ET_EXTENT_HEADER_BAD;
+	if (eh->eh_depth == 0)
+		entry_size = sizeof(struct ext3_extent);
+	else
+		entry_size = sizeof(struct ext3_extent_idx);
+
+	eh_max = (size - sizeof(*eh)) / entry_size;
+	/* Allow two extent-sized items at the end of the block, for
+	 * ext4_extent_tail with checksum in the future. */
+	if ((ext2fs_le16_to_cpu(eh->eh_max) > eh_max) ||
+	    (ext2fs_le16_to_cpu(eh->eh_max) < (eh_max - 2)))
+		return EXT2_ET_EXTENT_HEADER_BAD;
+
+	return 0;
+}
+
+
+/*
+ * Begin functions to handle an inode's extent information
+ */
+void ext2fs_extent_free(ext2_extent_handle_t handle)
+{
+	int			i;
+
+	if (!handle)
+		return;
+
+	if (handle->path) {
+		for (i=1; i <= handle->max_depth; i++) {
+			if (handle->path[i].buf)
+				ext2fs_free_mem(&handle->path[i].buf);
+		}
+		ext2fs_free_mem(&handle->path);
+	}
+	ext2fs_free_mem(&handle);
+}
+
+errcode_t ext2fs_extent_open(ext2_filsys fs, ext2_ino_t ino,
+				    ext2_extent_handle_t *ret_handle)
+{
+	return ext2fs_extent_open2(fs, ino, NULL, ret_handle);
+}
+
+errcode_t ext2fs_extent_open2(ext2_filsys fs, ext2_ino_t ino,
+				    struct ext2_inode *inode,
+				    ext2_extent_handle_t *ret_handle)
+{
+	struct ext2_extent_handle	*handle;
+	errcode_t			retval;
+	int				i;
+	struct ext3_extent_header	*eh;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	if (!inode)
+		if ((ino == 0) || (ino > fs->super->s_inodes_count))
+			return EXT2_ET_BAD_INODE_NUM;
+
+	retval = ext2fs_get_mem(sizeof(struct ext2_extent_handle), &handle);
+	if (retval)
+		return retval;
+	memset(handle, 0, sizeof(struct ext2_extent_handle));
+
+	handle->ino = ino;
+	handle->fs = fs;
+
+	if (inode) {
+		handle->inode = inode;
+	} else {
+		handle->inode = &handle->inodebuf;
+		retval = ext2fs_read_inode(fs, ino, handle->inode);
+		if (retval)
+			goto errout;
+	}
+
+	eh = (struct ext3_extent_header *) &handle->inode->i_block[0];
+
+	for (i=0; i < EXT2_N_BLOCKS; i++)
+		if (handle->inode->i_block[i])
+			break;
+	if (i >= EXT2_N_BLOCKS) {
+		eh->eh_magic = ext2fs_cpu_to_le16(EXT3_EXT_MAGIC);
+		eh->eh_depth = 0;
+		eh->eh_entries = 0;
+		i = (sizeof(handle->inode->i_block) - sizeof(*eh)) /
+			sizeof(struct ext3_extent);
+		eh->eh_max = ext2fs_cpu_to_le16(i);
+		handle->inode->i_flags |= EXT4_EXTENTS_FL;
+	}
+
+	if (!(handle->inode->i_flags & EXT4_EXTENTS_FL)) {
+		retval = EXT2_ET_INODE_NOT_EXTENT;
+		goto errout;
+	}
+
+	retval = ext2fs_extent_header_verify(eh, sizeof(handle->inode->i_block));
+	if (retval)
+		goto errout;
+
+	handle->max_depth = ext2fs_le16_to_cpu(eh->eh_depth);
+	handle->type = ext2fs_le16_to_cpu(eh->eh_magic);
+
+	retval = ext2fs_get_mem(((handle->max_depth+1) *
+				 sizeof(struct extent_path)),
+				&handle->path);
+	memset(handle->path, 0,
+	       (handle->max_depth+1) * sizeof(struct extent_path));
+	handle->path[0].buf = (char *) handle->inode->i_block;
+
+	handle->path[0].left = handle->path[0].entries =
+		ext2fs_le16_to_cpu(eh->eh_entries);
+	handle->path[0].max_entries = ext2fs_le16_to_cpu(eh->eh_max);
+	handle->path[0].curr = 0;
+	handle->path[0].end_blk =
+		(EXT2_I_SIZE(handle->inode) + fs->blocksize - 1) >>
+		 EXT2_BLOCK_SIZE_BITS(fs->super);
+	handle->path[0].visit_num = 1;
+	handle->level = 0;
+	handle->magic = EXT2_ET_MAGIC_EXTENT_HANDLE;
+
+	*ret_handle = handle;
+	return 0;
+
+errout:
+	ext2fs_extent_free(handle);
+	return retval;
+}
+
+/*
+ * This function is responsible for (optionally) moving through the
+ * extent tree and then returning the current extent
+ */
+errcode_t ext2fs_extent_get(ext2_extent_handle_t handle,
+			    int flags, struct ext2fs_extent *extent)
+{
+	struct extent_path	*path, *newpath;
+	struct ext3_extent_header	*eh;
+	struct ext3_extent_idx		*ix = 0;
+	struct ext3_extent		*ex;
+	errcode_t			retval;
+	blk64_t				blk;
+	blk64_t				end_blk;
+	int				orig_op, op;
+
+	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
+
+	if (!handle->path)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+	orig_op = op = flags & EXT2_EXTENT_MOVE_MASK;
+
+retry:
+	path = handle->path + handle->level;
+	if ((orig_op == EXT2_EXTENT_NEXT) ||
+	    (orig_op == EXT2_EXTENT_NEXT_LEAF)) {
+		if (handle->level < handle->max_depth) {
+			/* interior node */
+			if (path->visit_num == 0) {
+				path->visit_num++;
+				op = EXT2_EXTENT_DOWN;
+			} else if (path->left > 0)
+				op = EXT2_EXTENT_NEXT_SIB;
+			else if (handle->level > 0)
+				op = EXT2_EXTENT_UP;
+			else
+				return EXT2_ET_EXTENT_NO_NEXT;
+		} else {
+			/* leaf node */
+			if (path->left > 0)
+				op = EXT2_EXTENT_NEXT_SIB;
+			else if (handle->level > 0)
+				op = EXT2_EXTENT_UP;
+			else
+				return EXT2_ET_EXTENT_NO_NEXT;
+		}
+		if (op != EXT2_EXTENT_NEXT_SIB) {
+#ifdef DEBUG_GET_EXTENT
+			printf("<<<< OP = %s\n",
+			       (op == EXT2_EXTENT_DOWN) ? "down" :
+			       ((op == EXT2_EXTENT_UP) ? "up" : "unknown"));
+#endif
+		}
+	}
+
+	if ((orig_op == EXT2_EXTENT_PREV) ||
+	    (orig_op == EXT2_EXTENT_PREV_LEAF)) {
+		if (handle->level < handle->max_depth) {
+			/* interior node */
+			if (path->visit_num > 0 ) {
+				/* path->visit_num = 0; */
+				op = EXT2_EXTENT_DOWN_AND_LAST;
+			} else if (path->left < path->entries-1)
+				op = EXT2_EXTENT_PREV_SIB;
+			else if (handle->level > 0)
+				op = EXT2_EXTENT_UP;
+			else
+				return EXT2_ET_EXTENT_NO_PREV;
+		} else {
+			/* leaf node */
+			if (path->left < path->entries-1)
+				op = EXT2_EXTENT_PREV_SIB;
+			else if (handle->level > 0)
+				op = EXT2_EXTENT_UP;
+			else
+				return EXT2_ET_EXTENT_NO_PREV;
+		}
+		if (op != EXT2_EXTENT_PREV_SIB) {
+#ifdef DEBUG_GET_EXTENT
+			printf("<<<< OP = %s\n",
+			       (op == EXT2_EXTENT_DOWN_AND_LAST) ? "down/last" :
+			       ((op == EXT2_EXTENT_UP) ? "up" : "unknown"));
+#endif
+		}
+	}
+
+	if (orig_op == EXT2_EXTENT_LAST_LEAF) {
+		if ((handle->level < handle->max_depth) &&
+		    (path->left == 0))
+			op = EXT2_EXTENT_DOWN;
+		else
+			op = EXT2_EXTENT_LAST_SIB;
+#ifdef DEBUG_GET_EXTENT
+		printf("<<<< OP = %s\n",
+			   (op == EXT2_EXTENT_DOWN) ? "down" : "last_sib");
+#endif
+	}
+
+	switch (op) {
+	case EXT2_EXTENT_CURRENT:
+		ix = path->curr;
+		break;
+	case EXT2_EXTENT_ROOT:
+		handle->level = 0;
+		path = handle->path + handle->level;
+		/* fallthrough */
+	case EXT2_EXTENT_FIRST_SIB:
+		path->left = path->entries;
+		path->curr = 0;
+		/* fallthrough */
+	case EXT2_EXTENT_NEXT_SIB:
+		if (path->left <= 0)
+			return EXT2_ET_EXTENT_NO_NEXT;
+		if (path->curr) {
+			ix = path->curr;
+			ix++;
+		} else {
+			eh = (struct ext3_extent_header *) path->buf;
+			ix = EXT_FIRST_INDEX(eh);
+		}
+		path->left--;
+		path->curr = ix;
+		path->visit_num = 0;
+		break;
+	case EXT2_EXTENT_PREV_SIB:
+		if (!path->curr ||
+		    path->left+1 >= path->entries)
+			return EXT2_ET_EXTENT_NO_PREV;
+		ix = path->curr;
+		ix--;
+		path->curr = ix;
+		path->left++;
+		if (handle->level < handle->max_depth)
+			path->visit_num = 1;
+		break;
+	case EXT2_EXTENT_LAST_SIB:
+		eh = (struct ext3_extent_header *) path->buf;
+		path->curr = EXT_LAST_EXTENT(eh);
+		ix = path->curr;
+		path->left = 0;
+		path->visit_num = 0;
+		break;
+	case EXT2_EXTENT_UP:
+		if (handle->level <= 0)
+			return EXT2_ET_EXTENT_NO_UP;
+		handle->level--;
+		path--;
+		ix = path->curr;
+		if ((orig_op == EXT2_EXTENT_PREV) ||
+		    (orig_op == EXT2_EXTENT_PREV_LEAF))
+			path->visit_num = 0;
+		break;
+	case EXT2_EXTENT_DOWN:
+	case EXT2_EXTENT_DOWN_AND_LAST:
+		if (!path->curr ||(handle->level >= handle->max_depth))
+			return EXT2_ET_EXTENT_NO_DOWN;
+
+		ix = path->curr;
+		newpath = path + 1;
+		if (!newpath->buf) {
+			retval = ext2fs_get_mem(handle->fs->blocksize,
+						&newpath->buf);
+			if (retval)
+				return retval;
+		}
+		blk = ext2fs_le32_to_cpu(ix->ei_leaf) +
+			((__u64) ext2fs_le16_to_cpu(ix->ei_leaf_hi) << 32);
+		if ((handle->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
+		    (handle->fs->io != handle->fs->image_io))
+			memset(newpath->buf, 0, handle->fs->blocksize);
+		else {
+			retval = io_channel_read_blk64(handle->fs->io,
+						     blk, 1, newpath->buf);
+			if (retval)
+				return retval;
+		}
+		handle->level++;
+
+		eh = (struct ext3_extent_header *) newpath->buf;
+
+		retval = ext2fs_extent_header_verify(eh, handle->fs->blocksize);
+		if (retval) {
+			handle->level--;
+			return retval;
+		}
+
+		newpath->left = newpath->entries =
+			ext2fs_le16_to_cpu(eh->eh_entries);
+		newpath->max_entries = ext2fs_le16_to_cpu(eh->eh_max);
+
+		if (path->left > 0) {
+			ix++;
+			newpath->end_blk = ext2fs_le32_to_cpu(ix->ei_block);
+		} else
+			newpath->end_blk = path->end_blk;
+
+		path = newpath;
+		if (op == EXT2_EXTENT_DOWN) {
+			ix = EXT_FIRST_INDEX((struct ext3_extent_header *) eh);
+			path->curr = ix;
+			path->left = path->entries - 1;
+			path->visit_num = 0;
+		} else {
+			ix = EXT_LAST_INDEX((struct ext3_extent_header *) eh);
+			path->curr = ix;
+			path->left = 0;
+			if (handle->level < handle->max_depth)
+				path->visit_num = 1;
+		}
+#ifdef DEBUG_GET_EXTENT
+		printf("Down to level %d/%d, end_blk=%llu\n",
+			   handle->level, handle->max_depth,
+			   path->end_blk);
+#endif
+		break;
+	default:
+		return EXT2_ET_OP_NOT_SUPPORTED;
+	}
+
+	if (!ix)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+	extent->e_flags = 0;
+#ifdef DEBUG_GET_EXTENT
+	printf("(Left %d)\n", path->left);
+#endif
+
+	if (handle->level == handle->max_depth) {
+		ex = (struct ext3_extent *) ix;
+
+		extent->e_pblk = ext2fs_le32_to_cpu(ex->ee_start) +
+			((__u64) ext2fs_le16_to_cpu(ex->ee_start_hi) << 32);
+		extent->e_lblk = ext2fs_le32_to_cpu(ex->ee_block);
+		extent->e_len = ext2fs_le16_to_cpu(ex->ee_len);
+		extent->e_flags |= EXT2_EXTENT_FLAGS_LEAF;
+		if (extent->e_len > EXT_INIT_MAX_LEN) {
+			extent->e_len -= EXT_INIT_MAX_LEN;
+			extent->e_flags |= EXT2_EXTENT_FLAGS_UNINIT;
+		}
+	} else {
+		extent->e_pblk = ext2fs_le32_to_cpu(ix->ei_leaf) +
+			((__u64) ext2fs_le16_to_cpu(ix->ei_leaf_hi) << 32);
+		extent->e_lblk = ext2fs_le32_to_cpu(ix->ei_block);
+		if (path->left > 0) {
+			ix++;
+			end_blk = ext2fs_le32_to_cpu(ix->ei_block);
+		} else
+			end_blk = path->end_blk;
+
+		extent->e_len = end_blk - extent->e_lblk;
+	}
+	if (path->visit_num)
+		extent->e_flags |= EXT2_EXTENT_FLAGS_SECOND_VISIT;
+
+	if (((orig_op == EXT2_EXTENT_NEXT_LEAF) ||
+	     (orig_op == EXT2_EXTENT_PREV_LEAF)) &&
+	    (handle->level != handle->max_depth))
+		goto retry;
+
+	if ((orig_op == EXT2_EXTENT_LAST_LEAF) &&
+	    ((handle->level != handle->max_depth) ||
+	     (path->left != 0)))
+		goto retry;
+
+	return 0;
+}
+
+static errcode_t update_path(ext2_extent_handle_t handle)
+{
+	blk64_t				blk;
+	errcode_t			retval;
+	struct ext3_extent_idx		*ix;
+
+	if (handle->level == 0) {
+		retval = ext2fs_write_inode(handle->fs, handle->ino,
+					    handle->inode);
+	} else {
+		ix = handle->path[handle->level - 1].curr;
+		blk = ext2fs_le32_to_cpu(ix->ei_leaf) +
+			((__u64) ext2fs_le16_to_cpu(ix->ei_leaf_hi) << 32);
+
+		retval = io_channel_write_blk64(handle->fs->io,
+				      blk, 1, handle->path[handle->level].buf);
+	}
+	return retval;
+}
+
+#if 0
+errcode_t ext2fs_extent_save_path(ext2_extent_handle_t handle,
+				  ext2_extent_path_t *ret_path)
+{
+	ext2_extent_path_t	save_path;
+	struct ext2fs_extent	extent;
+	struct ext2_extent_info	info;
+	errcode_t		retval;
+
+	retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
+	if (retval)
+		return retval;
+
+	retval = ext2fs_extent_get_info(handle, &info);
+	if (retval)
+		return retval;
+
+	retval = ext2fs_get_mem(sizeof(struct ext2_extent_path), &save_path);
+	if (retval)
+		return retval;
+	memset(save_path, 0, sizeof(struct ext2_extent_path));
+
+	save_path->magic = EXT2_ET_MAGIC_EXTENT_PATH;
+	save_path->leaf_height = info.max_depth - info.curr_level - 1;
+	save_path->lblk = extent.e_lblk;
+
+	*ret_path = save_path;
+	return 0;
+}
+
+errcode_t ext2fs_extent_free_path(ext2_extent_path_t path)
+{
+	EXT2_CHECK_MAGIC(path, EXT2_ET_MAGIC_EXTENT_PATH);
+
+	ext2fs_free_mem(&path);
+	return 0;
+}
+#endif
+
+/*
+ * Go to the node at leaf_level which contains logical block blk.
+ *
+ * leaf_level is height from the leaf node level, i.e.
+ * leaf_level 0 is at leaf node, leaf_level 1 is 1 above etc.
+ *
+ * If "blk" has no mapping (hole) then handle is left at last
+ * extent before blk.
+ */
+errcode_t ext2fs_extent_goto2(ext2_extent_handle_t handle,
+			      int leaf_level, blk64_t blk)
+{
+	struct ext2fs_extent	extent;
+	errcode_t		retval;
+
+	retval = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent);
+	if (retval) {
+		if (retval == EXT2_ET_EXTENT_NO_NEXT)
+			retval = EXT2_ET_EXTENT_NOT_FOUND;
+		return retval;
+	}
+
+	if (leaf_level > handle->max_depth) {
+#ifdef DEBUG
+		printf("leaf level %d greater than tree depth %d\n",
+			leaf_level, handle->max_depth);
+#endif
+		return EXT2_ET_OP_NOT_SUPPORTED;
+	}
+
+#ifdef DEBUG
+	printf("goto extent ino %u, level %d, %llu\n", handle->ino,
+	       leaf_level, blk);
+#endif
+
+#ifdef DEBUG_GOTO_EXTENTS
+	dbg_print_extent("root", &extent);
+#endif
+	while (1) {
+		if (handle->max_depth - handle->level == leaf_level) {
+			/* block is in this &extent */
+			if ((blk >= extent.e_lblk) &&
+			    (blk < extent.e_lblk + extent.e_len))
+				return 0;
+			if (blk < extent.e_lblk) {
+				retval = ext2fs_extent_get(handle,
+							   EXT2_EXTENT_PREV_SIB,
+							   &extent);
+				return EXT2_ET_EXTENT_NOT_FOUND;
+			}
+			retval = ext2fs_extent_get(handle,
+						   EXT2_EXTENT_NEXT_SIB,
+						   &extent);
+			if (retval == EXT2_ET_EXTENT_NO_NEXT)
+				return EXT2_ET_EXTENT_NOT_FOUND;
+			if (retval)
+				return retval;
+			continue;
+		}
+
+		retval = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT_SIB,
+					   &extent);
+		if (retval == EXT2_ET_EXTENT_NO_NEXT)
+			goto go_down;
+		if (retval)
+			return retval;
+
+#ifdef DEBUG_GOTO_EXTENTS
+		dbg_print_extent("next", &extent);
+#endif
+		if (blk == extent.e_lblk)
+			goto go_down;
+		if (blk > extent.e_lblk)
+			continue;
+
+		retval = ext2fs_extent_get(handle, EXT2_EXTENT_PREV_SIB,
+					   &extent);
+		if (retval)
+			return retval;
+
+#ifdef DEBUG_GOTO_EXTENTS
+		dbg_print_extent("prev", &extent);
+#endif
+
+	go_down:
+		retval = ext2fs_extent_get(handle, EXT2_EXTENT_DOWN,
+					   &extent);
+		if (retval)
+			return retval;
+
+#ifdef DEBUG_GOTO_EXTENTS
+		dbg_print_extent("down", &extent);
+#endif
+	}
+}
+
+errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle,
+			     blk64_t blk)
+{
+	return ext2fs_extent_goto2(handle, 0, blk);
+}
+
+/*
+ * Traverse back up to root fixing parents of current node as needed.
+ *
+ * If we changed start of first entry in a node, fix parent index start
+ * and so on.
+ *
+ * Safe to call for any position in node; if not at the first entry,
+ * will  simply return.
+ */
+errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle)
+{
+	int				retval = 0;
+	int				orig_height;
+	blk64_t				start;
+	struct extent_path		*path;
+	struct ext2fs_extent		extent;
+	struct ext2_extent_info		info;
+
+	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
+
+	if (!(handle->fs->flags & EXT2_FLAG_RW))
+		return EXT2_ET_RO_FILSYS;
+
+	if (!handle->path)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+	path = handle->path + handle->level;
+	if (!path->curr)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+	retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
+	if (retval)
+		goto done;
+
+	/* modified node's start block */
+	start = extent.e_lblk;
+
+	if ((retval = ext2fs_extent_get_info(handle, &info)))
+		return retval;
+	orig_height = info.max_depth - info.curr_level;
+
+	/* traverse up until index not first, or startblk matches, or top */
+	while (handle->level > 0 &&
+	       (path->left == path->entries - 1)) {
+		retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP, &extent);
+		if (retval)
+			goto done;
+		if (extent.e_lblk == start)
+			break;
+		path = handle->path + handle->level;
+		extent.e_len += (extent.e_lblk - start);
+		extent.e_lblk = start;
+		retval = ext2fs_extent_replace(handle, 0, &extent);
+		if (retval)
+			goto done;
+		update_path(handle);
+	}
+
+	/* put handle back to where we started */
+	retval = ext2fs_extent_goto2(handle, orig_height, start);
+done:
+	return retval;
+}
+
+errcode_t ext2fs_extent_replace(ext2_extent_handle_t handle,
+				int flags EXT2FS_ATTR((unused)),
+				struct ext2fs_extent *extent)
+{
+	struct extent_path		*path;
+	struct ext3_extent_idx		*ix;
+	struct ext3_extent		*ex;
+
+	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
+
+	if (!(handle->fs->flags & EXT2_FLAG_RW))
+		return EXT2_ET_RO_FILSYS;
+
+	if (!handle->path)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+	path = handle->path + handle->level;
+	if (!path->curr)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+#ifdef DEBUG
+	printf("extent replace: %u ", handle->ino);
+	dbg_print_extent(0, extent);
+#endif
+
+	if (handle->level == handle->max_depth) {
+		ex = path->curr;
+
+		ex->ee_block = ext2fs_cpu_to_le32(extent->e_lblk);
+		ex->ee_start = ext2fs_cpu_to_le32(extent->e_pblk & 0xFFFFFFFF);
+		ex->ee_start_hi = ext2fs_cpu_to_le16(extent->e_pblk >> 32);
+		if (extent->e_flags & EXT2_EXTENT_FLAGS_UNINIT) {
+			if (extent->e_len > EXT_UNINIT_MAX_LEN)
+				return EXT2_ET_EXTENT_INVALID_LENGTH;
+			ex->ee_len = ext2fs_cpu_to_le16(extent->e_len +
+							EXT_INIT_MAX_LEN);
+		} else {
+			if (extent->e_len > EXT_INIT_MAX_LEN)
+				return EXT2_ET_EXTENT_INVALID_LENGTH;
+			ex->ee_len = ext2fs_cpu_to_le16(extent->e_len);
+		}
+	} else {
+		ix = path->curr;
+
+		ix->ei_leaf = ext2fs_cpu_to_le32(extent->e_pblk & 0xFFFFFFFF);
+		ix->ei_leaf_hi = ext2fs_cpu_to_le16(extent->e_pblk >> 32);
+		ix->ei_block = ext2fs_cpu_to_le32(extent->e_lblk);
+		ix->ei_unused = 0;
+	}
+	update_path(handle);
+	return 0;
+}
+
+/*
+ * allocate a new block, move half the current node to it, and update parent
+ *
+ * handle will be left pointing at original record.
+ */
+errcode_t ext2fs_extent_node_split(ext2_extent_handle_t handle)
+{
+	errcode_t			retval = 0;
+	blk64_t				new_node_pblk;
+	blk64_t				new_node_start;
+	blk64_t				orig_lblk;
+	blk64_t				goal_blk = 0;
+	int				orig_height;
+	char				*block_buf = NULL;
+	struct ext2fs_extent		extent;
+	struct extent_path		*path, *newpath = 0;
+	struct ext3_extent_header	*eh, *neweh;
+	int				tocopy;
+	int				new_root = 0;
+	struct ext2_extent_info		info;
+
+	/* basic sanity */
+	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
+
+	if (!(handle->fs->flags & EXT2_FLAG_RW))
+		return EXT2_ET_RO_FILSYS;
+
+	if (!handle->path)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+#ifdef DEBUG
+	printf("splitting node at level %d\n", handle->level);
+#endif
+	retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
+	if (retval)
+		goto done;
+
+	retval = ext2fs_extent_get_info(handle, &info);
+	if (retval)
+		goto done;
+
+	/* save the position we were originally splitting... */
+	orig_height = info.max_depth - info.curr_level;
+	orig_lblk = extent.e_lblk;
+
+	/* Is there room in the parent for a new entry? */
+	if (handle->level &&
+			(handle->path[handle->level - 1].entries >=
+			 handle->path[handle->level - 1].max_entries)) {
+
+#ifdef DEBUG
+		printf("parent level %d full; splitting it too\n",
+							handle->level - 1);
+#endif
+		/* split the parent */
+		retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP, &extent);
+		if (retval)
+			goto done;
+		goal_blk = extent.e_pblk;
+
+		retval = ext2fs_extent_node_split(handle);
+		if (retval)
+			goto done;
+
+		/* get handle back to our original split position */
+		retval = ext2fs_extent_goto2(handle, orig_height, orig_lblk);
+		if (retval)
+			goto done;
+	}
+
+	/* At this point, parent should have room for this split */
+	path = handle->path + handle->level;
+	if (!path->curr)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+	/* extent header of the current node we'll split */
+	eh = (struct ext3_extent_header *)path->buf;
+
+	/* splitting root level means moving them all out */
+	if (handle->level == 0) {
+		new_root = 1;
+		tocopy = ext2fs_le16_to_cpu(eh->eh_entries);
+		retval = ext2fs_get_mem(((handle->max_depth+2) *
+					 sizeof(struct extent_path)),
+					&newpath);
+		if (retval)
+			goto done;
+		memset(newpath, 0,
+		       ((handle->max_depth+2) * sizeof(struct extent_path)));
+	} else {
+		tocopy = ext2fs_le16_to_cpu(eh->eh_entries) / 2;
+	}
+
+#ifdef DEBUG
+	printf("will copy out %d of %d entries at level %d\n",
+				tocopy, ext2fs_le16_to_cpu(eh->eh_entries),
+				handle->level);
+#endif
+
+	if (!tocopy) {
+#ifdef DEBUG
+		printf("Nothing to copy to new block!\n");
+#endif
+		retval = EXT2_ET_CANT_SPLIT_EXTENT;
+		goto done;
+	}
+
+	/* first we need a new block, or can do nothing. */
+	block_buf = malloc(handle->fs->blocksize);
+	if (!block_buf) {
+		retval = ENOMEM;
+		goto done;
+	}
+
+	if (!goal_blk) {
+		dgrp_t	group = ext2fs_group_of_ino(handle->fs, handle->ino);
+		__u8	log_flex = handle->fs->super->s_log_groups_per_flex;
+
+		if (log_flex)
+			group = group & ~((1 << (log_flex)) - 1);
+		goal_blk = ext2fs_group_first_block2(handle->fs, group);
+	}
+	retval = ext2fs_alloc_block2(handle->fs, goal_blk, block_buf,
+				    &new_node_pblk);
+	if (retval)
+		goto done;
+
+#ifdef DEBUG
+	printf("will copy to new node at block %lu\n",
+	       (unsigned long) new_node_pblk);
+#endif
+
+	/* Copy data into new block buffer */
+	/* First the header for the new block... */
+	neweh = (struct ext3_extent_header *) block_buf;
+	memcpy(neweh, eh, sizeof(struct ext3_extent_header));
+	neweh->eh_entries = ext2fs_cpu_to_le16(tocopy);
+	neweh->eh_max = ext2fs_cpu_to_le16((handle->fs->blocksize -
+			 sizeof(struct ext3_extent_header)) /
+				sizeof(struct ext3_extent));
+
+	/* then the entries for the new block... */
+	memcpy(EXT_FIRST_INDEX(neweh),
+		EXT_FIRST_INDEX(eh) +
+			(ext2fs_le16_to_cpu(eh->eh_entries) - tocopy),
+		sizeof(struct ext3_extent_idx) * tocopy);
+
+	new_node_start = ext2fs_le32_to_cpu(EXT_FIRST_INDEX(neweh)->ei_block);
+
+	/* ...and write the new node block out to disk. */
+	retval = io_channel_write_blk64(handle->fs->io, new_node_pblk, 1,
+					block_buf);
+
+	if (retval)
+		goto done;
+
+	/* OK! we've created the new node; now adjust the tree */
+
+	/* current path now has fewer active entries, we copied some out */
+	if (handle->level == 0) {
+		memcpy(newpath, path,
+		       sizeof(struct extent_path) * (handle->max_depth+1));
+		handle->path = newpath;
+		newpath = path;
+		path = handle->path;
+		path->entries = 1;
+		path->left = path->max_entries - 1;
+		handle->max_depth++;
+		eh->eh_depth = ext2fs_cpu_to_le16(handle->max_depth);
+	} else {
+		path->entries -= tocopy;
+		path->left -= tocopy;
+	}
+
+	eh->eh_entries = ext2fs_cpu_to_le16(path->entries);
+	/* this writes out the node, incl. the modified header */
+	retval = update_path(handle);
+	if (retval)
+		goto done;
+
+	/* now go up and insert/replace index for new node we created */
+	if (new_root) {
+		retval = ext2fs_extent_get(handle, EXT2_EXTENT_FIRST_SIB, &extent);
+		if (retval)
+			goto done;
+
+		extent.e_lblk = new_node_start;
+		extent.e_pblk = new_node_pblk;
+		extent.e_len = handle->path[0].end_blk - extent.e_lblk;
+		retval = ext2fs_extent_replace(handle, 0, &extent);
+		if (retval)
+			goto done;
+	} else {
+		__u32 new_node_length;
+
+		retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP, &extent);
+		/* will insert after this one; it's length is shorter now */
+		new_node_length = new_node_start - extent.e_lblk;
+		extent.e_len -= new_node_length;
+		retval = ext2fs_extent_replace(handle, 0, &extent);
+		if (retval)
+			goto done;
+
+		/* now set up the new extent and insert it */
+		extent.e_lblk = new_node_start;
+		extent.e_pblk = new_node_pblk;
+		extent.e_len = new_node_length;
+		retval = ext2fs_extent_insert(handle, EXT2_EXTENT_INSERT_AFTER, &extent);
+		if (retval)
+			goto done;
+	}
+
+	/* get handle back to our original position */
+	retval = ext2fs_extent_goto2(handle, orig_height, orig_lblk);
+	if (retval)
+		goto done;
+
+	/* new node hooked in, so update inode block count (do this here?) */
+	handle->inode->i_blocks += (handle->fs->blocksize *
+				    EXT2FS_CLUSTER_RATIO(handle->fs)) / 512;
+	retval = ext2fs_write_inode(handle->fs, handle->ino,
+				    handle->inode);
+	if (retval)
+		goto done;
+
+done:
+	if (newpath)
+		ext2fs_free_mem(&newpath);
+	free(block_buf);
+
+	return retval;
+}
+
+errcode_t ext2fs_extent_insert(ext2_extent_handle_t handle, int flags,
+				      struct ext2fs_extent *extent)
+{
+	struct extent_path		*path;
+	struct ext3_extent_idx		*ix;
+	struct ext3_extent_header	*eh;
+	errcode_t			retval;
+
+	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
+
+	if (!(handle->fs->flags & EXT2_FLAG_RW))
+		return EXT2_ET_RO_FILSYS;
+
+	if (!handle->path)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+#ifdef DEBUG
+	printf("extent insert: %u ", handle->ino);
+	dbg_print_extent(0, extent);
+#endif
+
+	path = handle->path + handle->level;
+
+	if (path->entries >= path->max_entries) {
+		if (flags & EXT2_EXTENT_INSERT_NOSPLIT) {
+			return EXT2_ET_CANT_INSERT_EXTENT;
+		} else {
+#ifdef DEBUG
+			printf("node full (level %d) - splitting\n",
+				   handle->level);
+#endif
+			retval = ext2fs_extent_node_split(handle);
+			if (retval)
+				return retval;
+			path = handle->path + handle->level;
+		}
+	}
+
+	eh = (struct ext3_extent_header *) path->buf;
+	if (path->curr) {
+		ix = path->curr;
+		if (flags & EXT2_EXTENT_INSERT_AFTER) {
+			ix++;
+			path->left--;
+		}
+	} else
+		ix = EXT_FIRST_INDEX(eh);
+
+	path->curr = ix;
+
+	if (path->left >= 0)
+		memmove(ix + 1, ix,
+			(path->left+1) * sizeof(struct ext3_extent_idx));
+	path->left++;
+	path->entries++;
+
+	eh = (struct ext3_extent_header *) path->buf;
+	eh->eh_entries = ext2fs_cpu_to_le16(path->entries);
+
+	retval = ext2fs_extent_replace(handle, 0, extent);
+	if (retval)
+		goto errout;
+
+	retval = update_path(handle);
+	if (retval)
+		goto errout;
+
+	return 0;
+
+errout:
+	ext2fs_extent_delete(handle, 0);
+	return retval;
+}
+
+/*
+ * Sets the physical block for a logical file block in the extent tree.
+ *
+ * May: map unmapped, unmap mapped, or remap mapped blocks.
+ *
+ * Mapping an unmapped block adds a single-block extent.
+ *
+ * Unmapping first or last block modifies extent in-place
+ *  - But may need to fix parent's starts too in first-block case
+ *
+ * Mapping any unmapped block requires adding a (single-block) extent
+ * and inserting into proper point in tree.
+ *
+ * Modifying (unmapping or remapping) a block in the middle
+ * of an extent requires splitting the extent.
+ *  - Remapping case requires new single-block extent.
+ *
+ * Remapping first or last block adds an extent.
+ *
+ * We really need extent adding to be smart about merging.
+ */
+
+errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
+				 blk64_t logical, blk64_t physical, int flags)
+{
+	errcode_t		ec, retval = 0;
+	int			mapped = 1; /* logical is mapped? */
+	int			orig_height;
+	int			extent_uninit = 0;
+	int			prev_uninit = 0;
+	int			next_uninit = 0;
+	int			new_uninit = 0;
+	int			max_len = EXT_INIT_MAX_LEN;
+	int			has_prev, has_next;
+	blk64_t			orig_lblk;
+	struct extent_path	*path;
+	struct ext2fs_extent	extent, next_extent, prev_extent;
+	struct ext2fs_extent	newextent;
+	struct ext2_extent_info	info;
+
+	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
+
+#ifdef DEBUG
+	printf("set_bmap ino %u log %lld phys %lld flags %d\n",
+	       handle->ino, logical, physical, flags);
+#endif
+
+	if (!(handle->fs->flags & EXT2_FLAG_RW))
+		return EXT2_ET_RO_FILSYS;
+
+	if (!handle->path)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+	path = handle->path + handle->level;
+
+	if (flags & EXT2_EXTENT_SET_BMAP_UNINIT) {
+		new_uninit = 1;
+		max_len = EXT_UNINIT_MAX_LEN;
+	}
+
+	/* if (re)mapping, set up new extent to insert */
+	if (physical) {
+		newextent.e_len = 1;
+		newextent.e_pblk = physical;
+		newextent.e_lblk = logical;
+		newextent.e_flags = EXT2_EXTENT_FLAGS_LEAF;
+		if (new_uninit)
+			newextent.e_flags |= EXT2_EXTENT_FLAGS_UNINIT;
+	}
+
+	/* special case if the extent tree is completely empty */
+	if ((handle->max_depth == 0) && (path->entries == 0)) {
+		retval = ext2fs_extent_insert(handle, 0, &newextent);
+		return retval;
+	}
+
+	/* save our original location in the extent tree */
+	if ((retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT,
+					&extent))) {
+		if (retval != EXT2_ET_NO_CURRENT_NODE)
+			return retval;
+		memset(&extent, 0, sizeof(extent));
+	}
+	if ((retval = ext2fs_extent_get_info(handle, &info)))
+		return retval;
+	orig_height = info.max_depth - info.curr_level;
+	orig_lblk = extent.e_lblk;
+
+	/* go to the logical spot we want to (re/un)map */
+	retval = ext2fs_extent_goto(handle, logical);
+	if (retval) {
+		if (retval == EXT2_ET_EXTENT_NOT_FOUND) {
+			retval = 0;
+			mapped = 0;
+			if (!physical) {
+#ifdef DEBUG
+				printf("block %llu already unmapped\n",
+					logical);
+#endif
+				goto done;
+			}
+		} else
+			goto done;
+	}
+
+	/*
+	 * This may be the extent *before* the requested logical,
+	 * if it's currently unmapped.
+	 *
+	 * Get the previous and next leaf extents, if they are present.
+	 */
+	retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
+	if (retval)
+		goto done;
+	if (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
+		extent_uninit = 1;
+	retval = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT_LEAF, &next_extent);
+	if (retval) {
+		has_next = 0;
+		if (retval != EXT2_ET_EXTENT_NO_NEXT)
+			goto done;
+	} else {
+		dbg_print_extent("set_bmap: next_extent",
+				 &next_extent);
+		has_next = 1;
+		if (next_extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
+			next_uninit = 1;
+	}
+	retval = ext2fs_extent_goto(handle, logical);
+	if (retval && retval != EXT2_ET_EXTENT_NOT_FOUND)
+		goto done;
+	retval = ext2fs_extent_get(handle, EXT2_EXTENT_PREV_LEAF, &prev_extent);
+	if (retval) {
+		has_prev = 0;
+		if (retval != EXT2_ET_EXTENT_NO_PREV)
+			goto done;
+	} else {
+		has_prev = 1;
+		dbg_print_extent("set_bmap: prev_extent",
+				 &prev_extent);
+		if (prev_extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
+			prev_uninit = 1;
+	}
+	retval = ext2fs_extent_goto(handle, logical);
+	if (retval && retval != EXT2_ET_EXTENT_NOT_FOUND)
+		goto done;
+
+	/* check if already pointing to the requested physical */
+	if (mapped && (new_uninit == extent_uninit) &&
+	    (extent.e_pblk + (logical - extent.e_lblk) == physical)) {
+#ifdef DEBUG
+		printf("physical block (at %llu) unchanged\n", logical);
+#endif
+		goto done;
+	}
+
+	if (!mapped) {
+#ifdef DEBUG
+		printf("mapping unmapped logical block %llu\n", logical);
+#endif
+		if ((logical == extent.e_lblk + extent.e_len) &&
+		    (physical == extent.e_pblk + extent.e_len) &&
+		    (new_uninit == extent_uninit) &&
+		    ((int) extent.e_len < max_len-1)) {
+			extent.e_len++;
+			retval = ext2fs_extent_replace(handle, 0, &extent);
+		} else if ((logical == extent.e_lblk - 1) &&
+			   (physical == extent.e_pblk - 1) &&
+			   (new_uninit == extent_uninit) &&
+			   ((int) extent.e_len < max_len - 1)) {
+			extent.e_len++;
+			extent.e_lblk--;
+			extent.e_pblk--;
+			retval = ext2fs_extent_replace(handle, 0, &extent);
+		} else if (has_next &&
+			   (logical == next_extent.e_lblk - 1) &&
+			   (physical == next_extent.e_pblk - 1) &&
+			   (new_uninit == next_uninit) &&
+			   ((int) next_extent.e_len < max_len - 1)) {
+			retval = ext2fs_extent_get(handle,
+						   EXT2_EXTENT_NEXT_LEAF,
+						   &next_extent);
+			if (retval)
+				goto done;
+			next_extent.e_len++;
+			next_extent.e_lblk--;
+			next_extent.e_pblk--;
+			retval = ext2fs_extent_replace(handle, 0, &next_extent);
+		} else if (logical < extent.e_lblk)
+			retval = ext2fs_extent_insert(handle, 0, &newextent);
+		else
+			retval = ext2fs_extent_insert(handle,
+				      EXT2_EXTENT_INSERT_AFTER, &newextent);
+		if (retval)
+			goto done;
+		retval = ext2fs_extent_fix_parents(handle);
+		if (retval)
+			goto done;
+	} else if ((logical == extent.e_lblk) && (extent.e_len == 1))  {
+#ifdef DEBUG
+		printf("(re/un)mapping only block in extent\n");
+#endif
+		if (physical) {
+			retval = ext2fs_extent_replace(handle, 0, &newextent);
+		} else {
+			retval = ext2fs_extent_delete(handle, 0);
+			if (retval)
+				goto done;
+			ec = ext2fs_extent_fix_parents(handle);
+			if (ec != EXT2_ET_NO_CURRENT_NODE)
+				retval = ec;
+		}
+
+		if (retval)
+			goto done;
+	} else if (logical == extent.e_lblk + extent.e_len - 1)  {
+#ifdef DEBUG
+		printf("(re/un)mapping last block in extent\n");
+#endif
+		if (physical) {
+			if (has_next &&
+			    (logical == (next_extent.e_lblk - 1)) &&
+			    (physical == (next_extent.e_pblk - 1)) &&
+			    (new_uninit == next_uninit) &&
+			    ((int) next_extent.e_len < max_len - 1)) {
+				retval = ext2fs_extent_get(handle,
+					EXT2_EXTENT_NEXT_LEAF, &next_extent);
+				if (retval)
+					goto done;
+				next_extent.e_len++;
+				next_extent.e_lblk--;
+				next_extent.e_pblk--;
+				retval = ext2fs_extent_replace(handle, 0,
+							       &next_extent);
+				if (retval)
+					goto done;
+				retval = ext2fs_extent_fix_parents(handle);
+				if (retval)
+					goto done;
+			} else
+				retval = ext2fs_extent_insert(handle,
+				      EXT2_EXTENT_INSERT_AFTER, &newextent);
+			if (retval)
+				goto done;
+			/* Now pointing at inserted extent; move back to prev */
+			retval = ext2fs_extent_get(handle,
+						   EXT2_EXTENT_PREV_LEAF,
+						   &extent);
+			if (retval)
+				goto done;
+		}
+		extent.e_len--;
+		retval = ext2fs_extent_replace(handle, 0, &extent);
+		if (retval)
+			goto done;
+	} else if (logical == extent.e_lblk) {
+#ifdef DEBUG
+		printf("(re/un)mapping first block in extent\n");
+#endif
+		if (physical) {
+			if (has_prev &&
+			    (logical == (prev_extent.e_lblk +
+					 prev_extent.e_len)) &&
+			    (physical == (prev_extent.e_pblk +
+					  prev_extent.e_len)) &&
+			    (new_uninit == prev_uninit) &&
+			    ((int) prev_extent.e_len < max_len-1)) {
+				retval = ext2fs_extent_get(handle, 
+					EXT2_EXTENT_PREV_LEAF, &prev_extent);
+				if (retval)
+					goto done;
+				prev_extent.e_len++;
+				retval = ext2fs_extent_replace(handle, 0,
+							       &prev_extent);
+			} else
+				retval = ext2fs_extent_insert(handle,
+							      0, &newextent);
+			if (retval)
+				goto done;
+			retval = ext2fs_extent_get(handle,
+						   EXT2_EXTENT_NEXT_LEAF,
+						   &extent);
+			if (retval)
+				goto done;
+		}
+		extent.e_pblk++;
+		extent.e_lblk++;
+		extent.e_len--;
+		retval = ext2fs_extent_replace(handle, 0, &extent);
+		if (retval)
+			goto done;
+		retval = ext2fs_extent_fix_parents(handle);
+		if (retval)
+			goto done;
+	} else {
+		__u32	orig_length;
+
+#ifdef DEBUG
+		printf("(re/un)mapping in middle of extent\n");
+#endif
+		/* need to split this extent; later */
+
+		orig_length = extent.e_len;
+
+		/* shorten pre-split extent */
+		extent.e_len = (logical - extent.e_lblk);
+		retval = ext2fs_extent_replace(handle, 0, &extent);
+		if (retval)
+			goto done;
+		/* insert our new extent, if any */
+		if (physical) {
+			/* insert new extent after current */
+			retval = ext2fs_extent_insert(handle,
+					EXT2_EXTENT_INSERT_AFTER, &newextent);
+			if (retval)
+				goto done;
+		}
+		/* add post-split extent */
+		extent.e_pblk += extent.e_len + 1;
+		extent.e_lblk += extent.e_len + 1;
+		extent.e_len = orig_length - extent.e_len - 1;
+		retval = ext2fs_extent_insert(handle,
+				EXT2_EXTENT_INSERT_AFTER, &extent);
+		if (retval)
+			goto done;
+	}
+
+done:
+	/* get handle back to its position */
+	if (orig_height > handle->max_depth)
+		orig_height = handle->max_depth; /* In case we shortened the tree */
+	ext2fs_extent_goto2(handle, orig_height, orig_lblk);
+	return retval;
+}
+
+errcode_t ext2fs_extent_delete(ext2_extent_handle_t handle, int flags)
+{
+	struct extent_path		*path;
+	char 				*cp;
+	struct ext3_extent_header	*eh;
+	errcode_t			retval = 0;
+
+	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
+
+	if (!(handle->fs->flags & EXT2_FLAG_RW))
+		return EXT2_ET_RO_FILSYS;
+
+	if (!handle->path)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+#ifdef DEBUG
+	{
+		struct ext2fs_extent	extent;
+
+		retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT,
+					   &extent);
+		if (retval == 0) {
+			printf("extent delete %u ", handle->ino);
+			dbg_print_extent(0, &extent);
+		}
+	}
+#endif
+
+	path = handle->path + handle->level;
+	if (!path->curr)
+		return EXT2_ET_NO_CURRENT_NODE;
+
+	cp = path->curr;
+
+	if (path->left) {
+		memmove(cp, cp + sizeof(struct ext3_extent_idx),
+			path->left * sizeof(struct ext3_extent_idx));
+		path->left--;
+	} else {
+		struct ext3_extent_idx	*ix = path->curr;
+		ix--;
+		path->curr = ix;
+	}
+	if (--path->entries == 0)
+		path->curr = 0;
+
+	/* if non-root node has no entries left, remove it & parent ptr to it */
+	if (path->entries == 0 && handle->level) {
+		if (!(flags & EXT2_EXTENT_DELETE_KEEP_EMPTY)) {
+			struct ext2fs_extent	extent;
+
+			retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP,
+								&extent);
+			if (retval)
+				return retval;
+
+			retval = ext2fs_extent_delete(handle, flags);
+			handle->inode->i_blocks -=
+				(handle->fs->blocksize *
+				 EXT2FS_CLUSTER_RATIO(handle->fs)) / 512;
+			retval = ext2fs_write_inode(handle->fs, handle->ino,
+						    handle->inode);
+			ext2fs_block_alloc_stats2(handle->fs,
+						  extent.e_pblk, -1);
+		}
+	} else {
+		eh = (struct ext3_extent_header *) path->buf;
+		eh->eh_entries = ext2fs_cpu_to_le16(path->entries);
+		if ((path->entries == 0) && (handle->level == 0))
+			eh->eh_depth = handle->max_depth = 0;
+		retval = update_path(handle);
+	}
+	return retval;
+}
+
+errcode_t ext2fs_extent_get_info(ext2_extent_handle_t handle,
+				 struct ext2_extent_info *info)
+{
+	struct extent_path		*path;
+
+	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
+
+	memset(info, 0, sizeof(struct ext2_extent_info));
+
+	path = handle->path + handle->level;
+	if (path) {
+		if (path->curr)
+			info->curr_entry = ((char *) path->curr - path->buf) /
+				sizeof(struct ext3_extent_idx);
+		else
+			info->curr_entry = 0;
+		info->num_entries = path->entries;
+		info->max_entries = path->max_entries;
+		info->bytes_avail = (path->max_entries - path->entries) *
+			sizeof(struct ext3_extent);
+	}
+
+	info->curr_level = handle->level;
+	info->max_depth = handle->max_depth;
+	info->max_lblk = ((__u64) 1 << 32) - 1;
+	info->max_pblk = ((__u64) 1 << 48) - 1;
+	info->max_len = (1UL << 15);
+	info->max_uninit_len = (1UL << 15) - 1;
+
+	return 0;
+}
+
+#ifdef DEBUG
+/*
+ * Override debugfs's prompt
+ */
+const char *debug_prog_name = "tst_extents";
+
+#endif
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/fiemap.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/fiemap.h
new file mode 100644
index 0000000..30bf555
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/fiemap.h
@@ -0,0 +1,68 @@
+/*
+ * FS_IOC_FIEMAP ioctl infrastructure.
+ *
+ * Some portions copyright (C) 2007 Cluster File Systems, Inc
+ *
+ * Authors: Mark Fasheh <mfasheh@suse.com>
+ *          Kalpak Shah <kalpak.shah@sun.com>
+ *          Andreas Dilger <adilger@sun.com>
+ */
+
+#ifndef _LINUX_FIEMAP_H
+#define _LINUX_FIEMAP_H
+
+struct fiemap_extent {
+	__u64 fe_logical;  /* logical offset in bytes for the start of
+			    * the extent from the beginning of the file */
+	__u64 fe_physical; /* physical offset in bytes for the start
+			    * of the extent from the beginning of the disk */
+	__u64 fe_length;   /* length in bytes for this extent */
+	__u64 fe_reserved64[2];
+	__u32 fe_flags;    /* FIEMAP_EXTENT_* flags for this extent */
+	__u32 fe_reserved[3];
+};
+
+struct fiemap {
+	__u64 fm_start;		/* logical offset (inclusive) at
+				 * which to start mapping (in) */
+	__u64 fm_length;	/* logical length of mapping which
+				 * userspace wants (in) */
+	__u32 fm_flags;		/* FIEMAP_FLAG_* flags for request (in/out) */
+	__u32 fm_mapped_extents;/* number of extents that were mapped (out) */
+	__u32 fm_extent_count;  /* size of fm_extents array (in) */
+	__u32 fm_reserved;
+	struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */
+};
+
+#ifndef FS_IOC_FIEMAP
+#define FS_IOC_FIEMAP	_IOWR('f', 11, struct fiemap)
+#endif
+
+#define FIEMAP_MAX_OFFSET	(~0ULL)
+
+#define FIEMAP_FLAG_SYNC	0x00000001 /* sync file data before map */
+#define FIEMAP_FLAG_XATTR	0x00000002 /* map extended attribute tree */
+
+#define FIEMAP_FLAGS_COMPAT	(FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR)
+
+#define FIEMAP_EXTENT_LAST		0x00000001 /* Last extent in file. */
+#define FIEMAP_EXTENT_UNKNOWN		0x00000002 /* Data location unknown. */
+#define FIEMAP_EXTENT_DELALLOC		0x00000004 /* Location still pending.
+						    * Sets EXTENT_UNKNOWN. */
+#define FIEMAP_EXTENT_ENCODED		0x00000008 /* Data can not be read
+						    * while fs is unmounted */
+#define FIEMAP_EXTENT_DATA_ENCRYPTED	0x00000080 /* Data is encrypted by fs.
+						    * Sets EXTENT_NO_BYPASS. */
+#define FIEMAP_EXTENT_NOT_ALIGNED	0x00000100 /* Extent offsets may not be
+						    * block aligned. */
+#define FIEMAP_EXTENT_DATA_INLINE	0x00000200 /* Data mixed with metadata.
+						    * Sets EXTENT_NOT_ALIGNED.*/
+#define FIEMAP_EXTENT_DATA_TAIL		0x00000400 /* Multiple files in block.
+						    * Sets EXTENT_NOT_ALIGNED.*/
+#define FIEMAP_EXTENT_UNWRITTEN		0x00000800 /* Space allocated, but
+						    * no data (i.e. zero). */
+#define FIEMAP_EXTENT_MERGED		0x00001000 /* File does not natively
+						    * support extents. Result
+						    * merged for efficiency. */
+
+#endif /* _LINUX_FIEMAP_H */
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/fileio.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/fileio.c
new file mode 100644
index 0000000..5a39c32
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/fileio.c
@@ -0,0 +1,499 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+#include "ext2fsP.h"
+
+struct ext2_file {
+	errcode_t		magic;
+	ext2_filsys 		fs;
+	ext2_ino_t		ino;
+	struct ext2_inode	inode;
+	int 			flags;
+	__u64			pos;
+	blk64_t			blockno;
+	blk64_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_array(3, fs->blocksize, &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 returns the pointer to the inode of a file from the structure
+ */
+struct ext2_inode *ext2fs_file_get_inode(ext2_file_t file)
+{
+	if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
+		return NULL;
+	return &file->inode;
+}
+
+/* This function returns the inode number from the structure */
+ext2_ino_t ext2fs_file_get_inode_num(ext2_file_t file)
+{
+	if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
+		return 0;
+	return file->ino;
+}
+
+/*
+ * 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_bmap2(fs, file->ino, &file->inode,
+				     BMAP_BUFFER, file->ino ? BMAP_ALLOC : 0,
+				     file->blockno, 0, &file->physblock);
+		if (retval)
+			return retval;
+	}
+
+	retval = io_channel_write_blk64(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)
+{
+	blk64_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_bmap2(fs, file->ino, &file->inode,
+				     BMAP_BUFFER, 0, file->blockno, 0,
+				     &file->physblock);
+		if (retval)
+			return retval;
+		if (!dontfill) {
+			if (file->physblock) {
+				retval = io_channel_read_blk64(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;
+
+		/*
+		 * OK, the physical block hasn't been allocated yet.
+		 * Allocate it.
+		 */
+		if (!file->physblock) {
+			retval = ext2fs_bmap2(fs, file->ino, &file->inode,
+					      BMAP_BUFFER,
+					      file->ino ? BMAP_ALLOC : 0,
+					      file->blockno, 0,
+					      &file->physblock);
+			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:
+	/* Update inode size */
+	if (count != 0 && EXT2_I_SIZE(&file->inode) < file->pos) {
+		errcode_t	rc;
+
+		rc = ext2fs_file_set_size2(file, file->pos);
+		if (retval == 0)
+			retval = rc;
+	}
+
+	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;
+}
+
+/* Zero the parts of the last block that are past EOF. */
+static errcode_t ext2fs_file_zero_past_offset(ext2_file_t file,
+					      ext2_off64_t offset)
+{
+	ext2_filsys fs = file->fs;
+	char *b = NULL;
+	ext2_off64_t off = offset % fs->blocksize;
+	blk64_t blk;
+	int ret_flags;
+	errcode_t retval;
+
+	if (off == 0)
+		return 0;
+
+	retval = sync_buffer_position(file);
+	if (retval)
+		return retval;
+
+	/* Is there an initialized block at the end? */
+	retval = ext2fs_bmap2(fs, file->ino, NULL, NULL, 0,
+			      offset / fs->blocksize, &ret_flags, &blk);
+	if (retval)
+		return retval;
+	if ((blk == 0) || (ret_flags & BMAP_RET_UNINIT))
+		return 0;
+
+	/* Zero to the end of the block */
+	retval = ext2fs_get_mem(fs->blocksize, &b);
+	if (retval)
+		return retval;
+
+	/* Read/zero/write block */
+	retval = io_channel_read_blk64(fs->io, blk, 1, b);
+	if (retval)
+		goto out;
+
+	memset(b + off, 0, fs->blocksize - off);
+
+	retval = io_channel_write_blk64(fs->io, blk, 1, b);
+	if (retval)
+		goto out;
+
+out:
+	ext2fs_free_mem(&b);
+	return retval;
+}
+
+/*
+ * This function sets the size of the file, truncating it if necessary
+ *
+ */
+errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size)
+{
+	ext2_off64_t	old_size;
+	errcode_t	retval;
+	blk64_t		old_truncate, truncate_block;
+
+	EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
+
+	if (size && ext2fs_file_block_offset_too_big(file->fs, &file->inode,
+					(size - 1) / file->fs->blocksize))
+		return EXT2_ET_FILE_TOO_BIG;
+	truncate_block = ((size + file->fs->blocksize - 1) >>
+			  EXT2_BLOCK_SIZE_BITS(file->fs->super));
+	old_size = EXT2_I_SIZE(&file->inode);
+	old_truncate = ((old_size + file->fs->blocksize - 1) >>
+		      EXT2_BLOCK_SIZE_BITS(file->fs->super));
+
+	/* If we're writing a large file, set the large_file flag */
+	if (LINUX_S_ISREG(file->inode.i_mode) &&
+	    ext2fs_needs_large_file_feature(EXT2_I_SIZE(&file->inode)) &&
+	    (!EXT2_HAS_RO_COMPAT_FEATURE(file->fs->super,
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ||
+	     file->fs->super->s_rev_level == EXT2_GOOD_OLD_REV)) {
+		file->fs->super->s_feature_ro_compat |=
+				EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
+		ext2fs_update_dynamic_rev(file->fs);
+		ext2fs_mark_super_dirty(file->fs);
+	}
+
+	file->inode.i_size = size & 0xffffffff;
+	file->inode.i_size_high = (size >> 32);
+	if (file->ino) {
+		retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
+		if (retval)
+			return retval;
+	}
+
+	retval = ext2fs_file_zero_past_offset(file, size);
+	if (retval)
+		return retval;
+
+	if (truncate_block >= old_truncate)
+		return 0;
+
+	return ext2fs_punch(file->fs, file->ino, &file->inode, 0,
+			    truncate_block, ~0ULL);
+}
+
+errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size)
+{
+	return ext2fs_file_set_size2(file, size);
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/finddev.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/finddev.c
new file mode 100644
index 0000000..311608d
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/finddev.c
@@ -0,0 +1,214 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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"
+#include "ext2fsP.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;
+	int    level = 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;
+			/* Avoid infinite loop */
+			if (++level >= EXT2FS_MAX_NESTED_LINKS)
+				break;
+		}
+	}
+	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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/flushb.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/flushb.c
new file mode 100644
index 0000000..98821fc
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/flushb.c
@@ -0,0 +1,79 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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;
+#elif defined(__linux__)
+#warning BLKFLSBUF not defined
+#endif
+#ifdef FDFLUSH
+		return ioctl(fd, FDFLUSH, 0);   /* In case this is a floppy */
+#elif defined(__linux__)
+#warning FDFLUSH not defined
+#endif
+	}
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/freefs.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/freefs.c
new file mode 100644
index 0000000..1ad2d91
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/freefs.c
@@ -0,0 +1,120 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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->image_header)
+		ext2fs_free_mem(&fs->image_header);
+
+	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);
+
+	if (fs->mmp_buf)
+		ext2fs_free_mem(&fs->mmp_buf);
+	if (fs->mmp_cmp)
+		ext2fs_free_mem(&fs->mmp_cmp);
+
+	fs->magic = 0;
+
+	ext2fs_free_mem(&fs);
+}
+
+/*
+ * 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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/gen_bitmap.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/gen_bitmap.c
new file mode 100644
index 0000000..0bff854
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/gen_bitmap.c
@@ -0,0 +1,585 @@
+/*
+ * gen_bitmap.c --- Generic (32-bit) bitmap routines
+ *
+ * Copyright (C) 2001 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+
+#include "config.h"
+#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"
+
+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_IS_32_BITMAP(bmap) \
+	(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \
+	 ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \
+	 ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP))
+
+#define EXT2FS_IS_64_BITMAP(bmap) \
+	(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP64) || \
+	 ((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP64) || \
+	 ((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP64))
+
+/*
+ * Used by previously inlined function, so we have to export this and
+ * not change the function signature
+ */
+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
+}
+
+static errcode_t check_magic(ext2fs_generic_bitmap bitmap)
+{
+	if (!bitmap || !((bitmap->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) ||
+			 (bitmap->magic == EXT2_ET_MAGIC_INODE_BITMAP) ||
+			 (bitmap->magic == EXT2_ET_MAGIC_BLOCK_BITMAP)))
+		return EXT2_ET_MAGIC_GENERIC_BITMAP;
+	return 0;
+}
+
+errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
+				     __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 = magic;
+	bitmap->fs = fs;
+	bitmap->start = start;
+	bitmap->end = end;
+	bitmap->real_end = real_end;
+	switch (magic) {
+	case EXT2_ET_MAGIC_INODE_BITMAP:
+		bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
+		break;
+	case EXT2_ET_MAGIC_BLOCK_BITMAP:
+		bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
+		break;
+	default:
+		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);
+	/* Round up to allow for the BT x86 instruction */
+	size = (size + 7) & ~3;
+	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 ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_GENERIC_BITMAP, 0,
+					  start, end, real_end, descr, 0, ret);
+}
+
+errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src,
+				     ext2fs_generic_bitmap *dest)
+{
+	return (ext2fs_make_generic_bitmap(src->magic, src->fs,
+					   src->start, src->end,
+					   src->real_end,
+					   src->description, src->bitmap,
+					   dest));
+}
+
+void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
+{
+	if (check_magic(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);
+}
+
+int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+					blk_t bitno)
+{
+	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+		if (EXT2FS_IS_64_BITMAP(bitmap)) {
+			ext2fs_warn_bitmap32(bitmap, __func__);
+			return ext2fs_test_generic_bmap(bitmap, bitno);
+		}
+#ifndef OMIT_COM_ERR
+		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+			"test_bitmap(%lu)", (unsigned long) bitno);
+#endif
+		return 0;
+	}
+
+	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);
+}
+
+int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+					 __u32 bitno)
+{
+	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+		if (EXT2FS_IS_64_BITMAP(bitmap)) {
+			ext2fs_warn_bitmap32(bitmap, __func__);
+			return ext2fs_mark_generic_bmap(bitmap, bitno);
+		}
+#ifndef OMIT_COM_ERR
+		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+			"mark_bitmap(%lu)", (unsigned long) bitno);
+#endif
+		return 0;
+	}
+
+	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 (!EXT2FS_IS_32_BITMAP(bitmap)) {
+		if (EXT2FS_IS_64_BITMAP(bitmap)) {
+			ext2fs_warn_bitmap32(bitmap, __func__);
+			return ext2fs_unmark_generic_bmap(bitmap, bitno);
+		}
+#ifndef OMIT_COM_ERR
+		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+			"mark_bitmap(%lu)", (unsigned long) bitno);
+#endif
+		return 0;
+	}
+
+	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);
+}
+
+__u32 ext2fs_get_generic_bitmap_start(ext2fs_generic_bitmap bitmap)
+{
+	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+		if (EXT2FS_IS_64_BITMAP(bitmap)) {
+			ext2fs_warn_bitmap32(bitmap, __func__);
+			return ext2fs_get_generic_bmap_start(bitmap);
+		}
+#ifndef OMIT_COM_ERR
+		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+			"get_bitmap_start");
+#endif
+		return 0;
+	}
+
+	return bitmap->start;
+}
+
+__u32 ext2fs_get_generic_bitmap_end(ext2fs_generic_bitmap bitmap)
+{
+	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+		if (EXT2FS_IS_64_BITMAP(bitmap)) {
+			ext2fs_warn_bitmap32(bitmap, __func__);
+			return ext2fs_get_generic_bmap_end(bitmap);
+		}
+#ifndef OMIT_COM_ERR
+		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+			"get_bitmap_end");
+#endif
+		return 0;
+	}
+	return bitmap->end;
+}
+
+void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap)
+{
+	if (!EXT2FS_IS_32_BITMAP(bitmap)) {
+		if (EXT2FS_IS_64_BITMAP(bitmap)) {
+			ext2fs_warn_bitmap32(bitmap, __func__);
+			ext2fs_clear_generic_bmap(bitmap);
+			return;
+		}
+#ifndef OMIT_COM_ERR
+		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+			"clear_generic_bitmap");
+#endif
+		return;
+	}
+
+	memset(bitmap->bitmap, 0,
+	       (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
+}
+
+errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,
+					  errcode_t magic, errcode_t neq,
+					  ext2_ino_t end, ext2_ino_t *oend)
+{
+	EXT2_CHECK_MAGIC(bitmap, magic);
+
+	if (end > bitmap->real_end)
+		return neq;
+	if (oend)
+		*oend = bitmap->end;
+	bitmap->end = end;
+	return 0;
+}
+
+errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
+				       __u32 new_end, __u32 new_real_end,
+				       ext2fs_generic_bitmap bmap)
+{
+	errcode_t	retval;
+	size_t		size, new_size;
+	__u32		bitno;
+
+	if (!bmap || (bmap->magic != magic))
+		return magic;
+
+	/*
+	 * 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_compare_generic_bitmap(errcode_t magic, errcode_t neq,
+					ext2fs_generic_bitmap bm1,
+					ext2fs_generic_bitmap bm2)
+{
+	blk_t	i;
+
+	if (!bm1 || bm1->magic != magic)
+		return magic;
+	if (!bm2 || bm2->magic != magic)
+		return magic;
+
+	if ((bm1->start != bm2->start) ||
+	    (bm1->end != bm2->end) ||
+	    (memcmp(bm1->bitmap, bm2->bitmap,
+		    (size_t) (bm1->end - bm1->start)/8)))
+		return neq;
+
+	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 neq;
+
+	return 0;
+}
+
+void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map)
+{
+	__u32	i, j;
+
+	/* Protect loop from wrap-around if map->real_end is maxed */
+	for (i=map->end+1, j = i - map->start;
+	     i <= map->real_end && i > map->end;
+	     i++, j++)
+		ext2fs_set_bit(j, map->bitmap);
+}
+
+errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,
+					  errcode_t magic,
+					  __u32 start, __u32 num,
+					  void *out)
+{
+	if (!bmap || (bmap->magic != magic))
+		return magic;
+
+	if ((start < bmap->start) || (start+num-1 > bmap->real_end))
+		return EXT2_ET_INVALID_ARGUMENT;
+
+	memcpy(out, bmap->bitmap + (start >> 3), (num+7) >> 3);
+	return 0;
+}
+
+errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap,
+					  errcode_t magic,
+					  __u32 start, __u32 num,
+					  void *in)
+{
+	if (!bmap || (bmap->magic != magic))
+		return magic;
+
+	if ((start < bmap->start) || (start+num-1 > bmap->real_end))
+		return EXT2_ET_INVALID_ARGUMENT;
+
+	memcpy(bmap->bitmap + (start >> 3), in, (num+7) >> 3);
+	return 0;
+}
+
+/*
+ * Compare @mem to zero buffer by 256 bytes.
+ * Return 1 if @mem is zeroed memory, otherwise return 0.
+ */
+int ext2fs_mem_is_zero(const char *mem, size_t len)
+{
+	static const char zero_buf[256];
+
+	while (len >= sizeof(zero_buf)) {
+		if (memcmp(mem, zero_buf, sizeof(zero_buf)))
+			return 0;
+		len -= sizeof(zero_buf);
+		mem += sizeof(zero_buf);
+	}
+	/* Deal with leftover bytes. */
+	if (len)
+		return !memcmp(mem, zero_buf, len);
+	return 1;
+}
+
+/*
+ * Return true if all of the bits in a specified range are clear
+ */
+static int ext2fs_test_clear_generic_bitmap_range(ext2fs_generic_bitmap bitmap,
+						  unsigned int start,
+						  unsigned int len)
+{
+	size_t start_byte, len_byte = len >> 3;
+	unsigned int start_bit, len_bit = len % 8;
+	int first_bit = 0;
+	int last_bit  = 0;
+	int mark_count = 0;
+	int mark_bit = 0;
+	int i;
+	const char *ADDR = bitmap->bitmap;
+
+	start -= bitmap->start;
+	start_byte = start >> 3;
+	start_bit = start % 8;
+
+	if (start_bit != 0) {
+		/*
+		 * The compared start block number or start inode number
+		 * is not the first bit in a byte.
+		 */
+		mark_count = 8 - start_bit;
+		if (len < 8 - start_bit) {
+			mark_count = (int)len;
+			mark_bit = len + start_bit - 1;
+		} else
+			mark_bit = 7;
+
+		for (i = mark_count; i > 0; i--, mark_bit--)
+			first_bit |= 1 << mark_bit;
+
+		/*
+		 * Compare blocks or inodes in the first byte.
+		 * If there is any marked bit, this function returns 0.
+		 */
+		if (first_bit & ADDR[start_byte])
+			return 0;
+		else if (len <= 8 - start_bit)
+			return 1;
+
+		start_byte++;
+		len_bit = (len - mark_count) % 8;
+		len_byte = (len - mark_count) >> 3;
+	}
+
+	/*
+	 * The compared start block number or start inode number is
+	 * the first bit in a byte.
+	 */
+	if (len_bit != 0) {
+		/*
+		 * The compared end block number or end inode number is
+		 * not the last bit in a byte.
+		 */
+		for (mark_bit = len_bit - 1; mark_bit >= 0; mark_bit--)
+			last_bit |= 1 << mark_bit;
+
+		/*
+		 * Compare blocks or inodes in the last byte.
+		 * If there is any marked bit, this function returns 0.
+		 */
+		if (last_bit & ADDR[start_byte + len_byte])
+			return 0;
+		else if (len_byte == 0)
+			return 1;
+	}
+
+	/* Check whether all bytes are 0 */
+	return ext2fs_mem_is_zero(ADDR + start_byte, len_byte);
+}
+
+errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap,
+						__u32 start, __u32 end,
+						__u32 *out)
+{
+	blk_t b;
+
+	if (start < bitmap->start || end > bitmap->end || start > end) {
+		ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
+		return EINVAL;
+	}
+
+	while (start <= end) {
+		b = ext2fs_test_bit(start - bitmap->start, bitmap->bitmap);
+		if (!b) {
+			*out = start;
+			return 0;
+		}
+		start++;
+	}
+
+	return ENOENT;
+}
+
+
+int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+				   blk_t block, int num)
+{
+	EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
+	if ((block < bitmap->start) || (block+num-1 > bitmap->real_end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+				   block, bitmap->description);
+		return 0;
+	}
+	return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap)
+						      bitmap, block, num);
+}
+
+int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
+				   ino_t inode, int num)
+{
+	EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
+	if ((inode < bitmap->start) || (inode+num-1 > bitmap->real_end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
+				   inode, bitmap->description);
+		return 0;
+	}
+	return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap)
+						      bitmap, inode, num);
+}
+
+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_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+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_fast_clear_bit(block + i - bitmap->start,
+				      bitmap->bitmap);
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/gen_bitmap64.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/gen_bitmap64.c
new file mode 100644
index 0000000..9ba7701
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/gen_bitmap64.c
@@ -0,0 +1,850 @@
+/*
+ * gen_bitmap64.c --- routines to read, write, and manipulate the new qinode and
+ * block bitmaps.
+ *
+ * Copyright (C) 2007, 2008 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+#include "bmap64.h"
+
+/*
+ * Design of 64-bit bitmaps
+ *
+ * In order maintain ABI compatibility with programs that don't
+ * understand about 64-bit blocks/inodes,
+ * ext2fs_allocate_inode_bitmap() and ext2fs_allocate_block_bitmap()
+ * will create old-style bitmaps unless the application passes the
+ * flag EXT2_FLAG_64BITS to ext2fs_open().  If this flag is
+ * passed, then we know the application has been recompiled, so we can
+ * use the new-style bitmaps.  If it is not passed, we have to return
+ * an error if trying to open a filesystem which needs 64-bit bitmaps.
+ *
+ * The new bitmaps use a new set of structure magic numbers, so that
+ * both the old-style and new-style interfaces can identify which
+ * version of the data structure was used.  Both the old-style and
+ * new-style interfaces will support either type of bitmap, although
+ * of course 64-bit operation will only be possible when both the
+ * new-style interface and the new-style bitmap are used.
+ *
+ * For example, the new bitmap interfaces will check the structure
+ * magic numbers and so will be able to detect old-stype bitmap.  If
+ * they see an old-style bitmap, they will pass it to the gen_bitmap.c
+ * functions for handling.  The same will be true for the old
+ * interfaces as well.
+ *
+ * The new-style interfaces will have several different back-end
+ * implementations, so we can support different encodings that are
+ * appropriate for different applications.  In general the default
+ * should be whatever makes sense, and what the application/library
+ * will use.  However, e2fsck may need specialized implementations for
+ * its own uses.  For example, when doing parent directory pointer
+ * loop detections in pass 3, the bitmap will *always* be sparse, so
+ * e2fsck can request an encoding which is optimized for that.
+ */
+
+static void warn_bitmap(ext2fs_generic_bitmap bitmap,
+			int code, __u64 arg)
+{
+#ifndef OMIT_COM_ERR
+	if (bitmap->description)
+		com_err(0, bitmap->base_error_code+code,
+			"#%llu for %s", arg, bitmap->description);
+	else
+		com_err(0, bitmap->base_error_code + code, "#%llu", arg);
+#endif
+}
+
+#ifdef BMAP_STATS_OPS
+#define INC_STAT(map, name) map->stats.name
+#else
+#define INC_STAT(map, name) ;;
+#endif
+
+
+errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
+				    int type, __u64 start, __u64 end,
+				    __u64 real_end,
+				    const char *descr,
+				    ext2fs_generic_bitmap *ret)
+{
+	ext2fs_generic_bitmap	bitmap;
+	struct ext2_bitmap_ops	*ops;
+	ext2_ino_t num_dirs;
+	errcode_t retval;
+
+	if (!type)
+		type = EXT2FS_BMAP64_BITARRAY;
+
+	switch (type) {
+	case EXT2FS_BMAP64_BITARRAY:
+		ops = &ext2fs_blkmap64_bitarray;
+		break;
+	case EXT2FS_BMAP64_RBTREE:
+		ops = &ext2fs_blkmap64_rbtree;
+		break;
+	case EXT2FS_BMAP64_AUTODIR:
+		retval = ext2fs_get_num_dirs(fs, &num_dirs);
+		if (retval || num_dirs > (fs->super->s_inodes_count / 320))
+			ops = &ext2fs_blkmap64_bitarray;
+		else
+			ops = &ext2fs_blkmap64_rbtree;
+		break;
+	default:
+		return EINVAL;
+	}
+
+	retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap),
+				    &bitmap);
+	if (retval)
+		return retval;
+
+#ifdef BMAP_STATS
+	if (gettimeofday(&bitmap->stats.created,
+			 (struct timezone *) NULL) == -1) {
+		perror("gettimeofday");
+		ext2fs_free_mem(&bitmap);
+		return 1;
+	}
+	bitmap->stats.type = type;
+#endif
+
+	/* XXX factor out, repeated in copy_bmap */
+	bitmap->magic = magic;
+	bitmap->fs = fs;
+	bitmap->start = start;
+	bitmap->end = end;
+	bitmap->real_end = real_end;
+	bitmap->bitmap_ops = ops;
+	bitmap->cluster_bits = 0;
+	switch (magic) {
+	case EXT2_ET_MAGIC_INODE_BITMAP64:
+		bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
+		break;
+	case EXT2_ET_MAGIC_BLOCK_BITMAP64:
+		bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
+		bitmap->cluster_bits = fs->cluster_ratio_bits;
+		break;
+	default:
+		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;
+
+	retval = bitmap->bitmap_ops->new_bmap(fs, bitmap);
+	if (retval) {
+		ext2fs_free_mem(&bitmap->description);
+		ext2fs_free_mem(&bitmap);
+		return retval;
+	}
+
+	*ret = bitmap;
+	return 0;
+}
+
+#ifdef BMAP_STATS
+static void ext2fs_print_bmap_statistics(ext2fs_generic_bitmap bitmap)
+{
+	struct ext2_bmap_statistics *stats = &bitmap->stats;
+#ifdef BMAP_STATS_OPS
+	float mark_seq_perc = 0.0, test_seq_perc = 0.0;
+	float mark_back_perc = 0.0, test_back_perc = 0.0;
+#endif
+	double inuse;
+	struct timeval now;
+
+#ifdef BMAP_STATS_OPS
+	if (stats->test_count) {
+		test_seq_perc = ((float)stats->test_seq /
+				 stats->test_count) * 100;
+		test_back_perc = ((float)stats->test_back /
+				  stats->test_count) * 100;
+	}
+
+	if (stats->mark_count) {
+		mark_seq_perc = ((float)stats->mark_seq /
+				 stats->mark_count) * 100;
+		mark_back_perc = ((float)stats->mark_back /
+				  stats->mark_count) * 100;
+	}
+#endif
+
+	if (gettimeofday(&now, (struct timezone *) NULL) == -1) {
+		perror("gettimeofday");
+		return;
+	}
+
+	inuse = (double) now.tv_sec + \
+		(((double) now.tv_usec) * 0.000001);
+	inuse -= (double) stats->created.tv_sec + \
+		(((double) stats->created.tv_usec) * 0.000001);
+
+	fprintf(stderr, "\n[+] %s bitmap (type %d)\n", bitmap->description,
+		stats->type);
+	fprintf(stderr, "=================================================\n");
+#ifdef BMAP_STATS_OPS
+	fprintf(stderr, "%16llu bits long\n",
+		bitmap->real_end - bitmap->start);
+	fprintf(stderr, "%16lu copy_bmap\n%16lu resize_bmap\n",
+		stats->copy_count, stats->resize_count);
+	fprintf(stderr, "%16lu mark bmap\n%16lu unmark_bmap\n",
+		stats->mark_count, stats->unmark_count);
+	fprintf(stderr, "%16lu test_bmap\n%16lu mark_bmap_extent\n",
+		stats->test_count, stats->mark_ext_count);
+	fprintf(stderr, "%16lu unmark_bmap_extent\n"
+		"%16lu test_clear_bmap_extent\n",
+		stats->unmark_ext_count, stats->test_ext_count);
+	fprintf(stderr, "%16lu set_bmap_range\n%16lu set_bmap_range\n",
+		stats->set_range_count, stats->get_range_count);
+	fprintf(stderr, "%16lu clear_bmap\n%16lu contiguous bit test (%.2f%%)\n",
+		stats->clear_count, stats->test_seq, test_seq_perc);
+	fprintf(stderr, "%16lu contiguous bit mark (%.2f%%)\n"
+		"%16llu bits tested backwards (%.2f%%)\n",
+		stats->mark_seq, mark_seq_perc,
+		stats->test_back, test_back_perc);
+	fprintf(stderr, "%16llu bits marked backwards (%.2f%%)\n"
+		"%16.2f seconds in use\n",
+		stats->mark_back, mark_back_perc, inuse);
+#endif /* BMAP_STATS_OPS */
+}
+#endif
+
+void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap)
+{
+	if (!bmap)
+		return;
+
+	if (EXT2FS_IS_32_BITMAP(bmap)) {
+		ext2fs_free_generic_bitmap(bmap);
+		return;
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bmap))
+		return;
+
+#ifdef BMAP_STATS
+	if (getenv("E2FSPROGS_BITMAP_STATS")) {
+		ext2fs_print_bmap_statistics(bmap);
+		bmap->bitmap_ops->print_stats(bmap);
+	}
+#endif
+
+	bmap->bitmap_ops->free_bmap(bmap);
+
+	if (bmap->description) {
+		ext2fs_free_mem(&bmap->description);
+		bmap->description = 0;
+	}
+	bmap->magic = 0;
+	ext2fs_free_mem(&bmap);
+}
+
+errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
+				   ext2fs_generic_bitmap *dest)
+{
+	char *descr, *new_descr;
+	ext2fs_generic_bitmap	new_bmap;
+	errcode_t retval;
+
+	if (!src)
+		return EINVAL;
+
+	if (EXT2FS_IS_32_BITMAP(src))
+		return ext2fs_copy_generic_bitmap(src, dest);
+
+	if (!EXT2FS_IS_64_BITMAP(src))
+		return EINVAL;
+
+	/* Allocate a new bitmap struct */
+	retval = ext2fs_get_memzero(sizeof(struct ext2fs_struct_generic_bitmap),
+				    &new_bmap);
+	if (retval)
+		return retval;
+
+
+#ifdef BMAP_STATS_OPS
+	src->stats.copy_count++;
+#endif
+#ifdef BMAP_STATS
+	if (gettimeofday(&new_bmap->stats.created,
+			 (struct timezone *) NULL) == -1) {
+		perror("gettimeofday");
+		ext2fs_free_mem(&new_bmap);
+		return 1;
+	}
+	new_bmap->stats.type = src->stats.type;
+#endif
+
+	/* Copy all the high-level parts over */
+	new_bmap->magic = src->magic;
+	new_bmap->fs = src->fs;
+	new_bmap->start = src->start;
+	new_bmap->end = src->end;
+	new_bmap->real_end = src->real_end;
+	new_bmap->bitmap_ops = src->bitmap_ops;
+	new_bmap->base_error_code = src->base_error_code;
+	new_bmap->cluster_bits = src->cluster_bits;
+
+	descr = src->description;
+	if (descr) {
+		retval = ext2fs_get_mem(strlen(descr)+10, &new_descr);
+		if (retval) {
+			ext2fs_free_mem(&new_bmap);
+			return retval;
+		}
+		sprintf(new_descr, "copy of %s", descr);
+		new_bmap->description = new_descr;
+	}
+
+	retval = src->bitmap_ops->copy_bmap(src, new_bmap);
+	if (retval) {
+		ext2fs_free_mem(&new_bmap->description);
+		ext2fs_free_mem(&new_bmap);
+		return retval;
+	}
+
+	*dest = new_bmap;
+
+	return 0;
+}
+
+errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
+				     __u64 new_end,
+				     __u64 new_real_end)
+{
+	if (!bmap)
+		return EINVAL;
+
+	if (EXT2FS_IS_32_BITMAP(bmap))
+		return ext2fs_resize_generic_bitmap(bmap->magic, new_end,
+						    new_real_end, bmap);
+
+	if (!EXT2FS_IS_64_BITMAP(bmap))
+		return EINVAL;
+
+	INC_STAT(bmap, resize_count);
+
+	return bmap->bitmap_ops->resize_bmap(bmap, new_end, new_real_end);
+}
+
+errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
+					errcode_t neq,
+					__u64 end, __u64 *oend)
+{
+	if (!bitmap)
+		return EINVAL;
+
+	if (EXT2FS_IS_32_BITMAP(bitmap)) {
+		ext2_ino_t tmp_oend;
+		int retval;
+
+		retval = ext2fs_fudge_generic_bitmap_end(bitmap, bitmap->magic,
+							 neq, end, &tmp_oend);
+		if (oend)
+			*oend = tmp_oend;
+		return retval;
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bitmap))
+		return EINVAL;
+
+	if (end > bitmap->real_end)
+		return neq;
+	if (oend)
+		*oend = bitmap->end;
+	bitmap->end = end;
+	return 0;
+}
+
+__u64 ext2fs_get_generic_bmap_start(ext2fs_generic_bitmap bitmap)
+{
+	if (!bitmap)
+		return EINVAL;
+
+	if (EXT2FS_IS_32_BITMAP(bitmap))
+		return ext2fs_get_generic_bitmap_start(bitmap);
+
+	if (!EXT2FS_IS_64_BITMAP(bitmap))
+		return EINVAL;
+
+	return bitmap->start;
+}
+
+__u64 ext2fs_get_generic_bmap_end(ext2fs_generic_bitmap bitmap)
+{
+	if (!bitmap)
+		return EINVAL;
+
+	if (EXT2FS_IS_32_BITMAP(bitmap))
+		return ext2fs_get_generic_bitmap_end(bitmap);
+
+	if (!EXT2FS_IS_64_BITMAP(bitmap))
+		return EINVAL;
+
+	return bitmap->end;
+}
+
+void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap)
+{
+	if (EXT2FS_IS_32_BITMAP(bitmap))
+		ext2fs_clear_generic_bitmap(bitmap);
+	else
+		bitmap->bitmap_ops->clear_bmap (bitmap);
+}
+
+int ext2fs_mark_generic_bmap(ext2fs_generic_bitmap bitmap,
+			     __u64 arg)
+{
+	if (!bitmap)
+		return 0;
+
+	if (EXT2FS_IS_32_BITMAP(bitmap)) {
+		if (arg & ~0xffffffffULL) {
+			ext2fs_warn_bitmap2(bitmap,
+					    EXT2FS_MARK_ERROR, 0xffffffff);
+			return 0;
+		}
+		return ext2fs_mark_generic_bitmap(bitmap, arg);
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bitmap))
+		return 0;
+
+	arg >>= bitmap->cluster_bits;
+
+#ifdef BMAP_STATS_OPS
+	if (arg == bitmap->stats.last_marked + 1)
+		bitmap->stats.mark_seq++;
+	if (arg < bitmap->stats.last_marked)
+		bitmap->stats.mark_back++;
+	bitmap->stats.last_marked = arg;
+	bitmap->stats.mark_count++;
+#endif
+
+	if ((arg < bitmap->start) || (arg > bitmap->end)) {
+		warn_bitmap(bitmap, EXT2FS_MARK_ERROR, arg);
+		return 0;
+	}
+
+	return bitmap->bitmap_ops->mark_bmap(bitmap, arg);
+}
+
+int ext2fs_unmark_generic_bmap(ext2fs_generic_bitmap bitmap,
+			       __u64 arg)
+{
+	if (!bitmap)
+		return 0;
+
+	if (EXT2FS_IS_32_BITMAP(bitmap)) {
+		if (arg & ~0xffffffffULL) {
+			ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR,
+					    0xffffffff);
+			return 0;
+		}
+		return ext2fs_unmark_generic_bitmap(bitmap, arg);
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bitmap))
+		return 0;
+
+	arg >>= bitmap->cluster_bits;
+
+	INC_STAT(bitmap, unmark_count);
+
+	if ((arg < bitmap->start) || (arg > bitmap->end)) {
+		warn_bitmap(bitmap, EXT2FS_UNMARK_ERROR, arg);
+		return 0;
+	}
+
+	return bitmap->bitmap_ops->unmark_bmap(bitmap, arg);
+}
+
+int ext2fs_test_generic_bmap(ext2fs_generic_bitmap bitmap,
+			     __u64 arg)
+{
+	if (!bitmap)
+		return 0;
+
+	if (EXT2FS_IS_32_BITMAP(bitmap)) {
+		if (arg & ~0xffffffffULL) {
+			ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR,
+					    0xffffffff);
+			return 0;
+		}
+		return ext2fs_test_generic_bitmap(bitmap, arg);
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bitmap))
+		return 0;
+
+	arg >>= bitmap->cluster_bits;
+
+#ifdef BMAP_STATS_OPS
+	bitmap->stats.test_count++;
+	if (arg == bitmap->stats.last_tested + 1)
+		bitmap->stats.test_seq++;
+	if (arg < bitmap->stats.last_tested)
+		bitmap->stats.test_back++;
+	bitmap->stats.last_tested = arg;
+#endif
+
+	if ((arg < bitmap->start) || (arg > bitmap->end)) {
+		warn_bitmap(bitmap, EXT2FS_TEST_ERROR, arg);
+		return 0;
+	}
+
+	return bitmap->bitmap_ops->test_bmap(bitmap, arg);
+}
+
+errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
+					__u64 start, unsigned int num,
+					void *in)
+{
+	if (!bmap)
+		return EINVAL;
+
+	if (EXT2FS_IS_32_BITMAP(bmap)) {
+		if ((start+num-1) & ~0xffffffffULL) {
+			ext2fs_warn_bitmap2(bmap, EXT2FS_UNMARK_ERROR,
+					    0xffffffff);
+			return EINVAL;
+		}
+		return ext2fs_set_generic_bitmap_range(bmap, bmap->magic,
+						       start, num, in);
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bmap))
+		return EINVAL;
+
+	INC_STAT(bmap, set_range_count);
+
+	return bmap->bitmap_ops->set_bmap_range(bmap, start, num, in);
+}
+
+errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
+					__u64 start, unsigned int num,
+					void *out)
+{
+	if (!bmap)
+		return EINVAL;
+
+	if (EXT2FS_IS_32_BITMAP(bmap)) {
+		if ((start+num-1) & ~0xffffffffULL) {
+			ext2fs_warn_bitmap2(bmap,
+					    EXT2FS_UNMARK_ERROR, 0xffffffff);
+			return EINVAL;
+		}
+		return ext2fs_get_generic_bitmap_range(bmap, bmap->magic,
+						       start, num, out);
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bmap))
+		return EINVAL;
+
+	INC_STAT(bmap, get_range_count);
+
+	return bmap->bitmap_ops->get_bmap_range(bmap, start, num, out);
+}
+
+errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
+				      ext2fs_generic_bitmap bm1,
+				      ext2fs_generic_bitmap bm2)
+{
+	blk64_t	i;
+
+	if (!bm1 || !bm2)
+		return EINVAL;
+	if (bm1->magic != bm2->magic)
+		return EINVAL;
+
+	/* Now we know both bitmaps have the same magic */
+	if (EXT2FS_IS_32_BITMAP(bm1))
+		return ext2fs_compare_generic_bitmap(bm1->magic, neq, bm1, bm2);
+
+	if (!EXT2FS_IS_64_BITMAP(bm1))
+		return EINVAL;
+
+	if ((bm1->start != bm2->start) ||
+	    (bm1->end != bm2->end))
+		return neq;
+
+	for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
+		if (ext2fs_test_generic_bmap(bm1, i) !=
+		    ext2fs_test_generic_bmap(bm2, i))
+			return neq;
+
+	return 0;
+}
+
+void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap)
+{
+	__u64	start, num;
+
+	if (EXT2FS_IS_32_BITMAP(bmap)) {
+		ext2fs_set_generic_bitmap_padding(bmap);
+		return;
+	}
+
+	start = bmap->end + 1;
+	num = bmap->real_end - bmap->end;
+	bmap->bitmap_ops->mark_bmap_extent(bmap, start, num);
+	/* XXX ought to warn on error */
+}
+
+int ext2fs_test_block_bitmap_range2(ext2fs_block_bitmap bmap,
+				    blk64_t block, unsigned int num)
+{
+	__u64	end = block + num;
+
+	if (!bmap)
+		return EINVAL;
+
+	if (num == 1)
+		return !ext2fs_test_generic_bmap((ext2fs_generic_bitmap)
+						 bmap, block);
+
+	if (EXT2FS_IS_32_BITMAP(bmap)) {
+		if ((block+num-1) & ~0xffffffffULL) {
+			ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
+					    EXT2FS_UNMARK_ERROR, 0xffffffff);
+			return EINVAL;
+		}
+		return ext2fs_test_block_bitmap_range(
+			(ext2fs_generic_bitmap) bmap, block, num);
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bmap))
+		return EINVAL;
+
+	INC_STAT(bmap, test_ext_count);
+
+	/* convert to clusters if necessary */
+	block >>= bmap->cluster_bits;
+	end += (1 << bmap->cluster_bits) - 1;
+	end >>= bmap->cluster_bits;
+	num = end - block;
+
+	if ((block < bmap->start) || (block+num-1 > bmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, block,
+				   bmap->description);
+		return EINVAL;
+	}
+
+	return bmap->bitmap_ops->test_clear_bmap_extent(bmap, block, num);
+}
+
+void ext2fs_mark_block_bitmap_range2(ext2fs_block_bitmap bmap,
+				     blk64_t block, unsigned int num)
+{
+	__u64	end = block + num;
+
+	if (!bmap)
+		return;
+
+	if (EXT2FS_IS_32_BITMAP(bmap)) {
+		if ((block+num-1) & ~0xffffffffULL) {
+			ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
+					    EXT2FS_UNMARK_ERROR, 0xffffffff);
+			return;
+		}
+		ext2fs_mark_block_bitmap_range((ext2fs_generic_bitmap) bmap,
+					       block, num);
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bmap))
+		return;
+
+	INC_STAT(bmap, mark_ext_count);
+
+	/* convert to clusters if necessary */
+	block >>= bmap->cluster_bits;
+	end += (1 << bmap->cluster_bits) - 1;
+	end >>= bmap->cluster_bits;
+	num = end - block;
+
+	if ((block < bmap->start) || (block+num-1 > bmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
+				   bmap->description);
+		return;
+	}
+
+	bmap->bitmap_ops->mark_bmap_extent(bmap, block, num);
+}
+
+void ext2fs_unmark_block_bitmap_range2(ext2fs_block_bitmap bmap,
+				       blk64_t block, unsigned int num)
+{
+	__u64	end = block + num;
+
+	if (!bmap)
+		return;
+
+	if (EXT2FS_IS_32_BITMAP(bmap)) {
+		if ((block+num-1) & ~0xffffffffULL) {
+			ext2fs_warn_bitmap2((ext2fs_generic_bitmap) bmap,
+					    EXT2FS_UNMARK_ERROR, 0xffffffff);
+			return;
+		}
+		ext2fs_unmark_block_bitmap_range((ext2fs_generic_bitmap) bmap,
+						 block, num);
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bmap))
+		return;
+
+	INC_STAT(bmap, unmark_ext_count);
+
+	/* convert to clusters if necessary */
+	block >>= bmap->cluster_bits;
+	end += (1 << bmap->cluster_bits) - 1;
+	end >>= bmap->cluster_bits;
+	num = end - block;
+
+	if ((block < bmap->start) || (block+num-1 > bmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
+				   bmap->description);
+		return;
+	}
+
+	bmap->bitmap_ops->unmark_bmap_extent(bmap, block, num);
+}
+
+void ext2fs_warn_bitmap32(ext2fs_generic_bitmap bitmap, const char *func)
+{
+#ifndef OMIT_COM_ERR
+	if (bitmap && bitmap->description)
+		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+			"called %s with 64-bit bitmap for %s", func,
+			bitmap->description);
+	else
+		com_err(0, EXT2_ET_MAGIC_GENERIC_BITMAP,
+			"called %s with 64-bit bitmap", func);
+#endif
+}
+
+errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
+					   ext2fs_block_bitmap *bitmap)
+{
+	ext2fs_block_bitmap	cmap, bmap;
+	errcode_t		retval;
+	blk64_t			i, b_end, c_end;
+	int			n, ratio;
+
+	bmap = *bitmap;
+
+	if (fs->cluster_ratio_bits == ext2fs_get_bitmap_granularity(bmap))
+		return 0;	/* Nothing to do */
+
+	retval = ext2fs_allocate_block_bitmap(fs, "converted cluster bitmap",
+					      &cmap);
+	if (retval)
+		return retval;
+
+	i = bmap->start;
+	b_end = bmap->end;
+	bmap->end = bmap->real_end;
+	c_end = cmap->end;
+	cmap->end = cmap->real_end;
+	n = 0;
+	ratio = 1 << fs->cluster_ratio_bits;
+	while (i < bmap->real_end) {
+		if (ext2fs_test_block_bitmap2(bmap, i)) {
+			ext2fs_mark_block_bitmap2(cmap, i);
+			i += ratio - n;
+			n = 0;
+			continue;
+		}
+		i++; n++;
+		if (n >= ratio)
+			n = 0;
+	}
+	bmap->end = b_end;
+	cmap->end = c_end;
+	ext2fs_free_block_bitmap(bmap);
+	*bitmap = cmap;
+	return 0;
+}
+
+errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
+					      __u64 start, __u64 end, __u64 *out)
+{
+	int b;
+
+	if (!bitmap)
+		return EINVAL;
+
+	if (EXT2FS_IS_64_BITMAP(bitmap) && bitmap->bitmap_ops->find_first_zero)
+		return bitmap->bitmap_ops->find_first_zero(bitmap, start,
+							   end, out);
+
+	if (EXT2FS_IS_32_BITMAP(bitmap)) {
+		blk_t blk = 0;
+		errcode_t retval;
+
+		if (((start) & ~0xffffffffULL) ||
+		    ((end) & ~0xffffffffULL)) {
+			ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
+			return EINVAL;
+		}
+
+		retval = ext2fs_find_first_zero_generic_bitmap(bitmap, start,
+							       end, &blk);
+		if (retval == 0)
+			*out = blk;
+		return retval;
+	}
+
+	if (!EXT2FS_IS_64_BITMAP(bitmap))
+		return EINVAL;
+
+	start >>= bitmap->cluster_bits;
+	end >>= bitmap->cluster_bits;
+
+	if (start < bitmap->start || end > bitmap->end || start > end) {
+		warn_bitmap(bitmap, EXT2FS_TEST_ERROR, start);
+		return EINVAL;
+	}
+
+	while (start <= end) {
+		b = bitmap->bitmap_ops->test_bmap(bitmap, start);
+		if (!b) {
+			*out = start << bitmap->cluster_bits;
+			return 0;
+		}
+		start++;
+	}
+
+	return ENOENT;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/gen_crc32ctable.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/gen_crc32ctable.c
new file mode 100644
index 0000000..9996e9d
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/gen_crc32ctable.c
@@ -0,0 +1,123 @@
+#include <stdio.h>
+#include "crc32c_defs.h"
+#include <inttypes.h>
+
+#define ENTRIES_PER_LINE 4
+
+#if CRC_LE_BITS <= 8
+#define LE_TABLE_SIZE (1 << CRC_LE_BITS)
+#else
+#define LE_TABLE_SIZE 256
+#endif
+
+#if CRC_BE_BITS <= 8
+#define BE_TABLE_SIZE (1 << CRC_BE_BITS)
+#else
+#define BE_TABLE_SIZE 256
+#endif
+
+static uint32_t crc32ctable_le[8][256];
+static uint32_t crc32ctable_be[8][256];
+
+/**
+ * crc32cinit_le() - allocate and initialize LE table data
+ *
+ * crc is the crc of the byte i; other entries are filled in based on the
+ * fact that crctable[i^j] = crctable[i] ^ crctable[j].
+ *
+ */
+static void crc32cinit_le(void)
+{
+	unsigned i, j;
+	uint32_t crc = 1;
+
+	crc32ctable_le[0][0] = 0;
+
+	for (i = LE_TABLE_SIZE >> 1; i; i >>= 1) {
+		crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+		for (j = 0; j < LE_TABLE_SIZE; j += 2 * i)
+			crc32ctable_le[0][i + j] = crc ^ crc32ctable_le[0][j];
+	}
+	for (i = 0; i < LE_TABLE_SIZE; i++) {
+		crc = crc32ctable_le[0][i];
+		for (j = 1; j < 8; j++) {
+			crc = crc32ctable_le[0][crc & 0xff] ^ (crc >> 8);
+			crc32ctable_le[j][i] = crc;
+		}
+	}
+}
+
+/**
+ * crc32cinit_be() - allocate and initialize BE table data
+ */
+static void crc32cinit_be(void)
+{
+	unsigned i, j;
+	uint32_t crc = 0x80000000;
+
+	crc32ctable_be[0][0] = 0;
+
+	for (i = 1; i < BE_TABLE_SIZE; i <<= 1) {
+		crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
+		for (j = 0; j < i; j++)
+			crc32ctable_be[0][i + j] = crc ^ crc32ctable_be[0][j];
+	}
+	for (i = 0; i < BE_TABLE_SIZE; i++) {
+		crc = crc32ctable_be[0][i];
+		for (j = 1; j < 8; j++) {
+			crc = crc32ctable_be[0][(crc >> 24) & 0xff] ^
+			      (crc << 8);
+			crc32ctable_be[j][i] = crc;
+		}
+	}
+}
+
+static void output_table(uint32_t table[8][256], int len, char trans)
+{
+	int i, j;
+
+	for (j = 0 ; j < 8; j++) {
+		printf("static const uint32_t t%d_%ce[] = {", j, trans);
+		for (i = 0; i < len - 1; i++) {
+			if ((i % ENTRIES_PER_LINE) == 0)
+				printf("\n");
+			printf("to%ce(0x%8.8xL),", trans, table[j][i]);
+			if ((i % ENTRIES_PER_LINE) != (ENTRIES_PER_LINE - 1))
+				printf(" ");
+		}
+		printf("to%ce(0x%8.8xL)};\n\n", trans, table[j][len - 1]);
+
+		if (trans == 'l') {
+			if ((j+1)*8 >= CRC_LE_BITS)
+				break;
+		} else {
+			if ((j+1)*8 >= CRC_BE_BITS)
+				break;
+		}
+	}
+}
+
+int main(int argc, char **argv)
+{
+	printf("/*\n");
+	printf(" * crc32ctable.h - CRC32c tables\n");
+	printf(" *    this file is generated - do not edit\n");
+	printf(" *	# gen_crc32ctable > crc32c_table.h\n");
+	printf(" *    with\n");
+	printf(" *	CRC_LE_BITS = %d\n", CRC_LE_BITS);
+	printf(" *	CRC_BE_BITS = %d\n", CRC_BE_BITS);
+	printf(" */\n");
+	printf("#include <stdint.h>\n");
+
+	if (CRC_LE_BITS > 1) {
+		crc32cinit_le();
+		output_table(crc32ctable_le, LE_TABLE_SIZE, 'l');
+	}
+
+	if (CRC_BE_BITS > 1) {
+		crc32cinit_be();
+		output_table(crc32ctable_be, BE_TABLE_SIZE, 'b');
+	}
+
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/get_pathname.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/get_pathname.c
new file mode 100644
index 0000000..52aea62
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/get_pathname.c
@@ -0,0 +1,172 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %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 "config.h"
+#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 = 0, *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 == EXT2_ET_NO_DIRECTORY) {
+		char tmp[32];
+
+		if (ino)
+			snprintf(tmp, sizeof(tmp), "<%u>/<%u>", dir, ino);
+		else
+			snprintf(tmp, sizeof(tmp), "<%u>", dir);
+		retval = ext2fs_get_mem(strlen(tmp)+1, name);
+		if (retval)
+			goto cleanup;
+		strcpy(*name, tmp);
+		return 0;
+	} else 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;
+	retval = 0;
+
+cleanup:
+	ext2fs_free_mem(&parent_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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/getsectsize.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/getsectsize.c
new file mode 100644
index 0000000..9c3f4a2
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/getsectsize.c
@@ -0,0 +1,110 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+#include "config.h"
+#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)
+#if !defined(BLKSSZGET)
+#define BLKSSZGET  _IO(0x12,104)/* get block device sector size */
+#endif
+#if !defined(BLKPBSZGET)
+#define BLKPBSZGET _IO(0x12,123)/* get block physical sector size */
+#endif
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+/*
+ * Returns the logical sector size of a device
+ */
+errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize)
+{
+	int	fd;
+
+	fd = ext2fs_open_file(file, O_RDONLY, 0);
+	if (fd < 0)
+		return errno;
+
+#ifdef BLKSSZGET
+	if (ioctl(fd, BLKSSZGET, sectsize) >= 0) {
+		close(fd);
+		return 0;
+	}
+#endif
+	*sectsize = 0;
+	close(fd);
+	return 0;
+}
+
+/*
+ * Return desired alignment for direct I/O
+ */
+int ext2fs_get_dio_alignment(int fd)
+{
+	int align = 0;
+
+#ifdef BLKSSZGET
+	if (ioctl(fd, BLKSSZGET, &align) < 0)
+		align = 0;
+#endif
+
+#ifdef _SC_PAGESIZE
+	if (align <= 0)
+		align = sysconf(_SC_PAGESIZE);
+#endif
+#ifdef HAVE_GETPAGESIZE
+	if (align <= 0)
+		align = getpagesize();
+#endif
+	if (align <= 0)
+		align = 4096;
+
+	return align;
+}
+
+/*
+ * Returns the physical sector size of a device
+ */
+errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize)
+{
+	int	fd;
+
+	fd = ext2fs_open_file(file, O_RDONLY, 0);
+	if (fd < 0)
+		return errno;
+
+#ifdef BLKPBSZGET
+	if (ioctl(fd, BLKPBSZGET, sectsize) >= 0) {
+		close(fd);
+		return 0;
+	}
+#endif
+	*sectsize = 0;
+	close(fd);
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/getsize.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/getsize.c
new file mode 100644
index 0000000..a9a4812
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/getsize.c
@@ -0,0 +1,311 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+#include "config.h"
+#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 HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include <ctype.h>
+
+#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_size2(const char *file, int blocksize,
+				  blk64_t *retblocks)
+{
+	int	fd, rc = 0;
+	unsigned long long size64;
+	ext2_loff_t high, low;
+
+	fd = ext2fs_open_file(file, O_RDONLY, 0);
+	if (fd < 0)
+		return errno;
+
+#ifdef DKIOCGETBLOCKCOUNT	/* For Apple Darwin */
+	if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) {
+		*retblocks = size64 / (blocksize / 512);
+		goto out;
+	}
+#endif
+
+#ifdef BLKGETSIZE64
+	{
+		int valid_blkgetsize64 = 1;
+#ifdef __linux__
+		struct utsname ut;
+
+		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) {
+			*retblocks = size64 / blocksize;
+			goto out;
+		}
+	}
+#endif /* BLKGETSIZE64 */
+
+#ifdef BLKGETSIZE
+	{
+		unsigned long	size;
+
+		if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
+			*retblocks = size / (blocksize / 512);
+			goto out;
+		}
+	}
+#endif
+
+#ifdef FDGETPRM
+	{
+		struct floppy_struct this_floppy;
+
+		if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
+			*retblocks = this_floppy.size / (blocksize / 512);
+			goto out;
+		}
+	}
+#endif
+
+#ifdef HAVE_SYS_DISKLABEL_H
+	{
+		int part;
+		struct disklabel lab;
+		struct partition *pp;
+		char ch;
+
+#if defined(DIOCGMEDIASIZE)
+		{
+			off_t ms;
+			u_int bs;
+			if (ioctl(fd, DIOCGMEDIASIZE, &ms) >= 0) {
+				*retblocks = ms / blocksize;
+				goto out;
+			}
+		}
+#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) {
+				*retblocks = pp->p_size / (blocksize / 512);
+				goto out;
+			}
+		}
+#endif /* defined(DIOCG*) */
+	}
+#endif /* HAVE_SYS_DISKLABEL_H */
+
+	{
+		ext2fs_struct_stat st;
+
+		if (ext2fs_fstat(fd, &st) == 0)
+			if (S_ISREG(st.st_mode)) {
+				*retblocks = st.st_size / blocksize;
+				goto out;
+			}
+	}
+
+	/*
+	 * 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);
+	size64 = low + 1;
+	*retblocks = size64 / blocksize;
+out:
+	close(fd);
+	return rc;
+}
+
+errcode_t ext2fs_get_device_size(const char *file, int blocksize,
+				 blk_t *retblocks)
+{
+	errcode_t retval;
+	blk64_t	blocks;
+
+	retval = ext2fs_get_device_size2(file, blocksize, &blocks);
+	if (retval)
+		return retval;
+	if (blocks >= (1ULL << 32))
+		return EFBIG;
+	*retblocks = (blk_t) blocks;
+	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 %u 1k blocks.\n", argv[1], blocks);
+	exit(0);
+}
+#endif
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/i_block.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/i_block.c
new file mode 100644
index 0000000..5ca57e4
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/i_block.c
@@ -0,0 +1,93 @@
+/*
+ * i_block.c --- Manage the i_block field for i_blocks
+ *
+ * Copyright (C) 2008 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 <errno.h>
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks)
+{
+	unsigned long long b = inode->i_blocks;
+
+	if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
+		b += ((long long) inode->osd2.linux2.l_i_blocks_hi) << 32;
+
+	if (!(fs->super->s_feature_ro_compat &
+	      EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
+	    !(inode->i_flags & EXT4_HUGE_FILE_FL))
+	    num_blocks *= fs->blocksize / 512;
+	num_blocks *= EXT2FS_CLUSTER_RATIO(fs);
+
+	b += num_blocks;
+
+	if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
+		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
+	else if (b > 0xFFFFFFFF)
+		return EOVERFLOW;
+	inode->i_blocks = b & 0xFFFFFFFF;
+	return 0;
+}
+
+errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks)
+{
+	unsigned long long b = inode->i_blocks;
+
+	if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
+		b += ((long long) inode->osd2.linux2.l_i_blocks_hi) << 32;
+
+	if (!(fs->super->s_feature_ro_compat &
+	      EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
+	    !(inode->i_flags & EXT4_HUGE_FILE_FL))
+	    num_blocks *= fs->blocksize / 512;
+	num_blocks *= EXT2FS_CLUSTER_RATIO(fs);
+
+	if (num_blocks > b)
+		return EOVERFLOW;
+
+	b -= num_blocks;
+
+	if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
+		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
+	inode->i_blocks = b & 0xFFFFFFFF;
+	return 0;
+}
+
+errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b)
+{
+	if (!(fs->super->s_feature_ro_compat &
+	      EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
+	    !(inode->i_flags & EXT4_HUGE_FILE_FL))
+		b *= fs->blocksize / 512;
+	b *= EXT2FS_CLUSTER_RATIO(fs);
+
+	inode->i_blocks = b & 0xFFFFFFFF;
+	if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
+		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
+	else if (b >> 32)
+		return EOVERFLOW;
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/icount.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/icount.c
new file mode 100644
index 0000000..c5ebf74
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/icount.c
@@ -0,0 +1,850 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+#include "tdb.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;
+	__u32		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;
+	struct ext2_icount_el	*last_lookup;
+	char			*tdb_fn;
+	TDB_CONTEXT		*tdb;
+};
+
+/*
+ * We now use a 32-bit counter field because it doesn't cost us
+ * anything extra for the in-memory data structure, due to alignment
+ * padding.  But there's no point changing the interface if most of
+ * the time we only care if the number is bigger than 65,000 or not.
+ * So use the following translation function to return a 16-bit count.
+ */
+#define icount_16_xlate(x) (((x) > 65500) ? 65500 : (x))
+
+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);
+	if (icount->tdb)
+		tdb_close(icount->tdb);
+	if (icount->tdb_fn) {
+		unlink(icount->tdb_fn);
+		free(icount->tdb_fn);
+	}
+
+	ext2fs_free_mem(&icount);
+}
+
+static errcode_t alloc_icount(ext2_filsys fs, int flags, ext2_icount_t *ret)
+{
+	ext2_icount_t	icount;
+	errcode_t	retval;
+
+	*ret = 0;
+
+	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, "icount", &icount->single);
+	if (retval)
+		goto errout;
+
+	if (flags & EXT2_ICOUNT_OPT_INCREMENT) {
+		retval = ext2fs_allocate_inode_bitmap(fs, "icount_inc",
+						      &icount->multiple);
+		if (retval)
+			goto errout;
+	} else
+		icount->multiple = 0;
+
+	icount->magic = EXT2_ET_MAGIC_ICOUNT;
+	icount->num_inodes = fs->super->s_inodes_count;
+
+	*ret = icount;
+	return 0;
+
+errout:
+	ext2fs_free_icount(icount);
+	return(retval);
+}
+
+struct uuid {
+	__u32	time_low;
+	__u16	time_mid;
+	__u16	time_hi_and_version;
+	__u16	clock_seq;
+	__u8	node[6];
+};
+
+static void unpack_uuid(void *in, struct uuid *uu)
+{
+	__u8	*ptr = in;
+	__u32	tmp;
+
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->time_low = tmp;
+
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->time_mid = tmp;
+
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->time_hi_and_version = tmp;
+
+	tmp = *ptr++;
+	tmp = (tmp << 8) | *ptr++;
+	uu->clock_seq = tmp;
+
+	memcpy(uu->node, ptr, 6);
+}
+
+static void uuid_unparse(void *uu, char *out)
+{
+	struct uuid uuid;
+
+	unpack_uuid(uu, &uuid);
+	sprintf(out,
+		"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
+		uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
+		uuid.node[0], uuid.node[1], uuid.node[2],
+		uuid.node[3], uuid.node[4], uuid.node[5]);
+}
+
+errcode_t ext2fs_create_icount_tdb(ext2_filsys fs, char *tdb_dir,
+				   int flags, ext2_icount_t *ret)
+{
+	ext2_icount_t	icount;
+	errcode_t	retval;
+	char 		*fn, uuid[40];
+	ext2_ino_t	num_inodes;
+	int		fd;
+
+	retval = alloc_icount(fs, flags,  &icount);
+	if (retval)
+		return retval;
+
+	retval = ext2fs_get_mem(strlen(tdb_dir) + 64, &fn);
+	if (retval)
+		goto errout;
+	uuid_unparse(fs->super->s_uuid, uuid);
+	sprintf(fn, "%s/%s-icount-XXXXXX", tdb_dir, uuid);
+	fd = mkstemp(fn);
+	if (fd < 0)
+		return fd;
+
+	/*
+	 * This is an overestimate of the size that we will need; the
+	 * ideal value is the number of used inodes with a count
+	 * greater than 1.  OTOH the times when we really need this is
+	 * with the backup programs that use lots of hard links, in
+	 * which case the number of inodes in use approaches the ideal
+	 * value.
+	 */
+	num_inodes = fs->super->s_inodes_count - fs->super->s_free_inodes_count;
+
+	icount->tdb_fn = fn;
+	icount->tdb = tdb_open(fn, num_inodes, TDB_NOLOCK | TDB_NOSYNC,
+			       O_RDWR | O_CREAT | O_TRUNC, 0600);
+	if (icount->tdb) {
+		close(fd);
+		*ret = icount;
+		return 0;
+	}
+
+	retval = errno;
+	close(fd);
+
+errout:
+	ext2fs_free_icount(icount);
+	return(retval);
+}
+
+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 = alloc_icount(fs, flags, &icount);
+	if (retval)
+		return retval;
+
+	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 %u entries, %d bytes.\n",
+	       icount->size, bytes);
+#endif
+	retval = ext2fs_get_array(icount->size, sizeof(struct ext2_icount_el),
+			 &icount->list);
+	if (retval)
+		goto errout;
+	memset(icount->list, 0, bytes);
+
+	icount->count = 0;
+	icount->cursor = 0;
+
+	/*
+	 * 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->last_lookup && icount->last_lookup->ino == ino)
+		return icount->last_lookup;
+
+	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 %u 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;
+	icount->last_lookup = el;
+	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)
+{
+	int	low, high, mid;
+
+	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) {
+		mid = ((unsigned)low + (unsigned)high) >> 1;
+		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;
+}
+
+static errcode_t set_inode_count(ext2_icount_t icount, ext2_ino_t ino,
+				 __u32 count)
+{
+	struct ext2_icount_el 	*el;
+	TDB_DATA key, data;
+
+	if (icount->tdb) {
+		key.dptr = (unsigned char *) &ino;
+		key.dsize = sizeof(ext2_ino_t);
+		data.dptr = (unsigned char *) &count;
+		data.dsize = sizeof(__u32);
+		if (count) {
+			if (tdb_store(icount->tdb, key, data, TDB_REPLACE))
+				return tdb_error(icount->tdb) +
+					EXT2_ET_TDB_SUCCESS;
+		} else {
+			if (tdb_delete(icount->tdb, key))
+				return tdb_error(icount->tdb) +
+					EXT2_ET_TDB_SUCCESS;
+		}
+		return 0;
+	}
+
+	el = get_icount_el(icount, ino, 1);
+	if (!el)
+		return EXT2_ET_NO_MEMORY;
+
+	el->count = count;
+	return 0;
+}
+
+static errcode_t get_inode_count(ext2_icount_t icount, ext2_ino_t ino,
+				 __u32 *count)
+{
+	struct ext2_icount_el 	*el;
+	TDB_DATA key, data;
+
+	if (icount->tdb) {
+		key.dptr = (unsigned char *) &ino;
+		key.dsize = sizeof(ext2_ino_t);
+
+		data = tdb_fetch(icount->tdb, key);
+		if (data.dptr == NULL) {
+			*count = 0;
+			return tdb_error(icount->tdb) + EXT2_ET_TDB_SUCCESS;
+		}
+
+		*count = *((__u32 *) data.dptr);
+		free(data.dptr);
+		return 0;
+	}
+	el = get_icount_el(icount, ino, 0);
+	if (!el) {
+		*count = 0;
+		return ENOENT;
+	}
+
+	*count = el->count;
+	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)
+{
+	__u32	val;
+	EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+	if (!ino || (ino > icount->num_inodes))
+		return EXT2_ET_INVALID_ARGUMENT;
+
+	if (ext2fs_test_inode_bitmap2(icount->single, ino)) {
+		*ret = 1;
+		return 0;
+	}
+	if (icount->multiple &&
+	    !ext2fs_test_inode_bitmap2(icount->multiple, ino)) {
+		*ret = 0;
+		return 0;
+	}
+	get_inode_count(icount, ino, &val);
+	*ret = icount_16_xlate(val);
+	return 0;
+}
+
+errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
+				  __u16 *ret)
+{
+	__u32			curr_value;
+
+	EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+	if (!ino || (ino > icount->num_inodes))
+		return EXT2_ET_INVALID_ARGUMENT;
+
+	if (ext2fs_test_inode_bitmap2(icount->single, ino)) {
+		/*
+		 * If the existing count is 1, then we know there is
+		 * no entry in the list.
+		 */
+		if (set_inode_count(icount, ino, 2))
+			return EXT2_ET_NO_MEMORY;
+		curr_value = 2;
+		ext2fs_unmark_inode_bitmap2(icount->single, ino);
+	} 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 we need to fix it.
+		 */
+		if (ext2fs_test_inode_bitmap2(icount->multiple, ino)) {
+			get_inode_count(icount, ino, &curr_value);
+			curr_value++;
+			if (set_inode_count(icount, ino, curr_value))
+				return EXT2_ET_NO_MEMORY;
+		} else {
+			/*
+			 * The count was zero; mark the single bitmap
+			 * and return.
+			 */
+			ext2fs_mark_inode_bitmap2(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.
+		 */
+		get_inode_count(icount, ino, &curr_value);
+		curr_value++;
+		if (set_inode_count(icount, ino, curr_value))
+			return EXT2_ET_NO_MEMORY;
+	}
+	if (icount->multiple)
+		ext2fs_mark_inode_bitmap2(icount->multiple, ino);
+	if (ret)
+		*ret = icount_16_xlate(curr_value);
+	return 0;
+}
+
+errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
+				  __u16 *ret)
+{
+	__u32			curr_value;
+
+	if (!ino || (ino > icount->num_inodes))
+		return EXT2_ET_INVALID_ARGUMENT;
+
+	EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+	if (ext2fs_test_inode_bitmap2(icount->single, ino)) {
+		ext2fs_unmark_inode_bitmap2(icount->single, ino);
+		if (icount->multiple)
+			ext2fs_unmark_inode_bitmap2(icount->multiple, ino);
+		else {
+			set_inode_count(icount, ino, 0);
+		}
+		if (ret)
+			*ret = 0;
+		return 0;
+	}
+
+	if (icount->multiple &&
+	    !ext2fs_test_inode_bitmap2(icount->multiple, ino))
+		return EXT2_ET_INVALID_ARGUMENT;
+
+	get_inode_count(icount, ino, &curr_value);
+	if (!curr_value)
+		return EXT2_ET_INVALID_ARGUMENT;
+	curr_value--;
+	if (set_inode_count(icount, ino, curr_value))
+		return EXT2_ET_NO_MEMORY;
+
+	if (curr_value == 1)
+		ext2fs_mark_inode_bitmap2(icount->single, ino);
+	if ((curr_value == 0) && icount->multiple)
+		ext2fs_unmark_inode_bitmap2(icount->multiple, ino);
+
+	if (ret)
+		*ret = icount_16_xlate(curr_value);
+	return 0;
+}
+
+errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
+			      __u16 count)
+{
+	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_bitmap2(icount->single, ino);
+		if (icount->multiple)
+			ext2fs_unmark_inode_bitmap2(icount->multiple, ino);
+		return 0;
+	}
+	if (count == 0) {
+		ext2fs_unmark_inode_bitmap2(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_bitmap2(icount->multiple, ino);
+		} else
+			set_inode_count(icount, ino, 0);
+		return 0;
+	}
+
+	if (set_inode_count(icount, ino, count))
+		return EXT2_ET_NO_MEMORY;
+	ext2fs_unmark_inode_bitmap2(icount->single, ino);
+	if (icount->multiple)
+		ext2fs_mark_inode_bitmap2(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;
+}
+
+#ifdef DEBUG
+
+ext2_filsys	test_fs;
+ext2_icount_t	icount;
+
+#define EXIT		0x00
+#define FETCH		0x01
+#define STORE		0x02
+#define INCREMENT	0x03
+#define DECREMENT	0x04
+
+struct test_program {
+	int		cmd;
+	ext2_ino_t	ino;
+	__u16		arg;
+	__u16		expected;
+};
+
+struct test_program prog[] = {
+	{ STORE, 42, 42, 42 },
+	{ STORE, 1,  1, 1 },
+	{ STORE, 2,  2, 2 },
+	{ STORE, 3,  3, 3 },
+	{ STORE, 10, 1, 1 },
+	{ STORE, 42, 0, 0 },
+	{ INCREMENT, 5, 0, 1 },
+	{ INCREMENT, 5, 0, 2 },
+	{ INCREMENT, 5, 0, 3 },
+	{ INCREMENT, 5, 0, 4 },
+	{ DECREMENT, 5, 0, 3 },
+	{ DECREMENT, 5, 0, 2 },
+	{ DECREMENT, 5, 0, 1 },
+	{ DECREMENT, 5, 0, 0 },
+	{ FETCH, 10, 0, 1 },
+	{ FETCH, 1, 0, 1 },
+	{ FETCH, 2, 0, 2 },
+	{ FETCH, 3, 0, 3 },
+	{ INCREMENT, 1, 0, 2 },
+	{ DECREMENT, 2, 0, 1 },
+	{ DECREMENT, 2, 0, 0 },
+	{ FETCH, 12, 0, 0 },
+	{ EXIT, 0, 0, 0 }
+};
+
+struct test_program extended[] = {
+	{ STORE, 1,  1, 1 },
+	{ STORE, 2,  2, 2 },
+	{ STORE, 3,  3, 3 },
+	{ STORE, 4,  4, 4 },
+	{ STORE, 5,  5, 5 },
+	{ STORE, 6,  1, 1 },
+	{ STORE, 7,  2, 2 },
+	{ STORE, 8,  3, 3 },
+	{ STORE, 9,  4, 4 },
+	{ STORE, 10, 5, 5 },
+	{ STORE, 11, 1, 1 },
+	{ STORE, 12, 2, 2 },
+	{ STORE, 13, 3, 3 },
+	{ STORE, 14, 4, 4 },
+	{ STORE, 15, 5, 5 },
+	{ STORE, 16, 1, 1 },
+	{ STORE, 17, 2, 2 },
+	{ STORE, 18, 3, 3 },
+	{ STORE, 19, 4, 4 },
+	{ STORE, 20, 5, 5 },
+	{ STORE, 21, 1, 1 },
+	{ STORE, 22, 2, 2 },
+	{ STORE, 23, 3, 3 },
+	{ STORE, 24, 4, 4 },
+	{ STORE, 25, 5, 5 },
+	{ STORE, 26, 1, 1 },
+	{ STORE, 27, 2, 2 },
+	{ STORE, 28, 3, 3 },
+	{ STORE, 29, 4, 4 },
+	{ STORE, 30, 5, 5 },
+	{ EXIT, 0, 0, 0 }
+};
+
+/*
+ * Setup the variables for doing the inode scan test.
+ */
+static void setup(void)
+{
+	errcode_t	retval;
+	struct ext2_super_block param;
+
+	initialize_ext2_error_table();
+
+	memset(&param, 0, sizeof(param));
+	ext2fs_blocks_count_set(&param, 12000);
+
+	retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, &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);
+	}
+}
+
+int run_test(int flags, int size, char *dir, struct test_program *prog)
+{
+	errcode_t	retval;
+	ext2_icount_t	icount;
+	struct test_program *pc;
+	__u16		result;
+	int		problem = 0;
+
+	if (dir) {
+		retval = ext2fs_create_icount_tdb(test_fs, dir,
+						  flags, &icount);
+		if (retval) {
+			com_err("run_test", retval,
+				"while creating icount using tdb");
+			exit(1);
+		}
+	} else {
+		retval = ext2fs_create_icount2(test_fs, flags, size, 0,
+					       &icount);
+		if (retval) {
+			com_err("run_test", retval, "while creating icount");
+			exit(1);
+		}
+	}
+	for (pc = prog; pc->cmd != EXIT; pc++) {
+		switch (pc->cmd) {
+		case FETCH:
+			printf("icount_fetch(%u) = ", pc->ino);
+			break;
+		case STORE:
+			retval = ext2fs_icount_store(icount, pc->ino, pc->arg);
+			if (retval) {
+				com_err("run_test", retval,
+					"while calling icount_store");
+				exit(1);
+			}
+			printf("icount_store(%u, %u) = ", pc->ino, pc->arg);
+			break;
+		case INCREMENT:
+			retval = ext2fs_icount_increment(icount, pc->ino, 0);
+			if (retval) {
+				com_err("run_test", retval,
+					"while calling icount_increment");
+				exit(1);
+			}
+			printf("icount_increment(%u) = ", pc->ino);
+			break;
+		case DECREMENT:
+			retval = ext2fs_icount_decrement(icount, pc->ino, 0);
+			if (retval) {
+				com_err("run_test", retval,
+					"while calling icount_decrement");
+				exit(1);
+			}
+			printf("icount_decrement(%u) = ", pc->ino);
+			break;
+		}
+		retval = ext2fs_icount_fetch(icount, pc->ino, &result);
+		if (retval) {
+			com_err("run_test", retval,
+				"while calling icount_fetch");
+			exit(1);
+		}
+		printf("%u (%s)\n", result, (result == pc->expected) ?
+		       "OK" : "NOT OK");
+		if (result != pc->expected)
+			problem++;
+	}
+	printf("icount size is %u\n", ext2fs_get_icount_size(icount));
+	retval = ext2fs_icount_validate(icount, stdout);
+	if (retval) {
+		com_err("run_test", retval, "while calling icount_validate");
+		exit(1);
+	}
+	ext2fs_free_icount(icount);
+	return problem;
+}
+
+
+int main(int argc, char **argv)
+{
+	int failed = 0;
+
+	setup();
+	printf("Standard icount run:\n");
+	failed += run_test(0, 0, 0, prog);
+	printf("\nMultiple bitmap test:\n");
+	failed += run_test(EXT2_ICOUNT_OPT_INCREMENT, 0, 0, prog);
+	printf("\nResizing icount:\n");
+	failed += run_test(0, 3, 0, extended);
+	printf("\nStandard icount run with tdb:\n");
+	failed += run_test(0, 0, ".", prog);
+	printf("\nMultiple bitmap test with tdb:\n");
+	failed += run_test(EXT2_ICOUNT_OPT_INCREMENT, 0, ".", prog);
+	if (failed)
+		printf("FAILED!\n");
+	return failed;
+}
+#endif
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/imager.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/imager.c
new file mode 100644
index 0000000..378a3c8
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/imager.c
@@ -0,0 +1,410 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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;
+	blk64_t		blk;
+	ssize_t		actual;
+	errcode_t	retval;
+	off_t		r;
+
+	buf = malloc(fs->blocksize * BUF_BLOCKS);
+	if (!buf)
+		return ENOMEM;
+
+	for (group = 0; group < fs->group_desc_count; group++) {
+		blk = ext2fs_inode_table_loc(fs, (unsigned)group);
+		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;
+			retval = io_channel_read_blk64(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;
+					r = lseek(fd, fs->blocksize, SEEK_CUR);
+					if (r < 0) {
+						retval = errno;
+						goto errout;
+					}
+					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;
+	blk64_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 = ext2fs_inode_table_loc(fs, (unsigned)group);
+		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_blk64(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)
+{
+	ext2fs_generic_bitmap	bmap;
+	errcode_t		retval;
+	ssize_t			actual;
+	__u32			itr, cnt, size;
+	int			c, total_size;
+	char			buf[1024];
+
+	if (flags & IMAGER_FLAG_INODEMAP) {
+		if (!fs->inode_map) {
+			retval = ext2fs_read_inode_bitmap(fs);
+			if (retval)
+				return retval;
+		}
+		bmap = fs->inode_map;
+		itr = 1;
+		cnt = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
+		size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
+	} else {
+		if (!fs->block_map) {
+			retval = ext2fs_read_block_bitmap(fs);
+			if (retval)
+				return retval;
+		}
+		bmap = fs->block_map;
+		itr = fs->super->s_first_data_block;
+		cnt = EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count;
+		size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
+	}
+	total_size = size * fs->group_desc_count;
+
+	while (cnt > 0) {
+		size = sizeof(buf);
+		if (size > (cnt >> 3))
+			size = (cnt >> 3);
+
+		retval = ext2fs_get_generic_bmap_range(bmap, itr,
+						       size << 3, buf);
+		if (retval)
+			return retval;
+
+		actual = write(fd, buf, size);
+		if (actual == -1)
+			return errno;
+		if (actual != (int) size)
+			return EXT2_ET_SHORT_READ;
+
+		itr += size << 3;
+		cnt -= size << 3;
+	}
+
+	size = total_size % fs->blocksize;
+	memset(buf, 0, sizeof(buf));
+	if (size) {
+		size = fs->blocksize - size;
+		while (size) {
+			c = size;
+			if (c > (int) sizeof(buf))
+				c = sizeof(buf);
+			actual = write(fd, buf, c);
+			if (actual == -1)
+				return errno;
+			if (actual != c)
+				return EXT2_ET_SHORT_WRITE;
+			size -= c;
+		}
+	}
+	return 0;
+}
+
+
+/*
+ * Read the block/inode bitmaps.
+ */
+errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
+{
+	ext2fs_generic_bitmap	bmap;
+	errcode_t		retval;
+	__u32			itr, cnt;
+	char			buf[1024];
+	unsigned int		size;
+	ssize_t			actual;
+
+	if (flags & IMAGER_FLAG_INODEMAP) {
+		if (!fs->inode_map) {
+			retval = ext2fs_read_inode_bitmap(fs);
+			if (retval)
+				return retval;
+		}
+		bmap = fs->inode_map;
+		itr = 1;
+		cnt = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
+		size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
+	} else {
+		if (!fs->block_map) {
+			retval = ext2fs_read_block_bitmap(fs);
+			if (retval)
+				return retval;
+		}
+		bmap = fs->block_map;
+		itr = fs->super->s_first_data_block;
+		cnt = EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count;
+		size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
+	}
+
+	while (cnt > 0) {
+		size = sizeof(buf);
+		if (size > (cnt >> 3))
+			size = (cnt >> 3);
+
+		actual = read(fd, buf, size);
+		if (actual == -1)
+			return errno;
+		if (actual != (int) size)
+			return EXT2_ET_SHORT_READ;
+
+		retval = ext2fs_set_generic_bmap_range(bmap, itr,
+						       size << 3, buf);
+		if (retval)
+			return retval;
+
+		itr += size << 3;
+		cnt -= size << 3;
+	}
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ind_block.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ind_block.c
new file mode 100644
index 0000000..aa82ae6
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ind_block.c
@@ -0,0 +1,67 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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;
+#ifdef WORDS_BIGENDIAN
+	blk_t		*block_nr;
+	int		i;
+	int		limit = fs->blocksize >> 2;
+#endif
+
+	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 WORDS_BIGENDIAN
+	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)
+{
+#ifdef WORDS_BIGENDIAN
+	blk_t		*block_nr;
+	int		i;
+	int		limit = fs->blocksize >> 2;
+#endif
+
+	if (fs->flags & EXT2_FLAG_IMAGE_FILE)
+		return 0;
+
+#ifdef WORDS_BIGENDIAN
+	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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/initialize.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/initialize.c
new file mode 100644
index 0000000..2db8b3c
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/initialize.c
@@ -0,0 +1,519 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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) */
+
+/*
+ * 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 unsigned 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 = EXT2_DESC_PER_BLOCK(sb);
+	unsigned long max_blocks = 0xffffffff;
+	unsigned long rsv_groups;
+	unsigned int rsv_gdb;
+
+	/* We set it at 1024x the current filesystem size, or
+	 * the upper block count limit (2^32), whichever is lower.
+	 */
+	if (ext2fs_blocks_count(sb) < max_blocks / 1024)
+		max_blocks = ext2fs_blocks_count(sb) * 1024;
+	/*
+	 * ext2fs_div64_ceil() is unnecessary because max_blocks is
+	 * max _GDT_ blocks, which is limited to 32 bits.
+	 */
+	rsv_groups = ext2fs_div_ceil(max_blocks - sb->s_first_data_block, bpg);
+	rsv_gdb = ext2fs_div_ceil(rsv_groups, 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 = %u\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;
+	unsigned int	rem;
+	unsigned int	overhead = 0;
+	unsigned int	ipg;
+	dgrp_t		i;
+	blk64_t		free_blocks;
+	blk_t		numblocks;
+	int		rsv_gdt;
+	int		csum_flag;
+	int		bigalloc_flag;
+	int		io_flags;
+	unsigned	reserved_inos;
+	char		*buf = 0;
+	char		c;
+	double		reserved_ratio;
+
+	if (!param || !ext2fs_blocks_count(param))
+		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;
+	fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE;
+#ifdef WORDS_BIGENDIAN
+	fs->flags |= EXT2_FLAG_SWAP_BYTES;
+#endif
+	io_flags = IO_FLAG_RW;
+	if (flags & EXT2_FLAG_EXCLUSIVE)
+		io_flags |= IO_FLAG_EXCLUSIVE;
+	if (flags & EXT2_FLAG_DIRECT_IO)
+		io_flags |= IO_FLAG_DIRECT_IO;
+	retval = manager->open(name, io_flags, &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))
+#define assign_field(field)	(super->field = param->field)
+
+	super->s_magic = EXT2_SUPER_MAGIC;
+	super->s_state = EXT2_VALID_FS;
+
+	bigalloc_flag = EXT2_HAS_RO_COMPAT_FEATURE(param,
+				   EXT4_FEATURE_RO_COMPAT_BIGALLOC);
+
+	assign_field(s_log_block_size);
+
+	if (bigalloc_flag) {
+		set_field(s_log_cluster_size, super->s_log_block_size+4);
+		if (super->s_log_block_size > super->s_log_cluster_size) {
+			retval = EXT2_ET_INVALID_ARGUMENT;
+			goto cleanup;
+		}
+	} else
+		super->s_log_cluster_size = super->s_log_block_size;
+
+	set_field(s_first_data_block, super->s_log_cluster_size ? 0 : 1);
+	set_field(s_max_mnt_count, 0);
+	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_default_mount_opts, 0);
+	set_field(s_first_meta_bg, 0);
+	set_field(s_raid_stride, 0);		/* default stride size: 0 */
+	set_field(s_raid_stripe_width, 0);	/* default stripe width: 0 */
+	set_field(s_log_groups_per_flex, 0);
+	set_field(s_flags, 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);
+		if (super->s_inode_size >= sizeof(struct ext2_inode_large)) {
+			int extra_isize = sizeof(struct ext2_inode_large) -
+				EXT2_GOOD_OLD_INODE_SIZE;
+			set_field(s_min_extra_isize, extra_isize);
+			set_field(s_want_extra_isize, extra_isize);
+		}
+	} else {
+		super->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
+		super->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
+	}
+
+	set_field(s_checkinterval, 0);
+	super->s_mkfs_time = super->s_lastcheck = fs->now ? fs->now : time(NULL);
+
+	super->s_creator_os = CREATOR_OS;
+
+	fs->fragsize = fs->blocksize = EXT2_BLOCK_SIZE(super);
+	fs->cluster_ratio_bits = super->s_log_cluster_size -
+		super->s_log_block_size;
+
+	if (bigalloc_flag) {
+		unsigned long long bpg;
+
+		if (param->s_blocks_per_group &&
+		    param->s_clusters_per_group &&
+		    ((param->s_clusters_per_group * EXT2FS_CLUSTER_RATIO(fs)) !=
+		     param->s_blocks_per_group)) {
+			retval = EXT2_ET_INVALID_ARGUMENT;
+			goto cleanup;
+		}
+		if (param->s_clusters_per_group)
+			assign_field(s_clusters_per_group);
+		else if (param->s_blocks_per_group)
+			super->s_clusters_per_group = 
+				param->s_blocks_per_group /
+				EXT2FS_CLUSTER_RATIO(fs);
+		else if (super->s_log_cluster_size + 15 < 32)
+			super->s_clusters_per_group = fs->blocksize * 8;
+		else
+			super->s_clusters_per_group = (fs->blocksize - 1) * 8;
+		if (super->s_clusters_per_group > EXT2_MAX_CLUSTERS_PER_GROUP(super))
+			super->s_clusters_per_group = EXT2_MAX_CLUSTERS_PER_GROUP(super);
+		bpg = EXT2FS_C2B(fs,
+			(unsigned long long) super->s_clusters_per_group);
+		if (bpg >= (((unsigned long long) 1) << 32)) {
+			retval = EXT2_ET_INVALID_ARGUMENT;
+			goto cleanup;
+		}
+		super->s_blocks_per_group = bpg;
+	} else {
+		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_clusters_per_group = super->s_blocks_per_group;
+	}
+
+	ext2fs_blocks_count_set(super, ext2fs_blocks_count(param) &
+				~((blk64_t) EXT2FS_CLUSTER_MASK(fs)));
+	ext2fs_r_blocks_count_set(super, ext2fs_r_blocks_count(param));
+	if (ext2fs_r_blocks_count(super) >= ext2fs_blocks_count(param)) {
+		retval = EXT2_ET_INVALID_ARGUMENT;
+		goto cleanup;
+	}
+
+	set_field(s_mmp_update_interval, 0);
+
+	/*
+	 * 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 = (dgrp_t) ext2fs_div64_ceil(
+		ext2fs_blocks_count(super) - super->s_first_data_block,
+		EXT2_BLOCKS_PER_GROUP(super));
+	if (fs->group_desc_count == 0) {
+		retval = EXT2_ET_TOOSMALL;
+		goto cleanup;
+	}
+
+	set_field(s_desc_size,
+		  super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
+		  EXT2_MIN_DESC_SIZE_64BIT : 0);
+
+	fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
+					  EXT2_DESC_PER_BLOCK(super));
+
+	i = fs->blocksize >= 4096 ? 1 : 4096 / fs->blocksize;
+
+	if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT &&
+	    (ext2fs_blocks_count(super) / i) > (1ULL << 32))
+		set_field(s_inodes_count, ~0U);
+	else
+		set_field(s_inodes_count, ext2fs_blocks_count(super) / 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 = ext2fs_div_ceil(super->s_inodes_count, fs->group_desc_count);
+	if (ipg > fs->blocksize * 8) {
+		if (!bigalloc_flag && super->s_blocks_per_group >= 256) {
+			/* Try again with slightly different parameters */
+			super->s_blocks_per_group -= 8;
+			ext2fs_blocks_count_set(super,
+						ext2fs_blocks_count(param));
+			super->s_clusters_per_group = super->s_blocks_per_group;
+			goto retry;
+		} else {
+			retval = EXT2_ET_TOO_MANY_INODES;
+			goto cleanup;
+		}
+	}
+
+	if (ipg > (unsigned) EXT2_MAX_INODES_PER_GROUP(super))
+		ipg = EXT2_MAX_INODES_PER_GROUP(super);
+
+ipg_retry:
+	super->s_inodes_per_group = ipg;
+
+	/*
+	 * 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.
+	 */
+	if (super->s_inodes_per_group < 8)
+		super->s_inodes_per_group = 8;
+	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
+	 */
+	if ((__u64)super->s_inodes_per_group * fs->group_desc_count > ~0U) {
+		ipg--;
+		goto ipg_retry;
+	}
+	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;
+	}
+
+	/*
+	 * Calculate the maximum number of bookkeeping blocks per
+	 * group.  It includes the superblock, the block group
+	 * descriptors, the block bitmap, the inode bitmap, the inode
+	 * table, and the reserved gdt blocks.
+	 */
+	overhead = (int) (3 + fs->inode_blocks_per_group +
+			  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) {
+		retval = EXT2_ET_TOO_MANY_INODES;
+		goto cleanup;
+	}
+
+	/*
+	 * See if the last group is big enough to support the
+	 * necessary data structures.  If not, we need to get rid of
+	 * it.  We need to recalculate the overhead for the last block
+	 * group, since it might or might not have a superblock
+	 * backup.
+	 */
+	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;
+	rem = ((ext2fs_blocks_count(super) - super->s_first_data_block) %
+	       super->s_blocks_per_group);
+	if ((fs->group_desc_count == 1) && rem && (rem < overhead)) {
+		retval = EXT2_ET_TOOSMALL;
+		goto cleanup;
+	}
+	if (rem && (rem < overhead+50)) {
+		ext2fs_blocks_count_set(super, ext2fs_blocks_count(super) -
+					rem);
+		/*
+		 * If blocks count is changed, we need to recalculate
+		 * reserved blocks count not to exceed 50%.
+		 */
+		reserved_ratio = 100.0 * ext2fs_r_blocks_count(param) /
+			ext2fs_blocks_count(param);
+		ext2fs_r_blocks_count_set(super, reserved_ratio *
+			ext2fs_blocks_count(super) / 100.0);
+
+		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;
+
+	strcpy(buf, "block bitmap for ");
+	strcat(buf, fs->device_name);
+	retval = ext2fs_allocate_subcluster_bitmap(fs, buf, &fs->block_map);
+	if (retval)
+		goto cleanup;
+
+	strcpy(buf, "inode bitmap for ");
+	strcat(buf, fs->device_name);
+	retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
+	if (retval)
+		goto cleanup;
+
+	ext2fs_free_mem(&buf);
+
+	retval = ext2fs_get_array(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.
+	 *
+	 * If FLEX_BG meta-data grouping is used, only account for the
+	 * superblock and group descriptors (the inode tables and
+	 * bitmaps will be accounted for when allocated).
+	 */
+	free_blocks = 0;
+	csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					       EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
+	reserved_inos = super->s_first_ino;
+	for (i = 0; i < fs->group_desc_count; i++) {
+		/*
+		 * Don't set the BLOCK_UNINIT group for the last group
+		 * because the block bitmap needs to be padded.
+		 */
+		if (csum_flag) {
+			if (i != fs->group_desc_count - 1)
+				ext2fs_bg_flags_set(fs, i,
+						    EXT2_BG_BLOCK_UNINIT);
+			ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT);
+			numblocks = super->s_inodes_per_group;
+			if (reserved_inos) {
+				if (numblocks > reserved_inos) {
+					numblocks -= reserved_inos;
+					reserved_inos = 0;
+				} else {
+					reserved_inos -= numblocks;
+					numblocks = 0;
+				}
+			}
+			ext2fs_bg_itable_unused_set(fs, i, numblocks);
+		}
+		numblocks = ext2fs_reserve_super_and_bgd(fs, i, fs->block_map);
+		if (fs->super->s_log_groups_per_flex)
+			numblocks += 2 + fs->inode_blocks_per_group;
+
+		free_blocks += numblocks;
+		ext2fs_bg_free_blocks_count_set(fs, i, numblocks);
+		ext2fs_bg_free_inodes_count_set(fs, i, fs->super->s_inodes_per_group);
+		ext2fs_bg_used_dirs_count_set(fs, i, 0);
+		ext2fs_group_desc_csum_set(fs, i);
+	}
+	free_blocks &= ~EXT2FS_CLUSTER_MASK(fs);
+	ext2fs_free_blocks_count_set(super, free_blocks);
+
+	c = (char) 255;
+	if (((int) c) == -1) {
+		super->s_flags |= EXT2_FLAGS_SIGNED_HASH;
+	} else {
+		super->s_flags |= EXT2_FLAGS_UNSIGNED_HASH;
+	}
+
+	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:
+	free(buf);
+	ext2fs_free(fs);
+	return retval;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/inline.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/inline.c
new file mode 100644
index 0000000..05da1f7
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/inline.c
@@ -0,0 +1,121 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600	/* for posix_memalign() */
+#endif
+
+#include "config.h"
+#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
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#include "ext2_fs.h"
+#define INCLUDE_INLINE_FUNCS
+#include "ext2fs.h"
+
+/*
+ * We used to define this as an inline, but since we are now using
+ * autoconf-defined #ifdef's, we need to export this as a
+ * library-provided function exclusively.
+ */
+errcode_t ext2fs_get_memalign(unsigned long size,
+			      unsigned long align, void *ptr)
+{
+	errcode_t retval;
+	void **p = ptr;
+
+	if (align < 8)
+		align = 8;
+#ifdef HAVE_POSIX_MEMALIGN
+	retval = posix_memalign(p, align, size);
+	if (retval) {
+		if (retval == ENOMEM)
+			return EXT2_ET_NO_MEMORY;
+		return retval;
+	}
+#else
+#ifdef HAVE_MEMALIGN
+	*p = memalign(align, size);
+	if (*p == NULL) {
+		if (errno)
+			return errno;
+		else
+			return EXT2_ET_NO_MEMORY;
+	}
+#else
+#ifdef HAVE_VALLOC
+	if (align > sizeof(long long))
+		*p = valloc(size);
+	else
+#endif
+		*p = malloc(size);
+	if ((unsigned long) *p & (align - 1)) {
+		free(*p);
+		*p = 0;
+	}
+	if (*p == 0)
+		return EXT2_ET_NO_MEMORY;
+#endif
+#endif
+	return 0;
+}
+
+#ifdef DEBUG
+static int isaligned(void *ptr, unsigned long align)
+{
+	return (((unsigned long) ptr & (align - 1)) == 0);
+}
+
+static errcode_t test_memalign(unsigned long align)
+{
+	void *ptr = 0;
+	errcode_t retval;
+
+	retval = ext2fs_get_memalign(32, align, &ptr);
+	if (!retval && !isaligned(ptr, align))
+		retval = EINVAL;
+	free(ptr);
+	printf("tst_memalign(%lu) is %s\n", align,
+	       retval ? error_message(retval) : "OK");
+	return retval;
+}
+
+int main(int argc, char **argv)
+{
+	int err = 0;
+
+	if (test_memalign(4))
+		err++;
+	if (test_memalign(32))
+		err++;
+	if (test_memalign(1024))
+		err++;
+	if (test_memalign(4096))
+		err++;
+	return err;
+}
+#endif
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/inode.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/inode.c
new file mode 100644
index 0000000..573a8fa
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/inode.c
@@ -0,0 +1,841 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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>
+#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;
+	blk64_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_array(fs->icache->cache_size,
+				  sizeof(struct ext2_inode_cache_ent),
+				  &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 = ext2fs_inode_table_loc(scan->fs,
+						     scan->current_group);
+	scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
+	scan->blocks_left = scan->fs->inode_blocks_per_group;
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+		scan->inodes_left -=
+			ext2fs_bg_itable_unused(fs, scan->current_group);
+		scan->blocks_left =
+			(scan->inodes_left +
+			 (fs->blocksize / scan->inode_size - 1)) *
+			scan->inode_size / fs->blocksize;
+	}
+	retval = io_channel_alloc_buf(fs->io, scan->inode_buffer_blocks,
+				      &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;
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
+		scan->scan_flags |= EXT2_SF_DO_LAZY;
+	*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)
+{
+	ext2_filsys fs = scan->fs;
+
+	scan->current_group++;
+	scan->groups_left--;
+
+	scan->current_block = ext2fs_inode_table_loc(scan->fs,
+						     scan->current_group);
+	scan->current_inode = scan->current_group *
+		EXT2_INODES_PER_GROUP(fs->super);
+
+	scan->bytes_left = 0;
+	scan->inodes_left = EXT2_INODES_PER_GROUP(fs->super);
+	scan->blocks_left = fs->inode_blocks_per_group;
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+		scan->inodes_left -=
+			ext2fs_bg_itable_unused(fs, scan->current_group);
+		scan->blocks_left =
+			(scan->inodes_left +
+			 (fs->blocksize / scan->inode_size - 1)) *
+			scan->inode_size / fs->blocksize;
+	}
+
+	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,
+					    blk64_t *num_blocks)
+{
+	blk64_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)
+{
+	blk64_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_blk64(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;
+	}
+	/*
+	 * These checks are done outside the above if statement so
+	 * they can be done for block group #0.
+	 */
+	if ((scan->scan_flags & EXT2_SF_DO_LAZY) &&
+	    (ext2fs_bg_flags_test(scan->fs, scan->current_group, EXT2_BG_INODE_UNINIT)
+	     ))
+		goto force_new_group;
+	if (scan->inodes_left == 0)
+		goto force_new_group;
+	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 WORDS_BIGENDIAN
+		memset(inode, 0, bufsize);
+		ext2fs_swap_inode_full(scan->fs,
+			       (struct ext2_inode_large *) inode,
+			       (struct ext2_inode_large *) scan->temp_buffer,
+			       0, bufsize);
+#else
+		*inode = *((struct ext2_inode *) scan->temp_buffer);
+#endif
+		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 WORDS_BIGENDIAN
+		memset(inode, 0, bufsize);
+		ext2fs_swap_inode_full(scan->fs,
+				(struct ext2_inode_large *) inode,
+				(struct ext2_inode_large *) scan->ptr,
+				0, bufsize);
+#else
+		memcpy(inode, scan->ptr, bufsize);
+#endif
+		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)
+{
+	blk64_t		block_nr;
+	unsigned long 	group, block, 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 &&
+	    ((bufsize == sizeof(struct ext2_inode)) ||
+	     (EXT2_INODE_SIZE(fs->super) == sizeof(struct ext2_inode)))) {
+		retval = (fs->read_inode)(fs, ino, inode);
+		if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
+			return retval;
+	}
+	if ((ino == 0) || (ino > fs->super->s_inodes_count))
+		return EXT2_ET_BAD_INODE_NUM;
+	/* 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 retrieved 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 (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);
+		if (group > fs->group_desc_count)
+			return EXT2_ET_BAD_INODE_NUM;
+		offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
+			EXT2_INODE_SIZE(fs->super);
+		block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
+		if (!ext2fs_inode_table_loc(fs, (unsigned) group))
+			return EXT2_ET_MISSING_INODE_TABLE;
+		block_nr = ext2fs_inode_table_loc(fs, group) +
+			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_blk64(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 WORDS_BIGENDIAN
+	ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) inode,
+			       (struct ext2_inode_large *) inode,
+			       0, bufsize);
+#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)
+{
+	blk64_t block_nr;
+	unsigned long group, block, 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) {
+			retval = ENOMEM;
+			goto errout;
+		}
+	} else
+		w_inode = &temp_inode;
+	memset(w_inode, 0, length);
+
+#ifdef WORDS_BIGENDIAN
+	ext2fs_swap_inode_full(fs, w_inode,
+			       (struct ext2_inode_large *) inode,
+			       1, bufsize);
+#else
+	memcpy(w_inode, inode, bufsize);
+#endif
+
+	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 (!ext2fs_inode_table_loc(fs, (unsigned) group)) {
+		retval = EXT2_ET_MISSING_INODE_TABLE;
+		goto errout;
+	}
+	block_nr = ext2fs_inode_table_loc(fs, (unsigned) group) + 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_blk64(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_blk64(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;
+	errcode_t		retval;
+	__u32 			t = fs->now ? fs->now : time(NULL);
+
+	if (!inode->i_ctime)
+		inode->i_ctime = t;
+	if (!inode->i_mtime)
+		inode->i_mtime = t;
+	if (!inode->i_atime)
+		inode->i_atime = t;
+
+	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;
+	if (!large_inode->i_crtime)
+		large_inode->i_crtime = t;
+
+	retval = ext2fs_write_inode_full(fs, ino, buf, size);
+	free(buf);
+	return retval;
+}
+
+
+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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/inode_io.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/inode_io.c
new file mode 100644
index 0000000..8e0944e
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/inode_io.c
@@ -0,0 +1,292 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 errcode_t inode_read_blk64(io_channel channel,
+				unsigned long long block, int count, void *data);
+static errcode_t inode_write_blk64(io_channel channel,
+				unsigned long long block, int count, 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,
+	NULL,
+	NULL,
+	inode_read_blk64,
+	inode_write_blk64
+};
+
+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 (io && io->name)
+		ext2fs_free_mem(&io->name);
+	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_blk64(io_channel channel,
+				unsigned long 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_read_blk(io_channel channel, unsigned long block,
+			       int count, void *buf)
+{
+	return inode_read_blk64(channel, block, count, buf);
+}
+
+static errcode_t inode_write_blk64(io_channel channel,
+				unsigned long 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_blk(io_channel channel, unsigned long block,
+				int count, const void *buf)
+{
+	return inode_write_blk64(channel, block, count, buf);
+}
+
+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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/io_manager.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/io_manager.c
new file mode 100644
index 0000000..34e4859
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/io_manager.c
@@ -0,0 +1,130 @@
+/*
+ * io_manager.c --- the I/O manager abstraction
+ */
+
+#include "config.h"
+#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;
+}
+
+errcode_t io_channel_read_blk64(io_channel channel, unsigned long long block,
+				 int count, void *data)
+{
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+
+	if (channel->manager->read_blk64)
+		return (channel->manager->read_blk64)(channel, block,
+						      count, data);
+
+	if ((block >> 32) != 0)
+		return EXT2_ET_IO_CHANNEL_NO_SUPPORT_64;
+
+	return (channel->manager->read_blk)(channel, (unsigned long) block,
+					     count, data);
+}
+
+errcode_t io_channel_write_blk64(io_channel channel, unsigned long long block,
+				 int count, const void *data)
+{
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+
+	if (channel->manager->write_blk64)
+		return (channel->manager->write_blk64)(channel, block,
+						       count, data);
+
+	if ((block >> 32) != 0)
+		return EXT2_ET_IO_CHANNEL_NO_SUPPORT_64;
+
+	return (channel->manager->write_blk)(channel, (unsigned long) block,
+					     count, data);
+}
+
+errcode_t io_channel_discard(io_channel channel, unsigned long long block,
+			     unsigned long long count)
+{
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+
+	if (channel->manager->discard)
+		return (channel->manager->discard)(channel, block, count);
+
+	return EXT2_ET_UNIMPLEMENTED;
+}
+
+errcode_t io_channel_alloc_buf(io_channel io, int count, void *ptr)
+{
+	size_t	size;
+
+	if (count == 0)
+		size = io->block_size;
+	else if (count > 0)
+		size = io->block_size * count;
+	else
+		size = -count;
+
+	if (io->align)
+		return ext2fs_get_memalign(size, io->align, ptr);
+	else
+		return ext2fs_get_mem(size, ptr);
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/irel.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/irel.h
new file mode 100644
index 0000000..8aaa2d2
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/irel.h
@@ -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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+struct ext2_inode_reference {
+	blk64_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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/irel_ma.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/irel_ma.c
new file mode 100644
index 0000000..c64b7e7
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/irel_ma.c
@@ -0,0 +1,377 @@
+/*
+ * irel_ma.c
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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_array(max_inode+1, sizeof(ext2_ino_t),
+		&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_array((max_inode+1,
+		sizeof(struct ext2_inode_relocate_entry), &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(max_inode+1,
+		sizeof(struct inode_reference_entry), &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_array(ent->max_refs,
+			sizeof(struct ext2_inode_reference), &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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ismounted.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ismounted.c
new file mode 100644
index 0000000..6c6ecff
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/ismounted.c
@@ -0,0 +1,438 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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_LINUX_LOOP_H
+#include <linux/loop.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_LINUX_MAJOR_H
+#include <linux/major.h>
+#endif /* HAVE_LINUX_MAJOR_H */
+#endif /* HAVE_LINUX_LOOP_H */
+#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"
+
+/*
+ * Check to see if a regular file is mounted.
+ * If /etc/mtab/ is a symlink of /proc/mounts, you will need the following check
+ * because the name in /proc/mounts is a loopback device not a regular file.
+ */
+static int check_loop_mounted(const char *mnt_fsname, dev_t mnt_rdev,
+				dev_t file_dev, ino_t file_ino)
+{
+#if defined(HAVE_LINUX_LOOP_H) && defined(HAVE_LINUX_MAJOR_H)
+	struct loop_info64 loopinfo;
+	int loop_fd, ret;
+
+	if (major(mnt_rdev) == LOOP_MAJOR) {
+		loop_fd = open(mnt_fsname, O_RDONLY);
+		if (loop_fd < 0)
+			return -1;
+
+		ret = ioctl(loop_fd, LOOP_GET_STATUS64, &loopinfo);
+		close(loop_fd);
+		if (ret < 0)
+			return -1;
+
+		if (file_dev == loopinfo.lo_device &&
+				file_ino == loopinfo.lo_inode)
+			return 1;
+	}
+#endif /* defined(HAVE_LINUX_LOOP_H) && defined(HAVE_LINUX_MAJOR_H) */
+	return 0;
+}
+
+#ifdef HAVE_SETMNTENT
+/*
+ * 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) {
+		if (errno == ENOENT) {
+			if (getenv("EXT2FS_NO_MTAB_OK"))
+				return 0;
+			else
+				return EXT2_ET_NO_MTAB_FILE;
+		}
+		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 (mnt->mnt_fsname[0] != '/')
+			continue;
+		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;
+				if (check_loop_mounted(mnt->mnt_fsname,
+						st_buf.st_rdev, file_dev,
+						file_ino) == 1)
+					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, 0600);
+		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_SETMNTENT */
+
+/*
+ * 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 */
+	if (!fgets(buf, sizeof(buf), f))
+		goto leave;
+	if (*buf && strncmp(buf, "Filename\t", 9))
+		/* Linux <=2.6.19 contained a bug in the /proc/swaps
+		 * code where the header would not be displayed
+		 */
+		goto valid_first_line;
+
+	while (fgets(buf, sizeof(buf), f)) {
+valid_first_line:
+		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__ */
+	}
+
+leave:
+	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)
+{
+	errcode_t	retval = 0;
+
+	if (is_swap_device(device)) {
+		*mount_flags = EXT2_MF_MOUNTED | EXT2_MF_SWAP;
+		strncpy(mtpt, "<swap>", mtlen);
+	} else {
+#ifdef HAVE_SETMNTENT
+		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_SETMNTENT */
+	}
+	if (retval)
+		return retval;
+
+#ifdef __linux__ /* This only works on Linux 2.6+ systems */
+	{
+		struct stat st_buf;
+
+		if (stat(device, &st_buf) == 0 && S_ISBLK(st_buf.st_mode)) {
+			int fd = open(device, O_RDONLY | O_EXCL);
+
+			if (fd >= 0)
+				close(fd);
+			else if (errno == EBUSY)
+				*mount_flags |= EXT2_MF_BUSY;
+		}
+	}
+#endif
+
+	return 0;
+}
+
+/*
+ * 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);
+	}
+
+	add_error_table(&et_ext2_error_table);
+	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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/jfs_compat.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/jfs_compat.h
new file mode 100644
index 0000000..7b8aafd
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/jfs_compat.h
@@ -0,0 +1,68 @@
+
+#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;
+	tid_t			j_failed_commit;
+};
+
+#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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/jfs_dat.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/jfs_dat.h
new file mode 100644
index 0000000..62778c6
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/jfs_dat.h
@@ -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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/jfs_user.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/jfs_user.h
new file mode 100644
index 0000000..3a52123
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/jfs_user.h
@@ -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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/kernel-jbd.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/kernel-jbd.h
new file mode 100644
index 0000000..059bf8f
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/kernel-jbd.h
@@ -0,0 +1,952 @@
+/*
+ * 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;
+
+/*
+ * Checksum types.
+ */
+#define JBD2_CRC32_CHKSUM   1
+#define JBD2_MD5_CHKSUM     2
+#define JBD2_SHA1_CHKSUM    3
+
+#define JBD2_CRC32_CHKSUM_SIZE 4
+
+#define JBD2_CHECKSUM_BYTES (32 / sizeof(__u32))
+/*
+ * Commit block header for storing transactional checksums:
+ */
+struct commit_header {
+	__u32		h_magic;
+	__u32		h_blocktype;
+	__u32		h_sequence;
+	unsigned char	h_chksum_type;
+	unsigned char	h_chksum_size;
+	unsigned char	h_padding[2];
+	__u32		h_chksum[JBD2_CHECKSUM_BYTES];
+	__u64		h_commit_sec;
+	__u32		h_commit_nsec;
+};
+
+/*
+ * 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 */
+	__u32		t_blocknr_high; /* most-significant high 32bits. */
+} journal_block_tag_t;
+
+#define JBD_TAG_SIZE64 (sizeof(journal_block_tag_t))
+#define JBD_TAG_SIZE32 (8)
+
+/*
+ * 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 & ext2fs_cpu_to_be32((mask))))
+#define JFS_HAS_RO_COMPAT_FEATURE(j,mask)				\
+	((j)->j_format_version >= 2 &&					\
+	 ((j)->j_superblock->s_feature_ro_compat & ext2fs_cpu_to_be32((mask))))
+#define JFS_HAS_INCOMPAT_FEATURE(j,mask)				\
+	((j)->j_format_version >= 2 &&					\
+	 ((j)->j_superblock->s_feature_incompat & ext2fs_cpu_to_be32((mask))))
+
+#define JFS_FEATURE_COMPAT_CHECKSUM	0x00000001
+
+#define JFS_FEATURE_INCOMPAT_REVOKE	0x00000001
+
+#define JFS_FEATURE_INCOMPAT_REVOKE		0x00000001
+#define JFS_FEATURE_INCOMPAT_64BIT		0x00000002
+#define JFS_FEATURE_INCOMPAT_ASYNC_COMMIT	0x00000004
+
+/* 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|\
+					 JFS_FEATURE_INCOMPAT_ASYNC_COMMIT|\
+					 JFS_FEATURE_INCOMPAT_64BIT)
+
+#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;
+
+	/* Failed journal commit ID */
+	unsigned int		j_failed_commit;
+};
+
+/*
+ * 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__   */
+
+static inline int tid_gt(tid_t x, tid_t y) EXT2FS_ATTR((unused));
+static inline int tid_geq(tid_t x, tid_t y) EXT2FS_ATTR((unused));
+
+/* 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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/kernel-list.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/kernel-list.h
new file mode 100644
index 0000000..01f4f6b
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/kernel-list.h
@@ -0,0 +1,109 @@
+#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 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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/link.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/link.c
new file mode 100644
index 0000000..bf3c859
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/link.c
@@ -0,0 +1,157 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+struct link_struct  {
+	ext2_filsys	fs;
+	const char	*name;
+	int		namelen;
+	ext2_ino_t	inode;
+	int		flags;
+	int		done;
+	unsigned int	blocksize;
+	errcode_t	err;
+	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;
+	unsigned int rec_len, min_rec_len, curr_rec_len;
+	int ret = 0;
+
+	if (ls->done)
+		return DIRENT_ABORT;
+
+	rec_len = EXT2_DIR_REC_LEN(ls->namelen);
+
+	ls->err = ext2fs_get_rec_len(ls->fs, dirent, &curr_rec_len);
+	if (ls->err)
+		return DIRENT_ABORT;
+
+	/*
+	 * See if the following directory entry (if any) is unused;
+	 * if so, absorb it into this one.
+	 */
+	next = (struct ext2_dir_entry *) (buf + offset + curr_rec_len);
+	if ((offset + (int) curr_rec_len < blocksize - 8) &&
+	    (next->inode == 0) &&
+	    (offset + (int) curr_rec_len + (int) next->rec_len <= blocksize)) {
+		curr_rec_len += next->rec_len;
+		ls->err = ext2fs_set_rec_len(ls->fs, curr_rec_len, dirent);
+		if (ls->err)
+			return DIRENT_ABORT;
+		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 (curr_rec_len < (min_rec_len + rec_len))
+			return ret;
+		rec_len = curr_rec_len - min_rec_len;
+		ls->err = ext2fs_set_rec_len(ls->fs, min_rec_len, dirent);
+		if (ls->err)
+			return DIRENT_ABORT;
+		next = (struct ext2_dir_entry *) (buf + offset +
+						  dirent->rec_len);
+		next->inode = 0;
+		next->name_len = 0;
+		ls->err = ext2fs_set_rec_len(ls->fs, rec_len, next);
+		if (ls->err)
+			return DIRENT_ABORT;
+		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 (curr_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.fs = fs;
+	ls.name = name;
+	ls.namelen = name ? strlen(name) : 0;
+	ls.inode = ino;
+	ls.flags = flags;
+	ls.done = 0;
+	ls.sb = fs->super;
+	ls.blocksize = fs->blocksize;
+	ls.err = 0;
+
+	retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
+				    0, link_proc, &ls);
+	if (retval)
+		return retval;
+	if (ls.err)
+		return ls.err;
+
+	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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/llseek.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/llseek.c
new file mode 100644
index 0000000..c3a98a2
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/llseek.c
@@ -0,0 +1,141 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+#include "config.h"
+#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 SIZEOF_LONG == SIZEOF_LONG_LONG
+
+#define llseek lseek
+
+#else /* SIZEOF_LONG != SIZEOF_LONG_LONG */
+
+#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)
+{
+#if SIZEOF_OFF_T >= SIZEOF_LONG_LONG
+	return lseek (fd, offset, origin);
+#else
+	ext2_loff_t result;
+	static int do_compat = 0;
+
+	if (do_compat)
+		goto fallback;
+
+	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++;
+	fallback:
+		if (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))
+			return lseek(fd, (off_t) offset, origin);
+		errno = EINVAL;
+		return -1;
+	}
+	return result;
+#endif
+}
+
+#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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/lookup.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/lookup.c
new file mode 100644
index 0000000..0e66e71
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/lookup.c
@@ -0,0 +1,70 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/mkdir.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/mkdir.c
new file mode 100644
index 0000000..b12bf2d
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/mkdir.c
@@ -0,0 +1,156 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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)
+{
+	ext2_extent_handle_t	handle;
+	errcode_t		retval;
+	struct ext2_inode	parent_inode, inode;
+	ext2_ino_t		ino = inum;
+	ext2_ino_t		scratch_ino;
+	blk64_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_block2(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;
+	ext2fs_iblk_set(fs, &inode, 1);
+	if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS)
+		inode.i_flags |= EXT4_EXTENTS_FL;
+	else
+		inode.i_block[0] = blk;
+	inode.i_links_count = 2;
+	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;
+
+	if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) {
+		retval = ext2fs_extent_open2(fs, ino, &inode, &handle);
+		if (retval)
+			goto cleanup;
+		retval = ext2fs_extent_set_bmap(handle, 0, blk, 0);
+		ext2fs_extent_free(handle);
+		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_stats2(fs, blk, +1);
+	ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
+
+cleanup:
+	if (block)
+		ext2fs_free_mem(&block);
+	return retval;
+
+}
+
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/mkjournal.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/mkjournal.c
new file mode 100644
index 0000000..d09c458
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/mkjournal.c
@@ -0,0 +1,637 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 num_blocks, int flags,
+					   char  **ret_jsb)
+{
+	errcode_t		retval;
+	journal_superblock_t	*jsb;
+
+	if (num_blocks < 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(num_blocks);
+	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 num_blocks, int flags)
+{
+	errcode_t	retval;
+	char		*buf = 0;
+	int		fd, ret_size;
+	blk_t		i;
+
+	if ((retval = ext2fs_create_journal_superblock(fs, num_blocks, flags,
+						       &buf)))
+		return retval;
+
+	/* Open the device or journal file */
+	if ((fd = open(filename, O_WRONLY)) < 0) {
+		retval = errno;
+		goto errfree;
+	}
+
+	/* 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);
+
+	if (flags & EXT2_MKJOURNAL_LAZYINIT)
+		goto success;
+
+	for (i = 1; i < num_blocks; i++) {
+		ret_size = write(fd, buf, fs->blocksize);
+		if (ret_size < 0) {
+			retval = errno;
+			goto errout;
+		}
+		if (ret_size != (int) fs->blocksize)
+			goto errout;
+	}
+
+success:
+	retval = 0;
+errout:
+	close(fd);
+errfree:
+	ext2fs_free_mem(&buf);
+	return retval;
+}
+
+/*
+ * Convenience function which zeros out _num_ blocks starting at
+ * _blk_.  In case of an error, the details of the error is returned
+ * via _ret_blk_ and _ret_count_ if they are non-NULL pointers.
+ * Returns 0 on success, and an error code on an error.
+ *
+ * As a special case, if the first argument is NULL, then it will
+ * attempt to free the static zeroizing buffer.  (This is to keep
+ * programs that check for memory leaks happy.)
+ */
+#define STRIDE_LENGTH 8
+errcode_t ext2fs_zero_blocks2(ext2_filsys fs, blk64_t blk, int num,
+			      blk64_t *ret_blk, int *ret_count)
+{
+	int		j, count;
+	static char	*buf;
+	errcode_t	retval;
+
+	/* If fs is null, clean up the static buffer and return */
+	if (!fs) {
+		if (buf) {
+			free(buf);
+			buf = 0;
+		}
+		return 0;
+	}
+	/* Allocate the zeroizing buffer if necessary */
+	if (!buf) {
+		buf = malloc(fs->blocksize * STRIDE_LENGTH);
+		if (!buf)
+			return ENOMEM;
+		memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
+	}
+	/* OK, do the write loop */
+	j=0;
+	while (j < num) {
+		if (blk % STRIDE_LENGTH) {
+			count = STRIDE_LENGTH - (blk % STRIDE_LENGTH);
+			if (count > (num - j))
+				count = num - j;
+		} else {
+			count = num - j;
+			if (count > STRIDE_LENGTH)
+				count = STRIDE_LENGTH;
+		}
+		retval = io_channel_write_blk64(fs->io, blk, count, buf);
+		if (retval) {
+			if (ret_count)
+				*ret_count = count;
+			if (ret_blk)
+				*ret_blk = blk;
+			return retval;
+		}
+		j += count; blk += count;
+	}
+	return 0;
+}
+
+errcode_t ext2fs_zero_blocks(ext2_filsys fs, blk_t blk, int num,
+			     blk_t *ret_blk, int *ret_count)
+{
+	blk64_t ret_blk2;
+	errcode_t retval;
+
+	retval = ext2fs_zero_blocks2(fs, blk, num, &ret_blk2, ret_count);
+	if (retval)
+		*ret_blk = (blk_t) ret_blk2;
+	return retval;
+}
+
+/*
+ * Helper function for creating the journal using direct I/O routines
+ */
+struct mkjournal_struct {
+	int		num_blocks;
+	int		newblocks;
+	blk64_t		goal;
+	blk64_t		blk_to_zero;
+	int		zero_count;
+	int		flags;
+	char		*buf;
+	errcode_t	err;
+};
+
+static int mkjournal_proc(ext2_filsys	fs,
+			  blk64_t	*blocknr,
+			  e2_blkcnt_t	blockcnt,
+			  blk64_t	ref_block EXT2FS_ATTR((unused)),
+			  int		ref_offset EXT2FS_ATTR((unused)),
+			  void		*priv_data)
+{
+	struct mkjournal_struct *es = (struct mkjournal_struct *) priv_data;
+	blk64_t	new_blk;
+	errcode_t	retval;
+
+	if (*blocknr) {
+		es->goal = *blocknr;
+		return 0;
+	}
+	if (blockcnt &&
+	    (EXT2FS_B2C(fs, es->goal) == EXT2FS_B2C(fs, es->goal+1)))
+		new_blk = es->goal+1;
+	else {
+		es->goal &= ~EXT2FS_CLUSTER_MASK(fs);
+		retval = ext2fs_new_block2(fs, es->goal, 0, &new_blk);
+		if (retval) {
+			es->err = retval;
+			return BLOCK_ABORT;
+		}
+		ext2fs_block_alloc_stats2(fs, new_blk, +1);
+		es->newblocks++;
+	}
+	if (blockcnt >= 0)
+		es->num_blocks--;
+
+	retval = 0;
+	if (blockcnt <= 0)
+		retval = io_channel_write_blk64(fs->io, new_blk, 1, es->buf);
+	else if (!(es->flags & EXT2_MKJOURNAL_LAZYINIT)) {
+		if (es->zero_count) {
+			if ((es->blk_to_zero + es->zero_count == new_blk) &&
+			    (es->zero_count < 1024))
+				es->zero_count++;
+			else {
+				retval = ext2fs_zero_blocks2(fs,
+							     es->blk_to_zero,
+							     es->zero_count,
+							     0, 0);
+				es->zero_count = 0;
+			}
+		}
+		if (es->zero_count == 0) {
+			es->blk_to_zero = new_blk;
+			es->zero_count = 1;
+		}
+	}
+
+	if (blockcnt == 0)
+		memset(es->buf, 0, fs->blocksize);
+
+	if (retval) {
+		es->err = retval;
+		return BLOCK_ABORT;
+	}
+	*blocknr = es->goal = new_blk;
+
+	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 num_blocks, int flags)
+{
+	char			*buf;
+	dgrp_t			group, start, end, i, log_flex;
+	errcode_t		retval;
+	struct ext2_inode	inode;
+	unsigned long long	inode_size;
+	struct mkjournal_struct	es;
+
+	if ((retval = ext2fs_create_journal_superblock(fs, num_blocks, flags,
+						       &buf)))
+		return retval;
+
+	if ((retval = ext2fs_read_bitmaps(fs)))
+		goto out2;
+
+	if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
+		goto out2;
+
+	if (inode.i_blocks > 0) {
+		retval = EEXIST;
+		goto out2;
+	}
+
+	es.num_blocks = num_blocks;
+	es.newblocks = 0;
+	es.buf = buf;
+	es.err = 0;
+	es.flags = flags;
+	es.zero_count = 0;
+
+	if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) {
+		inode.i_flags |= EXT4_EXTENTS_FL;
+		if ((retval = ext2fs_write_inode(fs, journal_ino, &inode)))
+			goto out2;
+	}
+
+	/*
+	 * Set the initial goal block to be roughly at the middle of
+	 * the filesystem.  Pick a group that has the largest number
+	 * of free blocks.
+	 */
+	group = ext2fs_group_of_blk2(fs, (ext2fs_blocks_count(fs->super) -
+					 fs->super->s_first_data_block) / 2);
+	log_flex = 1 << fs->super->s_log_groups_per_flex;
+	if (fs->super->s_log_groups_per_flex && (group > log_flex)) {
+		group = group & ~(log_flex - 1);
+		while ((group < fs->group_desc_count) &&
+		       ext2fs_bg_free_blocks_count(fs, group) == 0)
+			group++;
+		if (group == fs->group_desc_count)
+			group = 0;
+		start = group;
+	} else
+		start = (group > 0) ? group-1 : group;
+	end = ((group+1) < fs->group_desc_count) ? group+1 : group;
+	group = start;
+	for (i=start+1; i <= end; i++)
+		if (ext2fs_bg_free_blocks_count(fs, i) >
+		    ext2fs_bg_free_blocks_count(fs, group))
+			group = i;
+
+	es.goal = ext2fs_group_first_block2(fs, group);
+	retval = ext2fs_block_iterate3(fs, journal_ino, BLOCK_FLAG_APPEND,
+				       0, mkjournal_proc, &es);
+	if (es.err) {
+		retval = es.err;
+		goto errout;
+	}
+	if (es.zero_count) {
+		retval = ext2fs_zero_blocks2(fs, es.blk_to_zero,
+					    es.zero_count, 0, 0);
+		if (retval)
+			goto errout;
+	}
+
+	if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
+		goto errout;
+
+	inode_size = (unsigned long long)fs->blocksize * num_blocks;
+	inode.i_size = inode_size & 0xFFFFFFFF;
+	inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
+	if (ext2fs_needs_large_file_feature(inode_size))
+		fs->super->s_feature_ro_compat |=
+			EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
+	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
+	inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
+	inode.i_links_count = 1;
+	inode.i_mode = LINUX_S_IFREG | 0600;
+
+	if ((retval = ext2fs_write_new_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[15] = inode.i_size_high;
+	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_zero_blocks2(0, 0, 0, 0, 0);
+out2:
+	ext2fs_free_mem(&buf);
+	return retval;
+}
+
+/*
+ * Find a reasonable journal file size (in blocks) given the number of blocks
+ * in the filesystem.  For very small filesystems, it is not reasonable to
+ * have a journal that fills more than half of the filesystem.
+ */
+int ext2fs_default_journal_size(__u64 num_blocks)
+{
+	if (num_blocks < 2048)
+		return -1;
+	if (num_blocks < 32768)
+		return (1024);
+	if (num_blocks < 256*1024)
+		return (4096);
+	if (num_blocks < 512*1024)
+		return (8192);
+	if (num_blocks < 1024*1024)
+		return (16384);
+	return 32768;
+}
+
+/*
+ * 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_blk64(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_blk64(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 num_blocks, int flags)
+{
+	errcode_t		retval;
+	ext2_ino_t		journal_ino;
+	struct stat		st;
+	char			jfile[1024];
+	int			mount_flags;
+	int			fd = -1;
+
+	if (flags & EXT2_MKJOURNAL_NO_MNT_CHECK)
+		mount_flags = 0;
+	else if ((retval = ext2fs_check_mount_point(fs->device_name,
+						    &mount_flags,
+						    jfile, sizeof(jfile)-10)))
+		return retval;
+
+	if (mount_flags & EXT2_MF_MOUNTED) {
+#if HAVE_EXT2_IOCTLS
+		int f = 0;
+#endif
+		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) {
+			retval = ioctl(fd, EXT2_IOC_SETFLAGS, &f);
+			close(fd);
+			if (retval)
+				return retval;
+		}
+#endif
+#endif
+
+		/* Create the journal file */
+		if ((fd = open(jfile, O_CREAT|O_WRONLY, 0600)) < 0)
+			return errno;
+
+		/* Note that we can't do lazy journal initialization for mounted
+		 * filesystems, since the zero writing is also allocating the
+		 * journal blocks.  We could use fallocate, but not all kernels
+		 * support that, and creating a journal on a mounted ext2
+		 * filesystems is extremely rare these days...  Ignore it. */
+		flags &= ~EXT2_MKJOURNAL_LAZYINIT;
+
+		if ((retval = write_journal_file(fs, jfile, num_blocks, flags)))
+			goto errout;
+
+		/* Get inode number of the journal file */
+		if (fstat(fd, &st) < 0) {
+			retval = errno;
+			goto errout;
+		}
+
+#if defined(HAVE_CHFLAGS) && defined(UF_NODUMP)
+		retval = fchflags (fd, UF_NODUMP|UF_IMMUTABLE);
+#else
+#if HAVE_EXT2_IOCTLS
+		if (ioctl(fd, EXT2_IOC_GETFLAGS, &f) < 0) {
+			retval = errno;
+			goto errout;
+		}
+		f |= EXT2_NODUMP_FL | EXT2_IMMUTABLE_FL;
+		retval = ioctl(fd, EXT2_IOC_SETFLAGS, &f);
+#endif
+#endif
+		if (retval) {
+			retval = errno;
+			goto errout;
+		}
+
+		if (close(fd) < 0) {
+			retval = errno;
+			fd = -1;
+			goto errout;
+		}
+		journal_ino = st.st_ino;
+	} else {
+		if ((mount_flags & EXT2_MF_BUSY) &&
+		    !(fs->flags & EXT2_FLAG_EXCLUSIVE)) {
+			retval = EBUSY;
+			goto errout;
+		}
+		journal_ino = EXT2_JOURNAL_INO;
+		if ((retval = write_journal_inode(fs, journal_ino,
+						  num_blocks, 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:
+	if (fd >= 0)
+		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, 0);
+	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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/mmp.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/mmp.c
new file mode 100644
index 0000000..e4c7dcc
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/mmp.c
@@ -0,0 +1,398 @@
+/*
+ * Helper functions for multiple mount protection (MMP).
+ *
+ * Copyright (C) 2011 Whamcloud, Inc.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include "config.h"
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/time.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "ext2fs/ext2_fs.h"
+#include "ext2fs/ext2fs.h"
+
+#ifndef O_DIRECT
+#define O_DIRECT 0
+#endif
+
+errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf)
+{
+	struct mmp_struct *mmp_cmp;
+	errcode_t retval = 0;
+
+	if ((mmp_blk <= fs->super->s_first_data_block) ||
+	    (mmp_blk >= ext2fs_blocks_count(fs->super)))
+		return EXT2_ET_MMP_BAD_BLOCK;
+
+	/* ext2fs_open() reserves fd0,1,2 to avoid stdio collision, so checking
+	 * mmp_fd <= 0 is OK to validate that the fd is valid.  This opens its
+	 * own fd to read the MMP block to ensure that it is using O_DIRECT,
+	 * regardless of how the io_manager is doing reads, to avoid caching of
+	 * the MMP block by the io_manager or the VM.  It needs to be fresh. */
+	if (fs->mmp_fd <= 0) {
+		fs->mmp_fd = open(fs->device_name, O_RDWR | O_DIRECT);
+		if (fs->mmp_fd < 0) {
+			retval = EXT2_ET_MMP_OPEN_DIRECT;
+			goto out;
+		}
+	}
+
+	if (fs->mmp_cmp == NULL) {
+		int align = ext2fs_get_dio_alignment(fs->mmp_fd);
+
+		retval = ext2fs_get_memalign(fs->blocksize, align,
+					     &fs->mmp_cmp);
+		if (retval)
+			return retval;
+	}
+
+	if ((blk64_t) ext2fs_llseek(fs->mmp_fd, mmp_blk * fs->blocksize,
+				    SEEK_SET) !=
+	    mmp_blk * fs->blocksize) {
+		retval = EXT2_ET_LLSEEK_FAILED;
+		goto out;
+	}
+
+	if (read(fs->mmp_fd, fs->mmp_cmp, fs->blocksize) != fs->blocksize) {
+		retval = EXT2_ET_SHORT_READ;
+		goto out;
+	}
+
+	mmp_cmp = fs->mmp_cmp;
+#ifdef WORDS_BIGENDIAN
+	ext2fs_swap_mmp(mmp_cmp);
+#endif
+
+	if (buf != NULL && buf != fs->mmp_cmp)
+		memcpy(buf, fs->mmp_cmp, fs->blocksize);
+
+	if (mmp_cmp->mmp_magic != EXT4_MMP_MAGIC) {
+		retval = EXT2_ET_MMP_MAGIC_INVALID;
+		goto out;
+	}
+
+out:
+	return retval;
+}
+
+errcode_t ext2fs_mmp_write(ext2_filsys fs, blk64_t mmp_blk, void *buf)
+{
+	struct mmp_struct *mmp_s = buf;
+	struct timeval tv;
+	errcode_t retval = 0;
+
+	gettimeofday(&tv, 0);
+	mmp_s->mmp_time = tv.tv_sec;
+	fs->mmp_last_written = tv.tv_sec;
+
+	if (fs->super->s_mmp_block < fs->super->s_first_data_block ||
+	    fs->super->s_mmp_block > ext2fs_blocks_count(fs->super))
+		return EXT2_ET_MMP_BAD_BLOCK;
+
+#ifdef WORDS_BIGENDIAN
+	ext2fs_swap_mmp(mmp_s);
+#endif
+
+	/* I was tempted to make this use O_DIRECT and the mmp_fd, but
+	 * this caused no end of grief, while leaving it as-is works. */
+	retval = io_channel_write_blk64(fs->io, mmp_blk, -(int)sizeof(struct mmp_struct), buf);
+
+#ifdef WORDS_BIGENDIAN
+	ext2fs_swap_mmp(mmp_s);
+#endif
+
+	/* Make sure the block gets to disk quickly */
+	io_channel_flush(fs->io);
+	return retval;
+}
+
+#ifdef HAVE_SRANDOM
+#define srand(x)	srandom(x)
+#define rand()		random()
+#endif
+
+unsigned ext2fs_mmp_new_seq(void)
+{
+	unsigned new_seq;
+	struct timeval tv;
+
+	gettimeofday(&tv, 0);
+	srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
+
+	gettimeofday(&tv, 0);
+	/* Crank the random number generator a few times */
+	for (new_seq = (tv.tv_sec ^ tv.tv_usec) & 0x1F; new_seq > 0; new_seq--)
+		rand();
+
+	do {
+		new_seq = rand();
+	} while (new_seq > EXT4_MMP_SEQ_MAX);
+
+	return new_seq;
+}
+
+static errcode_t ext2fs_mmp_reset(ext2_filsys fs)
+{
+	struct mmp_struct *mmp_s = NULL;
+	errcode_t retval = 0;
+
+	if (fs->mmp_buf == NULL) {
+		retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
+		if (retval)
+			goto out;
+	}
+
+	memset(fs->mmp_buf, 0, fs->blocksize);
+	mmp_s = fs->mmp_buf;
+
+	mmp_s->mmp_magic = EXT4_MMP_MAGIC;
+	mmp_s->mmp_seq = EXT4_MMP_SEQ_CLEAN;
+	mmp_s->mmp_time = 0;
+#if _BSD_SOURCE || _XOPEN_SOURCE >= 500
+	gethostname(mmp_s->mmp_nodename, sizeof(mmp_s->mmp_nodename));
+#else
+	mmp_s->mmp_nodename[0] = '\0';
+#endif
+	strncpy(mmp_s->mmp_bdevname, fs->device_name,
+		sizeof(mmp_s->mmp_bdevname));
+
+	mmp_s->mmp_check_interval = fs->super->s_mmp_update_interval;
+	if (mmp_s->mmp_check_interval < EXT4_MMP_MIN_CHECK_INTERVAL)
+		mmp_s->mmp_check_interval = EXT4_MMP_MIN_CHECK_INTERVAL;
+
+	retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
+out:
+	return retval;
+}
+
+errcode_t ext2fs_mmp_clear(ext2_filsys fs)
+{
+	errcode_t retval = 0;
+
+	if (!(fs->flags & EXT2_FLAG_RW))
+		return EXT2_ET_RO_FILSYS;
+
+	retval = ext2fs_mmp_reset(fs);
+
+	return retval;
+}
+
+errcode_t ext2fs_mmp_init(ext2_filsys fs)
+{
+	struct ext2_super_block *sb = fs->super;
+	blk64_t mmp_block;
+	errcode_t retval;
+
+	if (sb->s_mmp_update_interval == 0)
+		sb->s_mmp_update_interval = EXT4_MMP_UPDATE_INTERVAL;
+	/* This is probably excessively large, but who knows? */
+	else if (sb->s_mmp_update_interval > EXT4_MMP_MAX_UPDATE_INTERVAL)
+		return EXT2_ET_INVALID_ARGUMENT;
+
+	if (fs->mmp_buf == NULL) {
+		retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
+		if (retval)
+			goto out;
+	}
+
+	retval = ext2fs_alloc_block2(fs, 0, fs->mmp_buf, &mmp_block);
+	if (retval)
+		goto out;
+
+	sb->s_mmp_block = mmp_block;
+
+	retval = ext2fs_mmp_reset(fs);
+	if (retval)
+		goto out;
+
+out:
+	return retval;
+}
+
+/*
+ * Make sure that the fs is not mounted or being fsck'ed while opening the fs.
+ */
+errcode_t ext2fs_mmp_start(ext2_filsys fs)
+{
+	struct mmp_struct *mmp_s;
+	unsigned seq;
+	unsigned int mmp_check_interval;
+	errcode_t retval = 0;
+
+	if (fs->mmp_buf == NULL) {
+		retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
+		if (retval)
+			goto mmp_error;
+	}
+
+	retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
+	if (retval)
+		goto mmp_error;
+
+	mmp_s = fs->mmp_buf;
+
+	mmp_check_interval = fs->super->s_mmp_update_interval;
+	if (mmp_check_interval < EXT4_MMP_MIN_CHECK_INTERVAL)
+		mmp_check_interval = EXT4_MMP_MIN_CHECK_INTERVAL;
+
+	seq = mmp_s->mmp_seq;
+	if (seq == EXT4_MMP_SEQ_CLEAN)
+		goto clean_seq;
+	if (seq == EXT4_MMP_SEQ_FSCK) {
+		retval = EXT2_ET_MMP_FSCK_ON;
+		goto mmp_error;
+	}
+
+	if (seq > EXT4_MMP_SEQ_FSCK) {
+		retval = EXT2_ET_MMP_UNKNOWN_SEQ;
+		goto mmp_error;
+	}
+
+	/*
+	 * If check_interval in MMP block is larger, use that instead of
+	 * check_interval from the superblock.
+	 */
+	if (mmp_s->mmp_check_interval > mmp_check_interval)
+		mmp_check_interval = mmp_s->mmp_check_interval;
+
+	sleep(2 * mmp_check_interval + 1);
+
+	retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
+	if (retval)
+		goto mmp_error;
+
+	if (seq != mmp_s->mmp_seq) {
+		retval = EXT2_ET_MMP_FAILED;
+		goto mmp_error;
+	}
+
+clean_seq:
+	if (!(fs->flags & EXT2_FLAG_RW))
+		goto mmp_error;
+
+	mmp_s->mmp_seq = seq = ext2fs_mmp_new_seq();
+#if _BSD_SOURCE || _XOPEN_SOURCE >= 500
+	gethostname(mmp_s->mmp_nodename, sizeof(mmp_s->mmp_nodename));
+#else
+	strcpy(mmp_s->mmp_nodename, "unknown host");
+#endif
+	strncpy(mmp_s->mmp_bdevname, fs->device_name,
+		sizeof(mmp_s->mmp_bdevname));
+
+	retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
+	if (retval)
+		goto mmp_error;
+
+	sleep(2 * mmp_check_interval + 1);
+
+	retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
+	if (retval)
+		goto mmp_error;
+
+	if (seq != mmp_s->mmp_seq) {
+		retval = EXT2_ET_MMP_FAILED;
+		goto mmp_error;
+	}
+
+	mmp_s->mmp_seq = EXT4_MMP_SEQ_FSCK;
+	retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
+	if (retval)
+		goto mmp_error;
+
+	return 0;
+
+mmp_error:
+	return retval;
+}
+
+/*
+ * Clear the MMP usage in the filesystem.  If this function returns an
+ * error EXT2_ET_MMP_CHANGE_ABORT it means the filesystem was modified
+ * by some other process while in use, and changes should be dropped, or
+ * risk filesystem corruption.
+ */
+errcode_t ext2fs_mmp_stop(ext2_filsys fs)
+{
+	struct mmp_struct *mmp, *mmp_cmp;
+	errcode_t retval = 0;
+
+	if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) ||
+	    !(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP))
+		goto mmp_error;
+
+	retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
+	if (retval)
+		goto mmp_error;
+
+	/* Check if the MMP block is not changed. */
+	mmp = fs->mmp_buf;
+	mmp_cmp = fs->mmp_cmp;
+	if (memcmp(mmp, mmp_cmp, sizeof(*mmp_cmp))) {
+		retval = EXT2_ET_MMP_CHANGE_ABORT;
+		goto mmp_error;
+	}
+
+	mmp_cmp->mmp_seq = EXT4_MMP_SEQ_CLEAN;
+	retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_cmp);
+
+mmp_error:
+	if (fs->mmp_fd > 0) {
+		close(fs->mmp_fd);
+		fs->mmp_fd = -1;
+	}
+
+	return retval;
+}
+
+#define EXT2_MIN_MMP_UPDATE_INTERVAL 60
+
+/*
+ * Update the on-disk mmp buffer, after checking that it hasn't been changed.
+ */
+errcode_t ext2fs_mmp_update(ext2_filsys fs)
+{
+	struct mmp_struct *mmp, *mmp_cmp;
+	struct timeval tv;
+	errcode_t retval = 0;
+
+	if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) ||
+	    !(fs->flags & EXT2_FLAG_RW) || (fs->flags & EXT2_FLAG_SKIP_MMP))
+		return 0;
+
+	gettimeofday(&tv, 0);
+	if (tv.tv_sec - fs->mmp_last_written < EXT2_MIN_MMP_UPDATE_INTERVAL)
+		return 0;
+
+	retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, NULL);
+	if (retval)
+		goto mmp_error;
+
+	mmp = fs->mmp_buf;
+	mmp_cmp = fs->mmp_cmp;
+
+	if (memcmp(mmp, mmp_cmp, sizeof(*mmp_cmp)))
+		return EXT2_ET_MMP_CHANGE_ABORT;
+
+	mmp->mmp_time = tv.tv_sec;
+	mmp->mmp_seq = EXT4_MMP_SEQ_FSCK;
+	retval = ext2fs_mmp_write(fs, fs->super->s_mmp_block, fs->mmp_buf);
+
+mmp_error:
+	return retval;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/namei.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/namei.c
new file mode 100644
index 0000000..307aecc
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/namei.c
@@ -0,0 +1,213 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* #define NAMEI_DEBUG */
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+#include "ext2fsP.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;
+	blk64_t blk;
+
+#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++ >= EXT2FS_MAX_NESTED_LINKS)
+		return EXT2_ET_SYMLINK_LOOP;
+
+	if (ext2fs_inode_data_blocks(fs,&ei)) {
+		retval = ext2fs_bmap2(fs, inode, &ei, NULL, 0, 0, NULL, &blk);
+		if (retval)
+			return retval;
+
+		retval = ext2fs_get_mem(fs->blocksize, &buffer);
+		if (retval)
+			return retval;
+
+		retval = io_channel_read_blk64(fs->io, blk, 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 *base_name;
+	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, &base_name, &namelen, &dir);
+	if (retval) return retval;
+	if (!namelen) {                     /* special case: '/usr/' etc */
+		*res_inode=dir;
+		return 0;
+	}
+	retval = ext2fs_lookup (fs, dir, base_name, 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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/native.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/native.c
new file mode 100644
index 0000000..ba3e0c8
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/native.c
@@ -0,0 +1,28 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/newdir.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/newdir.c
new file mode 100644
index 0000000..3e2c0db
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/newdir.c
@@ -0,0 +1,82 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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;
+
+	retval = ext2fs_set_rec_len(fs, fs->blocksize, dir);
+	if (retval) {
+		ext2fs_free_mem(&buf);
+		return retval;
+	}
+
+	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 = fs->blocksize - 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);
+		retval = ext2fs_set_rec_len(fs, rec_len, dir);
+		if (retval) {
+			ext2fs_free_mem(&buf);
+			return retval;
+		}
+		dir->inode = parent_ino;
+		dir->name_len = 2 | filetype;
+		dir->name[0] = '.';
+		dir->name[1] = '.';
+
+	}
+	*block = buf;
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/nt_io.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/nt_io.c
new file mode 100644
index 0000000..0f10543
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/nt_io.c
@@ -0,0 +1,1496 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %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)
+			{
+				free(io->name);
+				free(io);
+			}
+
+			if (NULL != NtData)
+			{
+				if(NULL != NtData->Handle)
+				{
+					_UnlockDrive(NtData->Handle);
+					_CloseDisk(NtData->Handle);
+				}
+
+				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;
+	}
+
+	free(channel->name);
+	free(channel);
+
+	if (NULL != NtData)
+	{
+		if(NULL != NtData->Handle)
+		{
+			_DismountDrive(NtData->Handle);
+			_UnlockDrive(NtData->Handle);
+			_CloseDisk(NtData->Handle);
+		}
+
+		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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/openfs.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/openfs.c
new file mode 100644
index 0000000..4cdbde1
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/openfs.c
@@ -0,0 +1,473 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "ext2_fs.h"
+
+
+#include "ext2fs.h"
+#include "e2image.h"
+
+blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs, blk64_t group_block,
+				     dgrp_t i)
+{
+	int	bg;
+	int	has_super = 0;
+	blk64_t	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 = EXT2_DESC_PER_BLOCK(fs->super) * i;
+	if (ext2fs_bg_has_super(fs, bg))
+		has_super = 1;
+	ret_blk = ext2fs_group_first_block2(fs, bg) + has_super;
+	/*
+	 * 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) <
+	     ext2fs_blocks_count(fs->super)))
+		ret_blk += fs->super->s_blocks_per_group;
+	return ret_blk;
+}
+
+blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, dgrp_t i)
+{
+	return ext2fs_descriptor_block_loc2(fs, group_block, i);
+}
+
+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
+ *	EXT2_FLAG_SKIP_MMP - Open without multi-mount protection check.
+ *	EXT2_FLAG_64BITS - Allow 64-bit bitfields (needed for large
+ *				filesystems)
+ */
+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, first_meta_bg;
+	__u32		features;
+	unsigned int	blocks_per_group, io_flags;
+	blk64_t		group_block, blk;
+	char		*dest, *cp;
+#ifdef WORDS_BIGENDIAN
+	unsigned int	groups_per_block;
+	struct ext2_group_desc *gdp;
+	int		j;
+#endif
+
+	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;
+	/* don't overwrite sb backups unless flag is explicitly cleared */
+	fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
+	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;
+	}
+
+	io_flags = 0;
+	if (flags & EXT2_FLAG_RW)
+		io_flags |= IO_FLAG_RW;
+	if (flags & EXT2_FLAG_EXCLUSIVE)
+		io_flags |= IO_FLAG_EXCLUSIVE;
+	if (flags & EXT2_FLAG_DIRECT_IO)
+		io_flags |= IO_FLAG_DIRECT_IO;
+	retval = manager->open(fs->device_name, io_flags, &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 = io_channel_alloc_buf(fs->io, -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,
+					     -(int)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 WORDS_BIGENDIAN
+	fs->flags |= EXT2_FLAG_SWAP_BYTES;
+	ext2fs_swap_super(fs->super);
+#else
+	if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
+		retval = EXT2_ET_UNIMPLEMENTED;
+		goto cleanup;
+	}
+#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)) {
+		features = fs->super->s_feature_incompat;
+#ifdef EXT2_LIB_SOFTSUPP_INCOMPAT
+		if (flags & EXT2_FLAG_SOFTSUPP_FEATURES)
+			features &= ~EXT2_LIB_SOFTSUPP_INCOMPAT;
+#endif
+		if (features & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
+			retval = EXT2_ET_UNSUPP_FEATURE;
+			goto cleanup;
+		}
+
+		features = fs->super->s_feature_ro_compat;
+#ifdef EXT2_LIB_SOFTSUPP_RO_COMPAT
+		if (flags & EXT2_FLAG_SOFTSUPP_FEATURES)
+			features &= ~EXT2_LIB_SOFTSUPP_RO_COMPAT;
+#endif
+		if ((flags & EXT2_FLAG_RW) &&
+		    (features & ~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;
+		}
+	}
+
+	if ((fs->super->s_log_block_size + EXT2_MIN_BLOCK_LOG_SIZE) >
+	    EXT2_MAX_BLOCK_LOG_SIZE) {
+		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+		goto cleanup;
+	}
+
+	/*
+	 * bigalloc requires cluster-aware bitfield operations, which at the
+	 * moment means we need EXT2_FLAG_64BITS.
+	 */
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_BIGALLOC) &&
+	    !(flags & EXT2_FLAG_64BITS)) {
+		retval = EXT2_ET_CANT_USE_LEGACY_BITMAPS;
+		goto cleanup;
+	}
+
+	if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					EXT4_FEATURE_RO_COMPAT_BIGALLOC) &&
+	    (fs->super->s_log_block_size != fs->super->s_log_cluster_size)) {
+		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+		goto cleanup;
+	}
+	fs->fragsize = fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
+	if (EXT2_INODE_SIZE(fs->super) < EXT2_GOOD_OLD_INODE_SIZE) {
+		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+		goto cleanup;
+	}
+	fs->cluster_ratio_bits = fs->super->s_log_cluster_size -
+		fs->super->s_log_block_size;
+	if (EXT2_BLOCKS_PER_GROUP(fs->super) !=
+	    EXT2_CLUSTERS_PER_GROUP(fs->super) << fs->cluster_ratio_bits) {
+		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+		goto cleanup;
+	}
+	fs->inode_blocks_per_group = ((EXT2_INODES_PER_GROUP(fs->super) *
+				       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;
+	}
+
+	if (EXT2_INODES_PER_GROUP(fs->super) == 0) {
+		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+		goto cleanup;
+	}
+
+	/*
+	 * 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) ||
+           EXT2_DESC_PER_BLOCK(fs->super) == 0 ||
+           fs->super->s_first_data_block >= ext2fs_blocks_count(fs->super)) {
+		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+		goto cleanup;
+	}
+	fs->group_desc_count = ext2fs_div64_ceil(ext2fs_blocks_count(fs->super) -
+						 fs->super->s_first_data_block,
+						 blocks_per_group);
+	if (fs->group_desc_count * EXT2_INODES_PER_GROUP(fs->super) !=
+	    fs->super->s_inodes_count) {
+		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+		goto cleanup;
+	}
+	fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
+					  EXT2_DESC_PER_BLOCK(fs->super));
+	retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize,
+				&fs->group_desc);
+	if (retval)
+		goto cleanup;
+	if (!group_block)
+		group_block = fs->super->s_first_data_block;
+	if (group_block == 0 && fs->blocksize == 1024)
+		group_block = 1; /* Deal with 1024 blocksize && bigalloc */
+	dest = (char *) fs->group_desc;
+#ifdef WORDS_BIGENDIAN
+	groups_per_block = EXT2_DESC_PER_BLOCK(fs->super);
+#endif
+	if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
+		first_meta_bg = fs->super->s_first_meta_bg;
+	else
+		first_meta_bg = fs->desc_blocks;
+	if (first_meta_bg) {
+		retval = io_channel_read_blk(fs->io, group_block+1,
+					     first_meta_bg, dest);
+		if (retval)
+			goto cleanup;
+#ifdef WORDS_BIGENDIAN
+		gdp = (struct ext2_group_desc *) dest;
+		for (j=0; j < groups_per_block*first_meta_bg; j++) {
+			gdp = ext2fs_group_desc(fs, fs->group_desc, j);
+			ext2fs_swap_group_desc2(fs, gdp);
+		}
+#endif
+		dest += fs->blocksize*first_meta_bg;
+	}
+	for (i=first_meta_bg ; i < fs->desc_blocks; i++) {
+		blk = ext2fs_descriptor_block_loc2(fs, group_block, i);
+		retval = io_channel_read_blk64(fs->io, blk, 1, dest);
+		if (retval)
+			goto cleanup;
+#ifdef WORDS_BIGENDIAN
+		for (j=0; j < groups_per_block; j++) {
+			gdp = ext2fs_group_desc(fs, fs->group_desc,
+						i * groups_per_block + j);
+			ext2fs_swap_group_desc2(fs, gdp);
+		}
+#endif
+		dest += fs->blocksize;
+	}
+
+	fs->stride = fs->super->s_raid_stride;
+
+	/*
+	 * If recovery is from backup superblock, Clear _UNININT flags &
+	 * reset bg_itable_unused to zero
+	 */
+	if (superblock > 1 && EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+		dgrp_t group;
+
+		for (group = 0; group < fs->group_desc_count; group++) {
+			ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
+			ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
+			ext2fs_bg_itable_unused_set(fs, group, 0);
+			/* The checksum will be reset later, but fix it here
+			 * anyway to avoid printing a lot of spurious errors. */
+			ext2fs_group_desc_csum_set(fs, group);
+		}
+		if (fs->flags & EXT2_FLAG_RW)
+			ext2fs_mark_super_dirty(fs);
+	}
+
+	if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) &&
+	    !(flags & EXT2_FLAG_SKIP_MMP) &&
+	    (flags & (EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE))) {
+		retval = ext2fs_mmp_start(fs);
+		if (retval) {
+			fs->flags |= EXT2_FLAG_SKIP_MMP; /* just do cleanup */
+			ext2fs_mmp_stop(fs);
+			goto cleanup;
+		}
+	}
+
+	fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR;
+	*ret_fs = fs;
+
+	return 0;
+cleanup:
+	if (flags & EXT2_FLAG_NOFREE_ON_ERROR)
+		*ret_fs = fs;
+	else
+		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)
+{
+	errcode_t err;
+
+	if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
+		return EXT2_ET_NOT_IMAGE_FILE;
+	err = io_channel_set_blksize(new_io, fs->blocksize);
+	if (err)
+		return err;
+	if ((new_io == fs->image_io) || (new_io == fs->io))
+		return 0;
+	if ((fs->image_io != fs->io) &&
+	    fs->image_io)
+		io_channel_close(fs->image_io);
+	if (fs->io)
+		io_channel_close(fs->io);
+	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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/progress.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/progress.c
new file mode 100644
index 0000000..8c9a6f1
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/progress.c
@@ -0,0 +1,97 @@
+/*
+ * progress.c - Numeric progress meter
+ *
+ * Copyright (C) 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 "config.h"
+#include "ext2fs.h"
+#include "ext2fsP.h"
+
+#include <time.h>
+
+static char spaces[80], backspaces[80];
+static time_t last_update;
+
+static int int_log10(unsigned int arg)
+{
+	int	l;
+
+	for (l=0; arg ; l++)
+		arg = arg / 10;
+	return l;
+}
+
+void ext2fs_numeric_progress_init(ext2_filsys fs,
+				  struct ext2fs_numeric_progress_struct * progress,
+				  const char *label, __u64 max)
+{
+	/*
+	 * The PRINT_PROGRESS flag turns on or off ALL
+	 * progress-related messages, whereas the SKIP_PROGRESS
+	 * environment variable prints the start and end messages but
+	 * not the numeric countdown in the middle.
+	 */
+	if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS))
+		return;
+
+	memset(spaces, ' ', sizeof(spaces)-1);
+	spaces[sizeof(spaces)-1] = 0;
+	memset(backspaces, '\b', sizeof(backspaces)-1);
+	backspaces[sizeof(backspaces)-1] = 0;
+
+	memset(progress, 0, sizeof(*progress));
+	if (getenv("E2FSPROGS_SKIP_PROGRESS"))
+		progress->skip_progress++;
+
+
+	/*
+	 * Figure out how many digits we need
+	 */
+	progress->max = max;
+	progress->log_max = int_log10(max);
+
+	if (label) {
+		fputs(label, stdout);
+		fflush(stdout);
+	}
+	last_update = 0;
+}
+
+void ext2fs_numeric_progress_update(ext2_filsys fs,
+				    struct ext2fs_numeric_progress_struct * progress,
+				    __u64 val)
+{
+	time_t now;
+
+	if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS))
+		return;
+	if (progress->skip_progress)
+		return;
+	now = time(0);
+	if (now == last_update)
+		return;
+	last_update = now;
+
+	printf("%*llu/%*llu", progress->log_max, val,
+	       progress->log_max, progress->max);
+	fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces);
+}
+
+void ext2fs_numeric_progress_close(ext2_filsys fs,
+				   struct ext2fs_numeric_progress_struct * progress,
+				   const char *message)
+{
+	if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS))
+		return;
+	fprintf(stdout, "%.*s", (2*progress->log_max)+1, spaces);
+	fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces);
+	if (message)
+		fputs(message, stdout);
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/punch.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/punch.c
new file mode 100644
index 0000000..25d7953
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/punch.c
@@ -0,0 +1,448 @@
+/*
+ * punch.c --- deallocate blocks allocated to an inode
+ *
+ * Copyright (C) 2010 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+#undef PUNCH_DEBUG
+
+/*
+ * 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;
+}
+
+/*
+ * This clever recursive function handles i_blocks[] as well as
+ * indirect, double indirect, and triple indirect blocks.  It iterates
+ * over the entries in the i_blocks array or indirect blocks, and for
+ * each one, will recursively handle any indirect blocks and then
+ * frees and deallocates the blocks.
+ */
+static errcode_t ind_punch(ext2_filsys fs, struct ext2_inode *inode,
+			   char *block_buf, blk_t *p, int level,
+			   blk_t start, blk_t count, int max)
+{
+	errcode_t	retval;
+	blk_t		b;
+	int		i;
+	blk64_t		offset, incr;
+	int		freed = 0;
+
+#ifdef PUNCH_DEBUG
+	printf("Entering ind_punch, level %d, start %u, count %u, "
+	       "max %d\n", level, start, count, max);
+#endif
+	incr = 1ULL << ((EXT2_BLOCK_SIZE_BITS(fs->super)-2)*level);
+	for (i=0, offset=0; i < max; i++, p++, offset += incr) {
+		if (offset >= start + count)
+			break;
+		if (*p == 0 || (offset+incr) <= start)
+			continue;
+		b = *p;
+		if (level > 0) {
+			blk_t start2;
+#ifdef PUNCH_DEBUG
+			printf("Reading indirect block %u\n", b);
+#endif
+			retval = ext2fs_read_ind_block(fs, b, block_buf);
+			if (retval)
+				return retval;
+			start2 = (start > offset) ? start - offset : 0;
+			retval = ind_punch(fs, inode, block_buf + fs->blocksize,
+					   (blk_t *) block_buf, level - 1,
+					   start2, count - offset,
+					   fs->blocksize >> 2);
+			if (retval)
+				return retval;
+			retval = ext2fs_write_ind_block(fs, b, block_buf);
+			if (retval)
+				return retval;
+			if (!check_zero_block(block_buf, fs->blocksize))
+				continue;
+		}
+#ifdef PUNCH_DEBUG
+		printf("Freeing block %u (offset %llu)\n", b, offset);
+#endif
+		ext2fs_block_alloc_stats(fs, b, -1);
+		*p = 0;
+		freed++;
+	}
+#ifdef PUNCH_DEBUG
+	printf("Freed %d blocks\n", freed);
+#endif
+	return ext2fs_iblk_sub_blocks(fs, inode, freed);
+}
+
+static errcode_t ext2fs_punch_ind(ext2_filsys fs, struct ext2_inode *inode,
+				  char *block_buf, blk_t start, blk_t count)
+{
+	errcode_t		retval;
+	char			*buf = 0;
+	int			level;
+	int			num = EXT2_NDIR_BLOCKS;
+	blk_t			*bp = inode->i_block;
+	blk_t			addr_per_block;
+	blk64_t			max = EXT2_NDIR_BLOCKS;
+
+	if (!block_buf) {
+		retval = ext2fs_get_array(3, fs->blocksize, &buf);
+		if (retval)
+			return retval;
+		block_buf = buf;
+	}
+
+	addr_per_block = (blk_t) fs->blocksize >> 2;
+
+	for (level = 0; level < 4; level++, max *= (blk64_t)addr_per_block) {
+#ifdef PUNCH_DEBUG
+		printf("Main loop level %d, start %u count %u "
+		       "max %llu num %d\n", level, start, count, max, num);
+#endif
+		if (start < max) {
+			retval = ind_punch(fs, inode, block_buf, bp, level,
+					   start, count, num);
+			if (retval)
+				goto errout;
+			if (count > max)
+				count -= max - start;
+			else
+				break;
+			start = 0;
+		} else
+			start -= max;
+		bp += num;
+		if (level == 0) {
+			num = 1;
+			max = 1;
+		}
+	}
+	retval = 0;
+errout:
+	if (buf)
+		ext2fs_free_mem(&buf);
+	return retval;
+}
+
+#ifdef PUNCH_DEBUG
+
+#define dbg_printf(f, a...)  printf(f, ## a)
+
+static void dbg_print_extent(char *desc, struct ext2fs_extent *extent)
+{
+	if (desc)
+		printf("%s: ", desc);
+	printf("extent: lblk %llu--%llu, len %u, pblk %llu, flags: ",
+	       extent->e_lblk, extent->e_lblk + extent->e_len - 1,
+	       extent->e_len, extent->e_pblk);
+	if (extent->e_flags & EXT2_EXTENT_FLAGS_LEAF)
+		fputs("LEAF ", stdout);
+	if (extent->e_flags & EXT2_EXTENT_FLAGS_UNINIT)
+		fputs("UNINIT ", stdout);
+	if (extent->e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)
+		fputs("2ND_VISIT ", stdout);
+	if (!extent->e_flags)
+		fputs("(none)", stdout);
+	fputc('\n', stdout);
+
+}
+#else
+#define dbg_print_extent(desc, ex)	do { } while (0)
+#define dbg_printf(f, a...)		do { } while (0)
+#endif
+
+/* Free a range of blocks, respecting cluster boundaries */
+static errcode_t punch_extent_blocks(ext2_filsys fs, ext2_ino_t ino,
+				     struct ext2_inode *inode,
+				     blk64_t lfree_start, blk64_t free_start,
+				     __u32 free_count, int *freed)
+{
+	blk64_t		pblk;
+	int		freed_now = 0;
+	__u32		cluster_freed;
+	errcode_t	retval = 0;
+
+	/* No bigalloc?  Just free each block. */
+	if (EXT2FS_CLUSTER_RATIO(fs) == 1) {
+		*freed += free_count;
+		while (free_count-- > 0)
+			ext2fs_block_alloc_stats2(fs, free_start++, -1);
+		return retval;
+	}
+
+	/*
+	 * Try to free up to the next cluster boundary.  We assume that all
+	 * blocks in a logical cluster map to blocks from the same physical
+	 * cluster, and that the offsets within the [pl]clusters match.
+	 */
+	if (free_start & EXT2FS_CLUSTER_MASK(fs)) {
+		retval = ext2fs_map_cluster_block(fs, ino, inode,
+						  lfree_start, &pblk);
+		if (retval)
+			goto errout;
+		if (!pblk) {
+			ext2fs_block_alloc_stats2(fs, free_start, -1);
+			freed_now++;
+		}
+		cluster_freed = EXT2FS_CLUSTER_RATIO(fs) -
+			(free_start & EXT2FS_CLUSTER_MASK(fs));
+		if (cluster_freed > free_count)
+			cluster_freed = free_count;
+		free_count -= cluster_freed;
+		free_start += cluster_freed;
+		lfree_start += cluster_freed;
+	}
+
+	/* Free whole clusters from the middle of the range. */
+	while (free_count > 0 && free_count >= EXT2FS_CLUSTER_RATIO(fs)) {
+		ext2fs_block_alloc_stats2(fs, free_start, -1);
+		freed_now++;
+		cluster_freed = EXT2FS_CLUSTER_RATIO(fs);
+		free_count -= cluster_freed;
+		free_start += cluster_freed;
+		lfree_start += cluster_freed;
+	}
+
+	/* Try to free the last cluster. */
+	if (free_count > 0) {
+		retval = ext2fs_map_cluster_block(fs, ino, inode,
+						  lfree_start, &pblk);
+		if (retval)
+			goto errout;
+		if (!pblk) {
+			ext2fs_block_alloc_stats2(fs, free_start, -1);
+			freed_now++;
+		}
+	}
+
+errout:
+	*freed += freed_now;
+	return retval;
+}
+
+static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino,
+				     struct ext2_inode *inode,
+				     blk64_t start, blk64_t end)
+{
+	ext2_extent_handle_t	handle = 0;
+	struct ext2fs_extent	extent;
+	errcode_t		retval;
+	blk64_t			free_start, next, lfree_start;
+	__u32			free_count, newlen;
+	int			freed = 0;
+	int			op;
+
+	retval = ext2fs_extent_open2(fs, ino, inode, &handle);
+	if (retval)
+		return retval;
+	/*
+	 * Find the extent closest to the start of the punch range.  We don't
+	 * check the return value because _goto() sets the current node to the
+	 * next-lowest extent if 'start' is in a hole, and doesn't set a
+	 * current node if there was a real error reading the extent tree.
+	 * In that case, _get() will error out.
+	 *
+	 * Note: If _get() returns 'no current node', that simply means that
+	 * there aren't any blocks mapped past this point in the file, so we're
+	 * done.
+	 */
+	ext2fs_extent_goto(handle, start);
+	retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
+	if (retval == EXT2_ET_NO_CURRENT_NODE) {
+		retval = 0;
+		goto errout;
+	} else if (retval)
+		goto errout;
+	while (1) {
+		op = EXT2_EXTENT_NEXT_LEAF;
+		dbg_print_extent("main loop", &extent);
+		next = extent.e_lblk + extent.e_len;
+		dbg_printf("start %llu, end %llu, next %llu\n",
+			   (unsigned long long) start,
+			   (unsigned long long) end,
+			   (unsigned long long) next);
+		if (start <= extent.e_lblk) {
+			if (end < extent.e_lblk)
+				goto next_extent;
+			dbg_printf("Case #%d\n", 1);
+			/* Start of deleted region before extent; 
+			   adjust beginning of extent */
+			free_start = extent.e_pblk;
+			lfree_start = extent.e_lblk;
+			if (next > end)
+				free_count = end - extent.e_lblk + 1;
+			else
+				free_count = extent.e_len;
+			extent.e_len -= free_count;
+			extent.e_lblk += free_count;
+			extent.e_pblk += free_count;
+		} else if (end >= next-1) {
+			if (start >= next)
+				break;
+			/* End of deleted region after extent;
+			   adjust end of extent */
+			dbg_printf("Case #%d\n", 2);
+			newlen = start - extent.e_lblk;
+			free_start = extent.e_pblk + newlen;
+			lfree_start = extent.e_lblk + newlen;
+			free_count = extent.e_len - newlen;
+			extent.e_len = newlen;
+		} else {
+			struct ext2fs_extent	newex;
+
+			dbg_printf("Case #%d\n", 3);
+			/* The hard case; we need to split the extent */
+			newex.e_pblk = extent.e_pblk +
+				(end + 1 - extent.e_lblk);
+			newex.e_lblk = end + 1;
+			newex.e_len = next - end - 1;
+			newex.e_flags = extent.e_flags;
+
+			extent.e_len = start - extent.e_lblk;
+			free_start = extent.e_pblk + extent.e_len;
+			lfree_start = extent.e_lblk + extent.e_len;
+			free_count = end - start + 1;
+
+			dbg_print_extent("inserting", &newex);
+			retval = ext2fs_extent_insert(handle,
+					EXT2_EXTENT_INSERT_AFTER, &newex);
+			if (retval)
+				goto errout;
+			/* Now pointing at inserted extent; so go back */
+			retval = ext2fs_extent_get(handle,
+						   EXT2_EXTENT_PREV_LEAF,
+						   &newex);
+			if (retval)
+				goto errout;
+		} 
+		if (extent.e_len) {
+			dbg_print_extent("replacing", &extent);
+			retval = ext2fs_extent_replace(handle, 0, &extent);
+		} else {
+			struct ext2fs_extent	newex;
+			blk64_t			old_lblk, next_lblk;
+			dbg_printf("deleting current extent%s\n", "");
+
+			/*
+			 * Save the location of the next leaf, then slip
+			 * back to the current extent.
+			 */
+			retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT,
+						   &newex);
+			if (retval)
+				goto errout;
+			old_lblk = newex.e_lblk;
+
+			retval = ext2fs_extent_get(handle,
+						   EXT2_EXTENT_NEXT_LEAF,
+						   &newex);
+			if (retval == EXT2_ET_EXTENT_NO_NEXT)
+				next_lblk = old_lblk;
+			else if (retval)
+				goto errout;
+			else
+				next_lblk = newex.e_lblk;
+
+			retval = ext2fs_extent_goto(handle, old_lblk);
+			if (retval)
+				goto errout;
+
+			/* Now delete the extent. */
+			retval = ext2fs_extent_delete(handle, 0);
+			if (retval)
+				goto errout;
+
+			/* Jump forward to the next extent. */
+			ext2fs_extent_goto(handle, next_lblk);
+			op = EXT2_EXTENT_CURRENT;
+		}
+		if (retval)
+			goto errout;
+		dbg_printf("Free start %llu, free count = %u\n",
+		       free_start, free_count);
+		retval = punch_extent_blocks(fs, ino, inode, lfree_start,
+					     free_start, free_count, &freed);
+		if (retval)
+			goto errout;
+	next_extent:
+		retval = ext2fs_extent_get(handle, op,
+					   &extent);
+		if (retval == EXT2_ET_EXTENT_NO_NEXT ||
+		    retval == EXT2_ET_NO_CURRENT_NODE)
+			break;
+		if (retval)
+			goto errout;
+	}
+	dbg_printf("Freed %d blocks\n", freed);
+	retval = ext2fs_iblk_sub_blocks(fs, inode, freed);
+errout:
+	ext2fs_extent_free(handle);
+	return retval;
+}
+	
+/*
+ * Deallocate all logical blocks starting at start to end, inclusive.
+ * If end is ~0, then this is effectively truncate.
+ */
+errcode_t ext2fs_punch(ext2_filsys fs, ext2_ino_t ino,
+		       struct ext2_inode *inode,
+		       char *block_buf, blk64_t start,
+		       blk64_t end)
+{
+	errcode_t		retval;
+	struct ext2_inode	inode_buf;
+
+	if (start > end)
+		return EINVAL;
+
+	/* Read inode structure if necessary */
+	if (!inode) {
+		retval = ext2fs_read_inode(fs, ino, &inode_buf);
+		if (retval)
+			return retval;
+		inode = &inode_buf;
+	}
+	if (inode->i_flags & EXT4_EXTENTS_FL)
+		retval = ext2fs_punch_extent(fs, ino, inode, start, end);
+	else {
+		blk_t	count;
+
+		if (start > ~0U)
+			return 0;
+		if (end > ~0U)
+			end = ~0U;
+		count = ((end - start + 1) < ~0U) ? (end - start + 1) : ~0U;
+		retval = ext2fs_punch_ind(fs, inode, block_buf, 
+					  (blk_t) start, count);
+	}
+	if (retval)
+		return retval;
+
+	return ext2fs_write_inode(fs, ino, inode);
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/qcow2.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/qcow2.c
new file mode 100644
index 0000000..547edc0
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/qcow2.c
@@ -0,0 +1,256 @@
+/*
+ * qcow2.c --- Functions to generate qcow2 formatted disk images.  This
+ * format is used originally by QEMU for virtual machines, and stores the
+ * filesystem data on disk in a packed format to avoid creating sparse
+ * image files that need lots of seeking to read and write.
+ *
+ * The qcow2 format supports zlib compression, but that is not yet
+ * implemented.
+ *
+ * It is possible to directly mount a qcow2 image using qemu-nbd:
+ *
+ * [root]# modprobe nbd max_part=63
+ * [root]# qemu-nbd -c /dev/nbd0 image.img
+ * [root]# mount /dev/nbd0p1 /mnt/qemu
+ *
+ * Format details at http://people.gnome.org/~markmc/qcow-image-format.html
+ *
+ * Copyright (C) 2010 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+#include "config.h"
+#include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <assert.h>
+
+#include "ext2fs/ext2fs.h"
+#include "qcow2.h"
+
+/* Functions for converting qcow2 image into raw image */
+
+struct ext2_qcow2_hdr *qcow2_read_header(int fd)
+{
+	void *buffer = NULL;
+	struct ext2_qcow2_hdr *hdr = NULL;
+	size_t size;
+	errcode_t ret;
+
+	ret = ext2fs_get_mem(sizeof(struct ext2_qcow2_hdr), &buffer);
+	if (ret)
+		return NULL;
+	memset(buffer, 0, sizeof(struct ext2_qcow2_hdr));
+
+	if (ext2fs_llseek(fd, 0, SEEK_SET < 0)) {
+		ext2fs_free_mem(&buffer);
+		return NULL;
+	}
+
+	size = read(fd, buffer, sizeof(struct ext2_qcow2_hdr));
+	if (size != sizeof(struct ext2_qcow2_hdr)) {
+		ext2fs_free_mem(&buffer);
+		return NULL;
+	}
+
+	hdr = (struct ext2_qcow2_hdr *)(buffer);
+
+	if ((ext2fs_be32_to_cpu(hdr->magic) != QCOW_MAGIC) ||
+	    (ext2fs_be32_to_cpu(hdr->version) != 2)) {
+		ext2fs_free_mem(&hdr);
+		return NULL;
+	}
+
+	return hdr;
+}
+
+static int qcow2_read_l1_table(struct ext2_qcow2_image *img)
+{
+	int fd = img->fd;
+	size_t size, l1_size = img->l1_size * sizeof(blk64_t);
+	blk64_t *table;
+	errcode_t ret;
+
+	ret = ext2fs_get_memzero(l1_size, &table);
+	if (ret)
+		return ret;
+
+	if (ext2fs_llseek(fd, img->l1_offset, SEEK_SET) < 0) {
+		ext2fs_free_mem(&table);
+		return errno;
+	}
+
+	size = read(fd, table, l1_size);
+	if (size != l1_size) {
+		ext2fs_free_mem(&table);
+		return errno;
+	}
+
+	img->l1_table = table;
+
+	return 0;
+}
+
+static int qcow2_read_l2_table(struct ext2_qcow2_image *img,
+			       ext2_off64_t offset, blk64_t **l2_table)
+{
+	int fd = img->fd;
+	size_t size;
+
+	assert(*l2_table);
+
+	if (ext2fs_llseek(fd, offset, SEEK_SET) < 0)
+		return errno;
+
+	size = read(fd, *l2_table, img->cluster_size);
+	if (size != img->cluster_size)
+		return errno;
+
+	return 0;
+}
+
+static int qcow2_copy_data(int fdin, int fdout, ext2_off64_t off_in,
+			   ext2_off64_t off_out, void *buf, size_t count)
+{
+	size_t size;
+
+	assert(buf);
+
+	if (ext2fs_llseek(fdout, off_out, SEEK_SET) < 0)
+		return errno;
+
+	if (ext2fs_llseek(fdin, off_in, SEEK_SET) < 0)
+		return errno;
+
+	size = read(fdin, buf, count);
+	if (size != count)
+		return errno;
+
+	size = write(fdout, buf, count);
+	if (size != count)
+		return errno;
+
+	return 0;
+}
+
+
+int qcow2_write_raw_image(int qcow2_fd, int raw_fd,
+			      struct ext2_qcow2_hdr *hdr)
+{
+	struct ext2_qcow2_image img;
+	errcode_t ret = 0;
+	unsigned int l1_index, l2_index;
+	ext2_off64_t offset;
+	blk64_t *l1_table, *l2_table = NULL;
+	void *copy_buf = NULL;
+	size_t size;
+
+	if (hdr->crypt_method)
+		return -QCOW_ENCRYPTED;
+
+	img.fd = qcow2_fd;
+	img.hdr = hdr;
+	img.l2_cache = NULL;
+	img.l1_table = NULL;
+	img.cluster_bits = ext2fs_be32_to_cpu(hdr->cluster_bits);
+	img.cluster_size = 1 << img.cluster_bits;
+	img.l1_size = ext2fs_be32_to_cpu(hdr->l1_size);
+	img.l1_offset = ext2fs_be64_to_cpu(hdr->l1_table_offset);
+	img.l2_size = 1 << (img.cluster_bits - 3);
+	img.image_size = ext2fs_be64_to_cpu(hdr->size);
+
+
+	ret = ext2fs_get_memzero(img.cluster_size, &l2_table);
+	if (ret)
+		goto out;
+
+	ret = ext2fs_get_memzero(1 << img.cluster_bits, &copy_buf);
+	if (ret)
+		goto out;
+
+	if (ext2fs_llseek(raw_fd, 0, SEEK_SET) < 0) {
+		ret = errno;
+		goto out;
+	}
+
+	ret = qcow2_read_l1_table(&img);
+	if (ret)
+		goto out;
+
+	l1_table = img.l1_table;
+	/* Walk through l1 table */
+	for (l1_index = 0; l1_index < img.l1_size; l1_index++) {
+		ext2_off64_t off_out;
+
+		offset = ext2fs_be64_to_cpu(l1_table[l1_index]) &
+			 ~QCOW_OFLAG_COPIED;
+
+		if ((offset > img.image_size) ||
+		    (offset <= 0))
+			continue;
+
+		if (offset & QCOW_OFLAG_COMPRESSED) {
+			ret = -QCOW_COMPRESSED;
+			goto out;
+		}
+
+		ret = qcow2_read_l2_table(&img, offset, &l2_table);
+		if (ret)
+			break;
+
+		/* Walk through l2 table and copy data blocks into raw image */
+		for (l2_index = 0; l2_index < img.l2_size; l2_index++) {
+			offset = ext2fs_be64_to_cpu(l2_table[l2_index]) &
+				 ~QCOW_OFLAG_COPIED;
+
+			if (offset == 0)
+				continue;
+
+			off_out = (l1_index * img.l2_size) +
+				  l2_index;
+			off_out <<= img.cluster_bits;
+			ret = qcow2_copy_data(qcow2_fd, raw_fd, offset,
+					off_out, copy_buf, img.cluster_size);
+			if (ret)
+				goto out;
+		}
+	}
+
+	/* Resize the output image to the filesystem size */
+	if (ext2fs_llseek(raw_fd, img.image_size - 1, SEEK_SET) < 0)
+		return errno;
+
+	((char *)copy_buf)[0] = 0;
+	size = write(raw_fd, copy_buf, 1);
+	if (size != 1) {
+		ret = errno;
+		goto out;
+	}
+
+out:
+	if (copy_buf)
+		ext2fs_free_mem(&copy_buf);
+	if (img.l1_table)
+		ext2fs_free_mem(&img.l1_table);
+	if (l2_table)
+		ext2fs_free_mem(&l2_table);
+	return ret;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/qcow2.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/qcow2.h
new file mode 100644
index 0000000..81e0ec9
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/qcow2.h
@@ -0,0 +1,113 @@
+/*
+ * qcow2.h --- structures and function prototypes for qcow2.c to generate
+ * qcow2 formatted disk images.  This format is used originally by QEMU
+ * for virtual machines, and stores the filesystem data on disk in a
+ * packed format to avoid creating sparse image files that need lots of
+ * seeking to read and write.
+ *
+ * The qcow2 format supports zlib compression, but that is not yet
+ * implemented.
+ *
+ * It is possible to directly mount a qcow2 image using qemu-nbd:
+ *
+ * [root]# modprobe nbd max_part=63
+ * [root]# qemu-nbd -c /dev/nbd0 image.img
+ * [root]# mount /dev/nbd0p1 /mnt/qemu
+ *
+ * Format details at http://people.gnome.org/~markmc/qcow-image-format.html
+ *
+ * Copyright (C) 2010 Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+/* Number of l2 tables in memory before writeback */
+#define L2_CACHE_PREALLOC	512
+
+
+#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
+#define QCOW_VERSION		2
+#define QCOW_OFLAG_COPIED	(1LL << 63)
+#define QCOW_OFLAG_COMPRESSED	(1LL << 62)
+
+#define QCOW_COMPRESSED		1
+#define QCOW_ENCRYPTED		2
+
+struct ext2_qcow2_hdr {
+	__u32	magic;
+	__u32	version;
+
+	__u64	backing_file_offset;
+	__u32	backing_file_size;
+
+	__u32	cluster_bits;
+	__u64	size;
+	__u32	crypt_method;
+
+	__u32	l1_size;
+	__u64	l1_table_offset;
+
+	__u64	refcount_table_offset;
+	__u32	refcount_table_clusters;
+
+	__u32	nb_snapshots;
+	__u64	snapshots_offset;
+};
+
+typedef struct ext2_qcow2_l2_table L2_CACHE_HEAD;
+
+struct ext2_qcow2_l2_table {
+	__u32		l1_index;
+	__u64		offset;
+	__u64		*data;
+	L2_CACHE_HEAD	*next;
+};
+
+struct ext2_qcow2_l2_cache {
+	L2_CACHE_HEAD	*used_head;
+	L2_CACHE_HEAD	*used_tail;
+	L2_CACHE_HEAD	*free_head;
+	__u32		free;
+	__u32		count;
+	__u64		next_offset;
+};
+
+struct ext2_qcow2_refcount {
+	__u64	*refcount_table;
+	__u64	refcount_table_offset;
+	__u64	refcount_block_offset;
+
+	__u32	refcount_table_clusters;
+	__u32	refcount_table_index;
+	__u32	refcount_block_index;
+
+	__u16	*refcount_block;
+};
+
+struct ext2_qcow2_image {
+	int	fd;
+	struct	ext2_qcow2_hdr		*hdr;
+	struct	ext2_qcow2_l2_cache	*l2_cache;
+	struct	ext2_qcow2_refcount	refcount;
+	__u32	cluster_size;
+	__u32	cluster_bits;
+	__u32	l1_size;
+	__u32	l2_size;
+
+	__u64	*l1_table;
+	__u64	l2_offset;
+	__u64	l1_offset;
+	__u64	image_size;
+};
+
+/* Function prototypes */
+
+/* qcow2.c */
+
+/* Functions for converting qcow2 image into raw image */
+struct ext2_qcow2_hdr *qcow2_read_header(int);
+int qcow2_write_raw_image(int, int, struct ext2_qcow2_hdr *);
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/rbtree.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/rbtree.c
new file mode 100644
index 0000000..9439303
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/rbtree.c
@@ -0,0 +1,451 @@
+/*
+  Red Black Trees
+  (C) 1999  Andrea Arcangeli <andrea@suse.de>
+  (C) 2002  David Woodhouse <dwmw2@infradead.org>
+
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+  linux/lib/rbtree.c
+*/
+
+#include "rbtree.h"
+
+static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
+{
+	struct rb_node *right = node->rb_right;
+	struct rb_node *parent = ext2fs_rb_parent(node);
+
+	if ((node->rb_right = right->rb_left))
+		ext2fs_rb_set_parent(right->rb_left, node);
+	right->rb_left = node;
+
+	ext2fs_rb_set_parent(right, parent);
+
+	if (parent)
+	{
+		if (node == parent->rb_left)
+			parent->rb_left = right;
+		else
+			parent->rb_right = right;
+	}
+	else
+		root->rb_node = right;
+	ext2fs_rb_set_parent(node, right);
+}
+
+static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
+{
+	struct rb_node *left = node->rb_left;
+	struct rb_node *parent = ext2fs_rb_parent(node);
+
+	if ((node->rb_left = left->rb_right))
+		ext2fs_rb_set_parent(left->rb_right, node);
+	left->rb_right = node;
+
+	ext2fs_rb_set_parent(left, parent);
+
+	if (parent)
+	{
+		if (node == parent->rb_right)
+			parent->rb_right = left;
+		else
+			parent->rb_left = left;
+	}
+	else
+		root->rb_node = left;
+	ext2fs_rb_set_parent(node, left);
+}
+
+void ext2fs_rb_insert_color(struct rb_node *node, struct rb_root *root)
+{
+	struct rb_node *parent, *gparent;
+
+	while ((parent = ext2fs_rb_parent(node)) && ext2fs_rb_is_red(parent))
+	{
+		gparent = ext2fs_rb_parent(parent);
+
+		if (parent == gparent->rb_left)
+		{
+			{
+				register struct rb_node *uncle = gparent->rb_right;
+				if (uncle && ext2fs_rb_is_red(uncle))
+				{
+					ext2fs_rb_set_black(uncle);
+					ext2fs_rb_set_black(parent);
+					ext2fs_rb_set_red(gparent);
+					node = gparent;
+					continue;
+				}
+			}
+
+			if (parent->rb_right == node)
+			{
+				register struct rb_node *tmp;
+				__rb_rotate_left(parent, root);
+				tmp = parent;
+				parent = node;
+				node = tmp;
+			}
+
+			ext2fs_rb_set_black(parent);
+			ext2fs_rb_set_red(gparent);
+			__rb_rotate_right(gparent, root);
+		} else {
+			{
+				register struct rb_node *uncle = gparent->rb_left;
+				if (uncle && ext2fs_rb_is_red(uncle))
+				{
+					ext2fs_rb_set_black(uncle);
+					ext2fs_rb_set_black(parent);
+					ext2fs_rb_set_red(gparent);
+					node = gparent;
+					continue;
+				}
+			}
+
+			if (parent->rb_left == node)
+			{
+				register struct rb_node *tmp;
+				__rb_rotate_right(parent, root);
+				tmp = parent;
+				parent = node;
+				node = tmp;
+			}
+
+			ext2fs_rb_set_black(parent);
+			ext2fs_rb_set_red(gparent);
+			__rb_rotate_left(gparent, root);
+		}
+	}
+
+	ext2fs_rb_set_black(root->rb_node);
+}
+
+static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
+			     struct rb_root *root)
+{
+	struct rb_node *other;
+
+	while ((!node || ext2fs_rb_is_black(node)) && node != root->rb_node)
+	{
+		if (parent->rb_left == node)
+		{
+			other = parent->rb_right;
+			if (ext2fs_rb_is_red(other))
+			{
+				ext2fs_rb_set_black(other);
+				ext2fs_rb_set_red(parent);
+				__rb_rotate_left(parent, root);
+				other = parent->rb_right;
+			}
+			if ((!other->rb_left || ext2fs_rb_is_black(other->rb_left)) &&
+			    (!other->rb_right || ext2fs_rb_is_black(other->rb_right)))
+			{
+				ext2fs_rb_set_red(other);
+				node = parent;
+				parent = ext2fs_rb_parent(node);
+			}
+			else
+			{
+				if (!other->rb_right || ext2fs_rb_is_black(other->rb_right))
+				{
+					ext2fs_rb_set_black(other->rb_left);
+					ext2fs_rb_set_red(other);
+					__rb_rotate_right(other, root);
+					other = parent->rb_right;
+				}
+				ext2fs_rb_set_color(other, ext2fs_rb_color(parent));
+				ext2fs_rb_set_black(parent);
+				ext2fs_rb_set_black(other->rb_right);
+				__rb_rotate_left(parent, root);
+				node = root->rb_node;
+				break;
+			}
+		}
+		else
+		{
+			other = parent->rb_left;
+			if (ext2fs_rb_is_red(other))
+			{
+				ext2fs_rb_set_black(other);
+				ext2fs_rb_set_red(parent);
+				__rb_rotate_right(parent, root);
+				other = parent->rb_left;
+			}
+			if ((!other->rb_left || ext2fs_rb_is_black(other->rb_left)) &&
+			    (!other->rb_right || ext2fs_rb_is_black(other->rb_right)))
+			{
+				ext2fs_rb_set_red(other);
+				node = parent;
+				parent = ext2fs_rb_parent(node);
+			}
+			else
+			{
+				if (!other->rb_left || ext2fs_rb_is_black(other->rb_left))
+				{
+					ext2fs_rb_set_black(other->rb_right);
+					ext2fs_rb_set_red(other);
+					__rb_rotate_left(other, root);
+					other = parent->rb_left;
+				}
+				ext2fs_rb_set_color(other, ext2fs_rb_color(parent));
+				ext2fs_rb_set_black(parent);
+				ext2fs_rb_set_black(other->rb_left);
+				__rb_rotate_right(parent, root);
+				node = root->rb_node;
+				break;
+			}
+		}
+	}
+	if (node)
+		ext2fs_rb_set_black(node);
+}
+
+void ext2fs_rb_erase(struct rb_node *node, struct rb_root *root)
+{
+	struct rb_node *child, *parent;
+	int color;
+
+	if (!node->rb_left)
+		child = node->rb_right;
+	else if (!node->rb_right)
+		child = node->rb_left;
+	else
+	{
+		struct rb_node *old = node, *left;
+
+		node = node->rb_right;
+		while ((left = node->rb_left) != NULL)
+			node = left;
+
+		if (ext2fs_rb_parent(old)) {
+			if (ext2fs_rb_parent(old)->rb_left == old)
+				ext2fs_rb_parent(old)->rb_left = node;
+			else
+				ext2fs_rb_parent(old)->rb_right = node;
+		} else
+			root->rb_node = node;
+
+		child = node->rb_right;
+		parent = ext2fs_rb_parent(node);
+		color = ext2fs_rb_color(node);
+
+		if (parent == old) {
+			parent = node;
+		} else {
+			if (child)
+				ext2fs_rb_set_parent(child, parent);
+			parent->rb_left = child;
+
+			node->rb_right = old->rb_right;
+			ext2fs_rb_set_parent(old->rb_right, node);
+		}
+
+		node->rb_parent_color = old->rb_parent_color;
+		node->rb_left = old->rb_left;
+		ext2fs_rb_set_parent(old->rb_left, node);
+
+		goto color;
+	}
+
+	parent = ext2fs_rb_parent(node);
+	color = ext2fs_rb_color(node);
+
+	if (child)
+		ext2fs_rb_set_parent(child, parent);
+	if (parent)
+	{
+		if (parent->rb_left == node)
+			parent->rb_left = child;
+		else
+			parent->rb_right = child;
+	}
+	else
+		root->rb_node = child;
+
+ color:
+	if (color == RB_BLACK)
+		__rb_erase_color(child, parent, root);
+}
+
+static void ext2fs_rb_augment_path(struct rb_node *node, rb_augment_f func, void *data)
+{
+	struct rb_node *parent;
+
+up:
+	func(node, data);
+	parent = ext2fs_rb_parent(node);
+	if (!parent)
+		return;
+
+	if (node == parent->rb_left && parent->rb_right)
+		func(parent->rb_right, data);
+	else if (parent->rb_left)
+		func(parent->rb_left, data);
+
+	node = parent;
+	goto up;
+}
+
+/*
+ * after inserting @node into the tree, update the tree to account for
+ * both the new entry and any damage done by rebalance
+ */
+void ext2fs_rb_augment_insert(struct rb_node *node, rb_augment_f func, void *data)
+{
+	if (node->rb_left)
+		node = node->rb_left;
+	else if (node->rb_right)
+		node = node->rb_right;
+
+	ext2fs_rb_augment_path(node, func, data);
+}
+
+/*
+ * before removing the node, find the deepest node on the rebalance path
+ * that will still be there after @node gets removed
+ */
+struct rb_node *ext2fs_rb_augment_erase_begin(struct rb_node *node)
+{
+	struct rb_node *deepest;
+
+	if (!node->rb_right && !node->rb_left)
+		deepest = ext2fs_rb_parent(node);
+	else if (!node->rb_right)
+		deepest = node->rb_left;
+	else if (!node->rb_left)
+		deepest = node->rb_right;
+	else {
+		deepest = ext2fs_rb_next(node);
+		if (deepest->rb_right)
+			deepest = deepest->rb_right;
+		else if (ext2fs_rb_parent(deepest) != node)
+			deepest = ext2fs_rb_parent(deepest);
+	}
+
+	return deepest;
+}
+
+/*
+ * after removal, update the tree to account for the removed entry
+ * and any rebalance damage.
+ */
+void ext2fs_rb_augment_erase_end(struct rb_node *node, rb_augment_f func, void *data)
+{
+	if (node)
+		ext2fs_rb_augment_path(node, func, data);
+}
+
+/*
+ * This function returns the first node (in sort order) of the tree.
+ */
+struct rb_node *ext2fs_rb_first(const struct rb_root *root)
+{
+	struct rb_node	*n;
+
+	n = root->rb_node;
+	if (!n)
+		return NULL;
+	while (n->rb_left)
+		n = n->rb_left;
+	return n;
+}
+
+struct rb_node *ext2fs_rb_last(const struct rb_root *root)
+{
+	struct rb_node	*n;
+
+	n = root->rb_node;
+	if (!n)
+		return NULL;
+	while (n->rb_right)
+		n = n->rb_right;
+	return n;
+}
+
+struct rb_node *ext2fs_rb_next(struct rb_node *node)
+{
+	struct rb_node *parent;
+
+	if (ext2fs_rb_parent(node) == node)
+		return NULL;
+
+	/* If we have a right-hand child, go down and then left as far
+	   as we can. */
+	if (node->rb_right) {
+		node = node->rb_right;
+		while (node->rb_left)
+			node=node->rb_left;
+		return (struct rb_node *)node;
+	}
+
+	/* No right-hand children.  Everything down and left is
+	   smaller than us, so any 'next' node must be in the general
+	   direction of our parent. Go up the tree; any time the
+	   ancestor is a right-hand child of its parent, keep going
+	   up. First time it's a left-hand child of its parent, said
+	   parent is our 'next' node. */
+	while ((parent = ext2fs_rb_parent(node)) && node == parent->rb_right)
+		node = parent;
+
+	return parent;
+}
+
+struct rb_node *ext2fs_rb_prev(struct rb_node *node)
+{
+	struct rb_node *parent;
+
+	if (ext2fs_rb_parent(node) == node)
+		return NULL;
+
+	/* If we have a left-hand child, go down and then right as far
+	   as we can. */
+	if (node->rb_left) {
+		node = node->rb_left;
+		while (node->rb_right)
+			node=node->rb_right;
+		return (struct rb_node *)node;
+	}
+
+	/* No left-hand children. Go up till we find an ancestor which
+	   is a right-hand child of its parent */
+	while ((parent = ext2fs_rb_parent(node)) && node == parent->rb_left)
+		node = parent;
+
+	return parent;
+}
+
+void ext2fs_rb_replace_node(struct rb_node *victim, struct rb_node *new,
+			  struct rb_root *root)
+{
+	struct rb_node *parent = ext2fs_rb_parent(victim);
+
+	/* Set the surrounding nodes to point to the replacement */
+	if (parent) {
+		if (victim == parent->rb_left)
+			parent->rb_left = new;
+		else
+			parent->rb_right = new;
+	} else {
+		root->rb_node = new;
+	}
+	if (victim->rb_left)
+		ext2fs_rb_set_parent(victim->rb_left, new);
+	if (victim->rb_right)
+		ext2fs_rb_set_parent(victim->rb_right, new);
+
+	/* Copy the pointers/colour from the victim to the replacement */
+	*new = *victim;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/rbtree.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/rbtree.h
new file mode 100644
index 0000000..3b0b078
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/rbtree.h
@@ -0,0 +1,180 @@
+/*
+  Red Black Trees
+  (C) 1999  Andrea Arcangeli <andrea@suse.de>
+
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+  linux/include/linux/rbtree.h
+
+  To use rbtrees you'll have to implement your own insert and search cores.
+  This will avoid us to use callbacks and to drop drammatically performances.
+  I know it's not the cleaner way,  but in C (not in C++) to get
+  performances and genericity...
+
+  Some example of insert and search follows here. The search is a plain
+  normal search over an ordered tree. The insert instead must be implemented
+  in two steps: First, the code must insert the element in order as a red leaf
+  in the tree, and then the support library function rb_insert_color() must
+  be called. Such function will do the not trivial work to rebalance the
+  rbtree, if necessary.
+
+-----------------------------------------------------------------------
+static inline struct page * rb_search_page_cache(struct inode * inode,
+						 unsigned long offset)
+{
+	struct rb_node * n = inode->i_rb_page_cache.rb_node;
+	struct page * page;
+
+	while (n)
+	{
+		page = rb_entry(n, struct page, rb_page_cache);
+
+		if (offset < page->offset)
+			n = n->rb_left;
+		else if (offset > page->offset)
+			n = n->rb_right;
+		else
+			return page;
+	}
+	return NULL;
+}
+
+static inline struct page * __rb_insert_page_cache(struct inode * inode,
+						   unsigned long offset,
+						   struct rb_node * node)
+{
+	struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
+	struct rb_node * parent = NULL;
+	struct page * page;
+
+	while (*p)
+	{
+		parent = *p;
+		page = rb_entry(parent, struct page, rb_page_cache);
+
+		if (offset < page->offset)
+			p = &(*p)->rb_left;
+		else if (offset > page->offset)
+			p = &(*p)->rb_right;
+		else
+			return page;
+	}
+
+	rb_link_node(node, parent, p);
+
+	return NULL;
+}
+
+static inline struct page * rb_insert_page_cache(struct inode * inode,
+						 unsigned long offset,
+						 struct rb_node * node)
+{
+	struct page * ret;
+	if ((ret = __rb_insert_page_cache(inode, offset, node)))
+		goto out;
+	rb_insert_color(node, &inode->i_rb_page_cache);
+ out:
+	return ret;
+}
+-----------------------------------------------------------------------
+*/
+
+#ifndef	_LINUX_RBTREE_H
+#define	_LINUX_RBTREE_H
+
+#include <stdlib.h>
+
+#undef offsetof
+#ifdef __compiler_offsetof
+#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#define container_of(ptr, type, member) ({			\
+	const __typeof__( ((type *)0)->member ) *__mptr = (ptr);	\
+	(type *)( (char *)__mptr - offsetof(type,member) );})
+
+struct rb_node
+{
+	unsigned long  rb_parent_color;
+#define	RB_RED		0
+#define	RB_BLACK	1
+	struct rb_node *rb_right;
+	struct rb_node *rb_left;
+} __attribute__((aligned(sizeof(long))));
+    /* The alignment might seem pointless, but allegedly CRIS needs it */
+
+struct rb_root
+{
+	struct rb_node *rb_node;
+};
+
+
+#define ext2fs_rb_parent(r)   ((struct rb_node *)((r)->rb_parent_color & ~3))
+#define ext2fs_rb_color(r)   ((r)->rb_parent_color & 1)
+#define ext2fs_rb_is_red(r)   (!ext2fs_rb_color(r))
+#define ext2fs_rb_is_black(r) ext2fs_rb_color(r)
+#define ext2fs_rb_set_red(r)  do { (r)->rb_parent_color &= ~1; } while (0)
+#define ext2fs_rb_set_black(r)  do { (r)->rb_parent_color |= 1; } while (0)
+
+static inline void ext2fs_rb_set_parent(struct rb_node *rb, struct rb_node *p)
+{
+	rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
+}
+static inline void ext2fs_rb_set_color(struct rb_node *rb, int color)
+{
+	rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
+}
+
+#define RB_ROOT	(struct rb_root) { NULL, }
+#define	ext2fs_rb_entry(ptr, type, member) container_of(ptr, type, member)
+
+#define EXT2FS_RB_EMPTY_ROOT(root)	((root)->rb_node == NULL)
+#define EXT2FS_RB_EMPTY_NODE(node)	(ext2fs_rb_parent(node) == node)
+#define EXT2FS_RB_CLEAR_NODE(node)	(ext2fs_rb_set_parent(node, node))
+
+extern void ext2fs_rb_insert_color(struct rb_node *, struct rb_root *);
+extern void ext2fs_rb_erase(struct rb_node *, struct rb_root *);
+
+typedef void (*rb_augment_f)(struct rb_node *node, void *data);
+
+extern void ext2fs_rb_augment_insert(struct rb_node *node,
+			      rb_augment_f func, void *data);
+extern struct rb_node *ext2fs_rb_augment_erase_begin(struct rb_node *node);
+extern void ext2fs_rb_augment_erase_end(struct rb_node *node,
+				 rb_augment_f func, void *data);
+
+/* Find logical next and previous nodes in a tree */
+extern struct rb_node *ext2fs_rb_next(struct rb_node *);
+extern struct rb_node *ext2fs_rb_prev(struct rb_node *);
+extern struct rb_node *ext2fs_rb_first(const struct rb_root *);
+extern struct rb_node *ext2fs_rb_last(const struct rb_root *);
+
+/* Fast replacement of a single node without remove/rebalance/add/rebalance */
+extern void ext2fs_rb_replace_node(struct rb_node *victim, struct rb_node *new,
+				 struct rb_root *root);
+
+static inline void ext2fs_rb_link_node(struct rb_node * node,
+				     struct rb_node * parent,
+				     struct rb_node ** rb_link)
+{
+	node->rb_parent_color = (unsigned long )parent;
+	node->rb_left = node->rb_right = NULL;
+
+	*rb_link = node;
+}
+
+#endif	/* _LINUX_RBTREE_H */
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/read_bb.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/read_bb.c
new file mode 100644
index 0000000..b5a0d7b
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/read_bb.c
@@ -0,0 +1,103 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 >= ext2fs_blocks_count(fs->super)))
+		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;
+		numblocks = inode.i_blocks;
+		if (!((fs->super->s_feature_ro_compat &
+		       EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
+		      (inode.i_flags & EXT4_HUGE_FILE_FL)))
+			numblocks = numblocks / (fs->blocksize / 512);
+		numblocks += 20;
+		if (numblocks < 50)
+			numblocks = 50;
+		if (numblocks > 50000)
+			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, BLOCK_FLAG_READ_ONLY,
+				       0, mark_bad_block, &rb);
+	if (retval)
+		return retval;
+
+	return rb.err;
+}
+
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/read_bb_file.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/read_bb_file.c
new file mode 100644
index 0000000..8d1ad1a
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/read_bb_file.c
@@ -0,0 +1,109 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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;
+	blk64_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, "%llu", &blockno);
+		if (count <= 0)
+			continue;
+		/* Badblocks isn't going to be updated for 64bit */
+		if (blockno >> 32)
+			return EOVERFLOW;
+		if (fs &&
+		    ((blockno < fs->super->s_first_data_block) ||
+		     (blockno >= ext2fs_blocks_count(fs->super)))) {
+			if (invalid)
+				(invalid)(fs, blockno, buf, priv_data);
+			continue;
+		}
+		retval = ext2fs_badblocks_list_add(*bb_list, blockno);
+		if (retval)
+			return retval;
+	}
+	return 0;
+}
+
+struct compat_struct {
+	void (*invalid)(ext2_filsys, blk_t);
+};
+
+static void call_compat_invalid(ext2_filsys fs, blk_t blk,
+				char *badstr EXT2FS_ATTR((unused)),
+				void *priv_data)
+{
+	struct compat_struct *st;
+
+	st = (struct compat_struct *) priv_data;
+	if (st->invalid)
+		(st->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))
+{
+	struct compat_struct st;
+
+	st.invalid = invalid;
+
+	return ext2fs_read_bb_FILE2(fs, f, bb_list, &st,
+				    call_compat_invalid);
+}
+
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/res_gdt.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/res_gdt.c
new file mode 100644
index 0000000..6449228
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/res_gdt.c
@@ -0,0 +1,230 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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;
+	unsigned long long	apb, inode_size;
+	/* FIXME-64 - can't deal with extents */
+	blk_t			dindir_blk, rsv_off, gdt_off, gdt_blk;
+	int			dindir_dirty = 0, inode_dirty = 0, sb_blk = 0;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	sb = fs->super;
+
+	retval = ext2fs_get_array(2, fs->blocksize, &dindir_buf);
+	if (retval)
+		return retval;
+	gdt_buf = (__u32 *)((char *)dindir_buf + fs->blocksize);
+
+	retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
+	if (retval)
+		goto out_free;
+
+	/*
+	 * File systems with a blocksize of 1024 and bigalloc have
+	 * sb->s_first_data_block of 0; yet the superblock is still at
+	 * block #1.  We compensate for it here.
+	 */
+	sb_blk = sb->s_first_data_block;
+	if (fs->blocksize == 1024 && sb_blk == 0)
+		sb_blk = 1;
+
+	/* Maximum possible file size (we donly use the dindirect blocks) */
+	apb = EXT2_ADDR_PER_BLOCK(sb);
+	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 = sb_blk + fs->desc_blocks +
+			sb->s_reserved_gdt_blocks + 2 +
+			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;
+		ext2fs_iblk_set(fs, &inode, 1);
+		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 = fs->now ? fs->now : time(0);
+	}
+
+	for (rsv_off = 0, gdt_off = fs->desc_blocks,
+	     gdt_blk = sb_blk + 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;
+			ext2fs_iblk_add_blocks(fs, &inode, 1);
+#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;
+				ext2fs_iblk_add_blocks(fs, &inode, 1);
+				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 = fs->now ? fs->now : time(0);
+		retval2 = ext2fs_write_new_inode(fs, EXT2_RESIZE_INO, &inode);
+		if (!retval)
+			retval = retval2;
+	}
+out_free:
+	ext2fs_free_mem(&dindir_buf);
+	return retval;
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/rw_bitmaps.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/rw_bitmaps.c
new file mode 100644
index 0000000..b7d65a9
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/rw_bitmaps.c
@@ -0,0 +1,357 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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"
+
+static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
+{
+	dgrp_t 		i;
+	unsigned int	j;
+	int		block_nbytes, inode_nbytes;
+	unsigned int	nbits;
+	errcode_t	retval;
+	char		*block_buf = NULL, *inode_buf = NULL;
+	int		csum_flag = 0;
+	blk64_t		blk;
+	blk64_t		blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block);
+	ext2_ino_t	ino_itr = 1;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	if (!(fs->flags & EXT2_FLAG_RW))
+		return EXT2_ET_RO_FILSYS;
+
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
+		csum_flag = 1;
+
+	inode_nbytes = block_nbytes = 0;
+	if (do_block) {
+		block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8;
+		retval = io_channel_alloc_buf(fs->io, 0, &block_buf);
+		if (retval)
+			goto errout;
+		memset(block_buf, 0xff, fs->blocksize);
+	}
+	if (do_inode) {
+		inode_nbytes = (size_t)
+			((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
+		retval = io_channel_alloc_buf(fs->io, 0, &inode_buf);
+		if (retval)
+			goto errout;
+		memset(inode_buf, 0xff, fs->blocksize);
+	}
+
+	for (i = 0; i < fs->group_desc_count; i++) {
+		if (!do_block)
+			goto skip_block_bitmap;
+
+		if (csum_flag && ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT)
+		    )
+			goto skip_this_block_bitmap;
+
+		retval = ext2fs_get_block_bitmap_range2(fs->block_map,
+				blk_itr, block_nbytes << 3, block_buf);
+		if (retval)
+			goto errout;
+
+		if (i == fs->group_desc_count - 1) {
+			/* Force bitmap padding for the last group */
+			nbits = EXT2FS_NUM_B2C(fs,
+				((ext2fs_blocks_count(fs->super)
+				  - (__u64) fs->super->s_first_data_block)
+				 % (__u64) EXT2_BLOCKS_PER_GROUP(fs->super)));
+			if (nbits)
+				for (j = nbits; j < fs->blocksize * 8; j++)
+					ext2fs_set_bit(j, block_buf);
+		}
+		blk = ext2fs_block_bitmap_loc(fs, i);
+		if (blk) {
+			retval = io_channel_write_blk64(fs->io, blk, 1,
+							block_buf);
+			if (retval) {
+				retval = EXT2_ET_BLOCK_BITMAP_WRITE;
+				goto errout;
+			}
+		}
+	skip_this_block_bitmap:
+		blk_itr += block_nbytes << 3;
+	skip_block_bitmap:
+
+		if (!do_inode)
+			continue;
+
+		if (csum_flag && ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)
+		    )
+			goto skip_this_inode_bitmap;
+
+		retval = ext2fs_get_inode_bitmap_range2(fs->inode_map,
+				ino_itr, inode_nbytes << 3, inode_buf);
+		if (retval)
+			goto errout;
+
+		blk = ext2fs_inode_bitmap_loc(fs, i);
+		if (blk) {
+			retval = io_channel_write_blk64(fs->io, blk, 1,
+						      inode_buf);
+			if (retval) {
+				retval = EXT2_ET_INODE_BITMAP_WRITE;
+				goto errout;
+			}
+		}
+	skip_this_inode_bitmap:
+		ino_itr += inode_nbytes << 3;
+
+	}
+	if (do_block) {
+		fs->flags &= ~EXT2_FLAG_BB_DIRTY;
+		ext2fs_free_mem(&block_buf);
+	}
+	if (do_inode) {
+		fs->flags &= ~EXT2_FLAG_IB_DIRTY;
+		ext2fs_free_mem(&inode_buf);
+	}
+	return 0;
+errout:
+	if (inode_buf)
+		ext2fs_free_mem(&inode_buf);
+	if (block_buf)
+		ext2fs_free_mem(&block_buf);
+	return retval;
+}
+
+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 = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8;
+	int inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8;
+	int csum_flag = 0;
+	unsigned int	cnt;
+	blk64_t	blk;
+	blk64_t	blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block);
+	blk64_t   blk_cnt;
+	ext2_ino_t ino_itr = 1;
+	ext2_ino_t ino_cnt;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	if ((block_nbytes > (int) fs->blocksize) ||
+	    (inode_nbytes > (int) fs->blocksize))
+		return EXT2_ET_CORRUPT_SUPERBLOCK;
+
+	fs->write_bitmaps = ext2fs_write_bitmaps;
+
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
+		csum_flag = 1;
+
+	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);
+		strcpy(buf, "block bitmap for ");
+		strcat(buf, fs->device_name);
+		retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map);
+		if (retval)
+			goto cleanup;
+		retval = io_channel_alloc_buf(fs->io, 0, &block_bitmap);
+		if (retval)
+			goto cleanup;
+	} else
+		block_nbytes = 0;
+	if (do_inode) {
+		if (fs->inode_map)
+			ext2fs_free_inode_bitmap(fs->inode_map);
+		strcpy(buf, "inode bitmap for ");
+		strcat(buf, fs->device_name);
+		retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
+		if (retval)
+			goto cleanup;
+		retval = io_channel_alloc_buf(fs->io, 0, &inode_bitmap);
+		if (retval)
+			goto cleanup;
+	} else
+		inode_nbytes = 0;
+	ext2fs_free_mem(&buf);
+
+	if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
+		blk = (fs->image_header->offset_inodemap / fs->blocksize);
+		ino_cnt = fs->super->s_inodes_count;
+		while (inode_nbytes > 0) {
+			retval = io_channel_read_blk64(fs->image_io, blk++,
+						     1, inode_bitmap);
+			if (retval)
+				goto cleanup;
+			cnt = fs->blocksize << 3;
+			if (cnt > ino_cnt)
+				cnt = ino_cnt;
+			retval = ext2fs_set_inode_bitmap_range2(fs->inode_map,
+					       ino_itr, cnt, inode_bitmap);
+			if (retval)
+				goto cleanup;
+			ino_itr += fs->blocksize << 3;
+			ino_cnt -= fs->blocksize << 3;
+			inode_nbytes -= fs->blocksize;
+		}
+		blk = (fs->image_header->offset_blockmap /
+		       fs->blocksize);
+		blk_cnt = (blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) *
+			fs->group_desc_count;
+		while (block_nbytes > 0) {
+			retval = io_channel_read_blk64(fs->image_io, blk++,
+						     1, block_bitmap);
+			if (retval)
+				goto cleanup;
+			cnt = fs->blocksize << 3;
+			if (cnt > blk_cnt)
+				cnt = blk_cnt;
+			retval = ext2fs_set_block_bitmap_range2(fs->block_map,
+				       blk_itr, cnt, block_bitmap);
+			if (retval)
+				goto cleanup;
+			blk_itr += fs->blocksize << 3;
+			blk_cnt -= fs->blocksize << 3;
+			block_nbytes -= fs->blocksize;
+		}
+		goto success_cleanup;
+	}
+
+	for (i = 0; i < fs->group_desc_count; i++) {
+		if (block_bitmap) {
+			blk = ext2fs_block_bitmap_loc(fs, i);
+			if (csum_flag &&
+			    ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
+			    ext2fs_group_desc_csum_verify(fs, i))
+				blk = 0;
+			if (blk) {
+				retval = io_channel_read_blk64(fs->io, blk,
+							       1, block_bitmap);
+				if (retval) {
+					retval = EXT2_ET_BLOCK_BITMAP_READ;
+					goto cleanup;
+				}
+			} else
+				memset(block_bitmap, 0, block_nbytes);
+			cnt = block_nbytes << 3;
+			retval = ext2fs_set_block_bitmap_range2(fs->block_map,
+					       blk_itr, cnt, block_bitmap);
+			if (retval)
+				goto cleanup;
+			blk_itr += block_nbytes << 3;
+		}
+		if (inode_bitmap) {
+			blk = ext2fs_inode_bitmap_loc(fs, i);
+			if (csum_flag &&
+			    ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) &&
+			    ext2fs_group_desc_csum_verify(fs, i))
+				blk = 0;
+			if (blk) {
+				retval = io_channel_read_blk64(fs->io, blk,
+							       1, inode_bitmap);
+				if (retval) {
+					retval = EXT2_ET_INODE_BITMAP_READ;
+					goto cleanup;
+				}
+			} else
+				memset(inode_bitmap, 0, inode_nbytes);
+			cnt = inode_nbytes << 3;
+			retval = ext2fs_set_inode_bitmap_range2(fs->inode_map,
+					       ino_itr, cnt, inode_bitmap);
+			if (retval)
+				goto cleanup;
+			ino_itr += inode_nbytes << 3;
+		}
+	}
+success_cleanup:
+	if (inode_bitmap)
+		ext2fs_free_mem(&inode_bitmap);
+	if (block_bitmap)
+		ext2fs_free_mem(&block_bitmap);
+	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 (inode_bitmap)
+		ext2fs_free_mem(&inode_bitmap);
+	if (block_bitmap)
+		ext2fs_free_mem(&block_bitmap);
+	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_write_inode_bitmap(ext2_filsys fs)
+{
+	return write_bitmaps(fs, 1, 0);
+}
+
+errcode_t ext2fs_write_block_bitmap (ext2_filsys fs)
+{
+	return write_bitmaps(fs, 0, 1);
+}
+
+errcode_t ext2fs_read_bitmaps(ext2_filsys fs)
+{
+	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)
+{
+	int do_inode = fs->inode_map && ext2fs_test_ib_dirty(fs);
+	int do_block = fs->block_map && ext2fs_test_bb_dirty(fs);
+
+	if (!do_inode && !do_block)
+		return 0;
+
+	return write_bitmaps(fs, do_inode, do_block);
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/swapfs.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/swapfs.c
new file mode 100644
index 0000000..56c66cc
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/swapfs.c
@@ -0,0 +1,353 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 WORDS_BIGENDIAN
+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_cluster_size = ext2fs_swab32(sb->s_log_cluster_size);
+	sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group);
+	sb->s_clusters_per_group = ext2fs_swab32(sb->s_clusters_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_desc_size = ext2fs_swab16(sb->s_desc_size);
+	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);
+	sb->s_blocks_count_hi = ext2fs_swab32(sb->s_blocks_count_hi);
+	sb->s_r_blocks_count_hi = ext2fs_swab32(sb->s_r_blocks_count_hi);
+	sb->s_free_blocks_hi = ext2fs_swab32(sb->s_free_blocks_hi);
+	sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize);
+	sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize);
+	sb->s_flags = ext2fs_swab32(sb->s_flags);
+	sb->s_mmp_update_interval = ext2fs_swab16(sb->s_mmp_update_interval);
+	sb->s_mmp_block = ext2fs_swab64(sb->s_mmp_block);
+	sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written);
+	sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum);
+	sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id);
+	sb->s_snapshot_r_blocks_count =
+		ext2fs_swab64(sb->s_snapshot_r_blocks_count);
+	sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list);
+	sb->s_usr_quota_inum = ext2fs_swab32(sb->s_usr_quota_inum);
+	sb->s_grp_quota_inum = ext2fs_swab32(sb->s_grp_quota_inum);
+	sb->s_overhead_blocks = ext2fs_swab32(sb->s_overhead_blocks);
+	sb->s_checksum = ext2fs_swab32(sb->s_checksum);
+
+	for (i=0; i < 4; i++)
+		sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
+
+	/* if journal backup is for a valid extent-based journal... */
+	if (ext2fs_extent_header_verify(sb->s_jnl_blocks,
+					sizeof(sb->s_jnl_blocks)) == 0) {
+		/* ... swap only the journal i_size and i_size_high,
+		 * and the extent data is not swapped on read */
+		i = 15;
+	} else {
+		/* direct/indirect journal: swap it all */
+		i = 0;
+	}
+	for (; i < 17; i++)
+		sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
+}
+
+void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
+{
+	struct ext4_group_desc *gdp4 = (struct ext4_group_desc *)gdp;
+
+	/* Do the 32-bit parts first */
+	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);
+	gdp->bg_flags = ext2fs_swab16(gdp->bg_flags);
+	gdp->bg_exclude_bitmap_lo = ext2fs_swab32(gdp->bg_exclude_bitmap_lo);
+	gdp->bg_block_bitmap_csum_lo =
+		ext2fs_swab16(gdp->bg_block_bitmap_csum_lo);
+	gdp->bg_inode_bitmap_csum_lo =
+		ext2fs_swab16(gdp->bg_inode_bitmap_csum_lo);
+	gdp->bg_itable_unused = ext2fs_swab16(gdp->bg_itable_unused);
+	gdp->bg_checksum = ext2fs_swab16(gdp->bg_checksum);
+	/* If we're 32-bit, we're done */
+	if (fs == NULL || EXT2_DESC_SIZE(fs->super) < EXT2_MIN_DESC_SIZE_64BIT)
+		return;
+
+	/* Swap the 64-bit parts */
+	gdp4->bg_block_bitmap_hi = ext2fs_swab32(gdp4->bg_block_bitmap_hi);
+	gdp4->bg_inode_bitmap_hi = ext2fs_swab32(gdp4->bg_inode_bitmap_hi);
+	gdp4->bg_inode_table_hi = ext2fs_swab32(gdp4->bg_inode_table_hi);
+	gdp4->bg_free_blocks_count_hi =
+		ext2fs_swab16(gdp4->bg_free_blocks_count_hi);
+	gdp4->bg_free_inodes_count_hi =
+		ext2fs_swab16(gdp4->bg_free_inodes_count_hi);
+	gdp4->bg_used_dirs_count_hi =
+		ext2fs_swab16(gdp4->bg_used_dirs_count_hi);
+	gdp4->bg_itable_unused_hi = ext2fs_swab16(gdp4->bg_itable_unused_hi);
+	gdp4->bg_exclude_bitmap_hi = ext2fs_swab16(gdp4->bg_exclude_bitmap_hi);
+	gdp4->bg_block_bitmap_csum_hi =
+		ext2fs_swab16(gdp4->bg_block_bitmap_csum_hi);
+	gdp4->bg_inode_bitmap_csum_hi =
+		ext2fs_swab16(gdp4->bg_inode_bitmap_csum_hi);
+}
+
+void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
+{
+	ext2fs_swap_group_desc2(0, gdp);
+}
+
+
+void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header,
+				 struct ext2_ext_attr_header *from_header)
+{
+	int n;
+
+	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);
+	to_header->h_hash     = ext2fs_swab32(from_header->h_hash);
+	for (n = 0; n < 4; n++)
+		to_header->h_reserved[n] =
+			ext2fs_swab32(from_header->h_reserved[n]);
+}
+
+void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry,
+				struct ext2_ext_attr_entry *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);
+	to_entry->e_hash	= ext2fs_swab32(from_entry->e_hash);
+}
+
+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;
+
+	if (to_header != from_header)
+		memcpy(to_header, from_header, bufsize);
+
+	if (has_header) {
+		ext2fs_swap_ext_attr_header(to_header, from_header);
+
+		from_entry = (struct ext2_ext_attr_entry *)(from_header+1);
+		to_entry   = (struct ext2_ext_attr_entry *)(to_header+1);
+	} else {
+		from_entry = (struct ext2_ext_attr_entry *)from_header;
+		to_entry   = (struct ext2_ext_attr_entry *)to_header;
+	}
+
+	while ((char *)from_entry < from_end && *(__u32 *)from_entry) {
+		ext2fs_swap_ext_attr_entry(to_entry, from_entry);
+		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, has_data_blocks, extra_isize, attr_magic;
+	int has_extents = 0;
+	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_file_acl = ext2fs_swab32(f->i_file_acl);
+	if (hostorder)
+		has_data_blocks = ext2fs_inode_data_blocks(fs,
+					   (struct ext2_inode *) f);
+	t->i_blocks = ext2fs_swab32(f->i_blocks);
+	if (!hostorder)
+		has_data_blocks = ext2fs_inode_data_blocks(fs,
+					   (struct ext2_inode *) t);
+	if (hostorder && (f->i_flags & EXT4_EXTENTS_FL))
+		has_extents = 1;
+	t->i_flags = ext2fs_swab32(f->i_flags);
+	if (!hostorder && (t->i_flags & EXT4_EXTENTS_FL))
+		has_extents = 1;
+	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
+	/* extent data are swapped on access, not here */
+	if (!has_extents && (!islnk || has_data_blocks)) {
+		for (i = 0; i < EXT2_N_BLOCKS; i++)
+			t->i_block[i] = ext2fs_swab32(f->i_block[i]);
+	} else if (t != f) {
+		for (i = 0; i < EXT2_N_BLOCKS; i++)
+			t->i_block[i] = f->i_block[i];
+	}
+	t->i_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_version =
+			ext2fs_swab32(f->osd1.linux1.l_i_version);
+		t->osd2.linux2.l_i_blocks_hi =
+			ext2fs_swab16(f->osd2.linux2.l_i_blocks_hi);
+		t->osd2.linux2.l_i_file_acl_high =
+			ext2fs_swab16(f->osd2.linux2.l_i_file_acl_high);
+		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_checksum_lo =
+			ext2fs_swab16(f->osd2.linux2.l_i_checksum_lo);
+		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;
+	default:
+		break;
+	}
+
+	if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
+		return; /* no i_extra_isize field */
+
+	if (hostorder)
+		extra_isize = f->i_extra_isize;
+	t->i_extra_isize = ext2fs_swab16(f->i_extra_isize);
+	if (!hostorder)
+		extra_isize = t->i_extra_isize;
+	if (extra_isize > EXT2_INODE_SIZE(fs->super) -
+				sizeof(struct ext2_inode)) {
+		/* this is error case: i_extra_size is too large */
+		return;
+	}
+
+	if (extra_isize >= 4)
+		t->i_checksum_hi = ext2fs_swab16(f->i_checksum_hi);
+	if (extra_isize >= 8)
+		t->i_ctime_extra = ext2fs_swab32(f->i_ctime_extra);
+	if (extra_isize >= 12)
+		t->i_mtime_extra = ext2fs_swab32(f->i_mtime_extra);
+	if (extra_isize >= 16)
+		t->i_atime_extra = ext2fs_swab32(f->i_atime_extra);
+	if (extra_isize >= 20)
+		t->i_crtime = ext2fs_swab32(f->i_crtime);
+	if (extra_isize >= 24)
+		t->i_crtime_extra = ext2fs_swab32(f->i_crtime_extra);
+	if (extra_isize >= 28)
+		t->i_version_hi = ext2fs_swab32(f->i_version_hi);
+
+	i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32);
+	if (bufsize < (int) i)
+		return; /* no space for EA magic */
+
+	eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) +
+					extra_isize);
+
+	attr_magic = *eaf;
+	if (!hostorder)
+		attr_magic = ext2fs_swab32(attr_magic);
+
+	if (attr_magic != EXT2_EXT_ATTR_MAGIC)
+		return; /* it seems no magic here */
+
+	eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) +
+					extra_isize);
+	*eat = ext2fs_swab32(*eaf);
+
+	/* convert EA(s) */
+	ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
+			     bufsize - sizeof(struct ext2_inode) -
+			     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));
+}
+
+void ext2fs_swap_mmp(struct mmp_struct *mmp)
+{
+	mmp->mmp_magic = ext2fs_swab32(mmp->mmp_magic);
+	mmp->mmp_seq = ext2fs_swab32(mmp->mmp_seq);
+	mmp->mmp_time = ext2fs_swab64(mmp->mmp_time);
+	mmp->mmp_check_interval = ext2fs_swab16(mmp->mmp_check_interval);
+}
+
+#endif
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/symlink.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/symlink.c
new file mode 100644
index 0000000..ad80444
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/symlink.c
@@ -0,0 +1,151 @@
+/*
+ * symlink.c --- make a symlink in the filesystem, based on mkdir.c
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino,
+			 const char *name, char *target)
+{
+	ext2_extent_handle_t	handle;
+	errcode_t		retval;
+	struct ext2_inode	inode;
+	ext2_ino_t		scratch_ino;
+	blk64_t			blk;
+	int			fastlink;
+	unsigned int		target_len;
+	char			*block_buf = 0;
+
+	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+	/* The Linux kernel doesn't allow for links longer than a block */
+	target_len = strlen(target);
+	if (target_len > fs->blocksize) {
+		retval = EXT2_ET_INVALID_ARGUMENT;
+		goto cleanup;
+	}
+
+	/*
+	 * Allocate a data block for slow links
+	 */
+	fastlink = (target_len < sizeof(inode.i_block));
+	if (!fastlink) {
+		retval = ext2fs_new_block2(fs, 0, 0, &blk);
+		if (retval)
+			goto cleanup;
+		retval = ext2fs_get_mem(fs->blocksize, &block_buf);
+		if (retval)
+			goto cleanup;
+	}
+
+	/*
+	 * Allocate an inode, if necessary
+	 */
+	if (!ino) {
+		retval = ext2fs_new_inode(fs, parent, LINUX_S_IFLNK | 0755,
+					  0, &ino);
+		if (retval)
+			goto cleanup;
+	}
+
+	/*
+	 * Create the inode structure....
+	 */
+	memset(&inode, 0, sizeof(struct ext2_inode));
+	inode.i_mode = LINUX_S_IFLNK | 0777;
+	inode.i_uid = inode.i_gid = 0;
+	ext2fs_iblk_set(fs, &inode, fastlink ? 0 : 1);
+	inode.i_links_count = 1;
+	inode.i_size = target_len;
+	/* The time fields are set by ext2fs_write_new_inode() */
+
+	if (fastlink) {
+		/* Fast symlinks, target stored in inode */
+		strcpy((char *)&inode.i_block, target);
+	} else {
+		/* Slow symlinks, target stored in the first block */
+		memset(block_buf, 0, fs->blocksize);
+		strcpy(block_buf, target);
+		if (fs->super->s_feature_incompat &
+		    EXT3_FEATURE_INCOMPAT_EXTENTS) {
+			/*
+			 * The extent bmap is setup after the inode and block
+			 * have been written out below.
+			 */
+			inode.i_flags |= EXT4_EXTENTS_FL;
+		}
+	}
+
+	/*
+	 * Write out the inode and inode data block.  The inode generation
+	 * number is assigned by write_new_inode, which means that the
+	 * operations using ino must come after it.
+	 */
+	retval = ext2fs_write_new_inode(fs, ino, &inode);
+	if (retval)
+		goto cleanup;
+
+	if (!fastlink) {
+		retval = ext2fs_bmap2(fs, ino, &inode, NULL, BMAP_SET, 0, NULL,
+				      &blk);
+		if (retval)
+			goto cleanup;
+
+		retval = io_channel_write_blk64(fs->io, blk, 1, block_buf);
+		if (retval)
+			goto cleanup;
+	}
+
+	/*
+	 * Link the symlink into the filesystem hierarchy
+	 */
+	if (name) {
+		retval = ext2fs_lookup(fs, parent, name, strlen(name), 0,
+				       &scratch_ino);
+		if (!retval) {
+			retval = EXT2_ET_FILE_EXISTS;
+			goto cleanup;
+		}
+		if (retval != EXT2_ET_FILE_NOT_FOUND)
+			goto cleanup;
+		retval = ext2fs_link(fs, parent, name, ino, EXT2_FT_SYMLINK);
+		if (retval)
+			goto cleanup;
+	}
+
+	/*
+	 * Update accounting....
+	 */
+	if (!fastlink)
+		ext2fs_block_alloc_stats2(fs, blk, +1);
+	ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
+
+cleanup:
+	if (block_buf)
+		ext2fs_free_mem(&block_buf);
+	return retval;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdb.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdb.c
new file mode 100644
index 0000000..61e30ed
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdb.c
@@ -0,0 +1,4140 @@
+/*
+URL: svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/tdb/common
+Rev: 23590
+Last Changed Date: 2007-06-22 13:36:10 -0400 (Fri, 22 Jun 2007)
+*/
+ /*
+   trivial database library - standalone version
+
+   Copyright (C) Andrew Tridgell              1999-2005
+   Copyright (C) Jeremy Allison               2000-2006
+   Copyright (C) Paul `Rusty' Russell         2000
+
+     ** NOTE! The following LGPL license applies to the tdb
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifdef CONFIG_STAND_ALONE
+#define HAVE_MMAP
+#define HAVE_STRDUP
+#define HAVE_SYS_MMAN_H
+#define HAVE_UTIME_H
+#define HAVE_UTIME
+#endif
+#define _XOPEN_SOURCE 600
+
+#include "config.h"
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <errno.h>
+#include <string.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <fcntl.h>
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#ifndef HAVE_STRDUP
+#define strdup rep_strdup
+static char *rep_strdup(const char *s)
+{
+	char *ret;
+	int length;
+	if (!s)
+		return NULL;
+
+	if (!length)
+		length = strlen(s);
+
+	ret = malloc(length + 1);
+	if (ret) {
+		strncpy(ret, s, length);
+		ret[length] = '\0';
+	}
+	return ret;
+}
+#endif
+
+#ifndef PRINTF_ATTRIBUTE
+#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 )
+/** Use gcc attribute to check printf fns.  a1 is the 1-based index of
+ * the parameter containing the format, and a2 the index of the first
+ * argument. Note that some gcc 2.x versions don't handle this
+ * properly **/
+#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
+#else
+#define PRINTF_ATTRIBUTE(a1, a2)
+#endif
+#endif
+
+typedef int bool;
+
+#include "tdb.h"
+
+static TDB_DATA tdb_null;
+
+#ifndef u32
+#define u32 unsigned
+#endif
+
+typedef u32 tdb_len_t;
+typedef u32 tdb_off_t;
+
+#ifndef offsetof
+#define offsetof(t,f) ((unsigned int)&((t *)0)->f)
+#endif
+
+#define TDB_MAGIC_FOOD "TDB file\n"
+#define TDB_VERSION (0x26011967 + 6)
+#define TDB_MAGIC (0x26011999U)
+#define TDB_FREE_MAGIC (~TDB_MAGIC)
+#define TDB_DEAD_MAGIC (0xFEE1DEAD)
+#define TDB_RECOVERY_MAGIC (0xf53bc0e7U)
+#define TDB_ALIGNMENT 4
+#define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGNMENT)
+#define DEFAULT_HASH_SIZE 131
+#define FREELIST_TOP (sizeof(struct tdb_header))
+#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1))
+#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24))
+#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC)
+#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r))
+#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t))
+#define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t))
+#define TDB_DATA_START(hash_size) TDB_HASH_TOP(hash_size-1)
+#define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start)
+#define TDB_SEQNUM_OFS    offsetof(struct tdb_header, sequence_number)
+#define TDB_PAD_BYTE 0x42
+#define TDB_PAD_U32  0x42424242
+
+/* NB assumes there is a local variable called "tdb" that is the
+ * current context, also takes doubly-parenthesized print-style
+ * argument. */
+#define TDB_LOG(x) tdb->log.log_fn x
+
+/* lock offsets */
+#define GLOBAL_LOCK      0
+#define ACTIVE_LOCK      4
+#define TRANSACTION_LOCK 8
+
+/* free memory if the pointer is valid and zero the pointer */
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
+#endif
+
+#define BUCKET(hash) ((hash) % tdb->header.hash_size)
+
+#define DOCONV() (tdb->flags & TDB_CONVERT)
+#define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x)
+
+
+/* the body of the database is made of one list_struct for the free space
+   plus a separate data list for each hash value */
+struct list_struct {
+	tdb_off_t next; /* offset of the next record in the list */
+	tdb_len_t rec_len; /* total byte length of record */
+	tdb_len_t key_len; /* byte length of key */
+	tdb_len_t data_len; /* byte length of data */
+	u32 full_hash; /* the full 32 bit hash of the key */
+	u32 magic;   /* try to catch errors */
+	/* the following union is implied:
+		union {
+			char record[rec_len];
+			struct {
+				char key[key_len];
+				char data[data_len];
+			}
+			u32 totalsize; (tailer)
+		}
+	*/
+};
+
+
+/* this is stored at the front of every database */
+struct tdb_header {
+	char magic_food[32]; /* for /etc/magic */
+	u32 version; /* version of the code */
+	u32 hash_size; /* number of hash entries */
+	tdb_off_t rwlocks; /* obsolete - kept to detect old formats */
+	tdb_off_t recovery_start; /* offset of transaction recovery region */
+	tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */
+	tdb_off_t reserved[29];
+};
+
+struct tdb_lock_type {
+	int list;
+	u32 count;
+	u32 ltype;
+};
+
+struct tdb_traverse_lock {
+	struct tdb_traverse_lock *next;
+	u32 off;
+	u32 hash;
+	int lock_rw;
+};
+
+
+struct tdb_methods {
+	int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int );
+	int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t);
+	void (*next_hash_chain)(struct tdb_context *, u32 *);
+	int (*tdb_oob)(struct tdb_context *, tdb_off_t , int );
+	int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t );
+	int (*tdb_brlock)(struct tdb_context *, tdb_off_t , int, int, int, size_t);
+};
+
+struct tdb_context {
+	char *name; /* the name of the database */
+	void *map_ptr; /* where it is currently mapped */
+	int fd; /* open file descriptor for the database */
+	tdb_len_t map_size; /* how much space has been mapped */
+	int read_only; /* opened read-only */
+	int traverse_read; /* read-only traversal */
+	struct tdb_lock_type global_lock;
+	int num_lockrecs;
+	struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */
+	enum TDB_ERROR ecode; /* error code for last tdb error */
+	struct tdb_header header; /* a cached copy of the header */
+	u32 flags; /* the flags passed to tdb_open */
+	struct tdb_traverse_lock travlocks; /* current traversal locks */
+	struct tdb_context *next; /* all tdbs to avoid multiple opens */
+	dev_t device;	/* uniquely identifies this tdb */
+	ino_t inode;	/* uniquely identifies this tdb */
+	struct tdb_logging_context log;
+	unsigned int (*hash_fn)(TDB_DATA *key);
+	int open_flags; /* flags used in the open - needed by reopen */
+	unsigned int num_locks; /* number of chain locks held */
+	const struct tdb_methods *methods;
+	struct tdb_transaction *transaction;
+	int page_size;
+	int max_dead_records;
+	bool have_transaction_lock;
+};
+
+
+/*
+  internal prototypes
+*/
+static int tdb_munmap(struct tdb_context *tdb);
+static void tdb_mmap(struct tdb_context *tdb);
+static int tdb_lock(struct tdb_context *tdb, int list, int ltype);
+static int tdb_unlock(struct tdb_context *tdb, int list, int ltype);
+static int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len);
+static int tdb_transaction_lock(struct tdb_context *tdb, int ltype);
+static int tdb_transaction_unlock(struct tdb_context *tdb);
+static int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len);
+static int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off);
+static int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off);
+static int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
+static int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
+static void *tdb_convert(void *buf, u32 size);
+static int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec);
+static tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_struct *rec);
+static int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
+static int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d);
+static int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off);
+static int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off);
+static int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec);
+static int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec);
+static int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec);
+static unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len);
+static int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key,
+		   tdb_off_t offset, tdb_len_t len,
+		   int (*parser)(TDB_DATA key, TDB_DATA data,
+				 void *private_data),
+		   void *private_data);
+static tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, u32 hash, int locktype,
+			   struct list_struct *rec);
+static void tdb_io_init(struct tdb_context *tdb);
+static int tdb_expand(struct tdb_context *tdb, tdb_off_t size);
+static int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off,
+		      struct list_struct *rec);
+
+
+/* file: error.c */
+
+enum TDB_ERROR tdb_error(struct tdb_context *tdb)
+{
+	return tdb->ecode;
+}
+
+static struct tdb_errname {
+	enum TDB_ERROR ecode; const char *estring;
+} emap[] = { {TDB_SUCCESS, "Success"},
+	     {TDB_ERR_CORRUPT, "Corrupt database"},
+	     {TDB_ERR_IO, "IO Error"},
+	     {TDB_ERR_LOCK, "Locking error"},
+	     {TDB_ERR_OOM, "Out of memory"},
+	     {TDB_ERR_EXISTS, "Record exists"},
+	     {TDB_ERR_NOLOCK, "Lock exists on other keys"},
+	     {TDB_ERR_EINVAL, "Invalid parameter"},
+	     {TDB_ERR_NOEXIST, "Record does not exist"},
+	     {TDB_ERR_RDONLY, "write not permitted"} };
+
+/* Error string for the last tdb error */
+const char *tdb_errorstr(struct tdb_context *tdb)
+{
+	u32 i;
+	for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++)
+		if (tdb->ecode == emap[i].ecode)
+			return emap[i].estring;
+	return "Invalid error code";
+}
+
+/* file: lock.c */
+
+#define TDB_MARK_LOCK 0x80000000
+
+/* a byte range locking function - return 0 on success
+   this functions locks/unlocks 1 byte at the specified offset.
+
+   On error, errno is also set so that errors are passed back properly
+   through tdb_open().
+
+   note that a len of zero means lock to end of file
+*/
+int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset,
+	       int rw_type, int lck_type, int probe, size_t len)
+{
+	struct flock fl;
+	int ret;
+
+	if (tdb->flags & TDB_NOLOCK) {
+		return 0;
+	}
+
+	if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) {
+		tdb->ecode = TDB_ERR_RDONLY;
+		return -1;
+	}
+
+	fl.l_type = rw_type;
+	fl.l_whence = SEEK_SET;
+	fl.l_start = offset;
+	fl.l_len = len;
+	fl.l_pid = 0;
+
+	do {
+		ret = fcntl(tdb->fd,lck_type,&fl);
+	} while (ret == -1 && errno == EINTR);
+
+	if (ret == -1) {
+		/* Generic lock error. errno set by fcntl.
+		 * EAGAIN is an expected return from non-blocking
+		 * locks. */
+		if (!probe && lck_type != F_SETLK) {
+			/* Ensure error code is set for log fun to examine. */
+			tdb->ecode = TDB_ERR_LOCK;
+			TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n",
+				 tdb->fd, offset, rw_type, lck_type, (int)len));
+		}
+		return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+	}
+	return 0;
+}
+
+
+/*
+  upgrade a read lock to a write lock. This needs to be handled in a
+  special way as some OSes (such as solaris) have too conservative
+  deadlock detection and claim a deadlock when progress can be
+  made. For those OSes we may loop for a while.
+*/
+int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len)
+{
+	int count = 1000;
+	while (count--) {
+		struct timeval tv;
+		if (tdb_brlock(tdb, offset, F_WRLCK, F_SETLKW, 1, len) == 0) {
+			return 0;
+		}
+		if (errno != EDEADLK) {
+			break;
+		}
+		/* sleep for as short a time as we can - more portable than usleep() */
+		tv.tv_sec = 0;
+		tv.tv_usec = 1;
+		select(0, NULL, NULL, NULL, &tv);
+	}
+	TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock_upgrade failed at offset %d\n", offset));
+	return -1;
+}
+
+
+/* lock a list in the database. list -1 is the alloc list */
+static int _tdb_lock(struct tdb_context *tdb, int list, int ltype, int op)
+{
+	struct tdb_lock_type *new_lck;
+	int i;
+	bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK);
+
+	ltype &= ~TDB_MARK_LOCK;
+
+	/* a global lock allows us to avoid per chain locks */
+	if (tdb->global_lock.count &&
+	    (ltype == tdb->global_lock.ltype || ltype == F_RDLCK)) {
+		return 0;
+	}
+
+	if (tdb->global_lock.count) {
+		return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+	}
+
+	if (list < -1 || list >= (int)tdb->header.hash_size) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid list %d for ltype=%d\n",
+			   list, ltype));
+		return -1;
+	}
+	if (tdb->flags & TDB_NOLOCK)
+		return 0;
+
+	for (i=0; i<tdb->num_lockrecs; i++) {
+		if (tdb->lockrecs[i].list == list) {
+			if (tdb->lockrecs[i].count == 0) {
+				/*
+				 * Can't happen, see tdb_unlock(). It should
+				 * be an assert.
+				 */
+				TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock: "
+					 "lck->count == 0 for list %d", list));
+			}
+			/*
+			 * Just increment the in-memory struct, posix locks
+			 * don't stack.
+			 */
+			tdb->lockrecs[i].count++;
+			return 0;
+		}
+	}
+
+	new_lck = (struct tdb_lock_type *)realloc(
+		tdb->lockrecs,
+		sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1));
+	if (new_lck == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	tdb->lockrecs = new_lck;
+
+	/* Since fcntl locks don't nest, we do a lock for the first one,
+	   and simply bump the count for future ones */
+	if (!mark_lock &&
+	    tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list, ltype, op,
+				     0, 1)) {
+		return -1;
+	}
+
+	tdb->num_locks++;
+
+	tdb->lockrecs[tdb->num_lockrecs].list = list;
+	tdb->lockrecs[tdb->num_lockrecs].count = 1;
+	tdb->lockrecs[tdb->num_lockrecs].ltype = ltype;
+	tdb->num_lockrecs += 1;
+
+	return 0;
+}
+
+/* lock a list in the database. list -1 is the alloc list */
+int tdb_lock(struct tdb_context *tdb, int list, int ltype)
+{
+	int ret;
+	ret = _tdb_lock(tdb, list, ltype, F_SETLKW);
+	if (ret) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d "
+			 "ltype=%d (%s)\n",  list, ltype, strerror(errno)));
+	}
+	return ret;
+}
+
+/* lock a list in the database. list -1 is the alloc list. non-blocking lock */
+int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype)
+{
+	return _tdb_lock(tdb, list, ltype, F_SETLK);
+}
+
+
+/* unlock the database: returns void because it's too late for errors. */
+	/* changed to return int it may be interesting to know there
+	   has been an error  --simo */
+int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
+{
+	int ret = -1;
+	int i;
+	struct tdb_lock_type *lck = NULL;
+	bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK);
+
+	ltype &= ~TDB_MARK_LOCK;
+
+	/* a global lock allows us to avoid per chain locks */
+	if (tdb->global_lock.count &&
+	    (ltype == tdb->global_lock.ltype || ltype == F_RDLCK)) {
+		return 0;
+	}
+
+	if (tdb->global_lock.count) {
+		return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+	}
+
+	if (tdb->flags & TDB_NOLOCK)
+		return 0;
+
+	/* Sanity checks */
+	if (list < -1 || list >= (int)tdb->header.hash_size) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size));
+		return ret;
+	}
+
+	for (i=0; i<tdb->num_lockrecs; i++) {
+		if (tdb->lockrecs[i].list == list) {
+			lck = &tdb->lockrecs[i];
+			break;
+		}
+	}
+
+	if ((lck == NULL) || (lck->count == 0)) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: count is 0\n"));
+		return -1;
+	}
+
+	if (lck->count > 1) {
+		lck->count--;
+		return 0;
+	}
+
+	/*
+	 * This lock has count==1 left, so we need to unlock it in the
+	 * kernel. We don't bother with decrementing the in-memory array
+	 * element, we're about to overwrite it with the last array element
+	 * anyway.
+	 */
+
+	if (mark_lock) {
+		ret = 0;
+	} else {
+		ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK,
+					       F_SETLKW, 0, 1);
+	}
+	tdb->num_locks--;
+
+	/*
+	 * Shrink the array by overwriting the element just unlocked with the
+	 * last array element.
+	 */
+
+	if (tdb->num_lockrecs > 1) {
+		*lck = tdb->lockrecs[tdb->num_lockrecs-1];
+	}
+	tdb->num_lockrecs -= 1;
+
+	/*
+	 * We don't bother with realloc when the array shrinks, but if we have
+	 * a completely idle tdb we should get rid of the locked array.
+	 */
+
+	if (tdb->num_lockrecs == 0) {
+		SAFE_FREE(tdb->lockrecs);
+	}
+
+	if (ret)
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n"));
+	return ret;
+}
+
+/*
+  get the transaction lock
+ */
+int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
+{
+	if (tdb->have_transaction_lock || tdb->global_lock.count) {
+		return 0;
+	}
+	if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype,
+				     F_SETLKW, 0, 1) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n"));
+		tdb->ecode = TDB_ERR_LOCK;
+		return -1;
+	}
+	tdb->have_transaction_lock = 1;
+	return 0;
+}
+
+/*
+  release the transaction lock
+ */
+int tdb_transaction_unlock(struct tdb_context *tdb)
+{
+	int ret;
+	if (!tdb->have_transaction_lock) {
+		return 0;
+	}
+	ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+	if (ret == 0) {
+		tdb->have_transaction_lock = 0;
+	}
+	return ret;
+}
+
+
+
+
+/* lock/unlock entire database */
+static int _tdb_lockall(struct tdb_context *tdb, int ltype, int op)
+{
+	bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK);
+
+	ltype &= ~TDB_MARK_LOCK;
+
+	/* There are no locks on read-only dbs */
+	if (tdb->read_only || tdb->traverse_read)
+		return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+
+	if (tdb->global_lock.count && tdb->global_lock.ltype == ltype) {
+		tdb->global_lock.count++;
+		return 0;
+	}
+
+	if (tdb->global_lock.count) {
+		/* a global lock of a different type exists */
+		return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+	}
+
+	if (tdb->num_locks != 0) {
+		/* can't combine global and chain locks */
+		return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+	}
+
+	if (!mark_lock &&
+	    tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, op,
+				     0, 4*tdb->header.hash_size)) {
+		if (op == F_SETLKW) {
+			TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno)));
+		}
+		return -1;
+	}
+
+	tdb->global_lock.count = 1;
+	tdb->global_lock.ltype = ltype;
+
+	return 0;
+}
+
+
+
+/* unlock entire db */
+static int _tdb_unlockall(struct tdb_context *tdb, int ltype)
+{
+	bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK);
+
+	ltype &= ~TDB_MARK_LOCK;
+
+	/* There are no locks on read-only dbs */
+	if (tdb->read_only || tdb->traverse_read) {
+		return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+	}
+
+	if (tdb->global_lock.ltype != ltype || tdb->global_lock.count == 0) {
+		return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+	}
+
+	if (tdb->global_lock.count > 1) {
+		tdb->global_lock.count--;
+		return 0;
+	}
+
+	if (!mark_lock &&
+	    tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW,
+				     0, 4*tdb->header.hash_size)) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed (%s)\n", strerror(errno)));
+		return -1;
+	}
+
+	tdb->global_lock.count = 0;
+	tdb->global_lock.ltype = 0;
+
+	return 0;
+}
+
+/* lock entire database with write lock */
+int tdb_lockall(struct tdb_context *tdb)
+{
+	return _tdb_lockall(tdb, F_WRLCK, F_SETLKW);
+}
+
+/* lock entire database with write lock - mark only */
+int tdb_lockall_mark(struct tdb_context *tdb)
+{
+	return _tdb_lockall(tdb, F_WRLCK | TDB_MARK_LOCK, F_SETLKW);
+}
+
+/* unlock entire database with write lock - unmark only */
+int tdb_lockall_unmark(struct tdb_context *tdb)
+{
+	return _tdb_unlockall(tdb, F_WRLCK | TDB_MARK_LOCK);
+}
+
+/* lock entire database with write lock - nonblocking varient */
+int tdb_lockall_nonblock(struct tdb_context *tdb)
+{
+	return _tdb_lockall(tdb, F_WRLCK, F_SETLK);
+}
+
+/* unlock entire database with write lock */
+int tdb_unlockall(struct tdb_context *tdb)
+{
+	return _tdb_unlockall(tdb, F_WRLCK);
+}
+
+/* lock entire database with read lock */
+int tdb_lockall_read(struct tdb_context *tdb)
+{
+	return _tdb_lockall(tdb, F_RDLCK, F_SETLKW);
+}
+
+/* lock entire database with read lock - nonblock varient */
+int tdb_lockall_read_nonblock(struct tdb_context *tdb)
+{
+	return _tdb_lockall(tdb, F_RDLCK, F_SETLK);
+}
+
+/* unlock entire database with read lock */
+int tdb_unlockall_read(struct tdb_context *tdb)
+{
+	return _tdb_unlockall(tdb, F_RDLCK);
+}
+
+/* lock/unlock one hash chain. This is meant to be used to reduce
+   contention - it cannot guarantee how many records will be locked */
+int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key)
+{
+	return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
+}
+
+/* lock/unlock one hash chain, non-blocking. This is meant to be used
+   to reduce contention - it cannot guarantee how many records will be
+   locked */
+int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key)
+{
+	return tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
+}
+
+/* mark a chain as locked without actually locking it. Warning! use with great caution! */
+int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key)
+{
+	return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK);
+}
+
+/* unmark a chain as locked without actually locking it. Warning! use with great caution! */
+int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key)
+{
+	return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK);
+}
+
+int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key)
+{
+	return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
+}
+
+int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key)
+{
+	return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
+}
+
+int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key)
+{
+	return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK);
+}
+
+
+
+/* record lock stops delete underneath */
+int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off)
+{
+	return off ? tdb->methods->tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0, 1) : 0;
+}
+
+/*
+  Write locks override our own fcntl readlocks, so check it here.
+  Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not
+  an error to fail to get the lock here.
+*/
+int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off)
+{
+	struct tdb_traverse_lock *i;
+	for (i = &tdb->travlocks; i; i = i->next)
+		if (i->off == off)
+			return -1;
+	return tdb->methods->tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1, 1);
+}
+
+/*
+  Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not
+  an error to fail to get the lock here.
+*/
+int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off)
+{
+	return tdb->methods->tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0, 1);
+}
+
+/* fcntl locks don't stack: avoid unlocking someone else's */
+int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off)
+{
+	struct tdb_traverse_lock *i;
+	u32 count = 0;
+
+	if (off == 0)
+		return 0;
+	for (i = &tdb->travlocks; i; i = i->next)
+		if (i->off == off)
+			count++;
+	return (count == 1 ? tdb->methods->tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0, 1) : 0);
+}
+
+/* file: io.c */
+
+/* check for an out of bounds access - if it is out of bounds then
+   see if the database has been expanded by someone else and expand
+   if necessary
+   note that "len" is the minimum length needed for the db
+*/
+static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, int probe)
+{
+	struct stat st;
+	if (len <= tdb->map_size)
+		return 0;
+	if (tdb->flags & TDB_INTERNAL) {
+		if (!probe) {
+			/* Ensure ecode is set for log fn. */
+			tdb->ecode = TDB_ERR_IO;
+			TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond internal malloc size %d\n",
+				 (int)len, (int)tdb->map_size));
+		}
+		return TDB_ERRCODE(TDB_ERR_IO, -1);
+	}
+
+	if (fstat(tdb->fd, &st) == -1) {
+		return TDB_ERRCODE(TDB_ERR_IO, -1);
+	}
+
+	if (st.st_size < (size_t)len) {
+		if (!probe) {
+			/* Ensure ecode is set for log fn. */
+			tdb->ecode = TDB_ERR_IO;
+			TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond eof at %d\n",
+				 (int)len, (int)st.st_size));
+		}
+		return TDB_ERRCODE(TDB_ERR_IO, -1);
+	}
+
+	/* Unmap, update size, remap */
+	if (tdb_munmap(tdb) == -1)
+		return TDB_ERRCODE(TDB_ERR_IO, -1);
+	tdb->map_size = st.st_size;
+	tdb_mmap(tdb);
+	return 0;
+}
+
+/* write a lump of data at a specified offset */
+static int tdb_write(struct tdb_context *tdb, tdb_off_t off,
+		     const void *buf, tdb_len_t len)
+{
+	if (len == 0) {
+		return 0;
+	}
+
+	if (tdb->read_only || tdb->traverse_read) {
+		tdb->ecode = TDB_ERR_RDONLY;
+		return -1;
+	}
+
+	if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0)
+		return -1;
+
+	if (tdb->map_ptr) {
+		memcpy(off + (char *)tdb->map_ptr, buf, len);
+	} else if (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) {
+		/* Ensure ecode is set for log fn. */
+		tdb->ecode = TDB_ERR_IO;
+		TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d len=%d (%s)\n",
+			   off, len, strerror(errno)));
+		return TDB_ERRCODE(TDB_ERR_IO, -1);
+	}
+	return 0;
+}
+
+/* Endian conversion: we only ever deal with 4 byte quantities */
+void *tdb_convert(void *buf, u32 size)
+{
+	u32 i, *p = (u32 *)buf;
+	for (i = 0; i < size / 4; i++)
+		p[i] = TDB_BYTEREV(p[i]);
+	return buf;
+}
+
+
+/* read a lump of data at a specified offset, maybe convert */
+static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf,
+		    tdb_len_t len, int cv)
+{
+	if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) {
+		return -1;
+	}
+
+	if (tdb->map_ptr) {
+		memcpy(buf, off + (char *)tdb->map_ptr, len);
+	} else {
+		ssize_t ret = pread(tdb->fd, buf, len, off);
+		if (ret != (ssize_t)len) {
+			/* Ensure ecode is set for log fn. */
+			tdb->ecode = TDB_ERR_IO;
+			TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_read failed at %d "
+				 "len=%d ret=%d (%s) map_size=%d\n",
+				 (int)off, (int)len, (int)ret, strerror(errno),
+				 (int)tdb->map_size));
+			return TDB_ERRCODE(TDB_ERR_IO, -1);
+		}
+	}
+	if (cv) {
+		tdb_convert(buf, len);
+	}
+	return 0;
+}
+
+
+
+/*
+  do an unlocked scan of the hash table heads to find the next non-zero head. The value
+  will then be confirmed with the lock held
+*/
+static void tdb_next_hash_chain(struct tdb_context *tdb, u32 *chain)
+{
+	u32 h = *chain;
+	if (tdb->map_ptr) {
+		for (;h < tdb->header.hash_size;h++) {
+			if (0 != *(u32 *)(TDB_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) {
+				break;
+			}
+		}
+	} else {
+		u32 off=0;
+		for (;h < tdb->header.hash_size;h++) {
+			if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &off) != 0 || off != 0) {
+				break;
+			}
+		}
+	}
+	(*chain) = h;
+}
+
+
+int tdb_munmap(struct tdb_context *tdb)
+{
+	if (tdb->flags & TDB_INTERNAL)
+		return 0;
+
+#ifdef HAVE_MMAP
+	if (tdb->map_ptr) {
+		int ret = munmap(tdb->map_ptr, tdb->map_size);
+		if (ret != 0)
+			return ret;
+	}
+#endif
+	tdb->map_ptr = NULL;
+	return 0;
+}
+
+void tdb_mmap(struct tdb_context *tdb)
+{
+	if (tdb->flags & TDB_INTERNAL)
+		return;
+
+#ifdef HAVE_MMAP
+	if (!(tdb->flags & TDB_NOMMAP)) {
+		tdb->map_ptr = mmap(NULL, tdb->map_size,
+				    PROT_READ|(tdb->read_only? 0:PROT_WRITE),
+				    MAP_SHARED|MAP_FILE, tdb->fd, 0);
+
+		/*
+		 * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!!
+		 */
+
+		if (tdb->map_ptr == MAP_FAILED) {
+			tdb->map_ptr = NULL;
+			TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %d (%s)\n",
+				 tdb->map_size, strerror(errno)));
+		}
+	} else {
+		tdb->map_ptr = NULL;
+	}
+#else
+	tdb->map_ptr = NULL;
+#endif
+}
+
+/* expand a file.  we prefer to use ftruncate, as that is what posix
+  says to use for mmap expansion */
+static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition)
+{
+	char buf[1024];
+
+	if (tdb->read_only || tdb->traverse_read) {
+		tdb->ecode = TDB_ERR_RDONLY;
+		return -1;
+	}
+
+	if (ftruncate(tdb->fd, size+addition) == -1) {
+		char b = 0;
+		if (pwrite(tdb->fd,  &b, 1, (size+addition) - 1) != 1) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n",
+				 size+addition, strerror(errno)));
+			return -1;
+		}
+	}
+
+	/* now fill the file with something. This ensures that the
+	   file isn't sparse, which would be very bad if we ran out of
+	   disk. This must be done with write, not via mmap */
+	memset(buf, TDB_PAD_BYTE, sizeof(buf));
+	while (addition) {
+		int n = addition>sizeof(buf)?sizeof(buf):addition;
+		int ret = pwrite(tdb->fd, buf, n, size);
+		if (ret != n) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of %d failed (%s)\n",
+				   n, strerror(errno)));
+			return -1;
+		}
+		addition -= n;
+		size += n;
+	}
+	return 0;
+}
+
+
+/* expand the database at least size bytes by expanding the underlying
+   file and doing the mmap again if necessary */
+int tdb_expand(struct tdb_context *tdb, tdb_off_t size)
+{
+	struct list_struct rec;
+	tdb_off_t offset;
+
+	if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n"));
+		return -1;
+	}
+
+	/* must know about any previous expansions by another process */
+	tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1);
+
+	/* always make room for at least 10 more records, and round
+           the database up to a multiple of the page size */
+	size = TDB_ALIGN(tdb->map_size + size*10, tdb->page_size) - tdb->map_size;
+
+	if (!(tdb->flags & TDB_INTERNAL))
+		tdb_munmap(tdb);
+
+	/*
+	 * We must ensure the file is unmapped before doing this
+	 * to ensure consistency with systems like OpenBSD where
+	 * writes and mmaps are not consistent.
+	 */
+
+	/* expand the file itself */
+	if (!(tdb->flags & TDB_INTERNAL)) {
+		if (tdb->methods->tdb_expand_file(tdb, tdb->map_size, size) != 0)
+			goto fail;
+	}
+
+	tdb->map_size += size;
+
+	if (tdb->flags & TDB_INTERNAL) {
+		char *new_map_ptr = (char *)realloc(tdb->map_ptr,
+						    tdb->map_size);
+		if (!new_map_ptr) {
+			tdb->map_size -= size;
+			goto fail;
+		}
+		tdb->map_ptr = new_map_ptr;
+	} else {
+		/*
+		 * We must ensure the file is remapped before adding the space
+		 * to ensure consistency with systems like OpenBSD where
+		 * writes and mmaps are not consistent.
+		 */
+
+		/* We're ok if the mmap fails as we'll fallback to read/write */
+		tdb_mmap(tdb);
+	}
+
+	/* form a new freelist record */
+	memset(&rec,'\0',sizeof(rec));
+	rec.rec_len = size - sizeof(rec);
+
+	/* link it into the free list */
+	offset = tdb->map_size - size;
+	if (tdb_free(tdb, offset, &rec) == -1)
+		goto fail;
+
+	tdb_unlock(tdb, -1, F_WRLCK);
+	return 0;
+ fail:
+	tdb_unlock(tdb, -1, F_WRLCK);
+	return -1;
+}
+
+/* read/write a tdb_off_t */
+int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d)
+{
+	return tdb->methods->tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV());
+}
+
+int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d)
+{
+	tdb_off_t off = *d;
+	return tdb->methods->tdb_write(tdb, offset, CONVERT(off), sizeof(*d));
+}
+
+
+/* read a lump of data, allocating the space for it */
+unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len)
+{
+	unsigned char *buf;
+
+	/* some systems don't like zero length malloc */
+	if (len == 0) {
+		len = 1;
+	}
+
+	if (!(buf = (unsigned char *)malloc(len))) {
+		/* Ensure ecode is set for log fn. */
+		tdb->ecode = TDB_ERR_OOM;
+		TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_alloc_read malloc failed len=%d (%s)\n",
+			   len, strerror(errno)));
+		return TDB_ERRCODE(TDB_ERR_OOM, buf);
+	}
+	if (tdb->methods->tdb_read(tdb, offset, buf, len, 0) == -1) {
+		SAFE_FREE(buf);
+		return NULL;
+	}
+	return buf;
+}
+
+/* Give a piece of tdb data to a parser */
+
+int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key,
+		   tdb_off_t offset, tdb_len_t len,
+		   int (*parser)(TDB_DATA key, TDB_DATA data,
+				 void *private_data),
+		   void *private_data)
+{
+	TDB_DATA data;
+	int result;
+
+	data.dsize = len;
+
+	if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) {
+		/*
+		 * Optimize by avoiding the malloc/memcpy/free, point the
+		 * parser directly at the mmap area.
+		 */
+		if (tdb->methods->tdb_oob(tdb, offset+len, 0) != 0) {
+			return -1;
+		}
+		data.dptr = offset + (unsigned char *)tdb->map_ptr;
+		return parser(key, data, private_data);
+	}
+
+	if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) {
+		return -1;
+	}
+
+	result = parser(key, data, private_data);
+	free(data.dptr);
+	return result;
+}
+
+/* read/write a record */
+int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec)
+{
+	if (tdb->methods->tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1)
+		return -1;
+	if (TDB_BAD_MAGIC(rec)) {
+		/* Ensure ecode is set for log fn. */
+		tdb->ecode = TDB_ERR_CORRUPT;
+		TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset));
+		return TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
+	}
+	return tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0);
+}
+
+int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec)
+{
+	struct list_struct r = *rec;
+	return tdb->methods->tdb_write(tdb, offset, CONVERT(r), sizeof(r));
+}
+
+static const struct tdb_methods io_methods = {
+	tdb_read,
+	tdb_write,
+	tdb_next_hash_chain,
+	tdb_oob,
+	tdb_expand_file,
+	tdb_brlock
+};
+
+/*
+  initialise the default methods table
+*/
+void tdb_io_init(struct tdb_context *tdb)
+{
+	tdb->methods = &io_methods;
+}
+
+/* file: transaction.c */
+
+/*
+  transaction design:
+
+  - only allow a single transaction at a time per database. This makes
+    using the transaction API simpler, as otherwise the caller would
+    have to cope with temporary failures in transactions that conflict
+    with other current transactions
+
+  - keep the transaction recovery information in the same file as the
+    database, using a special 'transaction recovery' record pointed at
+    by the header. This removes the need for extra journal files as
+    used by some other databases
+
+  - dynamically allocated the transaction recover record, re-using it
+    for subsequent transactions. If a larger record is needed then
+    tdb_free() the old record to place it on the normal tdb freelist
+    before allocating the new record
+
+  - during transactions, keep a linked list of writes all that have
+    been performed by intercepting all tdb_write() calls. The hooked
+    transaction versions of tdb_read() and tdb_write() check this
+    linked list and try to use the elements of the list in preference
+    to the real database.
+
+  - don't allow any locks to be held when a transaction starts,
+    otherwise we can end up with deadlock (plus lack of lock nesting
+    in posix locks would mean the lock is lost)
+
+  - if the caller gains a lock during the transaction but doesn't
+    release it then fail the commit
+
+  - allow for nested calls to tdb_transaction_start(), re-using the
+    existing transaction record. If the inner transaction is cancelled
+    then a subsequent commit will fail
+
+  - keep a mirrored copy of the tdb hash chain heads to allow for the
+    fast hash heads scan on traverse, updating the mirrored copy in
+    the transaction version of tdb_write
+
+  - allow callers to mix transaction and non-transaction use of tdb,
+    although once a transaction is started then an exclusive lock is
+    gained until the transaction is committed or cancelled
+
+  - the commit stategy involves first saving away all modified data
+    into a linearised buffer in the transaction recovery area, then
+    marking the transaction recovery area with a magic value to
+    indicate a valid recovery record. In total 4 fsync/msync calls are
+    needed per commit to prevent race conditions. It might be possible
+    to reduce this to 3 or even 2 with some more work.
+
+  - check for a valid recovery record on open of the tdb, while the
+    global lock is held. Automatically recover from the transaction
+    recovery area if needed, then continue with the open as
+    usual. This allows for smooth crash recovery with no administrator
+    intervention.
+
+  - if TDB_NOSYNC is passed to flags in tdb_open then transactions are
+    still available, but no transaction recovery area is used and no
+    fsync/msync calls are made.
+
+*/
+
+struct tdb_transaction_el {
+	struct tdb_transaction_el *next, *prev;
+	tdb_off_t offset;
+	tdb_len_t length;
+	unsigned char *data;
+};
+
+/*
+  hold the context of any current transaction
+*/
+struct tdb_transaction {
+	/* we keep a mirrored copy of the tdb hash heads here so
+	   tdb_next_hash_chain() can operate efficiently */
+	u32 *hash_heads;
+
+	/* the original io methods - used to do IOs to the real db */
+	const struct tdb_methods *io_methods;
+
+	/* the list of transaction elements. We use a doubly linked
+	   list with a last pointer to allow us to keep the list
+	   ordered, with first element at the front of the list. It
+	   needs to be doubly linked as the read/write traversals need
+	   to be backwards, while the commit needs to be forwards */
+	struct tdb_transaction_el *elements, *elements_last;
+
+	/* non-zero when an internal transaction error has
+	   occurred. All write operations will then fail until the
+	   transaction is ended */
+	int transaction_error;
+
+	/* when inside a transaction we need to keep track of any
+	   nested tdb_transaction_start() calls, as these are allowed,
+	   but don't create a new transaction */
+	int nesting;
+
+	/* old file size before transaction */
+	tdb_len_t old_map_size;
+};
+
+
+/*
+  read while in a transaction. We need to check first if the data is in our list
+  of transaction elements, then if not do a real read
+*/
+static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf,
+			    tdb_len_t len, int cv)
+{
+	struct tdb_transaction_el *el;
+
+	/* we need to walk the list backwards to get the most recent data */
+	for (el=tdb->transaction->elements_last;el;el=el->prev) {
+		tdb_len_t partial;
+
+		if (off+len <= el->offset) {
+			continue;
+		}
+		if (off >= el->offset + el->length) {
+			continue;
+		}
+
+		/* an overlapping read - needs to be split into up to
+		   2 reads and a memcpy */
+		if (off < el->offset) {
+			partial = el->offset - off;
+			if (transaction_read(tdb, off, buf, partial, cv) != 0) {
+				goto fail;
+			}
+			len -= partial;
+			off += partial;
+			buf = (void *)(partial + (char *)buf);
+		}
+		if (off + len <= el->offset + el->length) {
+			partial = len;
+		} else {
+			partial = el->offset + el->length - off;
+		}
+		memcpy(buf, el->data + (off - el->offset), partial);
+		if (cv) {
+			tdb_convert(buf, len);
+		}
+		len -= partial;
+		off += partial;
+		buf = (void *)(partial + (char *)buf);
+
+		if (len != 0 && transaction_read(tdb, off, buf, len, cv) != 0) {
+			goto fail;
+		}
+
+		return 0;
+	}
+
+	/* its not in the transaction elements - do a real read */
+	return tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv);
+
+fail:
+	TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%d len=%d\n", off, len));
+	tdb->ecode = TDB_ERR_IO;
+	tdb->transaction->transaction_error = 1;
+	return -1;
+}
+
+
+/*
+  write while in a transaction
+*/
+static int transaction_write(struct tdb_context *tdb, tdb_off_t off,
+			     const void *buf, tdb_len_t len)
+{
+	struct tdb_transaction_el *el, *best_el=NULL;
+
+	if (len == 0) {
+		return 0;
+	}
+
+	/* if the write is to a hash head, then update the transaction
+	   hash heads */
+	if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP &&
+	    off < FREELIST_TOP+TDB_HASHTABLE_SIZE(tdb)) {
+		u32 chain = (off-FREELIST_TOP) / sizeof(tdb_off_t);
+		memcpy(&tdb->transaction->hash_heads[chain], buf, len);
+	}
+
+	/* first see if we can replace an existing entry */
+	for (el=tdb->transaction->elements_last;el;el=el->prev) {
+		tdb_len_t partial;
+
+		if (best_el == NULL && off == el->offset+el->length) {
+			best_el = el;
+		}
+
+		if (off+len <= el->offset) {
+			continue;
+		}
+		if (off >= el->offset + el->length) {
+			continue;
+		}
+
+		/* an overlapping write - needs to be split into up to
+		   2 writes and a memcpy */
+		if (off < el->offset) {
+			partial = el->offset - off;
+			if (transaction_write(tdb, off, buf, partial) != 0) {
+				goto fail;
+			}
+			len -= partial;
+			off += partial;
+			buf = (const void *)(partial + (const char *)buf);
+		}
+		if (off + len <= el->offset + el->length) {
+			partial = len;
+		} else {
+			partial = el->offset + el->length - off;
+		}
+		memcpy(el->data + (off - el->offset), buf, partial);
+		len -= partial;
+		off += partial;
+		buf = (const void *)(partial + (const char *)buf);
+
+		if (len != 0 && transaction_write(tdb, off, buf, len) != 0) {
+			goto fail;
+		}
+
+		return 0;
+	}
+
+	/* see if we can append the new entry to an existing entry */
+	if (best_el && best_el->offset + best_el->length == off &&
+	    (off+len < tdb->transaction->old_map_size ||
+	     off > tdb->transaction->old_map_size)) {
+		unsigned char *data = best_el->data;
+		el = best_el;
+		el->data = (unsigned char *)realloc(el->data,
+						    el->length + len);
+		if (el->data == NULL) {
+			tdb->ecode = TDB_ERR_OOM;
+			tdb->transaction->transaction_error = 1;
+			el->data = data;
+			return -1;
+		}
+		if (buf) {
+			memcpy(el->data + el->length, buf, len);
+		} else {
+			memset(el->data + el->length, TDB_PAD_BYTE, len);
+		}
+		el->length += len;
+		return 0;
+	}
+
+	/* add a new entry at the end of the list */
+	el = (struct tdb_transaction_el *)malloc(sizeof(*el));
+	if (el == NULL) {
+		tdb->ecode = TDB_ERR_OOM;
+		tdb->transaction->transaction_error = 1;
+		return -1;
+	}
+	el->next = NULL;
+	el->prev = tdb->transaction->elements_last;
+	el->offset = off;
+	el->length = len;
+	el->data = (unsigned char *)malloc(len);
+	if (el->data == NULL) {
+		free(el);
+		tdb->ecode = TDB_ERR_OOM;
+		tdb->transaction->transaction_error = 1;
+		return -1;
+	}
+	if (buf) {
+		memcpy(el->data, buf, len);
+	} else {
+		memset(el->data, TDB_PAD_BYTE, len);
+	}
+	if (el->prev) {
+		el->prev->next = el;
+	} else {
+		tdb->transaction->elements = el;
+	}
+	tdb->transaction->elements_last = el;
+	return 0;
+
+fail:
+	TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", off, len));
+	tdb->ecode = TDB_ERR_IO;
+	tdb->transaction->transaction_error = 1;
+	return -1;
+}
+
+/*
+  accelerated hash chain head search, using the cached hash heads
+*/
+static void transaction_next_hash_chain(struct tdb_context *tdb, u32 *chain)
+{
+	u32 h = *chain;
+	for (;h < tdb->header.hash_size;h++) {
+		/* the +1 takes account of the freelist */
+		if (0 != tdb->transaction->hash_heads[h+1]) {
+			break;
+		}
+	}
+	(*chain) = h;
+}
+
+/*
+  out of bounds check during a transaction
+*/
+static int transaction_oob(struct tdb_context *tdb, tdb_off_t len, int probe)
+{
+	if (len <= tdb->map_size) {
+		return 0;
+	}
+	return TDB_ERRCODE(TDB_ERR_IO, -1);
+}
+
+/*
+  transaction version of tdb_expand().
+*/
+static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size,
+				   tdb_off_t addition)
+{
+	/* add a write to the transaction elements, so subsequent
+	   reads see the zero data */
+	if (transaction_write(tdb, size, NULL, addition) != 0) {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+  brlock during a transaction - ignore them
+*/
+static int transaction_brlock(struct tdb_context *tdb, tdb_off_t offset,
+			      int rw_type, int lck_type, int probe, size_t len)
+{
+	return 0;
+}
+
+static const struct tdb_methods transaction_methods = {
+	transaction_read,
+	transaction_write,
+	transaction_next_hash_chain,
+	transaction_oob,
+	transaction_expand_file,
+	transaction_brlock
+};
+
+
+/*
+  start a tdb transaction. No token is returned, as only a single
+  transaction is allowed to be pending per tdb_context
+*/
+int tdb_transaction_start(struct tdb_context *tdb)
+{
+	/* some sanity checks */
+	if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction on a read-only or internal db\n"));
+		tdb->ecode = TDB_ERR_EINVAL;
+		return -1;
+	}
+
+	/* cope with nested tdb_transaction_start() calls */
+	if (tdb->transaction != NULL) {
+		tdb->transaction->nesting++;
+		TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n",
+			 tdb->transaction->nesting));
+		return 0;
+	}
+
+	if (tdb->num_locks != 0 || tdb->global_lock.count) {
+		/* the caller must not have any locks when starting a
+		   transaction as otherwise we'll be screwed by lack
+		   of nested locks in posix */
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction with locks held\n"));
+		tdb->ecode = TDB_ERR_LOCK;
+		return -1;
+	}
+
+	if (tdb->travlocks.next != NULL) {
+		/* you cannot use transactions inside a traverse (although you can use
+		   traverse inside a transaction) as otherwise you can end up with
+		   deadlock */
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction within a traverse\n"));
+		tdb->ecode = TDB_ERR_LOCK;
+		return -1;
+	}
+
+	tdb->transaction = (struct tdb_transaction *)
+		calloc(sizeof(struct tdb_transaction), 1);
+	if (tdb->transaction == NULL) {
+		tdb->ecode = TDB_ERR_OOM;
+		return -1;
+	}
+
+	/* get the transaction write lock. This is a blocking lock. As
+	   discussed with Volker, there are a number of ways we could
+	   make this async, which we will probably do in the future */
+	if (tdb_transaction_lock(tdb, F_WRLCK) == -1) {
+		SAFE_FREE(tdb->transaction);
+		return -1;
+	}
+
+	/* get a read lock from the freelist to the end of file. This
+	   is upgraded to a write lock during the commit */
+	if (tdb_brlock(tdb, FREELIST_TOP, F_RDLCK, F_SETLKW, 0, 0) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n"));
+		tdb->ecode = TDB_ERR_LOCK;
+		goto fail;
+	}
+
+	/* setup a copy of the hash table heads so the hash scan in
+	   traverse can be fast */
+	tdb->transaction->hash_heads = (u32 *)
+		calloc(tdb->header.hash_size+1, sizeof(u32));
+	if (tdb->transaction->hash_heads == NULL) {
+		tdb->ecode = TDB_ERR_OOM;
+		goto fail;
+	}
+	if (tdb->methods->tdb_read(tdb, FREELIST_TOP, tdb->transaction->hash_heads,
+				   TDB_HASHTABLE_SIZE(tdb), 0) != 0) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to read hash heads\n"));
+		tdb->ecode = TDB_ERR_IO;
+		goto fail;
+	}
+
+	/* make sure we know about any file expansions already done by
+	   anyone else */
+	tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1);
+	tdb->transaction->old_map_size = tdb->map_size;
+
+	/* finally hook the io methods, replacing them with
+	   transaction specific methods */
+	tdb->transaction->io_methods = tdb->methods;
+	tdb->methods = &transaction_methods;
+
+	/* by calling this transaction write here, we ensure that we don't grow the
+	   transaction linked list due to hash table updates */
+	if (transaction_write(tdb, FREELIST_TOP, tdb->transaction->hash_heads,
+			      TDB_HASHTABLE_SIZE(tdb)) != 0) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to prime hash table\n"));
+		tdb->ecode = TDB_ERR_IO;
+		tdb->methods = tdb->transaction->io_methods;
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
+	tdb_transaction_unlock(tdb);
+	SAFE_FREE(tdb->transaction->hash_heads);
+	SAFE_FREE(tdb->transaction);
+	return -1;
+}
+
+
+/*
+  cancel the current transaction
+*/
+int tdb_transaction_cancel(struct tdb_context *tdb)
+{
+	if (tdb->transaction == NULL) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n"));
+		return -1;
+	}
+
+	if (tdb->transaction->nesting != 0) {
+		tdb->transaction->transaction_error = 1;
+		tdb->transaction->nesting--;
+		return 0;
+	}
+
+	tdb->map_size = tdb->transaction->old_map_size;
+
+	/* free all the transaction elements */
+	while (tdb->transaction->elements) {
+		struct tdb_transaction_el *el = tdb->transaction->elements;
+		tdb->transaction->elements = el->next;
+		free(el->data);
+		free(el);
+	}
+
+	/* remove any global lock created during the transaction */
+	if (tdb->global_lock.count != 0) {
+		tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 4*tdb->header.hash_size);
+		tdb->global_lock.count = 0;
+	}
+
+	/* remove any locks created during the transaction */
+	if (tdb->num_locks != 0) {
+		int i;
+		for (i=0;i<tdb->num_lockrecs;i++) {
+			tdb_brlock(tdb,FREELIST_TOP+4*tdb->lockrecs[i].list,
+				   F_UNLCK,F_SETLKW, 0, 1);
+		}
+		tdb->num_locks = 0;
+		tdb->num_lockrecs = 0;
+		SAFE_FREE(tdb->lockrecs);
+	}
+
+	/* restore the normal io methods */
+	tdb->methods = tdb->transaction->io_methods;
+
+	tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
+	tdb_transaction_unlock(tdb);
+	SAFE_FREE(tdb->transaction->hash_heads);
+	SAFE_FREE(tdb->transaction);
+
+	return 0;
+}
+
+/*
+  sync to disk
+*/
+static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t length)
+{
+	if (fsync(tdb->fd) != 0) {
+		tdb->ecode = TDB_ERR_IO;
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n"));
+		return -1;
+	}
+#if defined(HAVE_MSYNC) && defined(MS_SYNC)
+	if (tdb->map_ptr) {
+		tdb_off_t moffset = offset & ~(tdb->page_size-1);
+		if (msync(moffset + (char *)tdb->map_ptr,
+			  length + (offset - moffset), MS_SYNC) != 0) {
+			tdb->ecode = TDB_ERR_IO;
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: msync failed - %s\n",
+				 strerror(errno)));
+			return -1;
+		}
+	}
+#endif
+	return 0;
+}
+
+
+/*
+  work out how much space the linearised recovery data will consume
+*/
+static tdb_len_t tdb_recovery_size(struct tdb_context *tdb)
+{
+	struct tdb_transaction_el *el;
+	tdb_len_t recovery_size = 0;
+
+	recovery_size = sizeof(u32);
+	for (el=tdb->transaction->elements;el;el=el->next) {
+		if (el->offset >= tdb->transaction->old_map_size) {
+			continue;
+		}
+		recovery_size += 2*sizeof(tdb_off_t) + el->length;
+	}
+
+	return recovery_size;
+}
+
+/*
+  allocate the recovery area, or use an existing recovery area if it is
+  large enough
+*/
+static int tdb_recovery_allocate(struct tdb_context *tdb,
+				 tdb_len_t *recovery_size,
+				 tdb_off_t *recovery_offset,
+				 tdb_len_t *recovery_max_size)
+{
+	struct list_struct rec;
+	const struct tdb_methods *methods = tdb->transaction->io_methods;
+	tdb_off_t recovery_head;
+
+	if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery head\n"));
+		return -1;
+	}
+
+	rec.rec_len = 0;
+
+	if (recovery_head != 0 &&
+	    methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery record\n"));
+		return -1;
+	}
+
+	*recovery_size = tdb_recovery_size(tdb);
+
+	if (recovery_head != 0 && *recovery_size <= rec.rec_len) {
+		/* it fits in the existing area */
+		*recovery_max_size = rec.rec_len;
+		*recovery_offset = recovery_head;
+		return 0;
+	}
+
+	/* we need to free up the old recovery area, then allocate a
+	   new one at the end of the file. Note that we cannot use
+	   tdb_allocate() to allocate the new one as that might return
+	   us an area that is being currently used (as of the start of
+	   the transaction) */
+	if (recovery_head != 0) {
+		if (tdb_free(tdb, recovery_head, &rec) == -1) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to free previous recovery area\n"));
+			return -1;
+		}
+	}
+
+	/* the tdb_free() call might have increased the recovery size */
+	*recovery_size = tdb_recovery_size(tdb);
+
+	/* round up to a multiple of page size */
+	*recovery_max_size = TDB_ALIGN(sizeof(rec) + *recovery_size, tdb->page_size) - sizeof(rec);
+	*recovery_offset = tdb->map_size;
+	recovery_head = *recovery_offset;
+
+	if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size,
+				     (tdb->map_size - tdb->transaction->old_map_size) +
+				     sizeof(rec) + *recovery_max_size) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to create recovery area\n"));
+		return -1;
+	}
+
+	/* remap the file (if using mmap) */
+	methods->tdb_oob(tdb, tdb->map_size + 1, 1);
+
+	/* we have to reset the old map size so that we don't try to expand the file
+	   again in the transaction commit, which would destroy the recovery area */
+	tdb->transaction->old_map_size = tdb->map_size;
+
+	/* write the recovery header offset and sync - we can sync without a race here
+	   as the magic ptr in the recovery record has not been set */
+	CONVERT(recovery_head);
+	if (methods->tdb_write(tdb, TDB_RECOVERY_HEAD,
+			       &recovery_head, sizeof(tdb_off_t)) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n"));
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/*
+  setup the recovery data that will be used on a crash during commit
+*/
+static int transaction_setup_recovery(struct tdb_context *tdb,
+				      tdb_off_t *magic_offset)
+{
+	struct tdb_transaction_el *el;
+	tdb_len_t recovery_size;
+	unsigned char *data, *p;
+	const struct tdb_methods *methods = tdb->transaction->io_methods;
+	struct list_struct *rec;
+	tdb_off_t recovery_offset, recovery_max_size;
+	tdb_off_t old_map_size = tdb->transaction->old_map_size;
+	u32 magic, tailer;
+
+	/*
+	  check that the recovery area has enough space
+	*/
+	if (tdb_recovery_allocate(tdb, &recovery_size,
+				  &recovery_offset, &recovery_max_size) == -1) {
+		return -1;
+	}
+
+	data = (unsigned char *)malloc(recovery_size + sizeof(*rec));
+	if (data == NULL) {
+		tdb->ecode = TDB_ERR_OOM;
+		return -1;
+	}
+
+	rec = (struct list_struct *)data;
+	memset(rec, 0, sizeof(*rec));
+
+	rec->magic    = 0;
+	rec->data_len = recovery_size;
+	rec->rec_len  = recovery_max_size;
+	rec->key_len  = old_map_size;
+	CONVERT(rec);
+
+	/* build the recovery data into a single blob to allow us to do a single
+	   large write, which should be more efficient */
+	p = data + sizeof(*rec);
+	for (el=tdb->transaction->elements;el;el=el->next) {
+		if (el->offset >= old_map_size) {
+			continue;
+		}
+		if (el->offset + el->length > tdb->transaction->old_map_size) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n"));
+			free(data);
+			tdb->ecode = TDB_ERR_CORRUPT;
+			return -1;
+		}
+		memcpy(p, &el->offset, 4);
+		memcpy(p+4, &el->length, 4);
+		if (DOCONV()) {
+			tdb_convert(p, 8);
+		}
+		/* the recovery area contains the old data, not the
+		   new data, so we have to call the original tdb_read
+		   method to get it */
+		if (methods->tdb_read(tdb, el->offset, p + 8, el->length, 0) != 0) {
+			free(data);
+			tdb->ecode = TDB_ERR_IO;
+			return -1;
+		}
+		p += 8 + el->length;
+	}
+
+	/* and the tailer */
+	tailer = sizeof(*rec) + recovery_max_size;
+	memcpy(p, &tailer, 4);
+	CONVERT(p);
+
+	/* write the recovery data to the recovery area */
+	if (methods->tdb_write(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery data\n"));
+		free(data);
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
+
+	/* as we don't have ordered writes, we have to sync the recovery
+	   data before we update the magic to indicate that the recovery
+	   data is present */
+	if (transaction_sync(tdb, recovery_offset, sizeof(*rec) + recovery_size) == -1) {
+		free(data);
+		return -1;
+	}
+
+	free(data);
+
+	magic = TDB_RECOVERY_MAGIC;
+	CONVERT(magic);
+
+	*magic_offset = recovery_offset + offsetof(struct list_struct, magic);
+
+	if (methods->tdb_write(tdb, *magic_offset, &magic, sizeof(magic)) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery magic\n"));
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
+
+	/* ensure the recovery magic marker is on disk */
+	if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+  commit the current transaction
+*/
+int tdb_transaction_commit(struct tdb_context *tdb)
+{
+	const struct tdb_methods *methods;
+	tdb_off_t magic_offset = 0;
+	u32 zero = 0;
+
+	if (tdb->transaction == NULL) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n"));
+		return -1;
+	}
+
+	if (tdb->transaction->transaction_error) {
+		tdb->ecode = TDB_ERR_IO;
+		tdb_transaction_cancel(tdb);
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: transaction error pending\n"));
+		return -1;
+	}
+
+	if (tdb->transaction->nesting != 0) {
+		tdb->transaction->nesting--;
+		return 0;
+	}
+
+	/* check for a null transaction */
+	if (tdb->transaction->elements == NULL) {
+		tdb_transaction_cancel(tdb);
+		return 0;
+	}
+
+	methods = tdb->transaction->io_methods;
+
+	/* if there are any locks pending then the caller has not
+	   nested their locks properly, so fail the transaction */
+	if (tdb->num_locks || tdb->global_lock.count) {
+		tdb->ecode = TDB_ERR_LOCK;
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: locks pending on commit\n"));
+		tdb_transaction_cancel(tdb);
+		return -1;
+	}
+
+	/* upgrade the main transaction lock region to a write lock */
+	if (tdb_brlock_upgrade(tdb, FREELIST_TOP, 0) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to upgrade hash locks\n"));
+		tdb->ecode = TDB_ERR_LOCK;
+		tdb_transaction_cancel(tdb);
+		return -1;
+	}
+
+	/* get the global lock - this prevents new users attaching to the database
+	   during the commit */
+	if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: failed to get global lock\n"));
+		tdb->ecode = TDB_ERR_LOCK;
+		tdb_transaction_cancel(tdb);
+		return -1;
+	}
+
+	if (!(tdb->flags & TDB_NOSYNC)) {
+		/* write the recovery data to the end of the file */
+		if (transaction_setup_recovery(tdb, &magic_offset) == -1) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: failed to setup recovery data\n"));
+			tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+			tdb_transaction_cancel(tdb);
+			return -1;
+		}
+	}
+
+	/* expand the file to the new size if needed */
+	if (tdb->map_size != tdb->transaction->old_map_size) {
+		if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size,
+					     tdb->map_size -
+					     tdb->transaction->old_map_size) == -1) {
+			tdb->ecode = TDB_ERR_IO;
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: expansion failed\n"));
+			tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+			tdb_transaction_cancel(tdb);
+			return -1;
+		}
+		tdb->map_size = tdb->transaction->old_map_size;
+		methods->tdb_oob(tdb, tdb->map_size + 1, 1);
+	}
+
+	/* perform all the writes */
+	while (tdb->transaction->elements) {
+		struct tdb_transaction_el *el = tdb->transaction->elements;
+
+		if (methods->tdb_write(tdb, el->offset, el->data, el->length) == -1) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n"));
+
+			/* we've overwritten part of the data and
+			   possibly expanded the file, so we need to
+			   run the crash recovery code */
+			tdb->methods = methods;
+			tdb_transaction_recover(tdb);
+
+			tdb_transaction_cancel(tdb);
+			tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n"));
+			return -1;
+		}
+		tdb->transaction->elements = el->next;
+		free(el->data);
+		free(el);
+	}
+
+	if (!(tdb->flags & TDB_NOSYNC)) {
+		/* ensure the new data is on disk */
+		if (transaction_sync(tdb, 0, tdb->map_size) == -1) {
+			return -1;
+		}
+
+		/* remove the recovery marker */
+		if (methods->tdb_write(tdb, magic_offset, &zero, 4) == -1) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: failed to remove recovery magic\n"));
+			return -1;
+		}
+
+		/* ensure the recovery marker has been removed on disk */
+		if (transaction_sync(tdb, magic_offset, 4) == -1) {
+			return -1;
+		}
+	}
+
+	tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+
+	/*
+	  TODO: maybe write to some dummy hdr field, or write to magic
+	  offset without mmap, before the last sync, instead of the
+	  utime() call
+	*/
+
+	/* on some systems (like Linux 2.6.x) changes via mmap/msync
+	   don't change the mtime of the file, this means the file may
+	   not be backed up (as tdb rounding to block sizes means that
+	   file size changes are quite rare too). The following forces
+	   mtime changes when a transaction completes */
+#ifdef HAVE_UTIME
+	utime(tdb->name, NULL);
+#endif
+
+	/* use a transaction cancel to free memory and remove the
+	   transaction locks */
+	tdb_transaction_cancel(tdb);
+	return 0;
+}
+
+
+/*
+  recover from an aborted transaction. Must be called with exclusive
+  database write access already established (including the global
+  lock to prevent new processes attaching)
+*/
+int tdb_transaction_recover(struct tdb_context *tdb)
+{
+	tdb_off_t recovery_head, recovery_eof;
+	unsigned char *data, *p;
+	u32 zero = 0;
+	struct list_struct rec;
+
+	/* find the recovery area */
+	if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery head\n"));
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
+
+	if (recovery_head == 0) {
+		/* we have never allocated a recovery record */
+		return 0;
+	}
+
+	/* read the recovery record */
+	if (tdb->methods->tdb_read(tdb, recovery_head, &rec,
+				   sizeof(rec), DOCONV()) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n"));
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
+
+	if (rec.magic != TDB_RECOVERY_MAGIC) {
+		/* there is no valid recovery data */
+		return 0;
+	}
+
+	if (tdb->read_only) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: attempt to recover read only database\n"));
+		tdb->ecode = TDB_ERR_CORRUPT;
+		return -1;
+	}
+
+	recovery_eof = rec.key_len;
+
+	data = (unsigned char *)malloc(rec.data_len);
+	if (data == NULL) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n"));
+		tdb->ecode = TDB_ERR_OOM;
+		return -1;
+	}
+
+	/* read the full recovery data */
+	if (tdb->methods->tdb_read(tdb, recovery_head + sizeof(rec), data,
+				   rec.data_len, 0) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n"));
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
+
+	/* recover the file data */
+	p = data;
+	while (p+8 < data + rec.data_len) {
+		u32 ofs, len;
+		if (DOCONV()) {
+			tdb_convert(p, 8);
+		}
+		memcpy(&ofs, p, 4);
+		memcpy(&len, p+4, 4);
+
+		if (tdb->methods->tdb_write(tdb, ofs, p+8, len) == -1) {
+			free(data);
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to recover %d bytes at offset %d\n", len, ofs));
+			tdb->ecode = TDB_ERR_IO;
+			return -1;
+		}
+		p += 8 + len;
+	}
+
+	free(data);
+
+	if (transaction_sync(tdb, 0, tdb->map_size) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync recovery\n"));
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
+
+	/* if the recovery area is after the recovered eof then remove it */
+	if (recovery_eof <= recovery_head) {
+		if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &zero) == -1) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery head\n"));
+			tdb->ecode = TDB_ERR_IO;
+			return -1;
+		}
+	}
+
+	/* remove the recovery magic */
+	if (tdb_ofs_write(tdb, recovery_head + offsetof(struct list_struct, magic),
+			  &zero) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery magic\n"));
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
+
+	/* reduce the file size to the old size */
+	tdb_munmap(tdb);
+	if (ftruncate(tdb->fd, recovery_eof) != 0) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to reduce to recovery size\n"));
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
+	tdb->map_size = recovery_eof;
+	tdb_mmap(tdb);
+
+	if (transaction_sync(tdb, 0, recovery_eof) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync2 recovery\n"));
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
+
+	TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %d byte database\n",
+		 recovery_eof));
+
+	/* all done */
+	return 0;
+}
+
+/* file: freelist.c */
+
+/* read a freelist record and check for simple errors */
+static int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct list_struct *rec)
+{
+	if (tdb->methods->tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1)
+		return -1;
+
+	if (rec->magic == TDB_MAGIC) {
+		/* this happens when a app is showdown while deleting a record - we should
+		   not completely fail when this happens */
+		TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%d - fixing\n",
+			 rec->magic, off));
+		rec->magic = TDB_FREE_MAGIC;
+		if (tdb->methods->tdb_write(tdb, off, rec, sizeof(*rec)) == -1)
+			return -1;
+	}
+
+	if (rec->magic != TDB_FREE_MAGIC) {
+		/* Ensure ecode is set for log fn. */
+		tdb->ecode = TDB_ERR_CORRUPT;
+		TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%d\n",
+			   rec->magic, off));
+		return TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
+	}
+	if (tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0)
+		return -1;
+	return 0;
+}
+
+
+
+/* Remove an element from the freelist.  Must have alloc lock. */
+static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_t next)
+{
+	tdb_off_t last_ptr, i;
+
+	/* read in the freelist top */
+	last_ptr = FREELIST_TOP;
+	while (tdb_ofs_read(tdb, last_ptr, &i) != -1 && i != 0) {
+		if (i == off) {
+			/* We've found it! */
+			return tdb_ofs_write(tdb, last_ptr, &next);
+		}
+		/* Follow chain (next offset is at start of record) */
+		last_ptr = i;
+	}
+	TDB_LOG((tdb, TDB_DEBUG_FATAL,"remove_from_freelist: not on list at off=%d\n", off));
+	return TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
+}
+
+
+/* update a record tailer (must hold allocation lock) */
+static int update_tailer(struct tdb_context *tdb, tdb_off_t offset,
+			 const struct list_struct *rec)
+{
+	tdb_off_t totalsize;
+
+	/* Offset of tailer from record header */
+	totalsize = sizeof(*rec) + rec->rec_len;
+	return tdb_ofs_write(tdb, offset + totalsize - sizeof(tdb_off_t),
+			 &totalsize);
+}
+
+/* Add an element into the freelist. Merge adjacent records if
+   neccessary. */
+int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec)
+{
+	tdb_off_t right, left;
+
+	/* Allocation and tailer lock */
+	if (tdb_lock(tdb, -1, F_WRLCK) != 0)
+		return -1;
+
+	/* set an initial tailer, so if we fail we don't leave a bogus record */
+	if (update_tailer(tdb, offset, rec) != 0) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed!\n"));
+		goto fail;
+	}
+
+	/* Look right first (I'm an Australian, dammit) */
+	right = offset + sizeof(*rec) + rec->rec_len;
+	if (right + sizeof(*rec) <= tdb->map_size) {
+		struct list_struct r;
+
+		if (tdb->methods->tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: right read failed at %u\n", right));
+			goto left;
+		}
+
+		/* If it's free, expand to include it. */
+		if (r.magic == TDB_FREE_MAGIC) {
+			if (remove_from_freelist(tdb, right, r.next) == -1) {
+				TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: right free failed at %u\n", right));
+				goto left;
+			}
+			rec->rec_len += sizeof(r) + r.rec_len;
+		}
+	}
+
+left:
+	/* Look left */
+	left = offset - sizeof(tdb_off_t);
+	if (left > TDB_DATA_START(tdb->header.hash_size)) {
+		struct list_struct l;
+		tdb_off_t leftsize;
+
+		/* Read in tailer and jump back to header */
+		if (tdb_ofs_read(tdb, left, &leftsize) == -1) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left offset read failed at %u\n", left));
+			goto update;
+		}
+
+		/* it could be uninitialised data */
+		if (leftsize == 0 || leftsize == TDB_PAD_U32) {
+			goto update;
+		}
+
+		left = offset - leftsize;
+
+		/* Now read in record */
+		if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize));
+			goto update;
+		}
+
+		/* If it's free, expand to include it. */
+		if (l.magic == TDB_FREE_MAGIC) {
+			if (remove_from_freelist(tdb, left, l.next) == -1) {
+				TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left free failed at %u\n", left));
+				goto update;
+			} else {
+				offset = left;
+				rec->rec_len += leftsize;
+			}
+		}
+	}
+
+update:
+	if (update_tailer(tdb, offset, rec) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset));
+		goto fail;
+	}
+
+	/* Now, prepend to free list */
+	rec->magic = TDB_FREE_MAGIC;
+
+	if (tdb_ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 ||
+	    tdb_rec_write(tdb, offset, rec) == -1 ||
+	    tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free record write failed at offset=%d\n", offset));
+		goto fail;
+	}
+
+	/* And we're done. */
+	tdb_unlock(tdb, -1, F_WRLCK);
+	return 0;
+
+ fail:
+	tdb_unlock(tdb, -1, F_WRLCK);
+	return -1;
+}
+
+
+/*
+   the core of tdb_allocate - called when we have decided which
+   free list entry to use
+ */
+static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, tdb_len_t length, tdb_off_t rec_ptr,
+				struct list_struct *rec, tdb_off_t last_ptr)
+{
+	struct list_struct newrec;
+	tdb_off_t newrec_ptr;
+
+	memset(&newrec, '\0', sizeof(newrec));
+
+	/* found it - now possibly split it up  */
+	if (rec->rec_len > length + MIN_REC_SIZE) {
+		/* Length of left piece */
+		length = TDB_ALIGN(length, TDB_ALIGNMENT);
+
+		/* Right piece to go on free list */
+		newrec.rec_len = rec->rec_len - (sizeof(*rec) + length);
+		newrec_ptr = rec_ptr + sizeof(*rec) + length;
+
+		/* And left record is shortened */
+		rec->rec_len = length;
+	} else {
+		newrec_ptr = 0;
+	}
+
+	/* Remove allocated record from the free list */
+	if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) {
+		return 0;
+	}
+
+	/* Update header: do this before we drop alloc
+	   lock, otherwise tdb_free() might try to
+	   merge with us, thinking we're free.
+	   (Thanks Jeremy Allison). */
+	rec->magic = TDB_MAGIC;
+	if (tdb_rec_write(tdb, rec_ptr, rec) == -1) {
+		return 0;
+	}
+
+	/* Did we create new block? */
+	if (newrec_ptr) {
+		/* Update allocated record tailer (we
+		   shortened it). */
+		if (update_tailer(tdb, rec_ptr, rec) == -1) {
+			return 0;
+		}
+
+		/* Free new record */
+		if (tdb_free(tdb, newrec_ptr, &newrec) == -1) {
+			return 0;
+		}
+	}
+
+	/* all done - return the new record offset */
+	return rec_ptr;
+}
+
+/* allocate some space from the free list. The offset returned points
+   to a unconnected list_struct within the database with room for at
+   least length bytes of total data
+
+   0 is returned if the space could not be allocated
+ */
+tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_struct *rec)
+{
+	tdb_off_t rec_ptr, last_ptr, newrec_ptr;
+	struct {
+		tdb_off_t rec_ptr, last_ptr;
+		tdb_len_t rec_len;
+	} bestfit;
+
+	if (tdb_lock(tdb, -1, F_WRLCK) == -1)
+		return 0;
+
+	/* Extra bytes required for tailer */
+	length += sizeof(tdb_off_t);
+
+ again:
+	last_ptr = FREELIST_TOP;
+
+	/* read in the freelist top */
+	if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1)
+		goto fail;
+
+	bestfit.rec_ptr = 0;
+	bestfit.last_ptr = 0;
+	bestfit.rec_len = 0;
+
+	/*
+	   this is a best fit allocation strategy. Originally we used
+	   a first fit strategy, but it suffered from massive fragmentation
+	   issues when faced with a slowly increasing record size.
+	 */
+	while (rec_ptr) {
+		if (tdb_rec_free_read(tdb, rec_ptr, rec) == -1) {
+			goto fail;
+		}
+
+		if (rec->rec_len >= length) {
+			if (bestfit.rec_ptr == 0 ||
+			    rec->rec_len < bestfit.rec_len) {
+				bestfit.rec_len = rec->rec_len;
+				bestfit.rec_ptr = rec_ptr;
+				bestfit.last_ptr = last_ptr;
+				/* consider a fit to be good enough if
+				   we aren't wasting more than half
+				   the space */
+				if (bestfit.rec_len < 2*length) {
+					break;
+				}
+			}
+		}
+
+		/* move to the next record */
+		last_ptr = rec_ptr;
+		rec_ptr = rec->next;
+	}
+
+	if (bestfit.rec_ptr != 0) {
+		if (tdb_rec_free_read(tdb, bestfit.rec_ptr, rec) == -1) {
+			goto fail;
+		}
+
+		newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, rec, bestfit.last_ptr);
+		tdb_unlock(tdb, -1, F_WRLCK);
+		return newrec_ptr;
+	}
+
+	/* we didn't find enough space. See if we can expand the
+	   database and if we can then try again */
+	if (tdb_expand(tdb, length + sizeof(*rec)) == 0)
+		goto again;
+ fail:
+	tdb_unlock(tdb, -1, F_WRLCK);
+	return 0;
+}
+
+/* file: freelistcheck.c */
+
+/* Check the freelist is good and contains no loops.
+   Very memory intensive - only do this as a consistency
+   checker. Heh heh - uses an in memory tdb as the storage
+   for the "seen" record list. For some reason this strikes
+   me as extremely clever as I don't have to write another tree
+   data structure implementation :-).
+ */
+
+static int seen_insert(struct tdb_context *mem_tdb, tdb_off_t rec_ptr)
+{
+	TDB_DATA key, data;
+
+	memset(&data, '\0', sizeof(data));
+	key.dptr = (unsigned char *)&rec_ptr;
+	key.dsize = sizeof(rec_ptr);
+	return tdb_store(mem_tdb, key, data, TDB_INSERT);
+}
+
+int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries)
+{
+	struct tdb_context *mem_tdb = NULL;
+	struct list_struct rec;
+	tdb_off_t rec_ptr, last_ptr;
+	int ret = -1;
+
+	*pnum_entries = 0;
+
+	mem_tdb = tdb_open("flval", tdb->header.hash_size,
+				TDB_INTERNAL, O_RDWR, 0600);
+	if (!mem_tdb) {
+		return -1;
+	}
+
+	if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
+		tdb_close(mem_tdb);
+		return 0;
+	}
+
+	last_ptr = FREELIST_TOP;
+
+	/* Store the FREELIST_TOP record. */
+	if (seen_insert(mem_tdb, last_ptr) == -1) {
+		ret = TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
+		goto fail;
+	}
+
+	/* read in the freelist top */
+	if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) {
+		goto fail;
+	}
+
+	while (rec_ptr) {
+
+		/* If we can't store this record (we've seen it
+		   before) then the free list has a loop and must
+		   be corrupt. */
+
+		if (seen_insert(mem_tdb, rec_ptr)) {
+			ret = TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
+			goto fail;
+		}
+
+		if (tdb_rec_free_read(tdb, rec_ptr, &rec) == -1) {
+			goto fail;
+		}
+
+		/* move to the next record */
+		last_ptr = rec_ptr;
+		rec_ptr = rec.next;
+		*pnum_entries += 1;
+	}
+
+	ret = 0;
+
+  fail:
+
+	tdb_close(mem_tdb);
+	tdb_unlock(tdb, -1, F_WRLCK);
+	return ret;
+}
+
+/* file: traverse.c */
+
+/* Uses traverse lock: 0 = finish, -1 = error, other = record offset */
+static int tdb_next_lock(struct tdb_context *tdb, struct tdb_traverse_lock *tlock,
+			 struct list_struct *rec)
+{
+	int want_next = (tlock->off != 0);
+
+	/* Lock each chain from the start one. */
+	for (; tlock->hash < tdb->header.hash_size; tlock->hash++) {
+		if (!tlock->off && tlock->hash != 0) {
+			/* this is an optimisation for the common case where
+			   the hash chain is empty, which is particularly
+			   common for the use of tdb with ldb, where large
+			   hashes are used. In that case we spend most of our
+			   time in tdb_brlock(), locking empty hash chains.
+
+			   To avoid this, we do an unlocked pre-check to see
+			   if the hash chain is empty before starting to look
+			   inside it. If it is empty then we can avoid that
+			   hash chain. If it isn't empty then we can't believe
+			   the value we get back, as we read it without a
+			   lock, so instead we get the lock and re-fetch the
+			   value below.
+
+			   Notice that not doing this optimisation on the
+			   first hash chain is critical. We must guarantee
+			   that we have done at least one fcntl lock at the
+			   start of a search to guarantee that memory is
+			   coherent on SMP systems. If records are added by
+			   others during the search then thats OK, and we
+			   could possibly miss those with this trick, but we
+			   could miss them anyway without this trick, so the
+			   semantics don't change.
+
+			   With a non-indexed ldb search this trick gains us a
+			   factor of around 80 in speed on a linux 2.6.x
+			   system (testing using ldbtest).
+			*/
+			tdb->methods->next_hash_chain(tdb, &tlock->hash);
+			if (tlock->hash == tdb->header.hash_size) {
+				continue;
+			}
+		}
+
+		if (tdb_lock(tdb, tlock->hash, tlock->lock_rw) == -1)
+			return -1;
+
+		/* No previous record?  Start at top of chain. */
+		if (!tlock->off) {
+			if (tdb_ofs_read(tdb, TDB_HASH_TOP(tlock->hash),
+				     &tlock->off) == -1)
+				goto fail;
+		} else {
+			/* Otherwise unlock the previous record. */
+			if (tdb_unlock_record(tdb, tlock->off) != 0)
+				goto fail;
+		}
+
+		if (want_next) {
+			/* We have offset of old record: grab next */
+			if (tdb_rec_read(tdb, tlock->off, rec) == -1)
+				goto fail;
+			tlock->off = rec->next;
+		}
+
+		/* Iterate through chain */
+		while( tlock->off) {
+			tdb_off_t current;
+			if (tdb_rec_read(tdb, tlock->off, rec) == -1)
+				goto fail;
+
+			/* Detect infinite loops. From "Shlomi Yaakobovich" <Shlomi@exanet.com>. */
+			if (tlock->off == rec->next) {
+				TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: loop detected.\n"));
+				goto fail;
+			}
+
+			if (!TDB_DEAD(rec)) {
+				/* Woohoo: we found one! */
+				if (tdb_lock_record(tdb, tlock->off) != 0)
+					goto fail;
+				return tlock->off;
+			}
+
+			/* Try to clean dead ones from old traverses */
+			current = tlock->off;
+			tlock->off = rec->next;
+			if (!(tdb->read_only || tdb->traverse_read) &&
+			    tdb_do_delete(tdb, current, rec) != 0)
+				goto fail;
+		}
+		tdb_unlock(tdb, tlock->hash, tlock->lock_rw);
+		want_next = 0;
+	}
+	/* We finished iteration without finding anything */
+	return TDB_ERRCODE(TDB_SUCCESS, 0);
+
+ fail:
+	tlock->off = 0;
+	if (tdb_unlock(tdb, tlock->hash, tlock->lock_rw) != 0)
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: On error unlock failed!\n"));
+	return -1;
+}
+
+/* traverse the entire database - calling fn(tdb, key, data) on each element.
+   return -1 on error or the record count traversed
+   if fn is NULL then it is not called
+   a non-zero return value from fn() indicates that the traversal should stop
+  */
+static int tdb_traverse_internal(struct tdb_context *tdb,
+				 tdb_traverse_func fn, void *private_data,
+				 struct tdb_traverse_lock *tl)
+{
+	TDB_DATA key, dbuf;
+	struct list_struct rec;
+	int ret, count = 0;
+
+	/* This was in the initializaton, above, but the IRIX compiler
+	 * did not like it.  crh
+	 */
+	tl->next = tdb->travlocks.next;
+
+	/* fcntl locks don't stack: beware traverse inside traverse */
+	tdb->travlocks.next = tl;
+
+	/* tdb_next_lock places locks on the record returned, and its chain */
+	while ((ret = tdb_next_lock(tdb, tl, &rec)) > 0) {
+		count++;
+		/* now read the full record */
+		key.dptr = tdb_alloc_read(tdb, tl->off + sizeof(rec),
+					  rec.key_len + rec.data_len);
+		if (!key.dptr) {
+			ret = -1;
+			if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0)
+				goto out;
+			if (tdb_unlock_record(tdb, tl->off) != 0)
+				TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n"));
+			goto out;
+		}
+		key.dsize = rec.key_len;
+		dbuf.dptr = key.dptr + rec.key_len;
+		dbuf.dsize = rec.data_len;
+
+		/* Drop chain lock, call out */
+		if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0) {
+			ret = -1;
+			SAFE_FREE(key.dptr);
+			goto out;
+		}
+		if (fn && fn(tdb, key, dbuf, private_data)) {
+			/* They want us to terminate traversal */
+			ret = count;
+			if (tdb_unlock_record(tdb, tl->off) != 0) {
+				TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: unlock_record failed!\n"));;
+				ret = -1;
+			}
+			SAFE_FREE(key.dptr);
+			goto out;
+		}
+		SAFE_FREE(key.dptr);
+	}
+out:
+	tdb->travlocks.next = tl->next;
+	if (ret < 0)
+		return -1;
+	else
+		return count;
+}
+
+
+/*
+  a write style traverse - temporarily marks the db read only
+*/
+int tdb_traverse_read(struct tdb_context *tdb,
+		      tdb_traverse_func fn, void *private_data)
+{
+	struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
+	int ret;
+
+	/* we need to get a read lock on the transaction lock here to
+	   cope with the lock ordering semantics of solaris10 */
+	if (tdb_transaction_lock(tdb, F_RDLCK)) {
+		return -1;
+	}
+
+	tdb->traverse_read++;
+	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
+	tdb->traverse_read--;
+
+	tdb_transaction_unlock(tdb);
+
+	return ret;
+}
+
+/*
+  a write style traverse - needs to get the transaction lock to
+  prevent deadlocks
+*/
+int tdb_traverse(struct tdb_context *tdb,
+		 tdb_traverse_func fn, void *private_data)
+{
+	struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
+	int ret;
+
+	if (tdb->read_only || tdb->traverse_read) {
+		return tdb_traverse_read(tdb, fn, private_data);
+	}
+
+	if (tdb_transaction_lock(tdb, F_WRLCK)) {
+		return -1;
+	}
+
+	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
+
+	tdb_transaction_unlock(tdb);
+
+	return ret;
+}
+
+
+/* find the first entry in the database and return its key */
+TDB_DATA tdb_firstkey(struct tdb_context *tdb)
+{
+	TDB_DATA key;
+	struct list_struct rec;
+
+	/* release any old lock */
+	if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0)
+		return tdb_null;
+	tdb->travlocks.off = tdb->travlocks.hash = 0;
+	tdb->travlocks.lock_rw = F_RDLCK;
+
+	/* Grab first record: locks chain and returned record. */
+	if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0)
+		return tdb_null;
+	/* now read the key */
+	key.dsize = rec.key_len;
+	key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize);
+
+	/* Unlock the hash chain of the record we just read. */
+	if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0)
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n"));
+	return key;
+}
+
+/* find the next entry in the database, returning its key */
+TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
+{
+	u32 oldhash;
+	TDB_DATA key = tdb_null;
+	struct list_struct rec;
+	unsigned char *k = NULL;
+
+	/* Is locked key the old key?  If so, traverse will be reliable. */
+	if (tdb->travlocks.off) {
+		if (tdb_lock(tdb,tdb->travlocks.hash,tdb->travlocks.lock_rw))
+			return tdb_null;
+		if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1
+		    || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),
+					    rec.key_len))
+		    || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) {
+			/* No, it wasn't: unlock it and start from scratch */
+			if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) {
+				SAFE_FREE(k);
+				return tdb_null;
+			}
+			if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) {
+				SAFE_FREE(k);
+				return tdb_null;
+			}
+			tdb->travlocks.off = 0;
+		}
+
+		SAFE_FREE(k);
+	}
+
+	if (!tdb->travlocks.off) {
+		/* No previous element: do normal find, and lock record */
+		tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec);
+		if (!tdb->travlocks.off)
+			return tdb_null;
+		tdb->travlocks.hash = BUCKET(rec.full_hash);
+		if (tdb_lock_record(tdb, tdb->travlocks.off) != 0) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno)));
+			return tdb_null;
+		}
+	}
+	oldhash = tdb->travlocks.hash;
+
+	/* Grab next record: locks chain and returned record,
+	   unlocks old record */
+	if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) {
+		key.dsize = rec.key_len;
+		key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec),
+					  key.dsize);
+		/* Unlock the chain of this new record */
+		if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0)
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
+	}
+	/* Unlock the chain of old record */
+	if (tdb_unlock(tdb, BUCKET(oldhash), tdb->travlocks.lock_rw) != 0)
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
+	return key;
+}
+
+/* file: dump.c */
+
+static tdb_off_t tdb_dump_record(struct tdb_context *tdb, int hash,
+				 tdb_off_t offset)
+{
+	struct list_struct rec;
+	tdb_off_t tailer_ofs, tailer;
+
+	if (tdb->methods->tdb_read(tdb, offset, (char *)&rec,
+				   sizeof(rec), DOCONV()) == -1) {
+		printf("ERROR: failed to read record at %u\n", offset);
+		return 0;
+	}
+
+	printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%d "
+	       "key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n",
+	       hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len,
+	       rec.full_hash, rec.magic);
+
+	tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off_t);
+
+	if (tdb_ofs_read(tdb, tailer_ofs, &tailer) == -1) {
+		printf("ERROR: failed to read tailer at %u\n", tailer_ofs);
+		return rec.next;
+	}
+
+	if (tailer != rec.rec_len + sizeof(rec)) {
+		printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n",
+				(unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec)));
+	}
+	return rec.next;
+}
+
+static int tdb_dump_chain(struct tdb_context *tdb, int i)
+{
+	tdb_off_t rec_ptr, top;
+
+	top = TDB_HASH_TOP(i);
+
+	if (tdb_lock(tdb, i, F_WRLCK) != 0)
+		return -1;
+
+	if (tdb_ofs_read(tdb, top, &rec_ptr) == -1)
+		return tdb_unlock(tdb, i, F_WRLCK);
+
+	if (rec_ptr)
+		printf("hash=%d\n", i);
+
+	while (rec_ptr) {
+		rec_ptr = tdb_dump_record(tdb, i, rec_ptr);
+	}
+
+	return tdb_unlock(tdb, i, F_WRLCK);
+}
+
+void tdb_dump_all(struct tdb_context *tdb)
+{
+	int i;
+	for (i=0;i<tdb->header.hash_size;i++) {
+		tdb_dump_chain(tdb, i);
+	}
+	printf("freelist:\n");
+	tdb_dump_chain(tdb, -1);
+}
+
+int tdb_printfreelist(struct tdb_context *tdb)
+{
+	int ret;
+	long total_free = 0;
+	tdb_off_t offset, rec_ptr;
+	struct list_struct rec;
+
+	if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0)
+		return ret;
+
+	offset = FREELIST_TOP;
+
+	/* read in the freelist top */
+	if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) {
+		tdb_unlock(tdb, -1, F_WRLCK);
+		return 0;
+	}
+
+	printf("freelist top=[0x%08x]\n", rec_ptr );
+	while (rec_ptr) {
+		if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec,
+					   sizeof(rec), DOCONV()) == -1) {
+			tdb_unlock(tdb, -1, F_WRLCK);
+			return -1;
+		}
+
+		if (rec.magic != TDB_FREE_MAGIC) {
+			printf("bad magic 0x%08x in free list\n", rec.magic);
+			tdb_unlock(tdb, -1, F_WRLCK);
+			return -1;
+		}
+
+		printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)] (end = 0x%08x)\n",
+		       rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len);
+		total_free += rec.rec_len;
+
+		/* move to the next record */
+		rec_ptr = rec.next;
+	}
+	printf("total rec_len = [0x%08x (%d)]\n", (int)total_free,
+               (int)total_free);
+
+	return tdb_unlock(tdb, -1, F_WRLCK);
+}
+
+/* file: tdb.c */
+
+/*
+  non-blocking increment of the tdb sequence number if the tdb has been opened using
+  the TDB_SEQNUM flag
+*/
+void tdb_increment_seqnum_nonblock(struct tdb_context *tdb)
+{
+	tdb_off_t seqnum=0;
+
+	if (!(tdb->flags & TDB_SEQNUM)) {
+		return;
+	}
+
+	/* we ignore errors from this, as we have no sane way of
+	   dealing with them.
+	*/
+	tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
+	seqnum++;
+	tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum);
+}
+
+/*
+  increment the tdb sequence number if the tdb has been opened using
+  the TDB_SEQNUM flag
+*/
+static void tdb_increment_seqnum(struct tdb_context *tdb)
+{
+	if (!(tdb->flags & TDB_SEQNUM)) {
+		return;
+	}
+
+	if (tdb_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) {
+		return;
+	}
+
+	tdb_increment_seqnum_nonblock(tdb);
+
+	tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1, 1);
+}
+
+static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data)
+{
+	return memcmp(data.dptr, key.dptr, data.dsize);
+}
+
+/* Returns 0 on fail.  On success, return offset of record, and fills
+   in rec */
+static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, u32 hash,
+			struct list_struct *r)
+{
+	tdb_off_t rec_ptr;
+
+	/* read in the hash top */
+	if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
+		return 0;
+
+	/* keep looking until we find the right record */
+	while (rec_ptr) {
+		if (tdb_rec_read(tdb, rec_ptr, r) == -1)
+			return 0;
+
+		if (!TDB_DEAD(r) && hash==r->full_hash
+		    && key.dsize==r->key_len
+		    && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r),
+				      r->key_len, tdb_key_compare,
+				      NULL) == 0) {
+			return rec_ptr;
+		}
+		rec_ptr = r->next;
+	}
+	return TDB_ERRCODE(TDB_ERR_NOEXIST, 0);
+}
+
+/* As tdb_find, but if you succeed, keep the lock */
+tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, u32 hash, int locktype,
+			   struct list_struct *rec)
+{
+	u32 rec_ptr;
+
+	if (tdb_lock(tdb, BUCKET(hash), locktype) == -1)
+		return 0;
+	if (!(rec_ptr = tdb_find(tdb, key, hash, rec)))
+		tdb_unlock(tdb, BUCKET(hash), locktype);
+	return rec_ptr;
+}
+
+
+/* update an entry in place - this only works if the new data size
+   is <= the old data size and the key exists.
+   on failure return -1.
+*/
+static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, u32 hash, TDB_DATA dbuf)
+{
+	struct list_struct rec;
+	tdb_off_t rec_ptr;
+
+	/* find entry */
+	if (!(rec_ptr = tdb_find(tdb, key, hash, &rec)))
+		return -1;
+
+	/* must be long enough key, data and tailer */
+	if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off_t)) {
+		tdb->ecode = TDB_SUCCESS; /* Not really an error */
+		return -1;
+	}
+
+	if (tdb->methods->tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len,
+		      dbuf.dptr, dbuf.dsize) == -1)
+		return -1;
+
+	if (dbuf.dsize != rec.data_len) {
+		/* update size */
+		rec.data_len = dbuf.dsize;
+		return tdb_rec_write(tdb, rec_ptr, &rec);
+	}
+
+	return 0;
+}
+
+/* find an entry in the database given a key */
+/* If an entry doesn't exist tdb_err will be set to
+ * TDB_ERR_NOEXIST. If a key has no data attached
+ * then the TDB_DATA will have zero length but
+ * a non-zero pointer
+ */
+TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key)
+{
+	tdb_off_t rec_ptr;
+	struct list_struct rec;
+	TDB_DATA ret;
+	u32 hash;
+
+	/* find which hash bucket it is in */
+	hash = tdb->hash_fn(&key);
+	if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec)))
+		return tdb_null;
+
+	ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len,
+				  rec.data_len);
+	ret.dsize = rec.data_len;
+	tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
+	return ret;
+}
+
+/*
+ * Find an entry in the database and hand the record's data to a parsing
+ * function. The parsing function is executed under the chain read lock, so it
+ * should be fast and should not block on other syscalls.
+ *
+ * DONT CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS.
+ *
+ * For mmapped tdb's that do not have a transaction open it points the parsing
+ * function directly at the mmap area, it avoids the malloc/memcpy in this
+ * case. If a transaction is open or no mmap is available, it has to do
+ * malloc/read/parse/free.
+ *
+ * This is interesting for all readers of potentially large data structures in
+ * the tdb records, ldb indexes being one example.
+ */
+
+int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key,
+		     int (*parser)(TDB_DATA key, TDB_DATA data,
+				   void *private_data),
+		     void *private_data)
+{
+	tdb_off_t rec_ptr;
+	struct list_struct rec;
+	int ret;
+	u32 hash;
+
+	/* find which hash bucket it is in */
+	hash = tdb->hash_fn(&key);
+
+	if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
+		return TDB_ERRCODE(TDB_ERR_NOEXIST, 0);
+	}
+
+	ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len,
+			     rec.data_len, parser, private_data);
+
+	tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
+
+	return ret;
+}
+
+/* check if an entry in the database exists
+
+   note that 1 is returned if the key is found and 0 is returned if not found
+   this doesn't match the conventions in the rest of this module, but is
+   compatible with gdbm
+*/
+static int tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, u32 hash)
+{
+	struct list_struct rec;
+
+	if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0)
+		return 0;
+	tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
+	return 1;
+}
+
+int tdb_exists(struct tdb_context *tdb, TDB_DATA key)
+{
+	u32 hash = tdb->hash_fn(&key);
+	return tdb_exists_hash(tdb, key, hash);
+}
+
+/* actually delete an entry in the database given the offset */
+int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct*rec)
+{
+	tdb_off_t last_ptr, i;
+	struct list_struct lastrec;
+
+	if (tdb->read_only || tdb->traverse_read) return -1;
+
+	if (tdb_write_lock_record(tdb, rec_ptr) == -1) {
+		/* Someone traversing here: mark it as dead */
+		rec->magic = TDB_DEAD_MAGIC;
+		return tdb_rec_write(tdb, rec_ptr, rec);
+	}
+	if (tdb_write_unlock_record(tdb, rec_ptr) != 0)
+		return -1;
+
+	/* find previous record in hash chain */
+	if (tdb_ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1)
+		return -1;
+	for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next)
+		if (tdb_rec_read(tdb, i, &lastrec) == -1)
+			return -1;
+
+	/* unlink it: next ptr is at start of record. */
+	if (last_ptr == 0)
+		last_ptr = TDB_HASH_TOP(rec->full_hash);
+	if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1)
+		return -1;
+
+	/* recover the space */
+	if (tdb_free(tdb, rec_ptr, rec) == -1)
+		return -1;
+	return 0;
+}
+
+static int tdb_count_dead(struct tdb_context *tdb, u32 hash)
+{
+	int res = 0;
+	tdb_off_t rec_ptr;
+	struct list_struct rec;
+
+	/* read in the hash top */
+	if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
+		return 0;
+
+	while (rec_ptr) {
+		if (tdb_rec_read(tdb, rec_ptr, &rec) == -1)
+			return 0;
+
+		if (rec.magic == TDB_DEAD_MAGIC) {
+			res += 1;
+		}
+		rec_ptr = rec.next;
+	}
+	return res;
+}
+
+/*
+ * Purge all DEAD records from a hash chain
+ */
+static int tdb_purge_dead(struct tdb_context *tdb, u32 hash)
+{
+	int res = -1;
+	struct list_struct rec;
+	tdb_off_t rec_ptr;
+
+	if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
+		return -1;
+	}
+
+	/* read in the hash top */
+	if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
+		goto fail;
+
+	while (rec_ptr) {
+		tdb_off_t next;
+
+		if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) {
+			goto fail;
+		}
+
+		next = rec.next;
+
+		if (rec.magic == TDB_DEAD_MAGIC
+		    && tdb_do_delete(tdb, rec_ptr, &rec) == -1) {
+			goto fail;
+		}
+		rec_ptr = next;
+	}
+	res = 0;
+ fail:
+	tdb_unlock(tdb, -1, F_WRLCK);
+	return res;
+}
+
+/* delete an entry in the database given a key */
+static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, u32 hash)
+{
+	tdb_off_t rec_ptr;
+	struct list_struct rec;
+	int ret;
+
+	if (tdb->max_dead_records != 0) {
+
+		/*
+		 * Allow for some dead records per hash chain, mainly for
+		 * tdb's with a very high create/delete rate like locking.tdb.
+		 */
+
+		if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
+			return -1;
+
+		if (tdb_count_dead(tdb, hash) >= tdb->max_dead_records) {
+			/*
+			 * Don't let the per-chain freelist grow too large,
+			 * delete all existing dead records
+			 */
+			tdb_purge_dead(tdb, hash);
+		}
+
+		if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) {
+			tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
+			return -1;
+		}
+
+		/*
+		 * Just mark the record as dead.
+		 */
+		rec.magic = TDB_DEAD_MAGIC;
+		ret = tdb_rec_write(tdb, rec_ptr, &rec);
+	}
+	else {
+		if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK,
+						   &rec)))
+			return -1;
+
+		ret = tdb_do_delete(tdb, rec_ptr, &rec);
+	}
+
+	if (ret == 0) {
+		tdb_increment_seqnum(tdb);
+	}
+
+	if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0)
+		TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n"));
+	return ret;
+}
+
+int tdb_delete(struct tdb_context *tdb, TDB_DATA key)
+{
+	u32 hash = tdb->hash_fn(&key);
+	return tdb_delete_hash(tdb, key, hash);
+}
+
+/*
+ * See if we have a dead record around with enough space
+ */
+static tdb_off_t tdb_find_dead(struct tdb_context *tdb, u32 hash,
+			       struct list_struct *r, tdb_len_t length)
+{
+	tdb_off_t rec_ptr;
+
+	/* read in the hash top */
+	if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
+		return 0;
+
+	/* keep looking until we find the right record */
+	while (rec_ptr) {
+		if (tdb_rec_read(tdb, rec_ptr, r) == -1)
+			return 0;
+
+		if (TDB_DEAD(r) && r->rec_len >= length) {
+			/*
+			 * First fit for simple coding, TODO: change to best
+			 * fit
+			 */
+			return rec_ptr;
+		}
+		rec_ptr = r->next;
+	}
+	return 0;
+}
+
+/* store an element in the database, replacing any existing element
+   with the same key
+
+   return 0 on success, -1 on failure
+*/
+int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
+{
+	struct list_struct rec;
+	u32 hash;
+	tdb_off_t rec_ptr;
+	char *p = NULL;
+	int ret = -1;
+
+	if (tdb->read_only || tdb->traverse_read) {
+		tdb->ecode = TDB_ERR_RDONLY;
+		return -1;
+	}
+
+	/* find which hash bucket it is in */
+	hash = tdb->hash_fn(&key);
+	if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
+		return -1;
+
+	/* check for it existing, on insert. */
+	if (flag == TDB_INSERT) {
+		if (tdb_exists_hash(tdb, key, hash)) {
+			tdb->ecode = TDB_ERR_EXISTS;
+			goto fail;
+		}
+	} else {
+		/* first try in-place update, on modify or replace. */
+		if (tdb_update_hash(tdb, key, hash, dbuf) == 0) {
+			goto done;
+		}
+		if (tdb->ecode == TDB_ERR_NOEXIST &&
+		    flag == TDB_MODIFY) {
+			/* if the record doesn't exist and we are in TDB_MODIFY mode then
+			 we should fail the store */
+			goto fail;
+		}
+	}
+	/* reset the error code potentially set by the tdb_update() */
+	tdb->ecode = TDB_SUCCESS;
+
+	/* delete any existing record - if it doesn't exist we don't
+           care.  Doing this first reduces fragmentation, and avoids
+           coalescing with `allocated' block before it's updated. */
+	if (flag != TDB_INSERT)
+		tdb_delete_hash(tdb, key, hash);
+
+	/* Copy key+value *before* allocating free space in case malloc
+	   fails and we are left with a dead spot in the tdb. */
+
+	if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) {
+		tdb->ecode = TDB_ERR_OOM;
+		goto fail;
+	}
+
+	memcpy(p, key.dptr, key.dsize);
+	if (dbuf.dsize)
+		memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize);
+
+	if (tdb->max_dead_records != 0) {
+		/*
+		 * Allow for some dead records per hash chain, look if we can
+		 * find one that can hold the new record. We need enough space
+		 * for key, data and tailer. If we find one, we don't have to
+		 * consult the central freelist.
+		 */
+		rec_ptr = tdb_find_dead(
+			tdb, hash, &rec,
+			key.dsize + dbuf.dsize + sizeof(tdb_off_t));
+
+		if (rec_ptr != 0) {
+			rec.key_len = key.dsize;
+			rec.data_len = dbuf.dsize;
+			rec.full_hash = hash;
+			rec.magic = TDB_MAGIC;
+			if (tdb_rec_write(tdb, rec_ptr, &rec) == -1
+			    || tdb->methods->tdb_write(
+				    tdb, rec_ptr + sizeof(rec),
+				    p, key.dsize + dbuf.dsize) == -1) {
+				goto fail;
+			}
+			goto done;
+		}
+	}
+
+	/*
+	 * We have to allocate some space from the freelist, so this means we
+	 * have to lock it. Use the chance to purge all the DEAD records from
+	 * the hash chain under the freelist lock.
+	 */
+
+	if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
+		goto fail;
+	}
+
+	if ((tdb->max_dead_records != 0)
+	    && (tdb_purge_dead(tdb, hash) == -1)) {
+		tdb_unlock(tdb, -1, F_WRLCK);
+		goto fail;
+	}
+
+	/* we have to allocate some space */
+	rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec);
+
+	tdb_unlock(tdb, -1, F_WRLCK);
+
+	if (rec_ptr == 0) {
+		goto fail;
+	}
+
+	/* Read hash top into next ptr */
+	if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1)
+		goto fail;
+
+	rec.key_len = key.dsize;
+	rec.data_len = dbuf.dsize;
+	rec.full_hash = hash;
+	rec.magic = TDB_MAGIC;
+
+	/* write out and point the top of the hash chain at it */
+	if (tdb_rec_write(tdb, rec_ptr, &rec) == -1
+	    || tdb->methods->tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1
+	    || tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) {
+		/* Need to tdb_unallocate() here */
+		goto fail;
+	}
+
+ done:
+	ret = 0;
+ fail:
+	if (ret == 0) {
+		tdb_increment_seqnum(tdb);
+	}
+
+	SAFE_FREE(p);
+	tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
+	return ret;
+}
+
+
+/* Append to an entry. Create if not exist. */
+int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
+{
+	u32 hash;
+	TDB_DATA dbuf;
+	int ret = -1;
+
+	/* find which hash bucket it is in */
+	hash = tdb->hash_fn(&key);
+	if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
+		return -1;
+
+	dbuf = tdb_fetch(tdb, key);
+
+	if (dbuf.dptr == NULL) {
+		dbuf.dptr = (unsigned char *)malloc(new_dbuf.dsize);
+	} else {
+		unsigned char *new_dptr = (unsigned char *)realloc(dbuf.dptr,
+						     dbuf.dsize + new_dbuf.dsize);
+		if (new_dptr == NULL) {
+			free(dbuf.dptr);
+		}
+		dbuf.dptr = new_dptr;
+	}
+
+	if (dbuf.dptr == NULL) {
+		tdb->ecode = TDB_ERR_OOM;
+		goto failed;
+	}
+
+	memcpy(dbuf.dptr + dbuf.dsize, new_dbuf.dptr, new_dbuf.dsize);
+	dbuf.dsize += new_dbuf.dsize;
+
+	ret = tdb_store(tdb, key, dbuf, 0);
+
+failed:
+	tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
+	SAFE_FREE(dbuf.dptr);
+	return ret;
+}
+
+
+/*
+  return the name of the current tdb file
+  useful for external logging functions
+*/
+const char *tdb_name(struct tdb_context *tdb)
+{
+	return tdb->name;
+}
+
+/*
+  return the underlying file descriptor being used by tdb, or -1
+  useful for external routines that want to check the device/inode
+  of the fd
+*/
+int tdb_fd(struct tdb_context *tdb)
+{
+	return tdb->fd;
+}
+
+/*
+  return the current logging function
+  useful for external tdb routines that wish to log tdb errors
+*/
+tdb_log_func tdb_log_fn(struct tdb_context *tdb)
+{
+	return tdb->log.log_fn;
+}
+
+
+/*
+  get the tdb sequence number. Only makes sense if the writers opened
+  with TDB_SEQNUM set. Note that this sequence number will wrap quite
+  quickly, so it should only be used for a 'has something changed'
+  test, not for code that relies on the count of the number of changes
+  made. If you want a counter then use a tdb record.
+
+  The aim of this sequence number is to allow for a very lightweight
+  test of a possible tdb change.
+*/
+int tdb_get_seqnum(struct tdb_context *tdb)
+{
+	tdb_off_t seqnum=0;
+
+	tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
+	return seqnum;
+}
+
+int tdb_hash_size(struct tdb_context *tdb)
+{
+	return tdb->header.hash_size;
+}
+
+size_t tdb_map_size(struct tdb_context *tdb)
+{
+	return tdb->map_size;
+}
+
+int tdb_get_flags(struct tdb_context *tdb)
+{
+	return tdb->flags;
+}
+
+
+/*
+  enable sequence number handling on an open tdb
+*/
+void tdb_enable_seqnum(struct tdb_context *tdb)
+{
+	tdb->flags |= TDB_SEQNUM;
+}
+
+/* file: open.c */
+
+/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */
+static struct tdb_context *tdbs = NULL;
+
+
+/* This is from a hash algorithm suggested by Rogier Wolff */
+static unsigned int default_tdb_hash(TDB_DATA *key)
+{
+	u32 value;	/* Used to compute the hash value.  */
+	u32   i;	/* Used to cycle through random values. */
+
+	/* Set the initial value from the key size. */
+	for (value = 0, i=0; i < key->dsize; i++)
+		value = value * 256 + key->dptr[i] + (value >> 24) * 241;
+
+	return value;
+}
+
+
+/* initialise a new database with a specified hash size */
+static int tdb_new_database(struct tdb_context *tdb, int hash_size)
+{
+	struct tdb_header *newdb;
+	int size, ret = -1;
+
+	/* We make it up in memory, then write it out if not internal */
+	size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t);
+	if (!(newdb = (struct tdb_header *)calloc(size, 1)))
+		return TDB_ERRCODE(TDB_ERR_OOM, -1);
+
+	/* Fill in the header */
+	newdb->version = TDB_VERSION;
+	newdb->hash_size = hash_size;
+	if (tdb->flags & TDB_INTERNAL) {
+		tdb->map_size = size;
+		tdb->map_ptr = (char *)newdb;
+		memcpy(&tdb->header, newdb, sizeof(tdb->header));
+		/* Convert the `ondisk' version if asked. */
+		CONVERT(*newdb);
+		return 0;
+	}
+	if (lseek(tdb->fd, 0, SEEK_SET) == -1)
+		goto fail;
+
+	if (ftruncate(tdb->fd, 0) == -1)
+		goto fail;
+
+	/* This creates an endian-converted header, as if read from disk */
+	CONVERT(*newdb);
+	memcpy(&tdb->header, newdb, sizeof(tdb->header));
+	/* Don't endian-convert the magic food! */
+	memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
+	if (write(tdb->fd, newdb, size) != size) {
+		ret = -1;
+	} else {
+		ret = 0;
+	}
+
+  fail:
+	SAFE_FREE(newdb);
+	return ret;
+}
+
+
+
+static int tdb_already_open(dev_t device,
+			    ino_t ino)
+{
+	struct tdb_context *i;
+
+	for (i = tdbs; i; i = i->next) {
+		if (i->device == device && i->inode == ino) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/* open the database, creating it if necessary
+
+   The open_flags and mode are passed straight to the open call on the
+   database file. A flags value of O_WRONLY is invalid. The hash size
+   is advisory, use zero for a default value.
+
+   Return is NULL on error, in which case errno is also set.  Don't
+   try to call tdb_error or tdb_errname, just do strerror(errno).
+
+   @param name may be NULL for internal databases. */
+struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags,
+		      int open_flags, mode_t mode)
+{
+	return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL);
+}
+
+/* a default logging function */
+static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
+static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
+{
+}
+
+
+struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
+				int open_flags, mode_t mode,
+				const struct tdb_logging_context *log_ctx,
+				tdb_hash_func hash_fn)
+{
+	struct tdb_context *tdb;
+	struct stat st;
+	int rev = 0, locked = 0;
+	unsigned char *vp;
+	u32 vertest;
+
+	if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) {
+		/* Can't log this */
+		errno = ENOMEM;
+		goto fail;
+	}
+	tdb_io_init(tdb);
+	tdb->fd = -1;
+	tdb->name = NULL;
+	tdb->map_ptr = NULL;
+	tdb->flags = tdb_flags;
+	tdb->open_flags = open_flags;
+	if (log_ctx) {
+		tdb->log = *log_ctx;
+	} else {
+		tdb->log.log_fn = null_log_fn;
+		tdb->log.log_private = NULL;
+	}
+	tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash;
+
+	/* cache the page size */
+	tdb->page_size = sysconf(_SC_PAGESIZE);
+	if (tdb->page_size <= 0) {
+		tdb->page_size = 0x2000;
+	}
+
+	if ((open_flags & O_ACCMODE) == O_WRONLY) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n",
+			 name));
+		errno = EINVAL;
+		goto fail;
+	}
+
+	if (hash_size == 0)
+		hash_size = DEFAULT_HASH_SIZE;
+	if ((open_flags & O_ACCMODE) == O_RDONLY) {
+		tdb->read_only = 1;
+		/* read only databases don't do locking or clear if first */
+		tdb->flags |= TDB_NOLOCK;
+		tdb->flags &= ~TDB_CLEAR_IF_FIRST;
+	}
+
+	/* internal databases don't mmap or lock, and start off cleared */
+	if (tdb->flags & TDB_INTERNAL) {
+		tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP);
+		tdb->flags &= ~TDB_CLEAR_IF_FIRST;
+		if (tdb_new_database(tdb, hash_size) != 0) {
+			TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!"));
+			goto fail;
+		}
+		goto internal;
+	}
+
+	if ((tdb->fd = open(name, open_flags, mode)) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n",
+			 name, strerror(errno)));
+		goto fail;	/* errno set by open(2) */
+	}
+
+	/* ensure there is only one process initialising at once */
+	if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get global lock on %s: %s\n",
+			 name, strerror(errno)));
+		goto fail;	/* errno set by tdb_brlock */
+	}
+
+	/* we need to zero database if we are the only one with it open */
+	if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
+	    (locked = (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0, 1) == 0))) {
+		open_flags |= O_CREAT;
+		if (ftruncate(tdb->fd, 0) == -1) {
+			TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
+				 "failed to truncate %s: %s\n",
+				 name, strerror(errno)));
+			goto fail; /* errno set by ftruncate */
+		}
+	}
+
+	if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
+	    || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
+	    || (tdb->header.version != TDB_VERSION
+		&& !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
+		/* its not a valid database - possibly initialise it */
+		if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
+			errno = EIO; /* ie bad format or something */
+			goto fail;
+		}
+		rev = (tdb->flags & TDB_CONVERT);
+	}
+	vp = (unsigned char *)&tdb->header.version;
+	vertest = (((u32)vp[0]) << 24) | (((u32)vp[1]) << 16) |
+		  (((u32)vp[2]) << 8) | (u32)vp[3];
+	tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0;
+	if (!rev)
+		tdb->flags &= ~TDB_CONVERT;
+	else {
+		tdb->flags |= TDB_CONVERT;
+		tdb_convert(&tdb->header, sizeof(tdb->header));
+	}
+	if (fstat(tdb->fd, &st) == -1)
+		goto fail;
+
+	if (tdb->header.rwlocks != 0) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n"));
+		goto fail;
+	}
+
+	/* Is it already in the open list?  If so, fail. */
+	if (tdb_already_open(st.st_dev, st.st_ino)) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
+			 "%s (%d,%d) is already open in this process\n",
+			 name, (int)st.st_dev, (int)st.st_ino));
+		errno = EBUSY;
+		goto fail;
+	}
+
+	if (!(tdb->name = (char *)strdup(name))) {
+		errno = ENOMEM;
+		goto fail;
+	}
+
+	tdb->map_size = st.st_size;
+	tdb->device = st.st_dev;
+	tdb->inode = st.st_ino;
+	tdb->max_dead_records = 0;
+	tdb_mmap(tdb);
+	if (locked) {
+		if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0, 1) == -1) {
+			TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
+				 "failed to take ACTIVE_LOCK on %s: %s\n",
+				 name, strerror(errno)));
+			goto fail;
+		}
+
+	}
+
+	/* We always need to do this if the CLEAR_IF_FIRST flag is set, even if
+	   we didn't get the initial exclusive lock as we need to let all other
+	   users know we're using it. */
+
+	if (tdb_flags & TDB_CLEAR_IF_FIRST) {
+		/* leave this lock in place to indicate it's in use */
+		if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1)
+			goto fail;
+	}
+
+	/* if needed, run recovery */
+	if (tdb_transaction_recover(tdb) == -1) {
+		goto fail;
+	}
+
+ internal:
+	/* Internal (memory-only) databases skip all the code above to
+	 * do with disk files, and resume here by releasing their
+	 * global lock and hooking into the active list. */
+	if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1) == -1)
+		goto fail;
+	tdb->next = tdbs;
+	tdbs = tdb;
+	return tdb;
+
+ fail:
+	{ int save_errno = errno;
+
+	if (!tdb)
+		return NULL;
+
+	if (tdb->map_ptr) {
+		if (tdb->flags & TDB_INTERNAL)
+			SAFE_FREE(tdb->map_ptr);
+		else
+			tdb_munmap(tdb);
+	}
+	SAFE_FREE(tdb->name);
+	if (tdb->fd != -1)
+		if (close(tdb->fd) != 0)
+			TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n"));
+	SAFE_FREE(tdb);
+	errno = save_errno;
+	return NULL;
+	}
+}
+
+/*
+ * Set the maximum number of dead records per hash chain
+ */
+
+void tdb_set_max_dead(struct tdb_context *tdb, int max_dead)
+{
+	tdb->max_dead_records = max_dead;
+}
+
+/**
+ * Close a database.
+ *
+ * @returns -1 for error; 0 for success.
+ **/
+int tdb_close(struct tdb_context *tdb)
+{
+	struct tdb_context **i;
+	int ret = 0;
+
+	if (tdb->transaction) {
+		tdb_transaction_cancel(tdb);
+	}
+
+	if (tdb->map_ptr) {
+		if (tdb->flags & TDB_INTERNAL)
+			SAFE_FREE(tdb->map_ptr);
+		else
+			tdb_munmap(tdb);
+	}
+	SAFE_FREE(tdb->name);
+	if (tdb->fd != -1)
+		ret = close(tdb->fd);
+	SAFE_FREE(tdb->lockrecs);
+
+	/* Remove from contexts list */
+	for (i = &tdbs; *i; i = &(*i)->next) {
+		if (*i == tdb) {
+			*i = tdb->next;
+			break;
+		}
+	}
+
+	memset(tdb, 0, sizeof(*tdb));
+	SAFE_FREE(tdb);
+
+	return ret;
+}
+
+/* register a loging function */
+void tdb_set_logging_function(struct tdb_context *tdb,
+                              const struct tdb_logging_context *log_ctx)
+{
+        tdb->log = *log_ctx;
+}
+
+void *tdb_get_logging_private(struct tdb_context *tdb)
+{
+	return tdb->log.log_private;
+}
+
+/* reopen a tdb - this can be used after a fork to ensure that we have an independent
+   seek pointer from our parent and to re-establish locks */
+int tdb_reopen(struct tdb_context *tdb)
+{
+	struct stat st;
+
+	if (tdb->flags & TDB_INTERNAL) {
+		return 0; /* Nothing to do. */
+	}
+
+	if (tdb->num_locks != 0 || tdb->global_lock.count) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n"));
+		goto fail;
+	}
+
+	if (tdb->transaction != 0) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n"));
+		goto fail;
+	}
+
+	if (tdb_munmap(tdb) != 0) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
+		goto fail;
+	}
+	if (close(tdb->fd) != 0)
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n"));
+	tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
+	if (tdb->fd == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno)));
+		goto fail;
+	}
+	if ((tdb->flags & TDB_CLEAR_IF_FIRST) &&
+	    (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1)) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n"));
+		goto fail;
+	}
+	if (fstat(tdb->fd, &st) != 0) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno)));
+		goto fail;
+	}
+	if (st.st_ino != tdb->inode || st.st_dev != tdb->device) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n"));
+		goto fail;
+	}
+	tdb_mmap(tdb);
+
+	return 0;
+
+fail:
+	tdb_close(tdb);
+	return -1;
+}
+
+/* reopen all tdb's */
+int tdb_reopen_all(int parent_longlived)
+{
+	struct tdb_context *tdb;
+
+	for (tdb=tdbs; tdb; tdb = tdb->next) {
+		/*
+		 * If the parent is longlived (ie. a
+		 * parent daemon architecture), we know
+		 * it will keep it's active lock on a
+		 * tdb opened with CLEAR_IF_FIRST. Thus
+		 * for child processes we don't have to
+		 * add an active lock. This is essential
+		 * to improve performance on systems that
+		 * keep POSIX locks as a non-scalable data
+		 * structure in the kernel.
+		 */
+		if (parent_longlived) {
+			/* Ensure no clear-if-first. */
+			tdb->flags &= ~TDB_CLEAR_IF_FIRST;
+		}
+
+		if (tdb_reopen(tdb) != 0)
+			return -1;
+	}
+
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdb.h b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdb.h
new file mode 100644
index 0000000..732ef0e
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdb.h
@@ -0,0 +1,213 @@
+#ifndef __TDB_H__
+#define __TDB_H__
+
+/*
+   Unix SMB/CIFS implementation.
+
+   trivial database library
+
+   Copyright (C) Andrew Tridgell 1999-2004
+
+     ** NOTE! The following LGPL license applies to the tdb
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+/* flags to tdb_store() */
+#define TDB_REPLACE 1
+#define TDB_INSERT 2
+#define TDB_MODIFY 3
+
+/* flags for tdb_open() */
+#define TDB_DEFAULT 0 /* just a readability place holder */
+#define TDB_CLEAR_IF_FIRST 1
+#define TDB_INTERNAL 2 /* don't store on disk */
+#define TDB_NOLOCK   4 /* don't do any locking */
+#define TDB_NOMMAP   8 /* don't use mmap */
+#define TDB_CONVERT 16 /* convert endian (internal use) */
+#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */
+#define TDB_NOSYNC   64 /* don't use synchronous transactions */
+#define TDB_SEQNUM   128 /* maintain a sequence number */
+
+#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret)
+
+/* error codes */
+enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,
+		TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT,
+		TDB_ERR_NOEXIST, TDB_ERR_EINVAL, TDB_ERR_RDONLY};
+
+/* debugging uses one of the following levels */
+enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR,
+		      TDB_DEBUG_WARNING, TDB_DEBUG_TRACE};
+
+typedef struct TDB_DATA {
+	unsigned char *dptr;
+	size_t dsize;
+} TDB_DATA;
+
+#ifndef PRINTF_ATTRIBUTE
+#if (__GNUC__ >= 3)
+/** Use gcc attribute to check printf fns.  a1 is the 1-based index of
+ * the parameter containing the format, and a2 the index of the first
+ * argument. Note that some gcc 2.x versions don't handle this
+ * properly **/
+#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
+#else
+#define PRINTF_ATTRIBUTE(a1, a2)
+#endif
+#endif
+
+/* ext2fs tdb renames */
+#define tdb_open ext2fs_tdb_open
+#define tdb_open_ex ext2fs_tdb_open_ex
+#define tdb_set_max_dead ext2fs_tdb_set_max_dead
+#define tdb_reopen ext2fs_tdb_reopen
+#define tdb_reopen_all ext2fs_tdb_reopen_all
+#define tdb_set_logging_function ext2fs_tdb_set_logging_function
+#define tdb_error ext2fs_tdb_error
+#define tdb_errorstr ext2fs_tdb_errorstr
+#define tdb_fetch ext2fs_tdb_fetch
+#define tdb_parse_record ext2fs_tdb_parse_record
+#define tdb_delete ext2fs_tdb_delete
+#define tdb_store ext2fs_tdb_store
+#define tdb_append ext2fs_tdb_append
+#define tdb_close ext2fs_tdb_close
+#define tdb_firstkey ext2fs_tdb_firstkey
+#define tdb_nextkey ext2fs_tdb_nextkey
+#define tdb_traverse ext2fs_tdb_traverse
+#define tdb_traverse_read ext2fs_tdb_traverse_read
+#define tdb_exists ext2fs_tdb_exists
+#define tdb_lockall ext2fs_tdb_lockall
+#define tdb_unlockall ext2fs_tdb_unlockall
+#define tdb_lockall_read ext2fs_tdb_lockall_read
+#define tdb_unlockall_read ext2fs_tdb_unlockall_read
+#define tdb_name ext2fs_tdb_name
+#define tdb_fd ext2fs_tdb_fd
+#define tdb_log_fn ext2fs_tdb_log_fn
+#define tdb_get_logging_private ext2fs_tdb_get_logging_private
+#define tdb_transaction_start ext2fs_tdb_transaction_start
+#define tdb_transaction_commit ext2fs_tdb_transaction_commit
+#define tdb_transaction_cancel ext2fs_tdb_transaction_cancel
+#define tdb_transaction_recover ext2fs_tdb_transaction_recover
+#define tdb_get_seqnum ext2fs_tdb_get_seqnum
+#define tdb_hash_size ext2fs_tdb_hash_size
+#define tdb_map_size ext2fs_tdb_map_size
+#define tdb_get_flags ext2fs_tdb_get_flags
+#define tdb_chainlock ext2fs_tdb_chainlock
+#define tdb_chainunlock ext2fs_tdb_chainunlock
+#define tdb_chainlock_read ext2fs_tdb_chainlock_read
+#define tdb_chainunlock_read ext2fs_tdb_chainunlock_read
+#define tdb_dump_all ext2fs_tdb_dump_all
+#define tdb_printfreelist ext2fs_tdb_printfreelist
+#define tdb_validate_freelist ext2fs_tdb_validate_freelist
+#define tdb_chainlock_mark ext2fs_tdb_chainlock_mark
+#define tdb_chainlock_nonblock ext2fs_tdb_chainlock_nonblock
+#define tdb_chainlock_unmark ext2fs_tdb_chainlock_unmark
+#define tdb_enable_seqnum ext2fs_tdb_enable_seqnum
+#define tdb_increment_seqnum_nonblock ext2fs_tdb_increment_seqnum_nonblock
+#define tdb_lock_nonblock ext2fs_tdb_lock_nonblock
+#define tdb_lockall_mark ext2fs_tdb_lockall_mark
+#define tdb_lockall_nonblock ext2fs_tdb_lockall_nonblock
+#define tdb_lockall_read_nonblock ext2fs_tdb_lockall_read_nonblock
+#define tdb_lockall_unmark ext2fs_tdb_lockall_unmark
+
+/* this is the context structure that is returned from a db open */
+typedef struct tdb_context TDB_CONTEXT;
+
+typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *);
+typedef void (*tdb_log_func)(struct tdb_context *, enum tdb_debug_level, const char *, ...) PRINTF_ATTRIBUTE(3, 4);
+typedef unsigned int (*tdb_hash_func)(TDB_DATA *key);
+
+struct tdb_logging_context {
+        tdb_log_func log_fn;
+        void *log_private;
+};
+
+struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags,
+		      int open_flags, mode_t mode);
+struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
+			 int open_flags, mode_t mode,
+			 const struct tdb_logging_context *log_ctx,
+			 tdb_hash_func hash_fn);
+void tdb_set_max_dead(struct tdb_context *tdb, int max_dead);
+
+int tdb_reopen(struct tdb_context *tdb);
+int tdb_reopen_all(int parent_longlived);
+void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx);
+enum TDB_ERROR tdb_error(struct tdb_context *tdb);
+const char *tdb_errorstr(struct tdb_context *tdb);
+TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key);
+int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key,
+		     int (*parser)(TDB_DATA key, TDB_DATA data,
+				   void *private_data),
+		     void *private_data);
+int tdb_delete(struct tdb_context *tdb, TDB_DATA key);
+int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
+int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf);
+int tdb_close(struct tdb_context *tdb);
+TDB_DATA tdb_firstkey(struct tdb_context *tdb);
+TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key);
+int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *);
+int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *);
+int tdb_exists(struct tdb_context *tdb, TDB_DATA key);
+int tdb_lockall(struct tdb_context *tdb);
+int tdb_lockall_nonblock(struct tdb_context *tdb);
+int tdb_unlockall(struct tdb_context *tdb);
+int tdb_lockall_read(struct tdb_context *tdb);
+int tdb_lockall_read_nonblock(struct tdb_context *tdb);
+int tdb_unlockall_read(struct tdb_context *tdb);
+int tdb_lockall_mark(struct tdb_context *tdb);
+int tdb_lockall_unmark(struct tdb_context *tdb);
+const char *tdb_name(struct tdb_context *tdb);
+int tdb_fd(struct tdb_context *tdb);
+tdb_log_func tdb_log_fn(struct tdb_context *tdb);
+void *tdb_get_logging_private(struct tdb_context *tdb);
+int tdb_transaction_start(struct tdb_context *tdb);
+int tdb_transaction_commit(struct tdb_context *tdb);
+int tdb_transaction_cancel(struct tdb_context *tdb);
+int tdb_transaction_recover(struct tdb_context *tdb);
+int tdb_get_seqnum(struct tdb_context *tdb);
+int tdb_hash_size(struct tdb_context *tdb);
+size_t tdb_map_size(struct tdb_context *tdb);
+int tdb_get_flags(struct tdb_context *tdb);
+void tdb_enable_seqnum(struct tdb_context *tdb);
+void tdb_increment_seqnum_nonblock(struct tdb_context *tdb);
+
+/* Low level locking functions: use with care */
+int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key);
+int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key);
+int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key);
+int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key);
+int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key);
+int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key);
+int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key);
+
+/* Debug functions. Not used in production. */
+void tdb_dump_all(struct tdb_context *tdb);
+int tdb_printfreelist(struct tdb_context *tdb);
+int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* tdb.h */
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdb/build-tdb b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdb/build-tdb
new file mode 100755
index 0000000..1cc18f7
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdb/build-tdb
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# This file creates a stand-alone TDB based on a set of sources from 
+# Samba
+
+#BASE_DIR=/usr/projects/samba/samba-4.0.0tp4/source/lib/tdb
+BASE_DIR=/usr/projects/samba/tdb
+
+rm -rf .pc
+
+FILES="error.c lock.c io.c transaction.c freelist.c \
+	freelistcheck.c traverse.c dump.c tdb.c open.c"
+
+(cd $BASE_DIR/common; svn info ) > .svninfo
+echo "/*" > tdb.c
+grep ^URL .svninfo >> tdb.c
+grep "^Last Changed Rev" .svninfo | sed -e 's/Last Changed //' >> tdb.c
+grep "^Last Changed Date" .svninfo >> tdb.c
+echo "*/" >> tdb.c
+
+cat $BASE_DIR/common/tdb_private.h >> tdb.c
+for i in $FILES; do
+	if [ `tail -n 1 tdb.c | wc -c` -gt 1 ]; then
+		printf "\n" >> tdb.c
+	fi
+	echo "/* file: $i */" >> tdb.c
+	sed -e '1,/#include "tdb_private.h"/d' < $BASE_DIR/common/$i >> tdb.c
+done
+
+cp $BASE_DIR/include/tdb.h .
+cp $BASE_DIR/tools/tdbtool.c .
+
+quilt push -a
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdbtool.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdbtool.c
new file mode 100644
index 0000000..eeac0c8
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tdbtool.c
@@ -0,0 +1,621 @@
+/*
+   Unix SMB/CIFS implementation.
+   Samba database functions
+   Copyright (C) Andrew Tridgell              1999-2000
+   Copyright (C) Paul `Rusty' Russell		   2000
+   Copyright (C) Jeremy Allison			   2000
+   Copyright (C) Andrew Esh                        2001
+
+   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
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "config.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <signal.h>
+#include <stdarg.h>
+
+#include "tdb.h"
+
+static int do_command(void);
+const char *cmdname;
+char *arg1, *arg2;
+size_t arg1len, arg2len;
+int bIterate = 0;
+char *line;
+TDB_DATA iterate_kbuf;
+char cmdline[1024];
+
+enum commands {
+	CMD_CREATE_TDB,
+	CMD_OPEN_TDB,
+	CMD_ERASE,
+	CMD_DUMP,
+	CMD_INSERT,
+	CMD_MOVE,
+	CMD_STORE,
+	CMD_SHOW,
+	CMD_KEYS,
+	CMD_HEXKEYS,
+	CMD_DELETE,
+	CMD_LIST_HASH_FREE,
+	CMD_LIST_FREE,
+	CMD_INFO,
+	CMD_FIRST,
+	CMD_NEXT,
+	CMD_SYSTEM,
+	CMD_QUIT,
+	CMD_HELP
+};
+
+typedef struct {
+	const char *name;
+	enum commands cmd;
+} COMMAND_TABLE;
+
+COMMAND_TABLE cmd_table[] = {
+	{"create",	CMD_CREATE_TDB},
+	{"open",	CMD_OPEN_TDB},
+	{"erase",	CMD_ERASE},
+	{"dump",	CMD_DUMP},
+	{"insert",	CMD_INSERT},
+	{"move",	CMD_MOVE},
+	{"store",	CMD_STORE},
+	{"show",	CMD_SHOW},
+	{"keys",	CMD_KEYS},
+	{"hexkeys",	CMD_HEXKEYS},
+	{"delete",	CMD_DELETE},
+	{"list",	CMD_LIST_HASH_FREE},
+	{"free",	CMD_LIST_FREE},
+	{"info",	CMD_INFO},
+	{"first",	CMD_FIRST},
+	{"1",		CMD_FIRST},
+	{"next",	CMD_NEXT},
+	{"n",		CMD_NEXT},
+	{"quit",	CMD_QUIT},
+	{"q",		CMD_QUIT},
+	{"!",		CMD_SYSTEM},
+	{NULL,		CMD_HELP}
+};
+
+/* a tdb tool for manipulating a tdb database */
+
+static TDB_CONTEXT *tdb;
+
+static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
+static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
+static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
+
+static void print_asc(const char *buf,int len)
+{
+	int i;
+
+	/* We're probably printing ASCII strings so don't try to display
+	   the trailing NULL character. */
+
+	if (buf[len - 1] == 0)
+	        len--;
+
+	for (i=0;i<len;i++)
+		printf("%c",isprint(buf[i])?buf[i]:'.');
+}
+
+static void print_data(const char *buf,int len)
+{
+	int i=0;
+	if (len<=0) return;
+	printf("[%03X] ",i);
+	for (i=0;i<len;) {
+		printf("%02X ",(int)buf[i]);
+		i++;
+		if (i%8 == 0) printf(" ");
+		if (i%16 == 0) {
+			print_asc(&buf[i-16],8); printf(" ");
+			print_asc(&buf[i-8],8); printf("\n");
+			if (i<len) printf("[%03X] ",i);
+		}
+	}
+	if (i%16) {
+		int n;
+
+		n = 16 - (i%16);
+		printf(" ");
+		if (n>8) printf(" ");
+		while (n--) printf("   ");
+
+		n = i%16;
+		if (n > 8) n = 8;
+		print_asc(&buf[i-(i%16)],n); printf(" ");
+		n = (i%16) - n;
+		if (n>0) print_asc(&buf[i-n],n);
+		printf("\n");
+	}
+}
+
+static void help(void)
+{
+	printf("\n"
+"tdbtool: \n"
+"  create    dbname     : create a database\n"
+"  open      dbname     : open an existing database\n"
+"  erase                : erase the database\n"
+"  dump                 : dump the database as strings\n"
+"  keys                 : dump the database keys as strings\n"
+"  hexkeys              : dump the database keys as hex values\n"
+"  info                 : print summary info about the database\n"
+"  insert    key  data  : insert a record\n"
+"  move      key  file  : move a record to a destination tdb\n"
+"  store     key  data  : store a record (replace)\n"
+"  show      key        : show a record by key\n"
+"  delete    key        : delete a record by key\n"
+"  list                 : print the database hash table and freelist\n"
+"  free                 : print the database freelist\n"
+"  ! command            : execute system command\n"
+"  1 | first            : print the first record\n"
+"  n | next             : print the next record\n"
+"  q | quit             : terminate\n"
+"  \\n                   : repeat 'next' command\n"
+"\n");
+}
+
+static void terror(const char *why)
+{
+	printf("%s\n", why);
+}
+
+static void create_tdb(const char *tdbname)
+{
+	if (tdb) tdb_close(tdb);
+	tdb = tdb_open(tdbname, 0, TDB_CLEAR_IF_FIRST,
+		       O_RDWR | O_CREAT | O_TRUNC, 0600);
+	if (!tdb) {
+		printf("Could not create %s: %s\n", tdbname, strerror(errno));
+	}
+}
+
+static void open_tdb(const char *tdbname)
+{
+	if (tdb) tdb_close(tdb);
+	tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600);
+	if (!tdb) {
+		printf("Could not open %s: %s\n", tdbname, strerror(errno));
+	}
+}
+
+static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen)
+{
+	TDB_DATA key, dbuf;
+
+	if ((keyname == NULL) || (keylen == 0)) {
+		terror("need key");
+		return;
+	}
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+	dbuf.dptr = (unsigned char *)data;
+	dbuf.dsize = datalen;
+
+	if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) {
+		terror("insert failed");
+	}
+}
+
+static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen)
+{
+	TDB_DATA key, dbuf;
+
+	if ((keyname == NULL) || (keylen == 0)) {
+		terror("need key");
+		return;
+	}
+
+	if ((data == NULL) || (datalen == 0)) {
+		terror("need data");
+		return;
+	}
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+	dbuf.dptr = (unsigned char *)data;
+	dbuf.dsize = datalen;
+
+	printf("Storing key:\n");
+	print_rec(tdb, key, dbuf, NULL);
+
+	if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
+		terror("store failed");
+	}
+}
+
+static void show_tdb(char *keyname, size_t keylen)
+{
+	TDB_DATA key, dbuf;
+
+	if ((keyname == NULL) || (keylen == 0)) {
+		terror("need key");
+		return;
+	}
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+
+	dbuf = tdb_fetch(tdb, key);
+	if (!dbuf.dptr) {
+	    terror("fetch failed");
+	    return;
+	}
+
+	print_rec(tdb, key, dbuf, NULL);
+
+	free( dbuf.dptr );
+
+	return;
+}
+
+static void delete_tdb(char *keyname, size_t keylen)
+{
+	TDB_DATA key;
+
+	if ((keyname == NULL) || (keylen == 0)) {
+		terror("need key");
+		return;
+	}
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+
+	if (tdb_delete(tdb, key) != 0) {
+		terror("delete failed");
+	}
+}
+
+static void move_rec(char *keyname, size_t keylen, char* tdbname)
+{
+	TDB_DATA key, dbuf;
+	TDB_CONTEXT *dst_tdb;
+
+	if ((keyname == NULL) || (keylen == 0)) {
+		terror("need key");
+		return;
+	}
+
+	if ( !tdbname ) {
+		terror("need destination tdb name");
+		return;
+	}
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+
+	dbuf = tdb_fetch(tdb, key);
+	if (!dbuf.dptr) {
+		terror("fetch failed");
+		return;
+	}
+
+	print_rec(tdb, key, dbuf, NULL);
+
+	dst_tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600);
+	if ( !dst_tdb ) {
+		terror("unable to open destination tdb");
+		return;
+	}
+
+	if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) {
+		terror("failed to move record");
+	}
+	else
+		printf("record moved\n");
+
+	tdb_close( dst_tdb );
+
+	return;
+}
+
+static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+	printf("\nkey %d bytes\n", (int)key.dsize);
+	print_asc((const char *)key.dptr, key.dsize);
+	printf("\ndata %d bytes\n", (int)dbuf.dsize);
+	print_data((const char *)dbuf.dptr, dbuf.dsize);
+	return 0;
+}
+
+static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+	printf("key %d bytes: ", (int)key.dsize);
+	print_asc((const char *)key.dptr, key.dsize);
+	printf("\n");
+	return 0;
+}
+
+static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+	printf("key %d bytes\n", (int)key.dsize);
+	print_data((const char *)key.dptr, key.dsize);
+	printf("\n");
+	return 0;
+}
+
+static int total_bytes;
+
+static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+	total_bytes += dbuf.dsize;
+	return 0;
+}
+
+static void info_tdb(void)
+{
+	int count;
+	total_bytes = 0;
+	if ((count = tdb_traverse(tdb, traverse_fn, NULL)) == -1)
+		printf("Error = %s\n", tdb_errorstr(tdb));
+	else
+		printf("%d records totalling %d bytes\n", count, total_bytes);
+}
+
+static char *tdb_getline(const char *prompt)
+{
+	static char thisline[1024];
+	char *p;
+	fputs(prompt, stdout);
+	thisline[0] = 0;
+	p = fgets(thisline, sizeof(thisline)-1, stdin);
+	if (p) p = strchr(p, '\n');
+	if (p) *p = 0;
+	return p?thisline:NULL;
+}
+
+static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
+                     void *state)
+{
+    return tdb_delete(the_tdb, key);
+}
+
+static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey)
+{
+	TDB_DATA dbuf;
+	*pkey = tdb_firstkey(the_tdb);
+
+	dbuf = tdb_fetch(the_tdb, *pkey);
+	if (!dbuf.dptr) terror("fetch failed");
+	else {
+		print_rec(the_tdb, *pkey, dbuf, NULL);
+	}
+}
+
+static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey)
+{
+	TDB_DATA dbuf;
+	*pkey = tdb_nextkey(the_tdb, *pkey);
+
+	dbuf = tdb_fetch(the_tdb, *pkey);
+	if (!dbuf.dptr)
+		terror("fetch failed");
+	else
+		print_rec(the_tdb, *pkey, dbuf, NULL);
+}
+
+static int do_command(void)
+{
+	COMMAND_TABLE *ctp = cmd_table;
+	enum commands mycmd = CMD_HELP;
+	int cmd_len;
+
+	if (cmdname && strlen(cmdname) == 0) {
+	    mycmd = CMD_NEXT;
+	} else {
+	    while (ctp->name) {
+		cmd_len = strlen(ctp->name);
+		if (strncmp(ctp->name,cmdname,cmd_len) == 0) {
+			mycmd = ctp->cmd;
+			break;
+		}
+		ctp++;
+	    }
+	}
+
+	switch (mycmd) {
+	case CMD_CREATE_TDB:
+            bIterate = 0;
+            create_tdb(arg1);
+	    return 0;
+	case CMD_OPEN_TDB:
+            bIterate = 0;
+            open_tdb(arg1);
+            return 0;
+	case CMD_SYSTEM:
+	    /* Shell command */
+	    system(arg1);
+	    return 0;
+	case CMD_QUIT:
+	    return 1;
+	default:
+	    /* all the rest require a open database */
+	    if (!tdb) {
+		bIterate = 0;
+		terror("database not open");
+		help();
+		return 0;
+	    }
+	    switch (mycmd) {
+	    case CMD_ERASE:
+		bIterate = 0;
+		tdb_traverse(tdb, do_delete_fn, NULL);
+		return 0;
+	    case CMD_DUMP:
+		bIterate = 0;
+		tdb_traverse(tdb, print_rec, NULL);
+		return 0;
+	    case CMD_INSERT:
+		bIterate = 0;
+		insert_tdb(arg1, arg1len,arg2,arg2len);
+		return 0;
+	    case CMD_MOVE:
+		bIterate = 0;
+		move_rec(arg1,arg1len,arg2);
+		return 0;
+	    case CMD_STORE:
+		bIterate = 0;
+		store_tdb(arg1,arg1len,arg2,arg2len);
+		return 0;
+	    case CMD_SHOW:
+		bIterate = 0;
+		show_tdb(arg1, arg1len);
+		return 0;
+	    case CMD_KEYS:
+		tdb_traverse(tdb, print_key, NULL);
+		return 0;
+	    case CMD_HEXKEYS:
+		tdb_traverse(tdb, print_hexkey, NULL);
+		return 0;
+	    case CMD_DELETE:
+		bIterate = 0;
+		delete_tdb(arg1,arg1len);
+		return 0;
+	    case CMD_LIST_HASH_FREE:
+		tdb_dump_all(tdb);
+		return 0;
+	    case CMD_LIST_FREE:
+		tdb_printfreelist(tdb);
+		return 0;
+	    case CMD_INFO:
+		info_tdb();
+		return 0;
+	    case CMD_FIRST:
+		bIterate = 1;
+		first_record(tdb, &iterate_kbuf);
+		return 0;
+	    case CMD_NEXT:
+	       if (bIterate)
+		  next_record(tdb, &iterate_kbuf);
+		return 0;
+	    case CMD_HELP:
+		help();
+		return 0;
+            case CMD_CREATE_TDB:
+            case CMD_OPEN_TDB:
+            case CMD_SYSTEM:
+            case CMD_QUIT:
+                /*
+                 * unhandled commands.  cases included here to avoid compiler
+                 * warnings.
+                 */
+                return 0;
+	    }
+	}
+
+	return 0;
+}
+
+static char *convert_string(char *instring, size_t *sizep)
+{
+    size_t length = 0;
+    char *outp, *inp;
+    char temp[3];
+
+
+    outp = inp = instring;
+
+    while (*inp) {
+	if (*inp == '\\') {
+	    inp++;
+	    if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) {
+		temp[0] = *inp++;
+		temp[1] = '\0';
+		if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) {
+		    temp[1] = *inp++;
+		    temp[2] = '\0';
+		}
+		*outp++ = (char)strtol((const char *)temp,NULL,16);
+	    } else {
+		*outp++ = *inp++;
+	    }
+	} else {
+	    *outp++ = *inp++;
+	}
+	length++;
+    }
+    *sizep = length;
+    return instring;
+}
+
+int main(int argc, char *argv[])
+{
+    cmdname = "";
+    arg1 = NULL;
+    arg1len = 0;
+    arg2 = NULL;
+    arg2len = 0;
+
+    if (argv[1]) {
+	cmdname = "open";
+	arg1 = argv[1];
+        do_command();
+	cmdname =  "";
+	arg1 = NULL;
+    }
+
+    switch (argc) {
+	case 1:
+	case 2:
+	    /* Interactive mode */
+	    while ((cmdname = tdb_getline("tdb> "))) {
+		arg2 = arg1 = NULL;
+		if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) {
+		    arg1++;
+		    arg2 = arg1;
+		    while (*arg2) {
+			if (*arg2 == ' ') {
+			    *arg2++ = '\0';
+			    break;
+			}
+			if ((*arg2++ == '\\') && (*arg2 == ' ')) {
+			    arg2++;
+			}
+		    }
+		}
+		if (arg1) arg1 = convert_string(arg1,&arg1len);
+		if (arg2) arg2 = convert_string(arg2,&arg2len);
+		if (do_command()) break;
+	    }
+	    break;
+	case 5:
+	    arg2 = convert_string(argv[4],&arg2len);
+	case 4:
+	    arg1 = convert_string(argv[3],&arg1len);
+	case 3:
+	    cmdname = argv[2];
+	default:
+	    do_command();
+	    break;
+    }
+
+    if (tdb) tdb_close(tdb);
+
+    return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/test_io.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/test_io.c
new file mode 100644
index 0000000..cac6721
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/test_io.c
@@ -0,0 +1,531 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#if HAVE_SECURE_GETENV
+#define _GNU_SOURCE
+#endif
+#if HAVE_SECURE_GETENV
+#define _GNU_SOURCE
+#endif
+#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);
+	void (*read_blk64)(unsigned long long block, int count, errcode_t err);
+	void (*write_blk64)(unsigned long 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_read_blk64(io_channel channel, unsigned long long block,
+			       int count, void *data);
+static errcode_t test_write_blk64(io_channel channel, unsigned long 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 errcode_t test_get_stats(io_channel channel, io_stats *stats);
+static errcode_t test_discard(io_channel channel, unsigned long long block,
+			      unsigned long long count);
+
+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,
+	test_get_stats,
+	test_read_blk64,
+	test_write_blk64,
+	test_discard,
+};
+
+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_read_blk64)
+	(unsigned long long block, int count, errcode_t err) = 0;
+void (*test_io_cb_write_blk64)
+	(unsigned long 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
+#define TEST_FLAG_DISCARD		0x40
+
+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, 0, 0, 0) == 0)
+		return NULL;
+#else
+#if (defined(linux) && defined(SYS_prctl))
+	if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
+		return NULL;
+#endif
+#endif
+
+#if defined(HAVE_SECURE_GETENV)
+	return secure_getenv(arg);
+#elif defined(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)
+		goto cleanup;
+	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)
+		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->read_blk64 = 	test_io_cb_read_blk64;
+	data->write_blk64 = 	test_io_cb_write_blk64;
+
+	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);
+
+	if (data->real)
+		io->align = data->real->align;
+
+	*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);
+		channel->align = data->real->align;
+	}
+	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_read_blk64(io_channel channel, unsigned long 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_blk64(data->real, block, count, buf);
+	if (data->read_blk64)
+		data->read_blk64(block, count, retval);
+	if (data->flags & TEST_FLAG_READ)
+		fprintf(data->outfile,
+			"Test_io: read_blk64(%llu, %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_blk64(io_channel channel, unsigned long 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_blk64(data->real, block, count, buf);
+	if (data->write_blk64)
+		data->write_blk64(block, count, retval);
+	if (data->flags & TEST_FLAG_WRITE)
+		fprintf(data->outfile,
+			"Test_io: write_blk64(%llu, %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;
+}
+
+static errcode_t test_get_stats(io_channel channel, io_stats *stats)
+{
+	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->get_stats) {
+		retval = (data->real->manager->get_stats)(data->real, stats);
+	}
+	return retval;
+}
+
+static errcode_t test_discard(io_channel channel, unsigned long long block,
+			      unsigned long long count)
+{
+	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_discard(data->real, block, count);
+	if (data->flags & TEST_FLAG_DISCARD)
+		fprintf(data->outfile,
+			"Test_io: discard(%llu, %llu) returned %s\n",
+			block, count, retval ? error_message(retval) : "OK");
+	return retval;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_badblocks.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_badblocks.c
new file mode 100644
index 0000000..3b39ef1
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_badblocks.c
@@ -0,0 +1,360 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 int test_expected_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("%u ", 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 %u 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 %u --- 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 %u --- 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;
+}
+
+static void invalid_proc(ext2_filsys fs, blk_t blk)
+{
+	if (blk == 34500) {
+		printf("Expected invalid block\n");
+		test_expected_fail++;
+	} else {
+		printf("Invalid block #: %u\n", blk);
+		test_fail++;
+	}
+}
+
+int file_test_invalid(badblocks_list bb)
+{
+	badblocks_list new_bb = 0;
+	errcode_t	retval;
+	ext2_filsys 	fs;
+	FILE	*f;
+
+	fs = malloc(sizeof(struct struct_ext2_filsys));
+	memset(fs, 0, sizeof(struct struct_ext2_filsys));
+	fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
+	fs->super = malloc(SUPERBLOCK_SIZE);
+	memset(fs->super, 0, SUPERBLOCK_SIZE);
+	fs->super->s_first_data_block = 1;
+	ext2fs_blocks_count_set(fs->super, 100);
+
+	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;
+	}
+	fprintf(f, "34500\n");
+
+	rewind(f);
+	test_expected_fail = 0;
+	retval = ext2fs_read_bb_FILE(fs, f, &new_bb, invalid_proc);
+	if (retval) {
+		com_err("file_test", retval, "while reading bad blocks");
+		return 1;
+	}
+	fclose(f);
+	if (!test_expected_fail) {
+		printf("Expected test failure didn't happen!\n");
+		test_fail++;
+	}
+
+
+	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;
+
+	add_error_table(&et_ext2_error_table);
+
+	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);
+
+	file_test_invalid(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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps.c
new file mode 100644
index 0000000..57bfd6c
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps.c
@@ -0,0 +1,653 @@
+/*
+ * tst_bitmaps.c
+ *
+ * Copyright (C) 2011 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "ss/ss.h"
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+#include "ext2fsP.h"
+
+extern ss_request_table tst_bitmaps_cmds;
+
+static char subsystem_name[] = "tst_bitmaps";
+static char version[] = "1.0";
+
+ext2_filsys	test_fs;
+int		exit_status = 0;
+
+static int source_file(const char *cmd_file, int sci_idx)
+{
+	FILE		*f;
+	char		buf[256];
+	char		*cp;
+	int		retval;
+	int 		noecho;
+
+	if (strcmp(cmd_file, "-") == 0)
+		f = stdin;
+	else {
+		f = fopen(cmd_file, "r");
+		if (!f) {
+			perror(cmd_file);
+			exit(1);
+		}
+	}
+	fflush(stdout);
+	fflush(stderr);
+	setbuf(stdout, NULL);
+	setbuf(stderr, NULL);
+	while (!feof(f)) {
+		if (fgets(buf, sizeof(buf), f) == NULL)
+			break;
+		if (buf[0] == '#')
+			continue;
+		noecho = 0;
+		if (buf[0] == '-') {
+			noecho = 1;
+			buf[0] = ' ';
+		}
+		cp = strchr(buf, '\n');
+		if (cp)
+			*cp = 0;
+		cp = strchr(buf, '\r');
+		if (cp)
+			*cp = 0;
+		if (!noecho)
+			printf("%s: %s\n", subsystem_name, buf);
+		retval = ss_execute_line(sci_idx, buf);
+		if (retval) {
+			ss_perror(sci_idx, retval, buf);
+			exit_status++;
+		}
+	}
+	return exit_status;
+}
+
+
+/*
+ * This function resets the libc getopt() function, which keeps
+ * internal state.  Bad design!  Stupid libc API designers!  No
+ * biscuit!
+ *
+ * BSD-derived getopt() functions require that optind be reset to 1 in
+ * order to reset getopt() state.  This used to be generally accepted
+ * way of resetting getopt().  However, glibc's getopt()
+ * has additional getopt() state beyond optind, and requires that
+ * optind be set zero to reset its state.  So the unfortunate state of
+ * affairs is that BSD-derived versions of getopt() misbehave if
+ * optind is set to 0 in order to reset getopt(), and glibc's getopt()
+ * will core dump if optind is set 1 in order to reset getopt().
+ *
+ * More modern versions of BSD require that optreset be set to 1 in
+ * order to reset getopt().   Sigh.  Standards, anyone?
+ *
+ * We hide the hair here.
+ */
+void reset_getopt(void)
+{
+#if defined(__GLIBC__) || defined(__linux__)
+	optind = 0;
+#else
+	optind = 1;
+#endif
+#ifdef HAVE_OPTRESET
+	optreset = 1;		/* Makes BSD getopt happy */
+#endif
+}
+
+/*
+ * This function will convert a string to an unsigned long, printing
+ * an error message if it fails, and returning success or failure in err.
+ */
+unsigned long parse_ulong(const char *str, const char *cmd,
+			  const char *descr, int *err)
+{
+	char		*tmp;
+	unsigned long	ret;
+
+	ret = strtoul(str, &tmp, 0);
+	if (*tmp == 0) {
+		if (err)
+			*err = 0;
+		return ret;
+	}
+	com_err(cmd, 0, "Bad %s - %s", descr, str);
+	if (err)
+		*err = 1;
+	else
+		exit(1);
+	return 0;
+}
+
+
+int check_fs_open(char *name)
+{
+	if (!test_fs) {
+		com_err(name, 0, "Filesystem not open");
+		return 1;
+	}
+	return 0;
+}
+
+static void setup_filesystem(const char *name,
+			     unsigned int blocks, unsigned int inodes,
+			     unsigned int type, int flags)
+{
+	struct ext2_super_block param;
+	errcode_t retval;
+
+	memset(&param, 0, sizeof(param));
+	ext2fs_blocks_count_set(&param, blocks);
+	param.s_inodes_count = inodes;
+
+	retval = ext2fs_initialize("test fs", flags, &param,
+				   test_io_manager, &test_fs);
+
+	if (retval) {
+		com_err(name, retval, "while initializing filesystem");
+		return;
+	}
+	test_fs->default_bitmap_type = type;
+	ext2fs_free_block_bitmap(test_fs->block_map);
+	test_fs->block_map = 0;
+	ext2fs_free_inode_bitmap(test_fs->inode_map);
+	test_fs->inode_map = 0;
+	retval = ext2fs_allocate_block_bitmap(test_fs, "block bitmap",
+					      &test_fs->block_map);
+	if (retval) {
+		com_err(name, retval, "while allocating block bitmap");
+		goto errout;
+	}
+	retval = ext2fs_allocate_inode_bitmap(test_fs, "inode bitmap",
+					      &test_fs->inode_map);
+	if (retval) {
+		com_err(name, retval, "while allocating inode bitmap");
+		goto errout;
+	}
+	return;
+
+errout:
+	ext2fs_close(test_fs);
+	test_fs = 0;
+}
+
+void setup_cmd(int argc, char **argv)
+{
+	int		c, err;
+	unsigned int	blocks = 128;
+	unsigned int	inodes = 0;
+	unsigned int	type = EXT2FS_BMAP64_BITARRAY;
+	int		flags = EXT2_FLAG_64BITS;
+
+	if (test_fs) {
+		ext2fs_close(test_fs);
+		test_fs = 0;
+	}
+
+	reset_getopt();
+	while ((c = getopt(argc, argv, "b:i:lt:")) != EOF) {
+		switch (c) {
+		case 'b':
+			blocks = parse_ulong(optarg, argv[0],
+					     "number of blocks", &err);
+			if (err)
+				return;
+			break;
+		case 'i':
+			inodes = parse_ulong(optarg, argv[0],
+					     "number of blocks", &err);
+			if (err)
+				return;
+			break;
+		case 'l':	/* Legacy bitmaps */
+			flags = 0;
+			break;
+		case 't':
+			type = parse_ulong(optarg, argv[0],
+					   "bitmap backend type", &err);
+			if (err)
+				return;
+			break;
+		default:
+			fprintf(stderr, "%s: usage: setup [-b blocks] "
+				"[-i inodes] [-t type]\n", argv[0]);
+			return;
+		}
+	}
+	setup_filesystem(argv[0], blocks, inodes, type, flags);
+}
+
+void close_cmd(int argc, char **argv)
+{
+	if (check_fs_open(argv[0]))
+		return;
+
+	ext2fs_close(test_fs);
+	test_fs = 0;
+}
+
+
+void dump_bitmap(ext2fs_generic_bitmap bmap, unsigned int start, unsigned num)
+{
+	unsigned char	*buf;
+	errcode_t	retval;
+	int		i, len = (num - start + 7) / 8;
+
+	buf = malloc(len);
+	if (!buf) {
+		com_err("dump_bitmap", 0, "couldn't allocate buffer");
+		return;
+	}
+	memset(buf, 0, len);
+	retval = ext2fs_get_generic_bmap_range(bmap, (__u64) start, num, buf);
+	if (retval) {
+		com_err("dump_bitmap", retval, 
+			"while calling ext2fs_generic_bmap_range");
+		free(buf);
+		return;
+	}
+	for (i=0; i < len; i++)
+		printf("%02x", buf[i]);
+	printf("\n");
+	printf("bits set: %u\n", ext2fs_bitcount(buf, len));
+	free(buf);
+}
+
+void dump_inode_bitmap_cmd(int argc, char **argv)
+{
+	if (check_fs_open(argv[0]))
+		return;
+
+	printf("inode bitmap: ");
+	dump_bitmap(test_fs->inode_map, 1, test_fs->super->s_inodes_count);
+}
+	
+void dump_block_bitmap_cmd(int argc, char **argv)
+{
+	if (check_fs_open(argv[0]))
+		return;
+
+	printf("block bitmap: ");
+	dump_bitmap(test_fs->block_map, test_fs->super->s_first_data_block,
+		    test_fs->super->s_blocks_count);
+}
+	
+void do_setb(int argc, char *argv[])
+{
+	unsigned int block, num;
+	int err;
+	int test_result, op_result;
+
+	if (check_fs_open(argv[0]))
+		return;
+
+	if (argc != 2 && argc != 3) {
+		com_err(argv[0], 0, "Usage: setb <block> [num]");
+		return;
+	}
+
+	block = parse_ulong(argv[1], argv[0], "block", &err);
+	if (err)
+		return;
+
+	if (argc == 3) {
+		num = parse_ulong(argv[2], argv[0], "num", &err);
+		if (err)
+			return;
+
+		ext2fs_mark_block_bitmap_range2(test_fs->block_map,
+						block, num);
+		printf("Marking blocks %u to %u\n", block, block + num - 1);
+		return;
+	}
+
+	test_result = ext2fs_test_block_bitmap2(test_fs->block_map, block);
+	op_result = ext2fs_mark_block_bitmap2(test_fs->block_map, block);
+	printf("Setting block %u, was %s before\n", block, op_result ?
+	       "set" : "clear");
+	if (!test_result != !op_result)
+		com_err(argv[0], 0, "*ERROR* test_result different! (%d, %d)",
+			test_result, op_result);
+}
+
+void do_clearb(int argc, char *argv[])
+{
+	unsigned int block, num;
+	int err;
+	int test_result, op_result;
+
+	if (check_fs_open(argv[0]))
+		return;
+
+	if (argc != 2 && argc != 3) {
+		com_err(argv[0], 0, "Usage: clearb <block> [num]");
+		return;
+	}
+
+	block = parse_ulong(argv[1], argv[0], "block", &err);
+	if (err)
+		return;
+
+	if (argc == 3) {
+		num = parse_ulong(argv[2], argv[0], "num", &err);
+		if (err)
+			return;
+
+		ext2fs_unmark_block_bitmap_range2(test_fs->block_map,
+						block, num);
+		printf("Clearing blocks %u to %u\n", block, block + num - 1);
+		return;
+	}
+
+	test_result = ext2fs_test_block_bitmap2(test_fs->block_map, block);
+	op_result = ext2fs_unmark_block_bitmap2(test_fs->block_map, block);
+	printf("Clearing block %u, was %s before\n", block, op_result ?
+	       "set" : "clear");
+	if (!test_result != !op_result)
+		com_err(argv[0], 0, "*ERROR* test_result different! (%d, %d)",
+			test_result, op_result);
+}
+
+void do_testb(int argc, char *argv[])
+{
+	unsigned int block, num;
+	int err;
+	int test_result;
+
+	if (check_fs_open(argv[0]))
+		return;
+
+	if (argc != 2 && argc != 3) {
+		com_err(argv[0], 0, "Usage: testb <block> [num]");
+		return;
+	}
+
+	block = parse_ulong(argv[1], argv[0], "block", &err);
+	if (err)
+		return;
+
+	if (argc == 3) {
+		num = parse_ulong(argv[2], argv[0], "num", &err);
+		if (err)
+			return;
+
+		test_result =
+			ext2fs_test_block_bitmap_range2(test_fs->block_map,
+							block, num);
+		printf("Blocks %u to %u are %sall clear.\n",
+		       block, block + num - 1, test_result ? "" : "NOT ");
+		return;
+	}
+
+	test_result = ext2fs_test_block_bitmap2(test_fs->block_map, block);
+	printf("Block %u is %s\n", block, test_result ? "set" : "clear");
+}
+
+void do_ffzb(int argc, char *argv[])
+{
+	unsigned int start, end;
+	int err;
+	errcode_t retval;
+	blk64_t out;
+
+	if (check_fs_open(argv[0]))
+		return;
+
+	if (argc != 3 && argc != 3) {
+		com_err(argv[0], 0, "Usage: ffzb <start> <end>");
+		return;
+	}
+
+	start = parse_ulong(argv[1], argv[0], "start", &err);
+	if (err)
+		return;
+
+	end = parse_ulong(argv[2], argv[0], "end", &err);
+	if (err)
+		return;
+
+	retval = ext2fs_find_first_zero_block_bitmap2(test_fs->block_map,
+						      start, end, &out);
+	if (retval) {
+		printf("ext2fs_find_first_zero_block_bitmap2() returned %s\n",
+		       error_message(retval));
+		return;
+	}
+	printf("First unmarked block is %llu\n", out);
+}
+
+
+void do_zerob(int argc, char *argv[])
+{
+	if (check_fs_open(argv[0]))
+		return;
+
+	printf("Clearing block bitmap.\n");
+	ext2fs_clear_block_bitmap(test_fs->block_map);
+}
+
+void do_seti(int argc, char *argv[])
+{
+	unsigned int inode;
+	int err;
+	int test_result, op_result;
+
+	if (check_fs_open(argv[0]))
+		return;
+
+	if (argc != 2) {
+		com_err(argv[0], 0, "Usage: seti <inode>");
+		return;
+	}
+
+	inode = parse_ulong(argv[1], argv[0], "inode", &err);
+	if (err)
+		return;
+
+	test_result = ext2fs_test_inode_bitmap2(test_fs->inode_map, inode);
+	op_result = ext2fs_mark_inode_bitmap2(test_fs->inode_map, inode);
+	printf("Setting inode %u, was %s before\n", inode, op_result ?
+	       "set" : "clear");
+	if (!test_result != !op_result) {
+		com_err(argv[0], 0, "*ERROR* test_result different! (%d, %d)",
+			test_result, op_result);
+		exit_status++;
+	}
+}
+
+void do_cleari(int argc, char *argv[])
+{
+	unsigned int inode;
+	int err;
+	int test_result, op_result;
+
+	if (check_fs_open(argv[0]))
+		return;
+
+	if (argc != 2) {
+		com_err(argv[0], 0, "Usage: clearb <inode>");
+		return;
+	}
+
+	inode = parse_ulong(argv[1], argv[0], "inode", &err);
+	if (err)
+		return;
+
+	test_result = ext2fs_test_inode_bitmap2(test_fs->inode_map, inode);
+	op_result = ext2fs_unmark_inode_bitmap2(test_fs->inode_map, inode);
+	printf("Clearing inode %u, was %s before\n", inode, op_result ?
+	       "set" : "clear");
+	if (!test_result != !op_result) {
+		com_err(argv[0], 0, "*ERROR* test_result different! (%d, %d)",
+			test_result, op_result);
+		exit_status++;
+	}
+}
+
+void do_testi(int argc, char *argv[])
+{
+	unsigned int inode;
+	int err;
+	int test_result;
+
+	if (check_fs_open(argv[0]))
+		return;
+
+	if (argc != 2) {
+		com_err(argv[0], 0, "Usage: testb <inode>");
+		return;
+	}
+
+	inode = parse_ulong(argv[1], argv[0], "inode", &err);
+	if (err)
+		return;
+
+	test_result = ext2fs_test_inode_bitmap2(test_fs->inode_map, inode);
+	printf("Inode %u is %s\n", inode, test_result ? "set" : "clear");
+}
+
+void do_ffzi(int argc, char *argv[])
+{
+	unsigned int start, end;
+	int err;
+	errcode_t retval;
+	ext2_ino_t out;
+
+	if (check_fs_open(argv[0]))
+		return;
+
+	if (argc != 3 && argc != 3) {
+		com_err(argv[0], 0, "Usage: ffzi <start> <end>");
+		return;
+	}
+
+	start = parse_ulong(argv[1], argv[0], "start", &err);
+	if (err)
+		return;
+
+	end = parse_ulong(argv[2], argv[0], "end", &err);
+	if (err)
+		return;
+
+	retval = ext2fs_find_first_zero_inode_bitmap2(test_fs->inode_map,
+						      start, end, &out);
+	if (retval) {
+		printf("ext2fs_find_first_zero_inode_bitmap2() returned %s\n",
+		       error_message(retval));
+		return;
+	}
+	printf("First unmarked inode is %u\n", out);
+}
+
+
+void do_zeroi(int argc, char *argv[])
+{
+	if (check_fs_open(argv[0]))
+		return;
+
+	printf("Clearing inode bitmap.\n");
+	ext2fs_clear_inode_bitmap(test_fs->inode_map);
+}
+
+int main(int argc, char **argv)
+{
+	unsigned int	blocks = 128;
+	unsigned int	inodes = 0;
+	unsigned int	type = EXT2FS_BMAP64_BITARRAY;
+	int		c, err, code;
+	char		*request = (char *)NULL;
+	char		*cmd_file = 0;
+	int		sci_idx;
+	int		flags = EXT2_FLAG_64BITS;
+
+	add_error_table(&et_ss_error_table);
+	add_error_table(&et_ext2_error_table);
+	while ((c = getopt (argc, argv, "b:i:lt:R:f:")) != EOF) {
+		switch (c) {
+		case 'b':
+			blocks = parse_ulong(optarg, argv[0],
+					     "number of blocks", &err);
+			if (err)
+				exit(1);
+			break;
+		case 'i':
+			inodes = parse_ulong(optarg, argv[0],
+					     "number of blocks", &err);
+			if (err)
+				exit(1);
+			break;
+		case 'l':	/* Legacy bitmaps */
+			flags = 0;
+			break;
+		case 't':
+			type = parse_ulong(optarg, argv[0],
+					   "bitmap backend type", &err);
+			if (err)
+				exit(1);
+			break;
+		case 'R':
+			request = optarg;
+			break;
+		case 'f':
+			cmd_file = optarg;
+			break;
+		default:
+			com_err(argv[0], 0, "Usage: %s [-R request] "
+				"[-f cmd_file]", subsystem_name);
+			exit(1);
+		}
+	}
+
+	sci_idx = ss_create_invocation(subsystem_name, version,
+				       (char *)NULL, &tst_bitmaps_cmds, &code);
+	if (code) {
+		ss_perror(sci_idx, code, "creating invocation");
+		exit(1);
+	}
+
+	(void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &code);
+	if (code) {
+		ss_perror(sci_idx, code, "adding standard requests");
+		exit (1);
+	}
+
+	printf("%s %s.  Type '?' for a list of commands.\n\n",
+	       subsystem_name, version);
+
+	setup_filesystem(argv[0], blocks, inodes, type, flags);
+
+	if (request) {
+		code = ss_execute_line(sci_idx, request);
+		if (code) {
+			ss_perror(sci_idx, code, request);
+			exit_status++;
+		}
+	} else if (cmd_file) {
+		exit_status = source_file(cmd_file, sci_idx);
+	} else {
+		ss_listen(sci_idx);
+	}
+
+	exit(exit_status);
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_cmd.ct b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_cmd.ct
new file mode 100644
index 0000000..1e1e5d3
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_cmd.ct
@@ -0,0 +1,45 @@
+command_table tst_bitmaps_cmds;
+
+request setup_cmd, "Setup file system",
+	setup;
+
+request close_cmd, "Close file system",
+	close;
+
+request dump_inode_bitmap_cmd, "Dump the inode bitmap",
+	dump_inode_bitmap, dump_ib;
+
+request dump_block_bitmap_cmd, "Dump the block bitmap",
+	dump_block_bitmap, dump_bb;
+
+request do_setb, "Set block",
+	set_block, setb;
+
+request do_clearb, "Clear block",
+	clear_block, clearb;
+
+request do_testb, "Test block",
+	test_block, testb;
+
+request do_ffzb, "Find first zero block",
+	find_first_zero_block, ffzb;
+
+request do_zerob, "Clear block bitmap",
+	clear_block_bitmap, zerob;
+
+request do_seti, "Set inode",
+	set_inode, seti;
+
+request do_cleari, "Clear inode",
+	clear_inode, cleari;
+
+request do_testi, "Test inode",
+	test_inode, testi;
+
+request do_ffzi, "Find first zero inode",
+	find_first_zero_inode, ffzi;
+
+request do_zeroi, "Clear inode bitmap",
+	clear_inode_bitmap, zeroi;
+
+end;
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_cmds b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_cmds
new file mode 100644
index 0000000..31e2a60
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_cmds
@@ -0,0 +1,99 @@
+setb 12
+setb 12
+clearb 12
+clearb 12
+setb 12
+setb 14
+setb 16
+testb 13
+testb 15
+testb 12
+testb 14
+setb 13
+setb 15
+testb 12
+testb 11
+testb 15
+testb 16
+dump_bb
+ffzb 11 16
+ffzb 12 16
+ffzb 12 20
+clearb 13
+ffzb 12 20
+setb 13
+clearb 12 7
+testb 12 7
+setb 15
+testb 12 7
+clearb 15
+testb 12 7
+setb 12 7
+dump_bb
+seti 2
+seti 5
+seti 4
+seti 3
+seti 4
+seti 5
+testi 6
+testi 1
+dump_ib
+ffzi 1 6
+ffzi 2 5
+ffzi 2 6
+cleari 4
+ffzi 2 6
+zeroi
+testi 5
+seti 5
+seti 5
+cleari 5
+cleari 5
+testi 17
+testi 6
+testi 4
+clearb 7 12
+dump_bb
+setb 1
+dump_bb
+setb 2
+dump_bb
+setb 3
+dump_bb
+setb 4
+dump_bb
+setb 5
+dump_bb
+setb 6
+dump_bb
+setb 7
+dump_bb
+setb 8
+dump_bb
+setb 10
+setb 12
+setb 14
+setb 17
+setb 19
+setb 24
+setb 26
+setb 27
+setb 30
+setb 31
+setb 32
+setb 35
+setb 39
+setb 40
+setb 44
+setb 46
+setb 47
+setb 49
+setb 51
+setb 52
+clearb 2
+clearb 3
+clearb 7
+dump_bb
+quit
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_exp b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_exp
new file mode 100644
index 0000000..2d62b66
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_exp
@@ -0,0 +1,211 @@
+tst_bitmaps 1.0.  Type '?' for a list of commands.
+
+tst_bitmaps: setb 12
+Setting block 12, was clear before
+tst_bitmaps: setb 12
+Setting block 12, was set before
+tst_bitmaps: clearb 12
+Clearing block 12, was set before
+tst_bitmaps: clearb 12
+Clearing block 12, was clear before
+tst_bitmaps: setb 12
+Setting block 12, was clear before
+tst_bitmaps: setb 14
+Setting block 14, was clear before
+tst_bitmaps: setb 16
+Setting block 16, was clear before
+tst_bitmaps: testb 13
+Block 13 is clear
+tst_bitmaps: testb 15
+Block 15 is clear
+tst_bitmaps: testb 12
+Block 12 is set
+tst_bitmaps: testb 14
+Block 14 is set
+tst_bitmaps: setb 13
+Setting block 13, was clear before
+tst_bitmaps: setb 15
+Setting block 15, was clear before
+tst_bitmaps: testb 12
+Block 12 is set
+tst_bitmaps: testb 11
+Block 11 is clear
+tst_bitmaps: testb 15
+Block 15 is set
+tst_bitmaps: testb 16
+Block 16 is set
+tst_bitmaps: dump_bb
+block bitmap: 00f80000000000000000000000000000
+bits set: 5
+tst_bitmaps: ffzb 11 16
+First unmarked block is 11
+tst_bitmaps: ffzb 12 16
+ext2fs_find_first_zero_block_bitmap2() returned No such file or directory
+tst_bitmaps: ffzb 12 20
+First unmarked block is 17
+tst_bitmaps: clearb 13
+Clearing block 13, was set before
+tst_bitmaps: ffzb 12 20
+First unmarked block is 13
+tst_bitmaps: setb 13
+Setting block 13, was clear before
+tst_bitmaps: clearb 12 7
+Clearing blocks 12 to 18
+tst_bitmaps: testb 12 7
+Blocks 12 to 18 are all clear.
+tst_bitmaps: setb 15
+Setting block 15, was clear before
+tst_bitmaps: testb 12 7
+Blocks 12 to 18 are NOT all clear.
+tst_bitmaps: clearb 15
+Clearing block 15, was set before
+tst_bitmaps: testb 12 7
+Blocks 12 to 18 are all clear.
+tst_bitmaps: setb 12 7
+Marking blocks 12 to 18
+tst_bitmaps: dump_bb
+block bitmap: 00f80300000000000000000000000000
+bits set: 7
+tst_bitmaps: seti 2
+Setting inode 2, was clear before
+tst_bitmaps: seti 5
+Setting inode 5, was clear before
+tst_bitmaps: seti 4
+Setting inode 4, was clear before
+tst_bitmaps: seti 3
+Setting inode 3, was clear before
+tst_bitmaps: seti 4
+Setting inode 4, was set before
+tst_bitmaps: seti 5
+Setting inode 5, was set before
+tst_bitmaps: testi 6
+Inode 6 is clear
+tst_bitmaps: testi 1
+Inode 1 is clear
+tst_bitmaps: dump_ib
+inode bitmap: 1e000000
+bits set: 4
+tst_bitmaps: ffzi 1 6
+First unmarked inode is 1
+tst_bitmaps: ffzi 2 5
+ext2fs_find_first_zero_inode_bitmap2() returned No such file or directory
+tst_bitmaps: ffzi 2 6
+First unmarked inode is 6
+tst_bitmaps: cleari 4
+Clearing inode 4, was set before
+tst_bitmaps: ffzi 2 6
+First unmarked inode is 4
+tst_bitmaps: zeroi
+Clearing inode bitmap.
+tst_bitmaps: testi 5
+Inode 5 is clear
+tst_bitmaps: seti 5
+Setting inode 5, was clear before
+tst_bitmaps: seti 5
+Setting inode 5, was set before
+tst_bitmaps: cleari 5
+Clearing inode 5, was set before
+tst_bitmaps: cleari 5
+Clearing inode 5, was clear before
+tst_bitmaps: testi 17
+Inode 17 is clear
+tst_bitmaps: testi 6
+Inode 6 is clear
+tst_bitmaps: testi 4
+Inode 4 is clear
+tst_bitmaps: clearb 7 12
+Clearing blocks 7 to 18
+tst_bitmaps: dump_bb
+block bitmap: 00000000000000000000000000000000
+bits set: 0
+tst_bitmaps: setb 1
+Setting block 1, was clear before
+tst_bitmaps: dump_bb
+block bitmap: 01000000000000000000000000000000
+bits set: 1
+tst_bitmaps: setb 2
+Setting block 2, was clear before
+tst_bitmaps: dump_bb
+block bitmap: 03000000000000000000000000000000
+bits set: 2
+tst_bitmaps: setb 3
+Setting block 3, was clear before
+tst_bitmaps: dump_bb
+block bitmap: 07000000000000000000000000000000
+bits set: 3
+tst_bitmaps: setb 4
+Setting block 4, was clear before
+tst_bitmaps: dump_bb
+block bitmap: 0f000000000000000000000000000000
+bits set: 4
+tst_bitmaps: setb 5
+Setting block 5, was clear before
+tst_bitmaps: dump_bb
+block bitmap: 1f000000000000000000000000000000
+bits set: 5
+tst_bitmaps: setb 6
+Setting block 6, was clear before
+tst_bitmaps: dump_bb
+block bitmap: 3f000000000000000000000000000000
+bits set: 6
+tst_bitmaps: setb 7
+Setting block 7, was clear before
+tst_bitmaps: dump_bb
+block bitmap: 7f000000000000000000000000000000
+bits set: 7
+tst_bitmaps: setb 8
+Setting block 8, was clear before
+tst_bitmaps: dump_bb
+block bitmap: ff000000000000000000000000000000
+bits set: 8
+tst_bitmaps: setb 10
+Setting block 10, was clear before
+tst_bitmaps: setb 12
+Setting block 12, was clear before
+tst_bitmaps: setb 14
+Setting block 14, was clear before
+tst_bitmaps: setb 17
+Setting block 17, was clear before
+tst_bitmaps: setb 19
+Setting block 19, was clear before
+tst_bitmaps: setb 24
+Setting block 24, was clear before
+tst_bitmaps: setb 26
+Setting block 26, was clear before
+tst_bitmaps: setb 27
+Setting block 27, was clear before
+tst_bitmaps: setb 30
+Setting block 30, was clear before
+tst_bitmaps: setb 31
+Setting block 31, was clear before
+tst_bitmaps: setb 32
+Setting block 32, was clear before
+tst_bitmaps: setb 35
+Setting block 35, was clear before
+tst_bitmaps: setb 39
+Setting block 39, was clear before
+tst_bitmaps: setb 40
+Setting block 40, was clear before
+tst_bitmaps: setb 44
+Setting block 44, was clear before
+tst_bitmaps: setb 46
+Setting block 46, was clear before
+tst_bitmaps: setb 47
+Setting block 47, was clear before
+tst_bitmaps: setb 49
+Setting block 49, was clear before
+tst_bitmaps: setb 51
+Setting block 51, was clear before
+tst_bitmaps: setb 52
+Setting block 52, was clear before
+tst_bitmaps: clearb 2
+Clearing block 2, was set before
+tst_bitmaps: clearb 3
+Clearing block 3, was set before
+tst_bitmaps: clearb 7
+Clearing block 7, was set before
+tst_bitmaps: dump_bb
+block bitmap: b92a85e6c4680d000000000000000000
+bits set: 25
+tst_bitmaps: quit
+tst_bitmaps: 
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitops.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitops.c
new file mode 100644
index 0000000..ed71447
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_bitops.c
@@ -0,0 +1,294 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 <sys/time.h>
+#include <sys/resource.h>
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+unsigned char bitarray[] = {
+	0x80, 0xF0, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0, 0x10, 0x20, 0x00, 0x00
+	};
+
+int bits_list[] = {
+	7, 12, 13, 14,15, 22, 30, 68, 77, -1,
+};
+
+#define BIG_TEST_BIT   (((unsigned) 1 << 31) + 42)
+
+
+int main(int argc, char **argv)
+{
+	int	i, j, size;
+	unsigned char testarray[12];
+	unsigned char *bigarray;
+
+	size = sizeof(bitarray)*8;
+#if 0
+	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);
+	}
+#endif
+
+	/* Test test_bit */
+	for (i=0,j=0; i < size; i++) {
+		if (ext2fs_test_bit(i, bitarray)) {
+			if (bits_list[j] == i) {
+				j++;
+			} else {
+				printf("Bit %d set, not expected\n", i);
+				exit(1);
+			}
+		} else {
+			if (bits_list[j] == i) {
+				printf("Expected bit %d to be clear.\n", i);
+				exit(1);
+			}
+		}
+	}
+	printf("ext2fs_test_bit appears to be correct\n");
+
+	/* Test ext2fs_set_bit */
+	memset(testarray, 0, sizeof(testarray));
+	for (i=0; bits_list[i] > 0; i++) {
+		ext2fs_set_bit(bits_list[i], testarray);
+	}
+	if (memcmp(testarray, bitarray, sizeof(testarray)) == 0) {
+		printf("ext2fs_set_bit test succeeded.\n");
+	} else {
+		printf("ext2fs_set_bit test failed.\n");
+		for (i=0; i < sizeof(testarray); i++) {
+			printf("%02x ", testarray[i]);
+		}
+		printf("\n");
+		exit(1);
+	}
+	for (i=0; bits_list[i] > 0; i++) {
+		ext2fs_clear_bit(bits_list[i], testarray);
+	}
+	for (i=0; i < sizeof(testarray); i++) {
+		if (testarray[i]) {
+			printf("ext2fs_clear_bit failed, "
+			       "testarray[%d] is %d\n", i, testarray[i]);
+			exit(1);
+		}
+	}
+	printf("ext2fs_clear_bit test succeed.\n");
+
+
+	/* Do bigarray test */
+	bigarray = malloc(1 << 29);
+	if (!bigarray) {
+		fprintf(stderr, "Failed to allocate scratch memory!\n");
+		exit(1);
+	}
+
+        bigarray[BIG_TEST_BIT >> 3] = 0;
+
+	ext2fs_set_bit(BIG_TEST_BIT, bigarray);
+	printf("big bit number (%u) test: %d, expected %d\n", BIG_TEST_BIT,
+	       bigarray[BIG_TEST_BIT >> 3], (1 << (BIG_TEST_BIT & 7)));
+	if (bigarray[BIG_TEST_BIT >> 3] != (1 << (BIG_TEST_BIT & 7)))
+		exit(1);
+
+	ext2fs_clear_bit(BIG_TEST_BIT, bigarray);
+
+	printf("big bit number (%u) test: %d, expected 0\n", BIG_TEST_BIT,
+	       bigarray[BIG_TEST_BIT >> 3]);
+	if (bigarray[BIG_TEST_BIT >> 3] != 0)
+		exit(1);
+
+	printf("ext2fs_set_bit big_test successful\n");
+
+
+	/* Now test ext2fs_fast_set_bit */
+	memset(testarray, 0, sizeof(testarray));
+	for (i=0; bits_list[i] > 0; i++) {
+		ext2fs_fast_set_bit(bits_list[i], testarray);
+	}
+	if (memcmp(testarray, bitarray, sizeof(testarray)) == 0) {
+		printf("ext2fs_fast_set_bit test succeeded.\n");
+	} else {
+		printf("ext2fs_fast_set_bit test failed.\n");
+		for (i=0; i < sizeof(testarray); i++) {
+			printf("%02x ", testarray[i]);
+		}
+		printf("\n");
+		exit(1);
+	}
+	for (i=0; bits_list[i] > 0; i++) {
+		ext2fs_clear_bit(bits_list[i], testarray);
+	}
+	for (i=0; i < sizeof(testarray); i++) {
+		if (testarray[i]) {
+			printf("ext2fs_clear_bit failed, "
+			       "testarray[%d] is %d\n", i, testarray[i]);
+			exit(1);
+		}
+	}
+	printf("ext2fs_clear_bit test succeed.\n");
+
+
+        bigarray[BIG_TEST_BIT >> 3] = 0;
+
+	ext2fs_fast_set_bit(BIG_TEST_BIT, bigarray);
+	printf("big bit number (%u) test: %d, expected %d\n", BIG_TEST_BIT,
+	       bigarray[BIG_TEST_BIT >> 3], (1 << (BIG_TEST_BIT & 7)));
+	if (bigarray[BIG_TEST_BIT >> 3] != (1 << (BIG_TEST_BIT & 7)))
+		exit(1);
+
+	ext2fs_fast_clear_bit(BIG_TEST_BIT, bigarray);
+
+	printf("big bit number (%u) test: %d, expected 0\n", BIG_TEST_BIT,
+	       bigarray[BIG_TEST_BIT >> 3]);
+	if (bigarray[BIG_TEST_BIT >> 3] != 0)
+		exit(1);
+
+	printf("ext2fs_fast_set_bit big_test successful\n");
+
+	/* Repeat foregoing tests for 64-bit bitops */
+
+	/* Test test_bit */
+	for (i=0,j=0; i < size; i++) {
+		if (ext2fs_test_bit64(i, bitarray)) {
+			if (bits_list[j] == i) {
+				j++;
+			} else {
+				printf("64-bit: Bit %d set, not expected\n",
+				       i);
+				exit(1);
+			}
+		} else {
+			if (bits_list[j] == i) {
+				printf("64-bit: "
+				       "Expected bit %d to be clear.\n", i);
+				exit(1);
+			}
+		}
+	}
+	printf("64-bit: ext2fs_test_bit appears to be correct\n");
+
+	/* Test ext2fs_set_bit */
+	memset(testarray, 0, sizeof(testarray));
+	for (i=0; bits_list[i] > 0; i++) {
+		ext2fs_set_bit64(bits_list[i], testarray);
+	}
+	if (memcmp(testarray, bitarray, sizeof(testarray)) == 0) {
+		printf("64-bit: ext2fs_set_bit test succeeded.\n");
+	} else {
+		printf("64-bit: ext2fs_set_bit test failed.\n");
+		for (i=0; i < sizeof(testarray); i++) {
+			printf("%02x ", testarray[i]);
+		}
+		printf("\n");
+		exit(1);
+	}
+	for (i=0; bits_list[i] > 0; i++) {
+		ext2fs_clear_bit64(bits_list[i], testarray);
+	}
+	for (i=0; i < sizeof(testarray); i++) {
+		if (testarray[i]) {
+			printf("64-bit: ext2fs_clear_bit failed, "
+			       "testarray[%d] is %d\n", i, testarray[i]);
+			exit(1);
+		}
+	}
+	printf("64-bit: ext2fs_clear_bit test succeed.\n");
+
+	/* Do bigarray test */
+	bigarray = malloc(1 << 29);
+	if (!bigarray) {
+		fprintf(stderr, "Failed to allocate scratch memory!\n");
+		exit(1);
+	}
+
+        bigarray[BIG_TEST_BIT >> 3] = 0;
+
+	ext2fs_set_bit64(BIG_TEST_BIT, bigarray);
+	printf("64-bit: big bit number (%u) test: %d, expected %d\n",
+	       BIG_TEST_BIT, bigarray[BIG_TEST_BIT >> 3],
+	       (1 << (BIG_TEST_BIT & 7)));
+	if (bigarray[BIG_TEST_BIT >> 3] != (1 << (BIG_TEST_BIT & 7)))
+		exit(1);
+
+	ext2fs_clear_bit64(BIG_TEST_BIT, bigarray);
+
+	printf("64-bit: big bit number (%u) test: %d, expected 0\n",
+	       BIG_TEST_BIT,
+	       bigarray[BIG_TEST_BIT >> 3]);
+	if (bigarray[BIG_TEST_BIT >> 3] != 0)
+		exit(1);
+
+	printf("64-bit: ext2fs_set_bit big_test successful\n");
+
+	/* Now test ext2fs_fast_set_bit */
+	memset(testarray, 0, sizeof(testarray));
+	for (i=0; bits_list[i] > 0; i++) {
+		ext2fs_fast_set_bit64(bits_list[i], testarray);
+	}
+	if (memcmp(testarray, bitarray, sizeof(testarray)) == 0) {
+		printf("64-bit: ext2fs_fast_set_bit test succeeded.\n");
+	} else {
+		printf("64-bit: ext2fs_fast_set_bit test failed.\n");
+		for (i=0; i < sizeof(testarray); i++) {
+			printf("%02x ", testarray[i]);
+		}
+		printf("\n");
+		exit(1);
+	}
+	for (i=0; bits_list[i] > 0; i++) {
+		ext2fs_clear_bit64(bits_list[i], testarray);
+	}
+	for (i=0; i < sizeof(testarray); i++) {
+		if (testarray[i]) {
+			printf("64-bit: ext2fs_clear_bit failed, "
+			       "testarray[%d] is %d\n", i, testarray[i]);
+			exit(1);
+		}
+	}
+	printf("64-bit: ext2fs_clear_bit test succeed.\n");
+
+        bigarray[BIG_TEST_BIT >> 3] = 0;
+
+	ext2fs_fast_set_bit64(BIG_TEST_BIT, bigarray);
+	printf("64-bit: big bit number (%u) test: %d, expected %d\n",
+	       BIG_TEST_BIT, bigarray[BIG_TEST_BIT >> 3],
+	       (1 << (BIG_TEST_BIT & 7)));
+	if (bigarray[BIG_TEST_BIT >> 3] != (1 << (BIG_TEST_BIT & 7)))
+		exit(1);
+
+	ext2fs_fast_clear_bit64(BIG_TEST_BIT, bigarray);
+
+	printf("64-bit: big bit number (%u) test: %d, expected 0\n",
+	       BIG_TEST_BIT, bigarray[BIG_TEST_BIT >> 3]);
+	if (bigarray[BIG_TEST_BIT >> 3] != 0)
+		exit(1);
+
+	printf("64-bit: ext2fs_fast_set_bit big_test successful\n");
+
+	exit(0);
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_byteswap.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_byteswap.c
new file mode 100644
index 0000000..c500cae
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_byteswap.c
@@ -0,0 +1,93 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_fs_struct.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_fs_struct.c
new file mode 100644
index 0000000..6f44df1
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_fs_struct.c
@@ -0,0 +1,81 @@
+/*
+ * This testing program checks the offset of the ext2_filsys structure
+ *
+ * Copyright (C) 2007 by Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "ext2fs.h"
+
+struct struct_ext2_filsys fs;
+
+#ifndef offsetof
+#define offsetof(type, member)  __builtin_offsetof (type, member)
+#endif
+#define check_field(x) cur_offset = do_field(#x, sizeof(fs.x),		\
+					offsetof(struct struct_ext2_filsys, x), \
+					cur_offset)
+
+static int do_field(const char *field, size_t size, int offset, int cur_offset)
+{
+	if (offset != cur_offset) {
+		printf("\t(padding %d bytes?)\n", offset - cur_offset);
+	}
+	printf("%8d %-30s %3u\n", offset, field, (unsigned) size);
+	return offset + size;
+}
+
+int main(int argc, char **argv)
+{
+#if (__GNUC__ >= 4)
+	int cur_offset = 0;
+
+	printf("%8s %-30s %3s\n", "offset", "field", "size");
+	check_field(magic);
+	check_field(io);
+	check_field(flags);
+	check_field(device_name);
+	check_field(super);
+	check_field(blocksize);
+	check_field(fragsize);
+	check_field(group_desc_count);
+	check_field(desc_blocks);
+	check_field(group_desc);
+	check_field(inode_blocks_per_group);
+	check_field(inode_map);
+	check_field(block_map);
+	check_field(get_blocks);
+	check_field(check_directory);
+	check_field(write_bitmaps);
+	check_field(read_inode);
+	check_field(write_inode);
+	check_field(badblocks);
+	check_field(dblist);
+	check_field(stride);
+	check_field(orig_super);
+	check_field(image_header);
+	check_field(umask);
+	check_field(now);
+	check_field(cluster_ratio_bits);
+	check_field(reserved);
+	check_field(priv_data);
+	check_field(icache);
+	check_field(image_io);
+	check_field(get_alloc_block);
+	check_field(block_alloc_stats);
+	check_field(mmp_buf);
+	check_field(mmp_cmp);
+	check_field(mmp_fd);
+	check_field(mmp_last_written);
+	printf("Ending offset is %d\n\n", cur_offset);
+#endif
+	exit(0);
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_getsectsize.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_getsectsize.c
new file mode 100644
index 0000000..a6b234e
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_getsectsize.c
@@ -0,0 +1,54 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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	lsectsize, psectsize;
+	int	retval;
+
+	if (argc < 2) {
+		fprintf(stderr, "Usage: %s device\n", argv[0]);
+		exit(1);
+	}
+
+	retval = ext2fs_get_device_sectsize(argv[1], &lsectsize);
+	if (retval) {
+		com_err(argv[0], retval,
+			"while calling ext2fs_get_device_sectsize");
+		exit(1);
+	}
+	retval = ext2fs_get_device_phys_sectsize(argv[1], &psectsize);
+	if (retval) {
+		com_err(argv[0], retval,
+			"while calling ext2fs_get_device_phys_sectsize");
+		exit(1);
+	}
+	printf("Device %s has logical/physical sector size of %d/%d.\n",
+	       argv[1], lsectsize, psectsize);
+	exit(0);
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_getsize.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_getsize.c
new file mode 100644
index 0000000..4ac2ea1
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_getsize.c
@@ -0,0 +1,46 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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);
+	}
+	add_error_table(&et_ext2_error_table);
+	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 %u blocks.\n", argv[1], blocks);
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_inode_size.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_inode_size.c
new file mode 100644
index 0000000..e20ec98
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_inode_size.c
@@ -0,0 +1,88 @@
+/*
+ * This testing program makes sure the ext2_inode structure is 1024 bytes long
+ *
+ * Copyright (C) 2007 by Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "ext2_fs.h"
+
+struct ext2_inode_large inode;
+
+#ifndef offsetof
+#define offsetof(type, member)  __builtin_offsetof(type, member)
+#endif
+
+#define check_field(x, s) cur_offset = do_field(#x, s, sizeof(inode.x),	       \
+					offsetof(struct ext2_inode_large, x),  \
+					cur_offset)
+
+static int do_field(const char *field, unsigned size, unsigned cur_size,
+		    unsigned offset, unsigned cur_offset)
+{
+	if (size != cur_size) {
+		printf("error: %s size %u should be %u\n",
+		       field, cur_size, size);
+		exit(1);
+	}
+	if (offset != cur_offset) {
+		printf("error: %s offset %u should be %u\n",
+		       field, cur_offset, offset);
+		exit(1);
+	}
+	printf("%8d %-30s %3u\n", offset, field, (unsigned) size);
+	return offset + size;
+}
+
+int main(int argc, char **argv)
+{
+#if (__GNUC__ >= 4)
+	int cur_offset = 0;
+
+	printf("%8s %-30s %3s\n", "offset", "field", "size");
+	check_field(i_mode, 2);
+	check_field(i_uid, 2);
+	check_field(i_size, 4);
+	check_field(i_atime, 4);
+	check_field(i_ctime, 4);
+	check_field(i_mtime, 4);
+	check_field(i_dtime, 4);
+	check_field(i_gid, 2);
+	check_field(i_links_count, 2);
+	check_field(i_blocks, 4);
+	check_field(i_flags, 4);
+	check_field(osd1.linux1.l_i_version, 4);
+	check_field(i_block, 15 * 4);
+	check_field(i_generation, 4);
+	check_field(i_file_acl, 4);
+	check_field(i_size_high, 4);
+	check_field(i_faddr, 4);
+	check_field(osd2.linux2.l_i_blocks_hi, 2);
+	check_field(osd2.linux2.l_i_file_acl_high, 2);
+	check_field(osd2.linux2.l_i_uid_high, 2);
+	check_field(osd2.linux2.l_i_gid_high, 2);
+	check_field(osd2.linux2.l_i_checksum_lo, 2);
+	check_field(osd2.linux2.l_i_reserved, 2);
+	do_field("Small inode end", 0, 0, cur_offset, 128);
+	check_field(i_extra_isize, 2);
+	check_field(i_checksum_hi, 2);
+	check_field(i_ctime_extra, 4);
+	check_field(i_mtime_extra, 4);
+	check_field(i_atime_extra, 4);
+	check_field(i_crtime, 4);
+	check_field(i_crtime_extra, 4);
+	check_field(i_version_hi, 4);
+	/* This size will change as new fields are added */
+	do_field("Large inode end", 0, 0, cur_offset, sizeof(inode));
+#endif
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_iscan.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_iscan.c
new file mode 100644
index 0000000..70bfbec
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_iscan.c
@@ -0,0 +1,225 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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"
+
+blk64_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 iscan_test_read_blk64(unsigned long long block, int count, errcode_t err)
+{
+	int	i;
+
+	if (first_no_comma)
+		first_no_comma = 0;
+	else
+		printf(", ");
+
+	if (count > 1)
+		printf("%llu-%llu", block, block+count-1);
+	else
+		printf("%llu", block);
+
+	for (i=0; i < count; i++, block++) {
+		if (ext2fs_test_block_bitmap2(touched_map, block)) {
+			printf("\nDuplicate block?!? --- %llu\n", block);
+			failed++;
+			first_no_comma = 1;
+		}
+		ext2fs_mark_block_bitmap2(touched_map, block);
+	}
+}
+
+static void iscan_test_read_blk(unsigned long block, int count, errcode_t err)
+{
+	iscan_test_read_blk64(block, count, err);
+}
+
+/*
+ * 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));
+	ext2fs_blocks_count_set(&param, 12000);
+
+
+	test_io_cb_read_blk = iscan_test_read_blk;
+	test_io_cb_read_blk64 = iscan_test_read_blk64;
+
+	retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, &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_bitmap2(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_bitmap2(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;
+	blk64_t	blk;
+
+	for (i=0; test_vec[i]; i++) {
+		if (ext2fs_test_block_bitmap2(touched_map, test_vec[i])) {
+			printf("Bad block was touched --- %llu\n", test_vec[i]);
+			failed++;
+			first_no_comma = 1;
+		}
+		ext2fs_mark_block_bitmap2(touched_map, test_vec[i]);
+	}
+	for (i = 0; i < test_fs->group_desc_count; i++) {
+		for (j=0, blk = ext2fs_inode_table_loc(test_fs, i);
+		     j < test_fs->inode_blocks_per_group;
+		     j++, blk++) {
+			if (!ext2fs_test_block_bitmap2(touched_map, blk) &&
+			    !ext2fs_test_block_bitmap2(bad_block_map, blk)) {
+				printf("Missing block --- %llu\n", blk);
+				failed++;
+			}
+		}
+	}
+	printf("Bad inodes: ");
+	for (i=1; i <= test_fs->super->s_inodes_count; i++) {
+		if (ext2fs_test_inode_bitmap2(bad_inode_map, i)) {
+			if (first)
+				first = 0;
+			else
+				printf(", ");
+			printf("%u", i);
+		}
+	}
+	printf("\n");
+}
+
+
+int main(int argc, char **argv)
+{
+	setup();
+	iterate();
+	check_map();
+	if (!failed)
+		printf("Inode scan tested OK!\n");
+	return failed;
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_super_size.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_super_size.c
new file mode 100644
index 0000000..85d87e1
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_super_size.c
@@ -0,0 +1,143 @@
+/*
+ * This testing program makes sure superblock size is 1024 bytes long
+ *
+ * Copyright (C) 2007 by Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "ext2_fs.h"
+
+#define sb_struct ext2_super_block
+#define sb_struct_name "ext2_super_block"
+
+struct sb_struct sb;
+
+#ifndef offsetof
+#define offsetof(type, member)  __builtin_offsetof (type, member)
+#endif
+
+#define check_field(x, s) cur_offset = do_field(#x, s, sizeof(sb.x),	       \
+						offsetof(struct sb_struct, x), \
+						cur_offset)
+
+static int do_field(const char *field, unsigned size, unsigned cur_size,
+		    unsigned offset, unsigned cur_offset)
+{
+	if (size != cur_size) {
+		printf("error: %s size %u should be %u\n",
+		       field, cur_size, size);
+		exit(1);
+	}
+	if (offset != cur_offset) {
+		printf("error: %s offset %u should be %u\n",
+		       field, cur_offset, offset);
+		exit(1);
+	}
+	printf("%8d %-30s %3u\n", offset, field, size);
+	return offset + size;
+}
+
+int main(int argc, char **argv)
+{
+#if (__GNUC__ >= 4)
+	int cur_offset = 0;
+
+	printf("%8s %-30s %3s\n", "offset", "field", "size");
+	check_field(s_inodes_count, 4);
+	check_field(s_blocks_count, 4);
+	check_field(s_r_blocks_count, 4);
+	check_field(s_free_blocks_count, 4);
+	check_field(s_free_inodes_count, 4);
+	check_field(s_first_data_block, 4);
+	check_field(s_log_block_size, 4);
+	check_field(s_log_cluster_size, 4);
+	check_field(s_blocks_per_group, 4);
+	check_field(s_clusters_per_group, 4);
+	check_field(s_inodes_per_group, 4);
+	check_field(s_mtime, 4);
+	check_field(s_wtime, 4);
+	check_field(s_mnt_count, 2);
+	check_field(s_max_mnt_count, 2);
+	check_field(s_magic, 2);
+	check_field(s_state, 2);
+	check_field(s_errors, 2);
+	check_field(s_minor_rev_level, 2);
+	check_field(s_lastcheck, 4);
+	check_field(s_checkinterval, 4);
+	check_field(s_creator_os, 4);
+	check_field(s_rev_level, 4);
+	check_field(s_def_resuid, 2);
+	check_field(s_def_resgid, 2);
+	check_field(s_first_ino, 4);
+	check_field(s_inode_size, 2);
+	check_field(s_block_group_nr, 2);
+	check_field(s_feature_compat, 4);
+	check_field(s_feature_incompat, 4);
+	check_field(s_feature_ro_compat, 4);
+	check_field(s_uuid, 16);
+	check_field(s_volume_name, 16);
+	check_field(s_last_mounted, 64);
+	check_field(s_algorithm_usage_bitmap, 4);
+	check_field(s_prealloc_blocks, 1);
+	check_field(s_prealloc_dir_blocks, 1);
+	check_field(s_reserved_gdt_blocks, 2);
+	check_field(s_journal_uuid, 16);
+	check_field(s_journal_inum, 4);
+	check_field(s_journal_dev, 4);
+	check_field(s_last_orphan, 4);
+	check_field(s_hash_seed, 4 * 4);
+	check_field(s_def_hash_version, 1);
+	check_field(s_jnl_backup_type, 1);
+	check_field(s_desc_size, 2);
+	check_field(s_default_mount_opts, 4);
+	check_field(s_first_meta_bg, 4);
+	check_field(s_mkfs_time, 4);
+	check_field(s_jnl_blocks, 17 * 4);
+	check_field(s_blocks_count_hi, 4);
+	check_field(s_r_blocks_count_hi, 4);
+	check_field(s_free_blocks_hi, 4);
+	check_field(s_min_extra_isize, 2);
+	check_field(s_want_extra_isize, 2);
+	check_field(s_flags, 4);
+	check_field(s_raid_stride, 2);
+	check_field(s_mmp_update_interval, 2);
+	check_field(s_mmp_block, 8);
+	check_field(s_raid_stripe_width, 4);
+	check_field(s_log_groups_per_flex, 1);
+	check_field(s_reserved_char_pad, 1);
+	check_field(s_reserved_pad, 2);
+	check_field(s_kbytes_written, 8);
+	check_field(s_snapshot_inum, 4);
+	check_field(s_snapshot_id, 4);
+	check_field(s_snapshot_r_blocks_count, 8);
+	check_field(s_snapshot_list, 4);
+	check_field(s_error_count, 4);
+	check_field(s_first_error_time, 4);
+	check_field(s_first_error_ino, 4);
+	check_field(s_first_error_block, 8);
+	check_field(s_first_error_func, 32);
+	check_field(s_first_error_line, 4);
+	check_field(s_last_error_time, 4);
+	check_field(s_last_error_ino, 4);
+	check_field(s_last_error_line, 4);
+	check_field(s_last_error_block, 8);
+	check_field(s_last_error_func, 32);
+	check_field(s_mount_opts, 64);
+	check_field(s_usr_quota_inum, 4);
+	check_field(s_grp_quota_inum, 4);
+	check_field(s_overhead_blocks, 4);
+	check_field(s_reserved, 108 * 4);
+	check_field(s_checksum, 4);
+	do_field("Superblock end", 0, 0, cur_offset, 1024);
+#endif
+	return 0;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_types.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_types.c
new file mode 100644
index 0000000..3e41128
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/tst_types.c
@@ -0,0 +1,64 @@
+/*
+ * This testing program makes sure the ext2_types header file
+ *
+ * Copyright (C) 2006 by Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "ext2fs/ext2_types.h"
+
+int main(int argc, char **argv)
+{
+	if (sizeof(__u8) != 1) {
+		printf("Sizeof(__u8) is %d should be 1\n",
+		       (int)sizeof(__u8));
+		exit(1);
+	}
+	if (sizeof(__s8) != 1) {
+		printf("Sizeof(_s8) is %d should be 1\n",
+		       (int)sizeof(__s8));
+		exit(1);
+	}
+	if (sizeof(__u16) != 2) {
+		printf("Sizeof(__u16) is %d should be 2\n",
+		       (int)sizeof(__u16));
+		exit(1);
+	}
+	if (sizeof(__s16) != 2) {
+		printf("Sizeof(__s16) is %d should be 2\n",
+		       (int)sizeof(__s16));
+		exit(1);
+	}
+	if (sizeof(__u32) != 4) {
+		printf("Sizeof(__u32) is %d should be 4\n",
+		       (int)sizeof(__u32));
+		exit(1);
+	}
+	if (sizeof(__s32) != 4) {
+		printf("Sizeof(__s32) is %d should be 4\n",
+		       (int)sizeof(__s32));
+		exit(1);
+	}
+	if (sizeof(__u64) != 8) {
+		printf("Sizeof(__u64) is %d should be 8\n",
+		       (int)sizeof(__u64));
+		exit(1);
+	}
+	if (sizeof(__s64) != 8) {
+		printf("Sizeof(__s64) is %d should be 8\n",
+		       (int)sizeof(__s64));
+		exit(1);
+	}
+	printf("The ext2_types.h types are correct.\n");
+	exit(0);
+}
+
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/undo_io.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/undo_io.c
new file mode 100644
index 0000000..56b0eeb
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/undo_io.c
@@ -0,0 +1,623 @@
+/*
+ * undo_io.c --- This is the undo io manager that copies the old data that
+ * copies the old data being overwritten into a tdb database
+ *
+ * Copyright IBM Corporation, 2007
+ * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+#include "config.h"
+#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 "tdb.h"
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+#ifdef __GNUC__
+#define ATTR(x) __attribute__(x)
+#else
+#define ATTR(x)
+#endif
+
+/*
+ * For checking structure magic numbers...
+ */
+
+#define EXT2_CHECK_MAGIC(struct, code) \
+	  if ((struct)->magic != (code)) return (code)
+
+struct undo_private_data {
+	int	magic;
+	TDB_CONTEXT *tdb;
+	char *tdb_file;
+
+	/* The backing io channel */
+	io_channel real;
+
+	int tdb_data_size;
+	int tdb_written;
+
+	/* to support offset in unix I/O manager */
+	ext2_loff_t offset;
+};
+
+static errcode_t undo_open(const char *name, int flags, io_channel *channel);
+static errcode_t undo_close(io_channel channel);
+static errcode_t undo_set_blksize(io_channel channel, int blksize);
+static errcode_t undo_read_blk64(io_channel channel, unsigned long long block,
+				 int count, void *data);
+static errcode_t undo_write_blk64(io_channel channel, unsigned long long block,
+				  int count, const void *data);
+static errcode_t undo_read_blk(io_channel channel, unsigned long block,
+			       int count, void *data);
+static errcode_t undo_write_blk(io_channel channel, unsigned long block,
+				int count, const void *data);
+static errcode_t undo_flush(io_channel channel);
+static errcode_t undo_write_byte(io_channel channel, unsigned long offset,
+				int size, const void *data);
+static errcode_t undo_set_option(io_channel channel, const char *option,
+				 const char *arg);
+static errcode_t undo_get_stats(io_channel channel, io_stats *stats);
+
+static struct struct_io_manager struct_undo_manager = {
+	EXT2_ET_MAGIC_IO_MANAGER,
+	"Undo I/O Manager",
+	undo_open,
+	undo_close,
+	undo_set_blksize,
+	undo_read_blk,
+	undo_write_blk,
+	undo_flush,
+	undo_write_byte,
+	undo_set_option,
+	undo_get_stats,
+	undo_read_blk64,
+	undo_write_blk64,
+};
+
+io_manager undo_io_manager = &struct_undo_manager;
+static io_manager undo_io_backing_manager ;
+static char *tdb_file;
+static int actual_size;
+
+static unsigned char mtime_key[] = "filesystem MTIME";
+static unsigned char blksize_key[] = "filesystem BLKSIZE";
+static unsigned char uuid_key[] = "filesystem UUID";
+
+errcode_t set_undo_io_backing_manager(io_manager manager)
+{
+	/*
+	 * We may want to do some validation later
+	 */
+	undo_io_backing_manager = manager;
+	return 0;
+}
+
+errcode_t set_undo_io_backup_file(char *file_name)
+{
+	tdb_file = strdup(file_name);
+
+	if (tdb_file == NULL) {
+		return EXT2_ET_NO_MEMORY;
+	}
+
+	return 0;
+}
+
+static errcode_t write_file_system_identity(io_channel undo_channel,
+							TDB_CONTEXT *tdb)
+{
+	errcode_t retval;
+	struct ext2_super_block super;
+	TDB_DATA tdb_key, tdb_data;
+	struct undo_private_data *data;
+	io_channel channel;
+	int block_size ;
+
+	data = (struct undo_private_data *) undo_channel->private_data;
+	channel = data->real;
+	block_size = channel->block_size;
+
+	io_channel_set_blksize(channel, SUPERBLOCK_OFFSET);
+	retval = io_channel_read_blk64(channel, 1, -SUPERBLOCK_SIZE, &super);
+	if (retval)
+		goto err_out;
+
+	/* Write to tdb file in the file system byte order */
+	tdb_key.dptr = mtime_key;
+	tdb_key.dsize = sizeof(mtime_key);
+	tdb_data.dptr = (unsigned char *) &(super.s_mtime);
+	tdb_data.dsize = sizeof(super.s_mtime);
+
+	retval = tdb_store(tdb, tdb_key, tdb_data, TDB_INSERT);
+	if (retval == -1) {
+		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
+		goto err_out;
+	}
+
+	tdb_key.dptr = uuid_key;
+	tdb_key.dsize = sizeof(uuid_key);
+	tdb_data.dptr = (unsigned char *)&(super.s_uuid);
+	tdb_data.dsize = sizeof(super.s_uuid);
+
+	retval = tdb_store(tdb, tdb_key, tdb_data, TDB_INSERT);
+	if (retval == -1) {
+		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
+	}
+
+err_out:
+	io_channel_set_blksize(channel, block_size);
+	return retval;
+}
+
+static errcode_t write_block_size(TDB_CONTEXT *tdb, int block_size)
+{
+	errcode_t retval;
+	TDB_DATA tdb_key, tdb_data;
+
+	tdb_key.dptr = blksize_key;
+	tdb_key.dsize = sizeof(blksize_key);
+	tdb_data.dptr = (unsigned char *)&(block_size);
+	tdb_data.dsize = sizeof(block_size);
+
+	retval = tdb_store(tdb, tdb_key, tdb_data, TDB_INSERT);
+	if (retval == -1) {
+		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
+	}
+
+	return retval;
+}
+
+static errcode_t undo_write_tdb(io_channel channel,
+				unsigned long long block, int count)
+
+{
+	int size, sz;
+	unsigned long long block_num, backing_blk_num;
+	errcode_t retval = 0;
+	ext2_loff_t offset;
+	struct undo_private_data *data;
+	TDB_DATA tdb_key, tdb_data;
+	unsigned char *read_ptr;
+	unsigned long long end_block;
+
+	data = (struct undo_private_data *) channel->private_data;
+
+	if (data->tdb == NULL) {
+		/*
+		 * Transaction database not initialized
+		 */
+		return 0;
+	}
+
+	if (count == 1)
+		size = channel->block_size;
+	else {
+		if (count < 0)
+			size = -count;
+		else
+			size = count * channel->block_size;
+	}
+	/*
+	 * Data is stored in tdb database as blocks of tdb_data_size size
+	 * This helps in efficient lookup further.
+	 *
+	 * We divide the disk to blocks of tdb_data_size.
+	 */
+	offset = (block * channel->block_size) + data->offset ;
+	block_num = offset / data->tdb_data_size;
+	end_block = (offset + size) / data->tdb_data_size;
+
+	tdb_transaction_start(data->tdb);
+	while (block_num <= end_block ) {
+
+		tdb_key.dptr = (unsigned char *)&block_num;
+		tdb_key.dsize = sizeof(block_num);
+		/*
+		 * Check if we have the record already
+		 */
+		if (tdb_exists(data->tdb, tdb_key)) {
+			/* Try the next block */
+			block_num++;
+			continue;
+		}
+		/*
+		 * Read one block using the backing I/O manager
+		 * The backing I/O manager block size may be
+		 * different from the tdb_data_size.
+		 * Also we need to recalcuate the block number with respect
+		 * to the backing I/O manager.
+		 */
+		offset = block_num * data->tdb_data_size;
+		backing_blk_num = (offset - data->offset) / channel->block_size;
+
+		count = data->tdb_data_size +
+				((offset - data->offset) % channel->block_size);
+		retval = ext2fs_get_mem(count, &read_ptr);
+		if (retval) {
+			tdb_transaction_cancel(data->tdb);
+			return retval;
+		}
+
+		memset(read_ptr, 0, count);
+		actual_size = 0;
+		if ((count % channel->block_size) == 0)
+			sz = count / channel->block_size;
+		else
+			sz = -count;
+		retval = io_channel_read_blk64(data->real, backing_blk_num,
+					     sz, read_ptr);
+		if (retval) {
+			if (retval != EXT2_ET_SHORT_READ) {
+				free(read_ptr);
+				tdb_transaction_cancel(data->tdb);
+				return retval;
+			}
+			/*
+			 * short read so update the record size
+			 * accordingly
+			 */
+			tdb_data.dsize = actual_size;
+		} else {
+			tdb_data.dsize = data->tdb_data_size;
+		}
+		tdb_data.dptr = read_ptr +
+				((offset - data->offset) % channel->block_size);
+#ifdef DEBUG
+		printf("Printing with key %lld data %x and size %d\n",
+		       block_num,
+		       tdb_data.dptr,
+		       tdb_data.dsize);
+#endif
+		if (!data->tdb_written) {
+			data->tdb_written = 1;
+			/* Write the blocksize to tdb file */
+			retval = write_block_size(data->tdb,
+						  data->tdb_data_size);
+			if (retval) {
+				tdb_transaction_cancel(data->tdb);
+				retval = EXT2_ET_TDB_ERR_IO;
+				free(read_ptr);
+				return retval;
+			}
+		}
+		retval = tdb_store(data->tdb, tdb_key, tdb_data, TDB_INSERT);
+		if (retval == -1) {
+			/*
+			 * TDB_ERR_EXISTS cannot happen because we
+			 * have already verified it doesn't exist
+			 */
+			tdb_transaction_cancel(data->tdb);
+			retval = EXT2_ET_TDB_ERR_IO;
+			free(read_ptr);
+			return retval;
+		}
+		free(read_ptr);
+		/* Next block */
+		block_num++;
+	}
+	tdb_transaction_commit(data->tdb);
+
+	return retval;
+}
+
+static errcode_t undo_io_read_error(io_channel channel ATTR((unused)),
+				    unsigned long block ATTR((unused)),
+				    int count ATTR((unused)),
+				    void *data ATTR((unused)),
+				    size_t size ATTR((unused)),
+				    int actual,
+				    errcode_t error ATTR((unused)))
+{
+	actual_size = actual;
+	return error;
+}
+
+static void undo_err_handler_init(io_channel channel)
+{
+	channel->read_error = undo_io_read_error;
+}
+
+static errcode_t undo_open(const char *name, int flags, io_channel *channel)
+{
+	io_channel	io = NULL;
+	struct undo_private_data *data = NULL;
+	errcode_t	retval;
+
+	if (name == 0)
+		return EXT2_ET_BAD_DEVICE_NAME;
+	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;
+	retval = ext2fs_get_mem(sizeof(struct undo_private_data), &data);
+	if (retval)
+		goto cleanup;
+
+	io->manager = undo_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 undo_private_data));
+	data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL;
+
+	if (undo_io_backing_manager) {
+		retval = undo_io_backing_manager->open(name, flags,
+						       &data->real);
+		if (retval)
+			goto cleanup;
+	} else {
+		data->real = 0;
+	}
+
+	/* setup the tdb file */
+	data->tdb = tdb_open(tdb_file, 0, TDB_CLEAR_IF_FIRST,
+			     O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600);
+	if (!data->tdb) {
+		retval = errno;
+		goto cleanup;
+	}
+
+	/*
+	 * setup err handler for read so that we know
+	 * when the backing manager fails do short read
+	 */
+	if (data->real)
+		undo_err_handler_init(data->real);
+
+	*channel = io;
+	return 0;
+
+cleanup:
+	if (data && data->real)
+		io_channel_close(data->real);
+	if (data)
+		ext2fs_free_mem(&data);
+	if (io)
+		ext2fs_free_mem(&io);
+	return retval;
+}
+
+static errcode_t undo_close(io_channel channel)
+{
+	struct undo_private_data *data;
+	errcode_t	retval = 0;
+
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+	data = (struct undo_private_data *) channel->private_data;
+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+
+	if (--channel->refcount > 0)
+		return 0;
+	/* Before closing write the file system identity */
+	retval = write_file_system_identity(channel, data->tdb);
+	if (retval)
+		return retval;
+	if (data->real)
+		retval = io_channel_close(data->real);
+	if (data->tdb)
+		tdb_close(data->tdb);
+	ext2fs_free_mem(&channel->private_data);
+	if (channel->name)
+		ext2fs_free_mem(&channel->name);
+	ext2fs_free_mem(&channel);
+
+	return retval;
+}
+
+static errcode_t undo_set_blksize(io_channel channel, int blksize)
+{
+	struct undo_private_data *data;
+	errcode_t		retval = 0;
+
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+	data = (struct undo_private_data *) channel->private_data;
+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+
+	if (data->real)
+		retval = io_channel_set_blksize(data->real, blksize);
+	/*
+	 * Set the block size used for tdb
+	 */
+	if (!data->tdb_data_size) {
+		data->tdb_data_size = blksize;
+	}
+	channel->block_size = blksize;
+	return retval;
+}
+
+static errcode_t undo_read_blk64(io_channel channel, unsigned long long block,
+			       int count, void *buf)
+{
+	errcode_t	retval = 0;
+	struct undo_private_data *data;
+
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+	data = (struct undo_private_data *) channel->private_data;
+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+
+	if (data->real)
+		retval = io_channel_read_blk64(data->real, block, count, buf);
+
+	return retval;
+}
+
+static errcode_t undo_read_blk(io_channel channel, unsigned long block,
+			       int count, void *buf)
+{
+	return undo_read_blk64(channel, block, count, buf);
+}
+
+static errcode_t undo_write_blk64(io_channel channel, unsigned long long block,
+				int count, const void *buf)
+{
+	struct undo_private_data *data;
+	errcode_t	retval = 0;
+
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+	data = (struct undo_private_data *) channel->private_data;
+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+	/*
+	 * First write the existing content into database
+	 */
+	retval = undo_write_tdb(channel, block, count);
+	if (retval)
+		 return retval;
+	if (data->real)
+		retval = io_channel_write_blk64(data->real, block, count, buf);
+
+	return retval;
+}
+
+static errcode_t undo_write_blk(io_channel channel, unsigned long block,
+				int count, const void *buf)
+{
+	return undo_write_blk64(channel, block, count, buf);
+}
+
+static errcode_t undo_write_byte(io_channel channel, unsigned long offset,
+				 int size, const void *buf)
+{
+	struct undo_private_data *data;
+	errcode_t	retval = 0;
+	ext2_loff_t	location;
+	unsigned long blk_num, count;;
+
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+	data = (struct undo_private_data *) channel->private_data;
+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+
+	location = offset + data->offset;
+	blk_num = location/channel->block_size;
+	/*
+	 * the size specified may spread across multiple blocks
+	 * also make sure we account for the fact that block start
+	 * offset for tdb is different from the backing I/O manager
+	 * due to possible different block size
+	 */
+	count = (size + (location % channel->block_size) +
+			channel->block_size  -1)/channel->block_size;
+	retval = undo_write_tdb(channel, blk_num, count);
+	if (retval)
+		return retval;
+	if (data->real && data->real->manager->write_byte)
+		retval = io_channel_write_byte(data->real, offset, size, buf);
+
+	return retval;
+}
+
+/*
+ * Flush data buffers to disk.
+ */
+static errcode_t undo_flush(io_channel channel)
+{
+	errcode_t	retval = 0;
+	struct undo_private_data *data;
+
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+	data = (struct undo_private_data *) channel->private_data;
+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+
+	if (data->real)
+		retval = io_channel_flush(data->real);
+
+	return retval;
+}
+
+static errcode_t undo_set_option(io_channel channel, const char *option,
+				 const char *arg)
+{
+	errcode_t	retval = 0;
+	struct undo_private_data *data;
+	unsigned long tmp;
+	char *end;
+
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+	data = (struct undo_private_data *) channel->private_data;
+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+
+	if (!strcmp(option, "tdb_data_size")) {
+		if (!arg)
+			return EXT2_ET_INVALID_ARGUMENT;
+
+		tmp = strtoul(arg, &end, 0);
+		if (*end)
+			return EXT2_ET_INVALID_ARGUMENT;
+		if (!data->tdb_data_size || !data->tdb_written) {
+			data->tdb_data_size = tmp;
+		}
+		return 0;
+	}
+	/*
+	 * Need to support offset option to work with
+	 * Unix I/O manager
+	 */
+	if (data->real && data->real->manager->set_option) {
+		retval = data->real->manager->set_option(data->real,
+							option, arg);
+	}
+	if (!retval && !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 retval;
+}
+
+static errcode_t undo_get_stats(io_channel channel, io_stats *stats)
+{
+	errcode_t	retval = 0;
+	struct undo_private_data *data;
+
+	EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+	data = (struct undo_private_data *) channel->private_data;
+	EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
+
+	if (data->real)
+		retval = (data->real->manager->get_stats)(data->real, stats);
+
+	return retval;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/unix_io.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/unix_io.c
new file mode 100644
index 0000000..19be630
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/unix_io.c
@@ -0,0 +1,965 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include "config.h"
+#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
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.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
+#if HAVE_LINUX_FALLOC_H
+#include <linux/falloc.h>
+#endif
+
+#if defined(__linux__) && defined(_IO) && !defined(BLKROGET)
+#define BLKROGET   _IO(0x12, 94) /* Get read-only status (0 = read_write).  */
+#endif
+
+#undef ALIGN_DEBUG
+
+#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 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	align;
+	int	access_time;
+	ext2_loff_t offset;
+	struct unix_cache cache[CACHE_SIZE];
+	void	*bounce;
+	struct struct_io_stats io_stats;
+};
+
+#define IS_ALIGNED(n, align) ((((unsigned long) n) & \
+			       ((unsigned long) ((align)-1))) == 0)
+
+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 errcode_t unix_get_stats(io_channel channel, io_stats *stats)
+;
+static void reuse_cache(io_channel channel, struct unix_private_data *data,
+		 struct unix_cache *cache, unsigned long long block);
+static errcode_t unix_read_blk64(io_channel channel, unsigned long long block,
+			       int count, void *data);
+static errcode_t unix_write_blk64(io_channel channel, unsigned long long block,
+				int count, const void *data);
+static errcode_t unix_discard(io_channel channel, unsigned long long block,
+			      unsigned long long count);
+
+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,
+	unix_write_byte,
+	unix_set_option,
+	unix_get_stats,
+	unix_read_blk64,
+	unix_write_blk64,
+	unix_discard,
+};
+
+io_manager unix_io_manager = &struct_unix_manager;
+
+static errcode_t unix_get_stats(io_channel channel, io_stats *stats)
+{
+	errcode_t 	retval = 0;
+
+	struct unix_private_data *data;
+
+	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 (stats)
+		*stats = &data->io_stats;
+
+	return retval;
+}
+
+/*
+ * Here are the raw I/O functions
+ */
+static errcode_t raw_read_blk(io_channel channel,
+			      struct unix_private_data *data,
+			      unsigned long long block,
+			      int count, void *bufv)
+{
+	errcode_t	retval;
+	ssize_t		size;
+	ext2_loff_t	location;
+	int		actual = 0;
+	unsigned char	*buf = bufv;
+
+	size = (count < 0) ? -count : count * channel->block_size;
+	data->io_stats.bytes_read += 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;
+	}
+	if ((channel->align == 0) ||
+	    (IS_ALIGNED(buf, channel->align) &&
+	     IS_ALIGNED(size, channel->align))) {
+		actual = read(data->dev, buf, size);
+		if (actual != size) {
+		short_read:
+			if (actual < 0)
+				actual = 0;
+			retval = EXT2_ET_SHORT_READ;
+			goto error_out;
+		}
+		return 0;
+	}
+
+#ifdef ALIGN_DEBUG
+	printf("raw_read_blk: O_DIRECT fallback: %p %lu\n", buf,
+	       (unsigned long) size);
+#endif
+
+	/*
+	 * The buffer or size which we're trying to read isn't aligned
+	 * to the O_DIRECT rules, so we need to do this the hard way...
+	 */
+	while (size > 0) {
+		actual = read(data->dev, data->bounce, channel->block_size);
+		if (actual != channel->block_size)
+			goto short_read;
+		actual = size;
+		if (size > channel->block_size)
+			actual = channel->block_size;
+		memcpy(buf, data->bounce, actual);
+		size -= actual;
+		buf += actual;
+	}
+	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;
+}
+
+static errcode_t raw_write_blk(io_channel channel,
+			       struct unix_private_data *data,
+			       unsigned long long block,
+			       int count, const void *bufv)
+{
+	ssize_t		size;
+	ext2_loff_t	location;
+	int		actual = 0;
+	errcode_t	retval;
+	const unsigned char *buf = bufv;
+
+	if (count == 1)
+		size = channel->block_size;
+	else {
+		if (count < 0)
+			size = -count;
+		else
+			size = count * channel->block_size;
+	}
+	data->io_stats.bytes_written += 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;
+	}
+
+	if ((channel->align == 0) ||
+	    (IS_ALIGNED(buf, channel->align) &&
+	     IS_ALIGNED(size, channel->align))) {
+		actual = write(data->dev, buf, size);
+		if (actual != size) {
+		short_write:
+			retval = EXT2_ET_SHORT_WRITE;
+			goto error_out;
+		}
+		return 0;
+	}
+
+#ifdef ALIGN_DEBUG
+	printf("raw_write_blk: O_DIRECT fallback: %p %lu\n", buf,
+	       (unsigned long) size);
+#endif
+	/*
+	 * The buffer or size which we're trying to write isn't aligned
+	 * to the O_DIRECT rules, so we need to do this the hard way...
+	 */
+	while (size > 0) {
+		if (size < channel->block_size) {
+			actual = read(data->dev, data->bounce,
+				      channel->block_size);
+			if (actual != channel->block_size) {
+				retval = EXT2_ET_SHORT_READ;
+				goto error_out;
+			}
+		}
+		actual = size;
+		if (size > channel->block_size)
+			actual = channel->block_size;
+		memcpy(data->bounce, buf, actual);
+		actual = write(data->dev, data->bounce, channel->block_size);
+		if (actual != channel->block_size)
+			goto short_write;
+		size -= actual;
+		buf += actual;
+	}
+	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 (cache->buf)
+			ext2fs_free_mem(&cache->buf);
+		retval = io_channel_alloc_buf(channel, 0, &cache->buf);
+		if (retval)
+			return retval;
+	}
+	if (channel->align) {
+		if (data->bounce)
+			ext2fs_free_mem(&data->bounce);
+		retval = io_channel_alloc_buf(channel, 0, &data->bounce);
+	}
+	return retval;
+}
+
+/* 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);
+	}
+	if (data->bounce)
+		ext2fs_free_mem(&data->bounce);
+}
+
+#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 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 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 */
+
+#ifdef __linux__
+#ifndef BLKDISCARDZEROES
+#define BLKDISCARDZEROES _IO(0x12,124)
+#endif
+#endif
+
+int ext2fs_open_file(const char *pathname, int flags, mode_t mode)
+{
+	if (mode)
+#if defined(HAVE_OPEN64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
+		return open64(pathname, flags, mode);
+	else
+		return open64(pathname, flags);
+#else
+		return open(pathname, flags, mode);
+	else
+		return open(pathname, flags);
+#endif
+}
+
+int ext2fs_stat(const char *path, ext2fs_struct_stat *buf)
+{
+#if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
+	return stat64(path, buf);
+#else
+	return stat(path, buf);
+#endif
+}
+
+int ext2fs_fstat(int fd, ext2fs_struct_stat *buf)
+{
+#if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
+	return fstat64(fd, buf);
+#else
+	return fstat(fd, buf);
+#endif
+}
+
+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;
+	int		f_nocache = 0;
+	ext2fs_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)
+		goto cleanup;
+	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;
+	data->io_stats.num_fields = 2;
+	data->dev = -1;
+
+	open_flags = (flags & IO_FLAG_RW) ? O_RDWR : O_RDONLY;
+	if (flags & IO_FLAG_EXCLUSIVE)
+		open_flags |= O_EXCL;
+#if defined(O_DIRECT)
+	if (flags & IO_FLAG_DIRECT_IO) {
+		open_flags |= O_DIRECT;
+		io->align = ext2fs_get_dio_alignment(data->dev);
+	}
+#elif defined(F_NOCACHE)
+	if (flags & IO_FLAG_DIRECT_IO) {
+		f_nocache = F_NOCACHE;
+		io->align = 4096;
+	}
+#endif
+	data->flags = flags;
+
+	data->dev = ext2fs_open_file(io->name, open_flags, 0);
+	if (data->dev < 0) {
+		retval = errno;
+		goto cleanup;
+	}
+	if (f_nocache) {
+		if (fcntl(data->dev, f_nocache, 1) < 0) {
+			retval = errno;
+			goto cleanup;
+		}
+	}
+
+	/*
+	 * If the device is really a block device, then set the
+	 * appropriate flag, otherwise we can set DISCARD_ZEROES flag
+	 * because we are going to use punch hole instead of discard
+	 * and if it succeed, subsequent read from sparse area returns
+	 * zero.
+	 */
+	if (ext2fs_stat(io->name, &st) == 0) {
+		if (S_ISBLK(st.st_mode))
+			io->flags |= CHANNEL_FLAGS_BLOCK_DEVICE;
+		else
+			io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES;
+	}
+
+#ifdef BLKDISCARDZEROES
+	{
+		int zeroes = 0;
+		if (ioctl(data->dev, BLKDISCARDZEROES, &zeroes) == 0 &&
+		    zeroes)
+			io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES;
+	}
+#endif
+
+#if defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+	/*
+	 * Some operating systems require that the buffers be aligned,
+	 * regardless of O_DIRECT
+	 */
+	if (!io->align)
+		io->align = 512;
+#endif
+
+
+	if ((retval = alloc_cache(io, data)))
+		goto cleanup;
+
+#ifdef BLKROGET
+	if (flags & IO_FLAG_RW) {
+		int error;
+		int readonly = 0;
+
+		/* Is the block device actually writable? */
+		error = ioctl(data->dev, BLKROGET, &readonly);
+		if (!error && readonly) {
+			retval = EPERM;
+			goto cleanup;
+		}
+	}
+#endif
+
+#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')) &&
+	    (ext2fs_stat(io->name, &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) {
+		if (data->dev >= 0)
+			close(data->dev);
+		free_cache(data);
+		ext2fs_free_mem(&data);
+	}
+	if (io) {
+		if (io->name) {
+			ext2fs_free_mem(&io->name);
+		}
+		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_blk64(io_channel channel, unsigned long 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 %lu\n", block);
+#endif
+			memcpy(cp, cache->buf, channel->block_size);
+			count--;
+			block++;
+			cp += channel->block_size;
+			continue;
+		}
+		if (count == 1) {
+			/*
+			 * Special case where we read directly into the
+			 * cache buffer; important in the O_DIRECT case
+			 */
+			cache = reuse[0];
+			reuse_cache(channel, data, cache, block);
+			if ((retval = raw_read_blk(channel, data, block, 1,
+						   cache->buf))) {
+				cache->in_use = 0;
+				return retval;
+			}
+			memcpy(cp, cache->buf, channel->block_size);
+			return 0;
+		}
+
+		/*
+		 * 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 %lu\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_read_blk(io_channel channel, unsigned long block,
+			       int count, void *buf)
+{
+	return unix_read_blk64(channel, block, count, buf);
+}
+
+static errcode_t unix_write_blk64(io_channel channel, unsigned long 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_blk(io_channel channel, unsigned long block,
+				int count, const void *buf)
+{
+	return unix_write_blk64(channel, block, count, buf);
+}
+
+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);
+
+	if (channel->align != 0) {
+#ifdef ALIGN_DEBUG
+		printf("unix_write_byte: O_DIRECT fallback\n");
+#endif
+		return EXT2_ET_UNIMPLEMENTED;
+	}
+
+#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 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 = strtoull(arg, &end, 0);
+		if (*end)
+			return EXT2_ET_INVALID_ARGUMENT;
+		data->offset = tmp;
+		if (data->offset < 0)
+			return EXT2_ET_INVALID_ARGUMENT;
+		return 0;
+	}
+	return EXT2_ET_INVALID_ARGUMENT;
+}
+
+#if defined(__linux__) && !defined(BLKDISCARD)
+#define BLKDISCARD		_IO(0x12,119)
+#endif
+
+static errcode_t unix_discard(io_channel channel, unsigned long long block,
+			      unsigned long long count)
+{
+	struct unix_private_data *data;
+	int		ret;
+
+	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->flags & CHANNEL_FLAGS_BLOCK_DEVICE) {
+#ifdef BLKDISCARD
+		__uint64_t range[2];
+
+		range[0] = (__uint64_t)(block) * channel->block_size;
+		range[1] = (__uint64_t)(count) * channel->block_size;
+
+		ret = ioctl(data->dev, BLKDISCARD, &range);
+#else
+		goto unimplemented;
+#endif
+	} else {
+#if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_PUNCH_HOLE)
+		/*
+		 * If we are not on block device, try to use punch hole
+		 * to reclaim free space.
+		 */
+		ret = fallocate(data->dev,
+				FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+				(off_t)(block) * channel->block_size,
+				(off_t)(count) * channel->block_size);
+#else
+		goto unimplemented;
+#endif
+	}
+	if (ret < 0) {
+		if (errno == EOPNOTSUPP)
+			goto unimplemented;
+		return errno;
+	}
+	return 0;
+unimplemented:
+	return EXT2_ET_UNIMPLEMENTED;
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/unlink.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/unlink.c
new file mode 100644
index 0000000..d2d31cc
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/unlink.c
@@ -0,0 +1,100 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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,
+		     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 (offset)
+		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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/valid_blk.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/valid_blk.c
new file mode 100644
index 0000000..895e36e
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/valid_blk.c
@@ -0,0 +1,61 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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_blocks2(ext2_filsys fs, 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 (ext2fs_file_acl_block(fs, inode) == 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;
+}
+
+int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode)
+{
+	return ext2fs_inode_has_valid_blocks2(NULL, inode);
+}
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/version.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/version.c
new file mode 100644
index 0000000..f8c8acf
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/version.c
@@ -0,0 +1,57 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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, dot_count = 0;
+
+	for (cp = ver_string; *cp; cp++) {
+		if (*cp == '.') {
+			if (dot_count++)
+				break;
+			else
+				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 --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/write_bb_file.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/write_bb_file.c
new file mode 100644
index 0000000..5834340
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/write_bb_file.c
@@ -0,0 +1,35 @@
+/*
+ * 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 Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#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, "%u\n", blk);
+	}
+	ext2fs_badblocks_list_iterate_end(bb_iter);
+	return 0;
+}