aboutsummaryrefslogtreecommitdiff
path: root/e2fslib
diff options
context:
space:
mode:
authorGuido Guenther <agx@sigxcpu.org>2006-11-18 23:48:07 +0100
committerGuido Guenther <agx@bogon.sigxcpu.org>2006-11-18 23:48:07 +0100
commitd1e063beb43e595680c65e3804d1f8ddff53373b (patch)
treef7256dfe1b807920270ec5113df6f6e4abf1ed0f /e2fslib
Imported Debian version 0.3.8.80.3.8.8
Diffstat (limited to 'e2fslib')
-rw-r--r--e2fslib/.cvsignore3
-rw-r--r--e2fslib/ChangeLog2274
-rw-r--r--e2fslib/MCONFIG199
-rw-r--r--e2fslib/Makefile642
-rw-r--r--e2fslib/Makefile.in477
-rw-r--r--e2fslib/alloc.c178
-rw-r--r--e2fslib/alloc.obin0 -> 17532 bytes
-rw-r--r--e2fslib/alloc_tables.c120
-rw-r--r--e2fslib/alloc_tables.obin0 -> 13672 bytes
-rw-r--r--e2fslib/badblocks.c236
-rw-r--r--e2fslib/badblocks.obin0 -> 11932 bytes
-rw-r--r--e2fslib/bb_compat.c63
-rw-r--r--e2fslib/bb_compat.obin0 -> 7600 bytes
-rw-r--r--e2fslib/bb_inode.c287
-rw-r--r--e2fslib/bb_inode.obin0 -> 18316 bytes
-rw-r--r--e2fslib/bitmaps.c213
-rw-r--r--e2fslib/bitmaps.obin0 -> 18880 bytes
-rw-r--r--e2fslib/bitops.c91
-rw-r--r--e2fslib/bitops.h718
-rw-r--r--e2fslib/bitops.obin0 -> 13556 bytes
-rw-r--r--e2fslib/block.c496
-rw-r--r--e2fslib/block.obin0 -> 23588 bytes
-rw-r--r--e2fslib/bmap.c237
-rw-r--r--e2fslib/bmap.obin0 -> 20372 bytes
-rw-r--r--e2fslib/bmove.c160
-rw-r--r--e2fslib/brel.h86
-rw-r--r--e2fslib/brel_ma.c197
-rw-r--r--e2fslib/check_desc.c68
-rw-r--r--e2fslib/check_desc.obin0 -> 11564 bytes
-rw-r--r--e2fslib/closefs.c291
-rw-r--r--e2fslib/closefs.obin0 -> 18440 bytes
-rw-r--r--e2fslib/cmp_bitmaps.c72
-rw-r--r--e2fslib/cmp_bitmaps.obin0 -> 12996 bytes
-rw-r--r--e2fslib/com_err.h40
-rw-r--r--e2fslib/dblist.c254
-rw-r--r--e2fslib/dblist.obin0 -> 19188 bytes
-rw-r--r--e2fslib/dblist_dir.c77
-rw-r--r--e2fslib/dblist_dir.obin0 -> 13940 bytes
-rw-r--r--e2fslib/dir_iterate.c137
-rw-r--r--e2fslib/dir_iterate.obin0 -> 15556 bytes
-rw-r--r--e2fslib/dirblock.c100
-rw-r--r--e2fslib/dirblock.obin0 -> 14216 bytes
-rw-r--r--e2fslib/dll/jump.funcs178
-rw-r--r--e2fslib/dll/jump.import166
-rw-r--r--e2fslib/dll/jump.params6
-rw-r--r--e2fslib/dll/jump.undefs2
-rw-r--r--e2fslib/dll/jump.vars6
-rw-r--r--e2fslib/dosio.c456
-rw-r--r--e2fslib/dosio.h153
-rw-r--r--e2fslib/dupfs.c92
-rw-r--r--e2fslib/dupfs.obin0 -> 13864 bytes
-rw-r--r--e2fslib/e2image.h51
-rw-r--r--e2fslib/e2p/e2p.h39
-rw-r--r--e2fslib/et/.cvsignore1
-rw-r--r--e2fslib/et/ChangeLog210
-rw-r--r--e2fslib/et/Makefile334
-rw-r--r--e2fslib/et/Makefile.in129
-rw-r--r--e2fslib/et/com_err.c120
-rw-r--r--e2fslib/et/com_err.h40
-rw-r--r--e2fslib/et/com_err.obin0 -> 7844 bytes
-rw-r--r--e2fslib/et/com_err.texinfo579
-rwxr-xr-xe2fslib/et/compile_et31
-rw-r--r--e2fslib/et/compile_et.sh.in31
-rw-r--r--e2fslib/et/error_message.c88
-rw-r--r--e2fslib/et/error_message.obin0 -> 6312 bytes
-rw-r--r--e2fslib/et/error_table.h42
-rw-r--r--e2fslib/et/et_c.awk187
-rw-r--r--e2fslib/et/et_h.awk159
-rw-r--r--e2fslib/et/et_name.c43
-rw-r--r--e2fslib/et/et_name.obin0 -> 3192 bytes
-rw-r--r--e2fslib/et/init_et.c63
-rw-r--r--e2fslib/et/init_et.obin0 -> 5184 bytes
-rw-r--r--e2fslib/et/internal.h30
-rw-r--r--e2fslib/et/libcom_err.abin0 -> 23006 bytes
-rw-r--r--e2fslib/et/vfprintf.c49
-rw-r--r--e2fslib/expanddir.c132
-rw-r--r--e2fslib/expanddir.obin0 -> 15012 bytes
-rw-r--r--e2fslib/ext2_err.c140
-rw-r--r--e2fslib/ext2_err.et276
-rw-r--r--e2fslib/ext2_err.et.in276
-rw-r--r--e2fslib/ext2_err.h106
-rw-r--r--e2fslib/ext2_err.obin0 -> 9224 bytes
-rw-r--r--e2fslib/ext2_ext_attr.h58
-rw-r--r--e2fslib/ext2_fs.h624
-rw-r--r--e2fslib/ext2_io.h100
-rw-r--r--e2fslib/ext2_types.h53
-rw-r--r--e2fslib/ext2_types.h.in53
-rw-r--r--e2fslib/ext2fs.h976
-rw-r--r--e2fslib/ext2fsP.h93
-rw-r--r--e2fslib/ext_attr.c100
-rw-r--r--e2fslib/ext_attr.obin0 -> 15324 bytes
-rw-r--r--e2fslib/fileio.c336
-rw-r--r--e2fslib/fileio.obin0 -> 20788 bytes
-rw-r--r--e2fslib/finddev.c208
-rw-r--r--e2fslib/finddev.obin0 -> 9920 bytes
-rw-r--r--e2fslib/flushb.c76
-rw-r--r--e2fslib/flushb.obin0 -> 4588 bytes
-rw-r--r--e2fslib/freefs.c137
-rw-r--r--e2fslib/freefs.obin0 -> 16244 bytes
-rw-r--r--e2fslib/gen_bitmap.c48
-rw-r--r--e2fslib/gen_bitmap.obin0 -> 12052 bytes
-rw-r--r--e2fslib/get_pathname.c158
-rw-r--r--e2fslib/get_pathname.obin0 -> 16440 bytes
-rw-r--r--e2fslib/getsize.c157
-rw-r--r--e2fslib/getsize.obin0 -> 6848 bytes
-rw-r--r--e2fslib/icount.c482
-rw-r--r--e2fslib/icount.obin0 -> 27388 bytes
-rw-r--r--e2fslib/imager.c380
-rw-r--r--e2fslib/imager.obin0 -> 20904 bytes
-rw-r--r--e2fslib/initialize.c326
-rw-r--r--e2fslib/initialize.obin0 -> 18024 bytes
-rw-r--r--e2fslib/inline.c32
-rw-r--r--e2fslib/inline.obin0 -> 30228 bytes
-rw-r--r--e2fslib/inode.c724
-rw-r--r--e2fslib/inode.obin0 -> 30508 bytes
-rw-r--r--e2fslib/irel.h114
-rw-r--r--e2fslib/irel_ma.c373
-rw-r--r--e2fslib/ismounted.c261
-rw-r--r--e2fslib/ismounted.obin0 -> 10124 bytes
-rw-r--r--e2fslib/jfs_dat.h64
-rw-r--r--e2fslib/jfs_user.h9
-rw-r--r--e2fslib/libcom_err.abin0 -> 23006 bytes
-rw-r--r--e2fslib/libext2fs.abin0 -> 800092 bytes
-rw-r--r--e2fslib/link.c121
-rw-r--r--e2fslib/link.obin0 -> 13500 bytes
-rw-r--r--e2fslib/linux/jfs.h682
-rw-r--r--e2fslib/linux/jfs_compat.h64
-rw-r--r--e2fslib/linux/list.h108
-rw-r--r--e2fslib/llseek.c132
-rw-r--r--e2fslib/llseek.obin0 -> 3716 bytes
-rw-r--r--e2fslib/lookup.c69
-rw-r--r--e2fslib/lookup.obin0 -> 12716 bytes
-rw-r--r--e2fslib/mkdir.c154
-rw-r--r--e2fslib/mkdir.obin0 -> 14556 bytes
-rw-r--r--e2fslib/mkjournal.c408
-rw-r--r--e2fslib/mkjournal.obin0 -> 23812 bytes
-rw-r--r--e2fslib/namei.c205
-rw-r--r--e2fslib/namei.obin0 -> 19168 bytes
-rw-r--r--e2fslib/native.c27
-rw-r--r--e2fslib/native.obin0 -> 3960 bytes
-rw-r--r--e2fslib/newdir.c72
-rw-r--r--e2fslib/newdir.obin0 -> 12464 bytes
-rw-r--r--e2fslib/nt_io.c1513
-rw-r--r--e2fslib/openfs.c240
-rw-r--r--e2fslib/openfs.obin0 -> 16392 bytes
-rw-r--r--e2fslib/read_bb.c95
-rw-r--r--e2fslib/read_bb.obin0 -> 12856 bytes
-rw-r--r--e2fslib/read_bb_file.c96
-rw-r--r--e2fslib/read_bb_file.obin0 -> 13552 bytes
-rw-r--r--e2fslib/rs_bitmap.c107
-rw-r--r--e2fslib/rs_bitmap.obin0 -> 13908 bytes
-rw-r--r--e2fslib/rw_bitmaps.c302
-rw-r--r--e2fslib/rw_bitmaps.obin0 -> 20296 bytes
-rw-r--r--e2fslib/swapfs.c145
-rw-r--r--e2fslib/swapfs.obin0 -> 15372 bytes
-rw-r--r--e2fslib/test_io.c265
-rw-r--r--e2fslib/test_io.obin0 -> 15060 bytes
-rw-r--r--e2fslib/tst_badblocks.c237
-rw-r--r--e2fslib/tst_bitops.c44
-rw-r--r--e2fslib/tst_byteswap.c92
-rw-r--r--e2fslib/tst_getsize.c44
-rw-r--r--e2fslib/tst_iscan.c218
-rw-r--r--e2fslib/unix_io.c556
-rw-r--r--e2fslib/unix_io.obin0 -> 21784 bytes
-rw-r--r--e2fslib/unlink.c80
-rw-r--r--e2fslib/unlink.obin0 -> 12960 bytes
-rw-r--r--e2fslib/util/.cvsignore1
-rw-r--r--e2fslib/util/ChangeLog132
-rw-r--r--e2fslib/util/Makefile231
-rw-r--r--e2fslib/util/Makefile.in39
-rw-r--r--e2fslib/util/gcc-wall-cleanup17
-rw-r--r--e2fslib/util/libecho.c78
-rwxr-xr-xe2fslib/util/substbin0 -> 80037 bytes
-rw-r--r--e2fslib/util/subst.c374
-rw-r--r--e2fslib/util/subst.conf16
-rw-r--r--e2fslib/util/subst.conf.in16
-rw-r--r--e2fslib/util/subst.obin0 -> 16392 bytes
-rw-r--r--e2fslib/valid_blk.c45
-rw-r--r--e2fslib/valid_blk.obin0 -> 5856 bytes
-rw-r--r--e2fslib/version.c50
-rw-r--r--e2fslib/version.h10
-rw-r--r--e2fslib/version.obin0 -> 5492 bytes
-rw-r--r--e2fslib/write_bb_file.c34
-rw-r--r--e2fslib/write_bb_file.obin0 -> 5300 bytes
184 files changed, 24992 insertions, 0 deletions
diff --git a/e2fslib/.cvsignore b/e2fslib/.cvsignore
new file mode 100644
index 0000000..66923b2
--- /dev/null
+++ b/e2fslib/.cvsignore
@@ -0,0 +1,3 @@
+ext2_err.c
+ext2_err.et
+ext2_err.h
diff --git a/e2fslib/ChangeLog b/e2fslib/ChangeLog
new file mode 100644
index 0000000..19b6825
--- /dev/null
+++ b/e2fslib/ChangeLog
@@ -0,0 +1,2274 @@
+2001-09-20 Theodore Tso <tytso@thunk.org>
+
+ * Release of E2fsprogs 1.25
+
+2001-09-16 Theodore Tso <tytso@valinux.com>
+
+ * ext2_ext_attr.h: Remove unneeded #include of <linux/config.h>
+ which was breaking the build on the Hurd. (Addresses
+ Debian bug #112414).
+
+2001-09-13 Theodore Ts'o <tytso@valinux.com>
+
+ * ismounted.c (check_mntent_file): We now validate the entry in
+ /etc/mtab to make sure the filesystem is really mounted,
+ since some broken distributions (read: Slackware) have
+ buggy boot scripts that don't initialize /etc/mtab before
+ checking non-root filesystems. (Slackware also doesn't
+ check the root filesystem separately, and reboot if the
+ root filesystem had changes applied to it, which is
+ dangerous and broken.)
+
+2001-09-02 Theodore Tso <tytso@thunk.org>
+
+ * Release of E2fsprogs 1.24a
+
+2001-08-30 Theodore Tso <tytso@thunk.org>
+
+ * Release of E2fsprogs 1.24
+
+2001-08-30 Theodore Tso <tytso@valinux.com>
+
+ * getsize.c (ext2fs_get_device_size): Back out BLKGETSIZE64
+ changes, since the ioctl number has been reused by another
+ unofficial patch.
+
+2001-08-15 Theodore Tso <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.23
+
+2001-08-05 Theodore Tso <tytso@valinux.com>
+
+ * alloc.c (ext2fs_new_inode, ext2fs_new_block): Use the fast
+ version of the bitmap test routines to speed up these
+ routines. (At some point I may want to make these
+ routines use the find_first_bit functions, but that will
+ add a lot of complexity since it means that these
+ functions will have to break the bitmap abstraction
+ boundary. It's not clear it's worth it.)
+
+ * mkjournal.c (mkjournal_proc): Remember the last block allocated
+ to speed up ext2fs_new_block().
+
+2001-07-29 Theodore Tso <tytso@valinux.com>
+
+ * finddev.c (scan_dir): Fix memory leak; we weren't calling
+ closedir() when exiting the function in all cases.
+
+2001-07-27 Theodore Tso <tytso@valinux.com>
+
+ * mkjournal.c (ext2fs_create_journal_superblock): Set the first
+ block usable in the journal for external journals to be 2
+ or 3, depending on the blocksize, so that the existing
+ kernel code does the right thing.
+
+ * getsize.c (ext2fs_get_device_size): Add support for the
+ BLKGETSIZE64 ioctl. (Ioctl defined by unofficial patches
+ from Ben LaHaise, but it's likely this interface won't
+ change.)
+
+ * mkjournal.c (ext2fs_add_journal_device): Use the correct block
+ when writing the journal superblock, too. (Oops! Needed
+ to make 1k filesystems with external journal to work.)
+
+2001-07-26 Theodore Tso <tytso@valinux.com>
+
+ * mkjournal.c (ext2fs_add_journal_device): Use the correct block
+ to find the journal superblock if the blocksize is 1024.
+
+2001-07-21 Theodore Tso <tytso@valinux.com>
+
+ * ext2_err.et.in (EXT2_ET_LOAD_EXT_JOURNAL): Add new error code
+
+2001-07-20 Theodore Tso <tytso@valinux.com>
+
+ * ext_attr.c (ext2fs_write_ext_attr): When writing the extended
+ attribute block, set the filesystem changed bit.
+
+ * bitops.h (ext2fs_find_first_bit_set, ext2fs_find_next_bit_set):
+ Comment out these functions since we're not using them.
+
+2001-07-10 Theodore Tso <tytso@valinux.com>
+
+ * closefs.c (write_primary_superblock): After writing changes to
+ the primary superblock, update the original superblock
+ copy so we don't have to re-write those changes in the
+ future.
+ (ext2fs_flush): Clear the superblock dirty flag after
+ we've flushed out changes to disk.
+
+2001-07-07 Theodore Tso <tytso@valinux.com>
+
+ * bitops.h (ext2fs_find_first_bit_set): Use %esi instead of %ebx
+ to avoid register conflicts when compiling in PIC mode.
+
+2001-07-04 Theodore Tso <tytso@valinux.com>
+
+ * bitops.h (ext2fs_find_first_bit_set, ext2fs_find_next_bit_set):
+ Add new functions (C and in i386 assembler) which quickly
+ find bits set in a bitmask.
+
+2001-06-23 Theodore Tso <tytso@valinux.com>
+
+ * Makefile.in, ext_attr.c, ext2_attr.c, ext2fs.h: Add new files
+ ext2_ext_attr.h and ext_attr.c for extended attributes
+ support.
+
+ * Release of E2fsprogs 1.22
+
+2001-06-22 Theodore Tso <tytso@valinux.com>
+
+ * mkjournal.c (ext2fs_add_journal_inode): Move close of file
+ descriptor so that adding a journal to a mounted
+ filesystem doesn't die. (Fixes a bug accidentally
+ introduced in e2fsprogs 1.21.)
+
+ * mkjournal.c (ext2fs_add_journal_inode): Only use fchflags if
+ HAVE_CHFLAGS and UF_NODUMP are defined, since the Hurd has
+ fchflags without defining UF_NODUMP. (Addresses Debian
+ bug #101361)
+
+ * flushb.c: Use platform independent method of defining the
+ BLKFLSBUF and FDFLUSH ioctl's. Also include sys/mount.h
+ since on newer glibc's BLKFLSBUF is defined there.
+
+ * bitops.h: The C language versions of ext2fs_swab16/32 need to be
+ included if EXT2FS_ENABLE_SWAPFS is defined, since we need
+ to support byte swapping even if we don't support the
+ conversion functions. (Fixes Debian bug #101686).
+
+ * dirblock.c (ext2fs_read_dir_block): Remove use of dir_entry_2
+ since the byte-swapping code all assumes the
+ ext2_dir_entry structure. (It's a question of whether or
+ not name_len should be byte-swapped or not, and whether
+ it's a 16 bit or 8 bit field.)
+
+2001-06-15 Theodore Tso <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.21
+
+2001-06-15 Theodore Tso <tytso@valinux.com>
+
+ * Makefile.in: Fix bug in installation of ext2_types.h. It is a
+ file which is generated and is therefore found in the
+ build directory, not source directory.
+
+ * ismounted.c (check_mntent_file): Use a test file in / to check
+ to see if the root filesystem is mounted read-only. This
+ protects against the case where /etc might not be on /, as
+ well as the case where /etc/mtab doesn't exist. (Both are
+ should-never happen scenarios, but you never know...)
+
+2001-06-14 Theodore Tso <tytso@valinux.com>
+
+ * ismounted.c (ext2fs_check_if_mounted): Fix grammer in comment.
+ Remove unneeded #pragma argsused, since the arguments are
+ always used.
+
+2001-06-13 Theodore Tso <tytso@valinux.com>
+
+ * ext2_types.h.in: If linux/types.h has been defined, then don't
+ try to redefine the typedefs.
+
+ * Makefile.in (HFILES): Add ext2_types.h to the list of files
+ which should be installed.
+
+ * ismounted.c (check_mntent_file): Work around GNU hurd brain
+ damage. Addresses Debian bug #100304.
+
+ * Makefile.in: Limit some .o files from being included into the
+ library if --disable-debugfs, --disable-swapfs,
+ --disable-imager, or --disable-resizer are used.
+
+2001-06-12 Theodore Tso <tytso@valinux.com>
+
+ * inode.c, tst_iscan.c: Stop using the compatibility badblocks
+ function, and use the ext2fs_badblocks_* functions
+ instead.
+
+2001-06-11 Theodore Tso <tytso@valinux.com>
+
+ * Makefile.in, gen_bitmap.c, bitops.h: Move inline functions
+ ext2fs_mark_generic_bitmap and
+ ext2fs_unmark_generic_bitmap to gen_bitmap.c as normal
+ functions. (This saves space and doesn't significantly
+ change the speed of e2fsck on a P-III.)
+
+ * ext2fs.h, bitops.h, block.c, bmap.c, closefs.c, dirblock.c,
+ inode.c, native.c, openfs.c, rw_bitmaps.c, swapfs.c: Only
+ include the byte-swapping logic if ENABLE_SWAPFS is turned
+ on or if we're on a big-endian machine.
+
+ * initialize.c (ext2fs_initialize):Use WORDS_BIGENDIAN directly to
+ set EXT2_FLAG_SWAP_BYTES, instead of using
+ ext2fs_native_flag.
+
+ * native.c (ext2fs_native_flag): Use WORDS_BIGENDIAN provided by
+ autoconf to determine whether or not return
+ EXT2_FLAG_SWAP_BYTES.
+
+2001-06-10 Theodore Tso <tytso@valinux.com>
+
+ * Makefile.in: Remove the dependence on the libe2p library.
+
+ * mkjournal.c (ext2fs_add_journal_inode): Replace use of fsetflags
+ with direct usage of the ioctl/fchflags so that we don't
+ have to depend on the libe2p library.
+
+2001-06-08 Theodore Tso <tytso@valinux.com>
+
+ * ext2_types.h.in: Use unsigned ints in favor of unsigned longs
+ when trying to find a 32-bit wide type.
+
+ * icount.c (insert_icount_el): Fix the code used to estimate the
+ size of the new icount array to be more intelligent, to
+ avoid reallocating the array too many times. Thanks to
+ Enrique Perez-Terron for pointing this out.
+
+2001-06-02 Theodore Tso <tytso@valinux.com>
+
+ * valid_blk.c (ext2fs_inode_has_valid_blocks): Only check i_blocks
+ for a symlink to determine whether it is a fast symlink.
+
+2001-06-01 Theodore Tso <tytso@valinux.com>
+
+ * Makefile.in, dosio.c, ext2_fs.h, ext2_types.h.in, ext2fs.h:
+ Move include/asm/types.h.in to lib/ext2fs/ext2_types.h.in.
+
+2001-05-25 Theodore Tso <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.20
+
+2001-05-25 Theodore Tso <tytso@valinux.com>
+
+ * ismounted.c: More cleanups for ismounted.c, some from Andreas,
+ some to clean up Andreas's patches. Use strncpy instead
+ of strcpy to save the root's mountpoint. Clean up #ifdef
+ structure. Remove uneeded variable in testing/debug driver.
+
+2001-05-24 Andreas Dilger <adilger@turbolinux.com>
+
+ * ismounted.c: Add check for root device which doesn't depend on
+ /etc/fstab or /proc/mounts to be correct. Don't call
+ endmntent() before we are done with mnt struct.
+
+2001-05-23 Theodore Tso <tytso@valinux.com>
+
+ * ext2_err.et.in (EXT2_ET_JOURNAL_UNSUPP_VERSION): Added new error
+ code.
+
+2001-05-21 Theodore Tso <tytso@valinux.com>
+
+ * ext2_fs.h: Change assignment of EXT2_FEATURE_COMPAT_DIR_INDEX to
+ make room for pre-existing usage of
+ EXT2_FEATURE_COMPAT_EXT_ATTR. Add flag EXT2_INDEX_FL with
+ the same codepoint as EXT2_BTREE_FL.
+
+2001-05-20 Theodore Tso <tytso@valinux.com>
+
+ * ext2fs.h: #include <> instead of "" for ext2fs and et header
+ files, since they will be installed in /usr/include
+
+2001-05-14 Theodore Tso <tytso@valinux.com>
+
+ * alloc.c, alloc_tables.c, badblocks.c, bb_compat.c, bb_inode.c,
+ bitmaps.c, bitops.c, block.c, bmap.c, bmove.c, brel_ma.c,
+ check_desc.c, closefs.c, cmp_bitmaps.c, dblist.c,
+ dblist_dir.c, dir_iterate.c, dirblock.c, dupfs.c,
+ expanddir.c, ext2_fs.h, fileio.c, finddev.c, flushb.c,
+ freefs.c, get_pathname.c, getsize.c, icount.c, imager.c,
+ initialize.c, inline.c, inode.c, irel_ma.c, ismounted.c,
+ link.c, lookup.c, mkdir.c, mkjournal.c, namei.c, native.c,
+ newdir.c, nt_io.c, openfs.c, read_bb.c, read_bb_file.c,
+ rs_bitmap.c, rw_bitmaps.c, swapfs.c, test_io.c,
+ tst_badblocks.c, tst_byteswap.c, tst_getsize.c,
+ tst_iscan.c, unix_io.c, unlink.c, valid_blk.c, version.c,
+ write_bb_file.c, ext2_fs.h: Moved file from include/linux.
+ Adjust all files in this directroy to include this file.
+
+ * mkjournal.c (ext2fs_create_journal_superblock): Remove redundant
+ code.
+
+2001-05-05 Theodore Tso <tytso@valinux.com>
+
+ * fileio.c (ext2fs_file_read): Factored out common code and
+ cleaned up function. Fixed a bug where if there was an
+ error reading from the disk, the number of bytes read
+ wasn't reliably set. (Fixes Debian bug #79163)
+ (ext2fs_file_write): Factored out common code and made
+ function more efficient; if writing a full block, don't
+ bother to do a read-modify-write cycle.
+
+2001-05-04 Theodore Tso <tytso@valinux.com>
+
+ * dirblock.c (ext2fs_read_dir_block): Check for an directory
+ record length which isn't a multiple four, and treat that
+ as an invalid. Scan the directory and return an error
+ (EXT2_ET_DIR_CORRUPTED) if the directory records are
+ corrupted.
+ (ext2fs_write_dir_block): If while byte-swapping the
+ directory block, if there's an error, abort and return
+ EXT2_ET_DIR_CORRUPTED.
+
+2001-05-02 Theodore Tso <tytso@valinux.com>
+
+ * ext2fs.h (EXT2_FLAG_IMAGE_FILE): Add new flag, and add
+ image_header field in the ext2_filsys structure
+
+ * block.c (block_iterate_ind, block_iterate_dind, block_iterate_tind):
+ * inode.c (ext2fs_read_inode):
+ * rw_bitmaps.c (read_bitmaps):
+ * openfs.c (ext2fs_open): Add support for EXT2_FLAG_IMAGE_FILE
+
+ * imager.c (ext2fs_image_bitmap_read): Fix bug in imager to make
+ sure the full bitmap is saved.
+
+2001-05-01 Theodore Tso <tytso@valinux.com>
+
+ * e2image.h (struct ext2_image_hdr): Add space for the device name
+ in the image header.
+
+ * dir_iterate.c (ext2fs_process_dir_block): Add a double-check to
+ make sure the rec_len is a multiple of 4, to prevent
+ bus-errors on architectures which care about mis-aligned
+ pointer references.
+
+2001-04-25 Theodore Tso <tytso@valinux.com>
+
+ * getsize.c (ext2fs_get_device_size): Use an unsigned long to
+ query the device sizes using the BLKGETSIZE ioctl.
+
+2001-04-16 Theodore Tso <tytso@valinux.com>
+
+ * ismounted.c (check_mntent): Check /proc/mounts on Linux systems
+ before checking /etc/mtab. The EXT2_MF_READONLY flag is
+ now set from the /etc/mtab options field for all
+ filesystems, not just the root filesystem. Add debugging
+ code to make it easier to test ext2fs_check_if_mounted().
+
+ * mkjournal.c (ext2fs_create_journal_superblock): Add safety
+ check; return an error if there's an attempt to create a
+ journal less than 1024 filesystem blocks.
+
+ * ext2_err.et.in, mkjournal.c: Change EXT2_JOURNAL_NOT_BLOCK and
+ EXT2_NO_JOURNAL_SB to be EXT2_ET_*.
+
+2001-02-20 Theodore Tso <tytso@valinux.com>
+
+ * bitops.h (ext2fs_swab16, ext2fs_swab32): Add i386 assembly
+ inline functions.
+
+ * tst_byteswap.c: New function to test the byteswap functions.
+ Add to regression test suite.
+
+2001-02-08 Theodore Tso <tytso@valinux.com>
+
+ * e2image.h (struct ext2_image_hdr): Fix type for fs_hostname
+
+2001-02-07 Theodore Tso <tytso@valinux.com>
+
+ * mkjournal.c (ext2fs_create_journal_superblock): Fix the setting
+ of s_first for external devices to always be 1, since
+ jsb->s_first is always relative to the start of the
+ journal superblock. Use htonl(1) when setting s_nr_users.
+
+2001-01-17 Theodore Ts'o <tytso@valinux.com>
+
+ * mkjournal.c (ext2fs_add_journal_device): Fix bug where the
+ device number of the filesystem (instead of the journal)
+ was being dropped into s_journal_dev.
+
+2001-01-15 Theodore Ts'o <tytso@valinux.com>
+
+ * initialize.c (ext2fs_initialize): Add support for initializing
+ the ext2 superblock for external journal devices. This
+ basically means we don't bother to allocate any block
+ group descriptors.
+
+ * openfs.c (ext2fs_open): Only open external journal devices if
+ the new flag EXT2_FLAG_JOURNAL_DEV_OK is passed to
+ ext2fs_open. When opening such devices, don't try to read
+ the block group descriptors, since they're not there.
+
+ * ext2_err.et.in (EXT2_NO_JOURNAL_SB): Add new error code
+
+ * mkjournal.c: Export a new function,
+ ext2fs_create_journal_superblock(), which allocates and
+ returns a buffer containing a journal superblock. This is
+ needed by mke2fs to create an external journal. Rewrote
+ ext2fs_add_journal_device() so that it no longer creates
+ the external journal, but rather adds a filesystem to an
+ existing external journal. It handles all of the UUID
+ manipulation.
+
+ * ext2fs.h: List the EXT3_FEATURE_JOURNAL_DEV as a flag supported
+ by the library. Define the EXT2_FLAG_JOURNAL_DEV_OK.
+ Changed function prototype for ext2fs_add_journal_device().
+
+2001-01-14 Theodore Ts'o <tytso@valinux.com>
+
+ * closefs.c (ext2fs_flush): Don't write out anything beyond the
+ primary superblock if EXT2_INCOMPAT_JOURNAL_DEV is
+ listed.
+
+2001-01-12 Theodore Ts'o <tytso@valinux.com>
+
+ * imager.c: Fix gcc -Wall complaints and a series of bugs where
+ retval wasn't set correctly. (Thanks to Andreas Dilger
+ for pointing this out.)
+
+2001-01-11 <tytso@snap.thunk.org>
+
+ * flushb.c (ext2fs_sync_device): New function which centralizes
+ all of the places which might try to use the BLKFLSBUF
+ or FDFLUSH ioctls (and usually failing to define them
+ since the system header files don't usually do this for
+ us, and we're trying to avoid usage of kernel include
+ files now).
+
+2001-01-10 <tytso@snap.thunk.org>
+
+ * alloc.c, bb_inode.c, bitmaps.c, bitops.h, block.c, bmap.c,
+ bmove.c, brel.h, cmp_bitmaps.c, dblist.c, dblist_dir.c,
+ dir_iterate.c, expanddir.c, ext2fs.h, ext2fsP.h, fileio.c,
+ finddev.c, get_pathname.c, icount.c, inode.c, irel.h,
+ irel_ma.c, ismounted.c, link.c, lookup.c, mkdir.c,
+ mkjournal.c, namei.c, newdir.c, read_bb_file.c, test_io.c,
+ tst_iscan.c, unix_io.c, unlink.c: Change use of ino_t to
+ ext2_ino_t, to protect applications that attempt to
+ compile -D_FILE_OFFSET_BITS=64, since this inexplicably
+ changes ino_t(!?). So we use ext2_ino_t to avoid an
+ unexpected ABI change.
+
+2001-01-05 <tytso@snap.thunk.org>
+
+ * dirblock.c (ext2fs_read_dir_block): Fix a potential case where
+ we may overrun allocated memory in case of a corrupted
+ filesystem (or an e2fsck test case :-) when byte-swapping
+ the directory block.
+
+ * ext2fs.h: Indent the #warning to fix gcc -Wall complaint.
+
+ * mkjournal.c (ext2fs_add_journal_device): Fix various gcc -Wall
+ complaints including a missing return 0 at the end of
+ ext2fs_add_journal_device.
+
+2001-01-03 <tytso@snap.thunk.org>
+
+ * Makefile.in: Link in libe2p when creating libext2fs as a shared
+ library, since mkjournal.c now references fsetflags().
+
+ * mkjournal.c (ext2fs_add_journal_inode): Folded in Andreas
+ Dilger's changes (with fixups) to allow on-line creation
+ of a journal file.
+
+ * ext2fs.h, closefs.c (ext2fs_flush): Add new flag,
+ EXT2_FLAG_SUPER_ONLY, which the close routines to only
+ update the superblock, and not the group descriptors.
+
+2000-12-30 Andreas Dilger <adilger@turbolinux.com>
+
+ * ismounted.c: add ext2fs_check_mount_point() function, which will
+ optionally return the mount point of a device if mounted
+
+2000-12-14 Andreas Dilger <adilger@turbolinux.com>
+
+ * mkjournal.c: rename ext2fs_add_journal_fs() to the more descriptive
+ ext2fs_add_journal_inode()
+
+2001-01-01 <tytso@snap.thunk.org>
+
+ * ext2fs.h: Remove definition of ext2fs_sb. Note: this may break
+ source (but not binary) compatibility of some users of the
+ ext2 library. They should just simply do a global search
+ and replace of struct ext2fs_sb with struct
+ ext2_super_block, and use their own private copy of
+ ext2_fs.h if they aren't already.
+
+ * closefs.c, initialize.c, link.c, newdir.c, openfs.c, swapfs.c:
+ Replace use of ext2fs_sb with ext2_super_block.
+
+2000-12-31 <tytso@snap.thunk.org>
+
+ * ext2fs.h: Cleaned up header file by removing definitions of
+ feature flags that might not have been defined in older
+ ext2 header files. Now that we're using our own
+ include/linux/ext2fs.h header file, this can never happen.
+
+ * jfs_dat.h: Removed old header file which is no longer needed.
+
+2000-12-13 Theodore Ts'o <tytso@valinux.com>
+
+ * closefs.c (ext2fs_update_dynamic_rev): New function suggested
+ by Andreas Dilger to update the filesystem revision to
+ EXT2_DYNAMIC_REV.
+
+ * swapfs.c (ext2fs_swap_super): Add byte swapping for the journal
+ fields.
+
+2000-12-09 <tytso@snap.thunk.org>
+
+ * ext2fs.h, mkjournal.c (ext2fs_add_journal_inode,
+ ext2fs_add_journal_device): Add a new argument to the APIs
+ of these function, which is a flags word. This is used to
+ allow the creation of a V1 superblock for those folks who
+ are using ext3 0.3b in production. Note, the user-land
+ interface for getting at this flag won't be documented, as
+ the V1 superblock is deprecated.
+
+ * mkjournal.c (init_journal_superblock): Sync Stephen's changes
+ which creates a V2 superblock instead of a V1 superblock.
+
+2000-11-21 <tytso@snap.thunk.org>
+
+ * test_io.c (test_write_blk, test_write_byte): Fix typos pointed
+ out by Andreas Dilger.
+
+2000-11-05 <tytso@snap.thunk.org>
+
+ * imager.c (ext2fs_image_{inode,super,bitmap}_{read,write},
+ ext2_fs.h, Makefile.in: New file that has routines that
+ save ext2fs metadata to a file.
+
+ * ext2_err.et.in (EXT2_ET_MAGIC_E2IMAGE): New error code assigned.
+
+ * e2image.h: New file which defines the file format for the ext2
+ image file. (Saved copy of ext2 metadata to a file as a
+ saving throw against worst-case damage.)
+
+2000-11-01 <tytso@snap.thunk.org>
+
+ * inode.c (ext2fs_flush_icache): Add new function
+ ext2fs_flush_icache() which flushes the internal inode
+ cache. Applications which modify the inode table blocks
+ directly must call this function.
+
+2000-10-26 <tytso@snap.thunk.org>
+
+ * mkjournal.c: Add #include of netinet/in.h, since Solaris
+ requires it for ntohl().
+
+ * ext2_io.h (io_channel_write_byte): Add new interface to allow
+ callers to write specific byte ranges. This is an
+ optional interface, which not all IO channels may
+ implement.
+
+ * unix_io.c (unix_write_byte):
+ * test_io.c (test_write_byte): Add implementation of the
+ write_byte function.
+
+ * closefs.c (write_primary_superblock, ext2fs_flush): Add a new
+ function which writes the primary superblock. If the IO
+ channel supports writing raw bytes directly, only fields
+ which were modified are written to the disk. This makes
+ it safe(r) to use utilities like tune2fs on a mounted
+ filesystem.
+
+ * freefs.c (ext2fs_free): Free the original superblock if it is
+ available.
+
+ * openfs.c (ext2fs_open): Store a copy of the original superblock
+ when opening it.
+
+ * ext2fs.h: Add a field to store the original superblock in the
+ ext2 context structure.
+
+2000-10-24 <tytso@snap.thunk.org>
+
+ * llseek.c: Add #ifdef's for IA64 (it's a 64-bit platform, so we
+ don't need to use llseek).
+
+2000-10-24 <tytso@valinux.com>
+
+ * Makefile.in, ext2fs.h, jfs_dat.h, mkjournal.c: Add functions for
+ creating an ext3 journal on a filesystem.
+
+2000-08-21 <tytso@valinux.com>
+
+ * ext2_err.et.in (EXT2_JOURNAL_NOT_BLOCK): Add new error code.
+
+2000-08-22 <tytso@valinux.com>
+
+ * unix_io.c: Make massive changes to support a multiple block
+ writethrough cacheing.
+
+ * ext2_io.h: Added flags field to the io_channel structure.
+
+2000-08-19 <tytso@valinux.com>
+
+ * finddev.c, ext2fs.h, Makefile.in: Add new file, finddev.c, which
+ provides the function ext2fs_find_block_device(). This
+ function returns the pathname to a block device, given its
+ device number.
+
+2000-07-13 <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.19
+
+2000-07-07 Theodore Ts'o <tytso@valinux.com>
+
+ * ext2fs.h (EXT2_LIB_FEATURE_INCOMPAT_SUPP): Add
+ EXT3_FEATURE_INCOMPAT_RECOVER (aka needs_recovery) to the
+ list of filesystem flags supported by the library.
+
+2000-07-04 Theodore Ts'o <tytso@valinux.com>
+
+ * ext2fs.h: Update to include latest journalling additions to the
+ superblock.
+
+ * dll/jump.funcs: Add new jumptable entries for
+ ext2fs_write_bb_FILE, ext2fs_read_bb_FILE2, and
+ ext2fs_badblocks_equal.
+
+ * tst_badblocks.c: Update test program to test
+ ext2fs_read_bb_FILE2 and ext2fs_write_FILE.
+
+ * write_bb_file.c (ext2fs_write_bb_FILE): New function which
+ writes out bad blocks list to a file.
+
+ * read_bb_file.c (ext2fs_read_bb_FILE2): Add new function which
+ changes the callback function to take two additional
+ arguments; a private blind pointer supplied by the caller,
+ and pointer to a char * containing a pointer to the
+ invalid string.
+
+ * badblocks.c (ext2fs_badblocks_equal): Add new function which
+ returns true if two badblocks list are equal.
+
+ * Makefile.in: Remove explicit link of -lc in the shared library.
+ (It shouldn't be necessary, and is harmful in some cases).
+
+2000-06-10 Theodore Ts'o <tytso@valinux.com>
+
+ * getsize.c (main): Add debugging code under #ifdef DEBUG
+
+2000-05-27 Theodore Ts'o <tytso@valinux.com>
+
+ * mkdir.c (ext2fs_mkdir): Read the parent directory's inode
+ earlier, so that if there's an error reading it, we can
+ more cleanly back out of the operation.
+
+2000-05-25 <tytso@snap.thunk.org>
+
+ * getsize.c (ext2fs_get_device_size): Use open64() instead of
+ open() if it exists. Under linux, manually define the
+ ioctl for BLKGETSIZE if it isn't already defined and it's
+ safe to do so.
+
+ * unix_io.c (unix_open): Use open64() instead of open() if it
+ exists.
+
+ * llseek.c: Simplify header includes of unistd.h. If lseek64 is
+ available (and prototypes are defined) use it in
+ preference to llseek.
+
+ * Makefile: Add hack dependency rule so that parallel makes work
+ correctly.
+
+2000-05-18 Theodore Ts'o <tytso@valinux.com>
+
+ * ext2fs.h: Add appropriate ifdef's to support C++ compilation.
+
+2000-04-03 Theodore Ts'o <tytso@valinux.com>
+
+ * block.c: Readibility tweak in conditionals involving
+ ctx->fs->flags.
+
+ * ext2fs.h: Use AUTOCONF SIZEOF_* macros if available to determine
+ how to define __s64 and __u64. Turn off "compression is
+ experimental" warning if the cpp macro
+ I_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL is defined.
+
+2000-02-11 <tytso@snap.thunk.org>
+
+ * ext2fs.h: Define EXT2FS_COMPRESSED_BLKADDR and HOLE_BLKADDR.
+ Conditionally include Compression as a supported type if
+ ENABLE_COMPRESSION (via --enable-compression) is turned on.
+
+ * swapfs.c (ext2fs_swap_super): Swap the compression usage bitmap.
+
+2000-02-08 <tytso@snap.thunk.org>
+
+ * bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
+ ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
+ ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap):
+ Change to return the previous state of the bit that is
+ being marked or unmarked. For speed optimization.
+
+2000-02-02 Theodore Ts'o <tytso@valinux.com>
+
+ * getsize.c, ismounted.c: Remove unneeded include of linux/fs.h
+
+ * swapfs.c: Remove #ifdef HAVE_EXT2_INODE_VERSION since it's not
+ needed any more; we know it will always be i_generation.
+ Add support for swapping the high bits of the uid and gid.
+
+1999-11-19 <tytso@valinux.com>
+
+ * mkdir.c (ext2fs_mkdir): Only update the parent's inode link
+ counts if the link was successful. Patch suggested by
+ jeremy@goop.org.
+
+ * Makefile.in (distclean): Remove TAGS and Makefile.in.old from
+ the source directory.
+
+1999-11-10 <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.18
+
+1999-11-08 <tytso@valinux.com>
+
+ * Makefile.in (tst_badblocks): Add freefs.o to the object list,
+ since ext2fs_badblocks_list_free was moved to freefs.c.
+
+ * tst_badblocks.c: Use the newer badblocks API names. Add
+ duplicate blocks to the test inputs to test dealing with
+ adding blocks which are already in the badblocks list.
+
+ * badblocks.c (ext2fs_badblocks_list_add): If appending to the end
+ of the list, use a shortcut O(1) operations instead of an
+ O(n) operation. (Idea suggested by David Beattie.)
+
+ * freefs.c (ext2fs_free): Use ext2fs_badblocks_list_free() instead
+ of badblocks_list_free(), to save a procedure call.
+
+1999-10-26 <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.17
+
+1999-10-26 <tytso@valinux.com>
+
+ * ext2fs.h: Add kludge to deal with the fact that egcs cpp doesn't
+ seem to handle ~0UL the same way as they used to.
+
+1999-10-25 <tytso@valinux.com>
+
+ * nt_io.c (_OpenNtName): Open the device using
+ FILE_SYNCHRONOUS_IO_NONALERT instead of
+ FILE_SYNCHRONOUS_IO_ALERT
+ (nt_open): At the end of the device open routine, unlock
+ the drive but do not dismount it.
+
+ * initialize.c (CREATOR_OS): Use __GNU__ instead of __gnu__ to
+ detect the Hurd OS.
+
+1999-10-22 <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.16
+
+1999-10-22 <tytso@valinux.com>
+
+ * mkdir.c (ext2fs_mkdir): Pass EXT2_FT_DIR flag to ext2fs_link().
+
+ * link.c (ext2fs_link): This call now uses the low three bits of
+ the flags parameter to pass the directory filetype
+ information; it will set the directory entry FILETYPE
+ information if the filesystem supports it.
+
+ * newdir.c (ext2fs_new_dir_block): If the FILETYPE superblock
+ option is set, then create the '.' and '..' entries with
+ the filetype set to EXT2_FT_DIR.
+
+1999-09-24 <tytso@valinux.com>
+
+ * nt_io.c: New file which supports I/O under Windows NT.
+
+1999-09-07 <tytso@valinux.com>
+
+ * ext2fs.h: Add new fields for journalling and define new
+ feature bits used by newer filesystems: IMAGIC_INODES,
+ HAS_JOURNAL, RECOVER.
+
+ * expanddir.c (ext2fs_expand_dir, expand_dir_proc): Change where
+ we update the inode block count and size files so that the
+ block count field is updated correctly when we create an
+ indirect block.
+
+1999-07-18 Theodore Ts'o <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.15
+
+1999-06-23 <tytso@valinux.com>
+
+ * swapfs.c (ext2fs_swap_inode): Add compatibility for Linux 2.3
+ kernels that use i_generation instead of i_version. Patch
+ supplied by Jon Bright <sircus@sircus.demon.co.uk>.
+
+1999-06-21 <tytso@valinux.com>
+
+ * dir_iterate.c (ext2fs_process_dir_block): Check for corrupted
+ directory entry before calling the callback function.
+ This should prevent some core dumps of insufficiently
+ paranoid callback functions.
+
+1999-05-29 <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: Add feature definition for AFS IMAGIC inodes.
+
+ * fileio.c (ext2fs_file_open): Remove obsolete comment stating
+ that we don't handle writing yet (we do). Fixed bug where
+ we weren't allocating a big enough buffer for ext2_bmap.
+
+1999-05-03 <tytso@rsts-11.mit.edu>
+
+ * openfs.c (ext2fs_open): Check to make sure that the number of
+ blocks per group is not zero --- if so, it must be a bad
+ superblock!
+
+1999-01-09 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs 1.14
+
+1999-01-07 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_read_inode, ext2fs_write_inode): Check to see if
+ the inode number is zero; if it's zero, return
+ EXT2_ET_BAD_INODE_NUM.
+
+1998-12-30 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c (ext2fs_initialize): Use EXT2_FIRST_INODE instead
+ of EXT2_FIRST_INO to ensure compatibility with Linux 1.2
+ header files.
+
+Mon Jan 4 02:32:09 1999 Theodore Y. Ts'o <tytso@mit.edu>
+
+ * llseek.c (ext2fs_llseek): Change ext2fs_llseek() in the
+ non-Linux case to use EINVAL by default, unless it isn't
+ defined, in which case we use EXT2_ET_INVALID_ARGUMENT
+ instead.
+
+1998-12-15 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs 1.13
+
+1998-12-03 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.in: Updated dependencies.
+
+1998-09-22 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c (ext2fs_initialize): Make sure that we allocate
+ enough inodes so that we can make a valid filesystem.
+
+1998-09-02 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * rw_bitmaps.c: Fixed signed/unsigned warnings.
+
+ * fileio.c (ext2fs_file_set_size): Remove unneeded extern from the
+ function declaration.
+
+ * dblist.c (make_dblist): Add safety check in case the dblist
+ pointer passed in is null (in which case, assign it to
+ fs->dblist). Fixed some signed/unsigned warnings.
+
+ * bmap.c: Make addr_per_block be of type blk_t to avoid
+ signed/unsigned warnings.
+
+ * namei.c (ext2fs_follow_link): Remove uneeded extern from the
+ function declaration.
+
+ * get_pathname.c (get_pathname_proc): Use return value from
+ ext2fs_get_mem, instead of checking if &gp->name is
+ NULL.
+
+ * dir_iterate.c (ext2fs_process_dir_block):
+ * dblist_dir.c (ext2fs_dblist_dir_iterate): Remove uneeded extern
+ from the function declaration.
+
+ * block.c (ext2fs_block_iterate2): If the read_inode call fails,
+ return the error directly instead of jumping to the
+ cleanup routine, since we don't need to do any cleanup.
+
+ * alloc_table.c (ext2fs_allocate_group_table): Make this
+ function take a dgrp_t for its group argument.
+
+ * ext2fs.h: Make dgrp_t an __u32 type, and make
+ fs->desc_group_count be of type dgrp_t.
+
+1998-07-27 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * badblocks.c (ext2fs_badblocks_list_add): Use a bigger increment
+ than 10 blocks when we need to expand the size of the
+ badblocks list.
+
+1998-07-09 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs 1.12
+
+1998-06-30 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * closefs.c (ext2fs_flush): Update the s_block_group_nr field as
+ appropriate for all of the block group copies, so that
+ it's clear where the beginning of the filesystem is on the
+ disk. (For when the partition table gets scrod.)
+
+ * ext2fs.h: Change the name of the feature from
+ EXT2_FEATURE_INCOMPAT_DIRNAME_SIZE to
+ EXT2_FEATURE_INCOMPAT_FILESIZE (to match with the kernel).
+
+1998-06-18 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (get_next_blockgroup): Fix bug where if
+ get_next_blockgroup() is called early because of a missing
+ inode table in a block group, the current_inode counter
+ wasn't incremented correctly.
+
+1998-06-16 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * read_bb.c (ext2fs_read_bb_inode): Make function more robust
+ against a completely trashed bad block inode.
+
+1998-06-10 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * alloc_tables.c (ext2fs_allocate_group_table): Fix bug so that if
+ the stride length hits a bad value, we retry the block
+ allocation starting at the beginning of the block group.
+
+ * ext2fs.h, bb_inode.c, block.c, bmove.c, dir_iterate.c,
+ expanddir.c, ext2fsP.h, read_bb.c: Change blkcnt_t to be
+ e2_blkcnt_t to avoid collision with LFS API.
+
+1998-05-01 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c (ext2fs_initialize): Initialize s_inodes_count in a
+ way that avoids overflows on disk sizes greater than 4GB.
+
+1998-04-28 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: Define EXT2_QSORT_TYPE appropriately for the
+ return type for comparison functions for qsort.
+
+ * dblist.c (dir_block_cmp): Use EXT2_QSORT_TYPE in function
+ declaration.
+
+1998-04-26 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h, bitops.h: Add support for the Watcom C compiler to do
+ inline functions.
+
+ * ext2fs.h, dosio.c: Use asm/types.h instead of linux/types.h to
+ evade a potential problem with glibc's header files trying
+ to spike out linux/types.h.
+
+ * ext2fs.h (ext2fs_resize_mem): Change the function prototype to
+ include the old size of the memory, which is needed for
+ some braindamaged memory allocation systems that don't
+ support realloc().
+
+ * badblocks.c (ext2fs_badblocks_list_add):
+ bb_inode.c (clear_bad_block_proc):
+ dblist.c (ext2fs_add_dir_block):
+ icount.c (insert_icount_el):
+ irel_ma.c (ima_put):
+ rs_bitmap.c (ext2fs_resize_generic_bitmap): Update functions to
+ pass the old size of the memory to be resized to
+ ext2fs_resize_mem().
+
+1998-03-30 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.in: Change to use new installation directory variables
+ convention. Fix uninstall rules to take $(DESTDIR) into
+ account.
+
+1998-03-29 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: If __STRICT_ANSI__ is defined and we're on a platform
+ with 32 bit longs, then we need to manually define __s64
+ and __u64, since the current kernel header files don't
+ define these if __STRICT_ANSI__ is defined. This is a
+ problem if we are compiling with full GCC warnings, since
+ we do need 64 bit support.
+
+ * Makefile.in (OBJS): Remove bmove.o from files to be built,
+ since we're not using ext2fs_move_blocks() and there
+ is some question as to its usefulness in its current
+ form.
+
+ * bmap.c (block_bmap): Remove unused function.
+
+ * bmove.c (process_block): Fix -Wall warning.
+
+1998-03-23 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * block.c (ext2fs_block_iterate3): Make the ref_offset field
+ contain the offset into the inode.i_blocks array when
+ ref_block is zero. Since we haven't done a formal
+ release of e2fsprogs since block_iterate2 was first
+ introduced, I removed block_iterate2, and renamed
+ block_iterate3 to be block_iterate2.
+
+ * bb_inode.c, bmove.c, dblist_dir.c, dir_iterate.c,
+ expanddir.c, ext2fs.h, ext2fsP.h, read_bb.c: Change
+ use of block_iterate and block_iterate2 to
+ block_iterate2 with the new prototype for the
+ interator function. (using blkcnt_t forr blockcount)
+
+1998-03-21 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: Add new superblock fields (s_algorithm_usage_bitmap,
+ s_prealloc_blocks, s_prealloc_dir_blocks). Added
+ conditional defines of new features COMPAT_DIR_PREALLOC,
+ RO_COMPAT_LARGE_FILE RO_COMPAT_BTREE_DIR,
+ INCOMPAT_COMPRESSION, INCOMPAT_DIRNAME_SIZE. Changed
+ the library to declare that we support COMPAT_DIR_PREALLOC,
+ INCOMPAT_DIRNAME_SIZE, RO_COMPAT_LARGE_FILE.
+
+ * fileio.c: Rename function ext2fs_file_llseek to be
+ ext2fs_file_lseek, which is more accurate.
+
+ * block.c: Add new function ext2fs_block_iterate3 which calls
+ the iterator function with the blockcount argument of
+ type blkcnt_t. This version of the function is
+ allowed to handle large files; the other fucntions are
+ not.
+
+ * ext2fs.h: Add new type blkcnt_t
+
+ * ext2_err.et.in: Add error code EXT2_ET_FILE_TOO_BIG
+
+ * block.c (ext2fs_block_iterate2): Fix bug where the block count
+ field wasn't getting correctly incremented for sparse
+ files when the indirect or doubly-indirect block
+ specified in the inode was zero.
+
+Sun Mar 8 22:42:47 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * unlink.c (unlink_proc):
+ * lookup.c (lookup_proc):
+ * link.c (link_proc):
+ * get_pathname.c (get_pathname_proc):
+ * dir_iterate.c (ext2fs_process_dir_block): Mask off high 8 bits
+ from dirent->name_len, so it can be used for other
+ purposes.
+
+ * ext2fs.h: Add definition of EXT2_FEATURE_INCOMPAT_DIRNAME_SIZE,
+ and indicate that we have support for this incompatible
+ option.
+
+Mon Feb 23 08:46:33 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2_err.et.in: Added new error code, EXT2_ET_CANCEL_REQUESTED.
+
+Fri Feb 20 23:58:01 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * dblist.c (ext2fs_get_num_dirs): Improve the estimation of the
+ number of directories when the block group information is
+ unreliable.
+
+1998-02-20 Theodore Y. Ts'o <tytso@edt.mit.edu>
+
+ * inode.c (ext2fs_get_next_inode): Always do the check to see if the
+ inode table is missing so that we catch the case where the
+ first block group is missing.
+
+ * getsize.c, ismounted.c, unix_io.c: #include errno.h since it's
+ needed.
+
+Mon Feb 16 16:16:00 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2_io.h, ext2fs.h: Protect against being included multiple times.
+
+ * bmove.c: #include ext2fsP.h instead of "ext2fs/ext2fs.h"
+
+ * test_io.c (test_flush): Add a debugging printf when the flush
+ method is called.
+
+ * rw_bitmaps.c (ext2fs_read_bitmaps): If the bitmaps are already
+ read in, return right away.
+
+Sun Feb 1 08:20:24 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * bitops.h: Don't try to do i386 inline asm functions if the
+ compiler isn't GCC.
+
+ * ext2fs.h: If EXT2_FLAT_INCLUDES is defined, #include e2_types.h,
+ instead of linux/types.h, and e2_bitops.h instead of
+ ext2fs/bitops.h.
+
+ * icount.c, version.c: Don't #include <et/com_err.h>, as it isn't
+ necessary.
+
+Sat Jan 17 13:13:31 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_open_inode_scan): Initialize the group variables
+ so that we don't need to call get_next_blockgroup() the
+ first time around. Saves a bit of time, and prevents us
+ from needing to assign -1 to current_group (which is an
+ unsigned value).
+
+ * icount.c (insert_icount_el): Cast the estimated number of inodes
+ from a float to an ino_t.
+
+ * alloc.c, alloc_tables.c, badlbocks.c, bb_compat.c, bb_inode.c,
+ bitmaps.c, bitops.c, block.c, bmap.c, bmove.c, brel_ma.c,
+ check_desc.c, closefs.c, cmp_bitmaps.c, dblist.c,
+ dblist_dir.c, dir_iterate.c, dirblock.c, dupfs.c,
+ expanddir.c, ext2fs.h, fileio.c, freefs.c,
+ get_pathname.c, getsize.c, icount.c, initialize.c,
+ inline.c, inode.c, irel_ma.c, ismounted.c, link.c,
+ lookup.c, mkdir.c, namei.c, native.c, newdir.c,
+ openfs.c, read_bb.c, read_bb_file.c, rs_bitmap.c,
+ rw_bitmaps.c, swapfs.c, test_io.c, tst_badblocks.c,
+ tst_getsize.c, tst_iscan.c, unix_io.c, unlink.c,
+ valid_blk.c, version.c: If EXT2_FLAT_INCLUDES is
+ defined, then assume all of the
+ ext2-specific header files are in a flat directory.
+
+ * block.c, bmove.c, dirblock.c, fileio.c: Explicitly cast
+ all assignments from void * to be compatible with C++.
+
+Tue Jan 6 11:28:15 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * closefs.c (ext2fs_flush): Add a call to io_channel_flush() to
+ make sure the contents of the disk are flushed to disk.
+
+Mon Dec 29 14:39:13 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * dblist.c (ext2fs_add_dir_block): Change new to be new_entry to
+ avoid C++ namespace clash.
+
+ * bitmaps.c (ext2fs_copy_bitmap): Change new to be new_map to
+ avoid C++ namespace clash.
+
+ * ext2fs.h, bb_inode.c, block.c, bmove.c, brel.h, brel_ma.c,
+ irel.h, irel_ma.c, dblist.c, dblist_dir.c, dir_iterate.c,
+ ext2fsP.h, expanddir.c, get_pathname.c, inode.c, link.c,
+ unlink.c: Change private to be priv_data (to avoid C++
+ namespace clash)
+
+Fri Nov 28 09:26:31 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * dblist.c (ext2fs_get_num_dirs): Make ext2fs_get_num_dirs more
+ paranoid about validating the directory counts from the
+ block group information.
+
+ * all files: Don't include stdlib.h anymore; include it in
+ ext2_fs.h, since that file requires stdlib.h
+
+Thu Nov 20 16:07:38 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * expanddir.c (ext2fs_expand_dir): Check to make sure the block
+ bitmap is loaded, and return an error if it is not.
+ (expand_dir_proc): Only use ext2fs_write_dir_block when
+ writing a directory block, not when writing out a fresh
+ indirect block.
+
+Tue Nov 11 22:46:45 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.in, tst_getsize.c: Added new file which is used to test
+ the ext2fs_get_device_size function.
+
+ * ext2_err.et.in (EXT2_ET_UNIMPLEMENTED): Added new error code.
+
+Sun Nov 2 20:36:13 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: Make ext2fs_get_mem take an unsigned argument.
+
+ * fileio.c (ext2fs_file_get_size, ext2fs_file_set_size,
+ ext2fs_file_get_fs): New functions added.
+
+
+Fri Oct 31 12:16:52 1997 <tytso@EDT.MIT.EDU>
+
+ * bitops.c (ext2fs_warn_bitmap, ext2fs_warn_bitmap2): Don't call
+ com_err if OMIT_COM_ERR is defined.
+
+Thu Oct 30 11:33:57 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Rename new error codes to _ET_ in them for consistency.
+
+Sat Oct 25 00:06:58 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * [all files, basically]: Added definition of ext2fs_get_mem,
+ ext2fs_free_mem, and ext2fs_resize_mem in ext2fs.h, and
+ changed all library routines to use these wrapper functions.
+
+ * dblist.c, mkdir.c: use EXT2_DIR_EXISTS and EXT2_DB_NOT_FOUND
+ instead of the system error messages.
+
+ * ext2_err.et.in: Added new error messages EXT2_DIR_EXISTS and
+ EXT2_DB_NOT_FOUND
+
+ * ext2fs.h: Added function declarations and constants for bmap.c
+ and fileio.c.
+
+ * ext2_err.et.in: Added new error messages EXT2_FILE_RO and
+ EXT2_ET_MAGIC_EXT2_FILE
+
+ * Makefile.in: Added files bmap.c and fileio.c, and temporarily
+ commented out brel_ma.c and irel_ma.c
+
+ * bmap.c: New file which maps a file's logical block number to its
+ physical block number.
+
+ * fileio.c: New file which implements simple file reading and
+ writing primitives.
+
+ * alloc.c (ext2fs_alloc_block): New function which allocates a
+ block, zeros it, and updates the filesystem accounting
+ records appropriately.
+
+Wed Oct 22 16:47:27 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2_err.et.in: Added new error codes: EXT2_NO_MEMORY,
+ EXT2_INVALID_ARGUMENT, EXT2_BLOCK_ALLOC_FAIL,
+ EXT2_INODE_ALLOC_FAIL, EXT2_NOT_DIRECTORY
+
+ * Change various library files to use these functions instead of
+ EINVAL, ENOENT, etc.
+
+Mon Oct 20 19:32:40 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * llseek.c: Check HAVE_LLSEEK_PROTOTYPE to see whether or not we
+ need to declare llseek().
+
+Sun Oct 19 18:56:22 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Rename io.h to be ext2_io.h (avoid namespace collisions)
+
+ * Add #ifdef's for HAVE_SYS_STAT_H and HAVE_SYS_TYPES_H
+
+Fri Oct 3 13:35:59 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * llseek.c (ext2fs_llseek): Fix type error for ext2fs_llseek()
+
+ * icount.c (ext2fs_icount_validate):
+ * bmove.c (process_block): Fix lint error in type for fprintf().
+
+Mon Sep 15 11:45:09 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_check_directory): Add support for the callback
+ to return the error code EXT2_ET_CALLBACK_NOTHANDLED.
+
+Thu Sep 4 12:28:22 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * bitmaps.c (ext2fs_set_bitmap_padding): New function which sets the
+ padding of the bitmap to be all one's.
+
+Wed Sep 3 14:27:30 1997 Theodore Y. Ts'o <tytso@edt.mit.edu>
+
+ * llseek.c: Added missing semicolon to glibc fixup declaration of
+ llseek().
+
+ * bmove.c: Add #include of errno.h
+
+Sat Aug 23 22:47:46 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.in (ELF_SO_VERSION): Bump version to be 2.4 since we've
+ added a new field to the io_channel (app_data).
+
+ * io.h: Add a new element to the io_channel structure, app_data.
+
+ * initialize.c, openfs.c: Set io->app_data to point at the
+ filesystem handle.
+
+Thu Aug 14 08:14:17 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * io.h: Change the prototype of ext2fs_llseek() to use int's
+ instead of unsigned int's.
+
+ * llseek.c: Change to allow PIC and !HAVE_LLSEEK. Add a prototype
+ to make life easer for GNU Libc 2.
+
+ * rw_bitmaps.c: On the PowerPC, the big-endian variant of the ext2
+ filesystem has its bitmaps stored as 32-bit words with bit
+ 0 as the LSB of each word. Thus a bitmap with only bit 0
+ set would be, as a string of bytes, 00 00 00 01 00 ... To
+ cope with this, we byte-reverse each word of a bitmap if
+ we have a big-endian filesystem, that is, if we are *not*
+ byte-swapping other word-sized numbers.
+
+Mon Aug 11 03:30:48 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * dosio.c: New file to do DOS/BIOS disk accesses.
+
+ * namei.c (open_namei): Make pathlen be of type size_t.
+
+ * llseek.c: Always #include stdlib.h since it's need to define
+ size_t.
+
+ * io.h: Use errcode_t for magic numbers.
+
+ * icount.c (get_icount_el): Use size_t where appropriate
+
+ * dupfs.c (ext2fs_dup_handle):
+ * dblist.c (dir_block_cmp): Use size_t where appropriate.
+
+ * read_bb.c (ext2fs_read_bb_inode):
+ * cmp_bitmaps.c (ext2fs_compare_inode_bitmap): Use blk_t, ino_t
+ and size_t where appropriate.
+
+ * closefs.c (ext2fs_flush): Use dgrp_t instead of int where
+ appropriate.
+
+ * openfs.c (ext2fs_open):
+ * check_desc.c (ext2fs_check_desc): Use blk_t instead of int where
+ appropriate.
+
+ * rw_bitmaps.c (read_bitmaps):
+ * irel_ma.c:
+ * inode.c (ext2fs_write_inode):
+ * initialize.c (ext2fs_initialize):
+ * brel_ma.c: Fix to make be 16-bit safe.
+
+ * link.c (ext2fs_link):
+ * unlink.c (ext2fs_unlink):
+ * lookup.c (lookup_proc):
+ * ismounted.c (ext2fs_check_if_mounted):
+ * block.c (xlate_func): Add #pragma argsused for Turbo C.
+
+Sun Aug 10 10:05:22 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * block.c (ext2fs_block_iterate2): Use retval which is a errcode_t
+ type.
+
+ * bitmaps.c (make_bitmap): Use size_t instead of int where
+ appropriate.
+
+ * bb_inode.c (set_bad_block_proc): Add #pragma argsused for Turbo C.
+
+ * alloc.c (ext2fs_new_inode): Use ino_t instead of int for the
+ group number.
+
+ * get_pathname.c: Use ino_t instead of int where appropriate.
+
+ * ext2fs.h: Make the magic structure element be errcode_t instead
+ of int.
+
+ * alloc.c alloc_tables.c badblocks.c bb_compat.c bb_inode.c
+ bitmaps.c block.c bmove.c brel_ma.c check_desc.c closefs.c
+ cmp_bitmaps.c dblist.c dblist_dir.c dir_iterate.c
+ dirblock.c dupfs.c expanddir.c freefs.c get_pathname.c
+ icount.c initialize.c inline.c inode.c irel_ma.c link.c
+ llseek.c lookup.c mkdir.c namei.c newdir.c read_bb.c
+ read_bb_file.c rs_bitmap.c rw_bitmaps.c swapfs.c
+ test_io.c tst_badblocks.c tst_iscan.c unix_io.c unlink.c
+ valid_blk.c version.c: Add an #ifdef for HAVE_UNISTD_H
+
+Tue Jun 17 01:33:20 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * unix_io.c (unix_read_blk): If ext2fs_llseek() fails, but errno
+ is zero, then return EXT2_IO_LLSEEK_FAILED.
+
+ * ext2_err.et.in: Add a new error code, EXT2_IO_LLSEEK_FAILED.
+
+ * Release of E2fsprogs 1.11
+
+Mon Jun 16 23:53:06 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * dblist.c (ext2fs_dblist_count): Added new function which returns
+ the number of directory blocks in dblist.
+
+Sat Jun 14 01:39:13 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * unix_io.c (unix_flush): Make the io_channel flush function do a
+ fsync to flush the kernel buffers to disk.
+
+Wed Jun 11 18:25:31 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_inode_scan_goto_blockgroup): Fix bug; the
+ current inode number wasn't being set by the
+ goto_blockgroup function.
+
+Mon Jun 9 10:45:48 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * bmove.c (ext2fs_move_blocks): New function which takes a bitmap
+ of blocks which need to be moved, and moves those blocks
+ to another location in the filesystem.
+
+ * rs_bitmap.c (ext2fs_resize_generic_bitmap): When expanding a
+ bitmap, make sure all of the new parts of the bitmap are
+ zero.
+
+Sun Jun 8 16:24:39 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * bitmaps.c (ext2fs_copy_bitmap): Fix bug; the destination bitmap
+ wasn't being returned to the caller.
+
+ * alloc_tables.c (ext2fs_allocate_group_table): Add new function
+ ext2fs_allocate_group_table() which sets the group tables
+ for a particular block group. The relevant code was
+ factored out of ext2fs_allocate_tables().
+
+ * dblist.c (make_dblist): Adjust the initial size of the directory
+ block list to be a bit more realistic (ten plus twice the
+ number of directories in the filesystem).
+
+Thu May 8 22:19:09 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * badblocks.c (ext2fs_badblocks_list_test): Fix bug where
+ ext2fs_badblocks_list_test would test the list (and exceed
+ array boundaries) if there were no bad blocks on the bad
+ blocks list. (Showed up when user tried: mke2fs -c -b 4096).
+
+Thu Apr 24 12:16:42 1997 Theodre Ts'o <tytso@localhost.mit.edu>
+
+ * Release of E2fsprogs version 1.10
+
+Thu Apr 24 10:13:42 1997 Theodre Ts'o <tytso@localhost.mit.edu>
+
+ * alloc_tables.c (ext2fs_allocate_tables): Correctly place the
+ inode and block bitmaps based on the RAID 0 stride
+ parameter (which is passed by mke2fs).
+
+ * ext2fs.h: Add "stride" parameter to ext2_filsys, to be used by
+ mke2fs to communicate the stride length to
+ ext2fs_allocate_tables()
+
+Wed Apr 23 21:50:42 1997 Theodre Ts'o <tytso@localhost.mit.edu>
+
+ * initialize.c (ext2fs_initialize): Fix to compile under Linux 1.2
+ systems. (We can't assume that the new filesystem types
+ are supported.)
+
+Wed Apr 23 18:40:53 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * alloc_tables.c (ext2fs_allocate_tables): Make sure that we
+ allocate the inode and block bitmaps inside block group at
+ all times.
+
+Mon Apr 21 00:06:28 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * alloc.c (ext2fs_new_block): Fix bug where if goal==0 and the
+ filesystem has no free blocks, ext2fs_new_block would loop
+ forever.
+
+ * dupfs.c (ext2fs_dup_handle): Duplicate an ext2 filesystem handle
+
+ * freefs.c (ext2fs_free_inode_cache): Decrement refcount and only
+ free if refcount goes to zero.
+
+ * inode.c (create_icache): Initialize refcount to 1.
+
+ * ext2fsP.h: Added refcount to ext2_inode_cache
+
+ * dblist.c (ext2fs_copy_dblist): New function to copy a directory
+ block list.
+
+ * badblocks.c (ext2fs_badblocks_copy): New function to copy a
+ badblocks structure.
+
+Sun Apr 20 23:19:51 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * bitmaps.c (ext2fs_copy_bitmap): New function to copy a bitmap.
+
+ * unix_io.c, test_io.c (unix_open, test_open): Initialize the
+ refcount to 1.
+ (unix_close, test_close): Decrement the refcount and only
+ close the io_channel if the refcount goes to 0.
+
+ * io.h: Add refcount to the io_channel structure. Add new macro
+ interface io_channel_bumpcount() to bump the refcount.
+
+Thu Apr 17 20:25:03 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_read_inode, ext2fs_write_inode): Use the inode
+ cache in the filesystem handle, instead of the inode cache
+ in a static variable.
+
+ * freefs.c: Added static function to free the inode cache (called by
+ ext2fs_free).
+
+ * ext2fsP.h: Added definition of the ext2_inode_cache structures.
+
+ * ext2fs.h: Added pointer to the inode_cache structure.
+
+ * block.c (block_iterate_ind, block_iterate_dind,
+ block_iterate_tind): If there are holes in the indirect,
+ doubly indirect, or triply indirect blocks, increment the
+ block count field automatically.
+
+Thu Apr 17 12:23:38 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.09
+
+Mon Apr 14 20:38:56 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * version.c (ext2fs_parse_version_string): Check the passed in
+ version string (instead of the hard-coded one).
+
+ * alloc_tables.c (ext2fs_allocate_tables): If the last block is
+ greater filesystem size, clamp it to prevent allocating a
+ block or inode bitmap beyond the filesystem.
+
+ * initialize.c (ext2fs_initialize): Fix bug where the metatdata
+ overhead calculation was accidentally removed.
+
+Fri Apr 11 18:56:26 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.08
+
+Thu Apr 10 13:15:15 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * dblist.c (ext2fs_set_dir_block): New function which sets the
+ block of a dblist entry, given the directory inode and
+ blockcnt.
+
+Sat Apr 5 12:42:42 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * alloc_tables.c (ext2fs_allocate_tables): Allocate the bitmap and
+ inode bitmaps at staggered locations across the block
+ groups, to avoid concentrating the bitmaps on a small
+ number of disks when using striped RAID arrays.
+
+ * initialize.c (ext2fs_initialize): By default, choose the maximum
+ possible number of blocks per group (based on the size of
+ the bitmaps in the blocksize).
+
+Fri Apr 4 11:28:16 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c (ext2fs_initialize): Add support for
+ EXT2_COMPAT_SPARSE_SUPER feature.
+
+ * closefs.c (ext2fs_bg_has_super): New function to determine
+ whether or a particular block group should have a
+ superblock and block group descriptor. Used for the
+ EXT2_COMPAT_SPARSE_SUPER feature is turned on.
+ (ext2fs_flush): Check ext2fs_bg_has_super to see whether
+ or not the superblock should be written out for the block
+ group.
+
+ * ext2fs.h (EXT2_COMPAT_SPARSE_SUPER): Define compatibility flag
+ for sparse duplicate superblocks.
+
+ * version.c (ext2fs_get_library_version): New function which
+ returns the library version.
+
+ * version.c (ext2fs_parse_version_string): New function which
+ parses a version string and returns a version number,
+ so application programs can compare version numbers as
+ integers.
+
+Wed Mar 26 00:43:52 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * icount.c (ext2fs_create_icount): Change function so that it also
+ takes a new argument which contains a "hint" icount
+ structure. This "hint" icount allows the create function
+ to set up the sorted list in advance. This reduces
+ significantly the amount of data moving needed to insert
+ these inodes into the list later.
+
+ * icount.c (ext2fs_icount_validate): New function which validates
+ that the icount structure's rep invariant.
+
+ * icount.c (get_icount_el): Completely revamped implementation
+ to subsume put_icount_el(). Put_icount_el() used to
+ use an O(N) implementation to insert in the middle
+ of the icount list. It now uses a O(ln N) to search
+ for where the icount should be inserted, and then uses
+ a memcpy to move the list down (instead of a for loop).
+
+ * icount.c (ext2fs_icount_fetch, ext2fs_icount_store,
+ ext2fs_icount_increment, ext2fs_icount_decrement): Check
+ to see if the inode is within bounds; if it isn't, return
+ EINVAL.
+
+ * bitops.h (ext2fs_test_generic_bitmap): Fix error message given
+ when a bad inode number is passed to test_generic_bitmap
+ to be EXT2FS_TEST_ERROR instead of the wrong
+ EXT2FS_UNMARK_ERROR.
+
+Wed Mar 12 13:32:05 1997 Theodore Y. Ts'o <tytso@mit.edu>
+
+ * Release of E2fsprogs version 1.07
+
+Sun Mar 2 16:46:18 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.in (ELF_VERSION): Change version to be 2.2
+
+Tue Feb 11 14:54:02 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * alloc.c (ext2fs_get_free_blocks): Change routine to use
+ ext2fs_fast_test_block_bitmap_range().
+
+ * bitops.h (ext2fs_fast_test_block_bitmap_range,
+ ext2fs_test_block_bitmap_range: New inline functions which
+ test to see whether a contiguous range of blocks is
+ available.
+
+Thu Feb 6 10:00:13 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * badblocks.c (ext2fs_badblocks_list_create): Rename sybmols to use
+ use ext2fs_badblocks_* instead of badblocks_*
+
+ * bb_compat.c: New file which translates between old badblocks_*()
+ names to ext2fs_badblocks_*()
+
+ * unlink.c (ext2fs_unlink): New file, moved ext2fs_unlink() from
+ link.c (since e2fsck doesn't use ext2fs_unlink()).
+
+ * rs_bitmap.c (ext2fs_resize_generic_bitmap): New file, contains
+ bitmap resizing routine moved from bitmaps.c, since e2fsck
+ doesn't need to use this function.
+
+ * lookup.c (ext2fs_lookup): Moved ext2fs_lookup to its own file,
+ since e2fsck only needs ext2fs_lookup.
+
+Mon Feb 3 10:11:40 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_open_inode_scan): Set fs->badblocks if it is not
+ already set; this is needed so that programs like dump
+ which use the inode scan functions will deal with
+ filesystems that have bad blocks in the inode table.
+
+Sun Feb 2 00:17:36 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h (struct_badblocks_list, struct_badblocks_iterate):
+ Moved to ext2fsP.h, since it doesn't need to be part of
+ the public interface.
+
+ * dir_iterate.c: Move ext2_dir_iterate out of namei.c.
+
+Sat Feb 1 10:14:55 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * dblist.c (ext2fs_get_num_dirs): New file, which implements a
+ directory block list abstraction. (Code moved from
+ e2fsck).
+
+ * ext2fs.h, inode.c: Moved definition of ext2_struct_inode_scan to
+ to inode.c (since no one else should be peeking inside it!)
+
+ * valid_blk.c (ext2_inode_has_valid_blocks): New function.
+
+ * openfs.c (ext2fs_open): Check the feature set in the ext2
+ superblock, and refuse to open filesystems if they contain
+ incompatible features. (Can be overriden with the
+ EXT2_FLAG_FORCE
+
+Sun Jan 12 11:31:46 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * block.c (ext2fs_block_iterate2): Added new function
+ ext2fs_block_iterate2 which changes the function
+ signature of the callback function to include the
+ referencing block and offset.
+
+ * inode.c (ext2fs_inode_scan_goto_blockgroup): Added new function
+ ext2fs_inode_scan_goto_blockgroup which allows an
+ application to jump to a particular block group while
+ doing an inode scan.
+
+Wed Jan 1 23:50:12 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * dirblock.c: Include string.h, since we use memcpy().
+
+Tue Dec 3 12:27:29 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * getsize.c (ext2fs_get_device_size): The ioctl BLKGETSIZE returns
+ a long not an int; this doesn't matter on i386 machines,
+ but it does on Alpha's.
+
+Fri Nov 29 20:57:37 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_write_inode, ext2fs_read_inode): If the inode
+ table pointer is NULL, then return an error indicating
+ that the inode table is missing.
+ (get_next_blockgroup, get_next_blocks,
+ ext2fs_get_next_inode): Don't treat a missing inode table
+ as permanent error. Return MISSING_INODE_TABLE, but as an
+ advisory error code, much like BAD_BLOCK_IN_INODE_TABLE.
+
+ * rw_bitmaps.c (ext2fs_write_block_bitmap,
+ ext2fs_write_inode_bitmap): If the inode or block bitmap
+ block is zero, then don't write out the inode or block
+ bitmap. The idea here is to avoid stomping on the
+ superblock.
+ (read_bitmaps): If the inode or block bitmap block is
+ zero, then fill in that portion of the inode or block
+ bitmap with all zeros.
+
+ * inode.c (ext2fs_get_next_inode): Fix bug in handling of bad
+ blocks in inode table when the inode table size is
+ non-standard (and can therefore span blocks).
+
+Tue Oct 29 20:13:14 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * alloc.c (ext2fs_new_block): Fix fencepost error in
+ ext2fs_new_block; make sure we don't try to allocate the
+ first block beyond the end of the filesystem.
+
+Mon Oct 14 11:00:48 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (check_for_inode_bad_blocks): New function called by
+ get_next_blocks() to avoid reading in bad blocks marked in
+ fs->badblocks. Inodes located in bad blocks are returned
+ by ext2fs_get_next_inode() returns the error code
+ EXT2_ET_BAD_BLOCK_IN_INODE_TABLE.
+
+ * alloc_tables.c (ext2fs_allocate_tables): New function which
+ performs the part of mke2fs's job of allocating the
+ filesystem tables.
+
+ * test_io.c (test_close): IO manager which is used for testing
+ purposes.
+
+Sun Oct 13 04:31:57 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_get_next_inode): Separate out the function of
+ setting up for a new block group to get_next_blockgroup().
+ Separate out the function of reading in blocks of the
+ inode table to get_next_blocks().
+
+ * ext2fs.h: Add the badblocks list to the ext2_filsys entry
+
+ * badblocks.c (badblocks_list_add, badblocks_list_test): Add
+ blocks to the badblock list in sorted order. This allows
+ badblocks_list_test to be coded using a binary search for
+ speed.
+
+Tue Oct 8 02:02:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.06
+
+Mon Oct 7 00:44:17 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h, block.c, closefs.c, dirblock.c, inode.c, native.c,
+ open.c: Change EXT2_SWAP to EXT2_FLAG_SWAP for
+ consistency's sake.
+
+ * closefs.c (ext2fs_flush): If the flag EXT2_MASTER_SB_ONLY is
+ set, then only write out the master superblock.
+
+Sun Oct 6 21:45:26 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * block.c (ext2fs_block_iterate): Fixed bug which caused
+ block_iterate to fail to handle HURD created filesystems;
+ it tested the inode translator field before the inode was
+ loaded.
+
+Tue Sep 17 14:08:24 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c (ext2fs_initialize): Make sure the description for
+ the inode bitmap is set correctly.
+
+ * bitmaps.c (ext2fs_allocate_generic_bitmap): Fix minor type typo.
+
+Thu Sep 12 15:23:07 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.05
+
+Sat Sep 7 07:36:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c: Override the kernel's idea of default
+ checkinterval from 0 (never) to 180 days.
+
+Wed Aug 28 03:20:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * namei.c (ext2fs_namei_follow): New function which follows
+ symbolic link (if any) at the target.
+
+Tue Aug 27 01:48:43 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_read_inode, ext2fs_write_inode): Add support
+ for shortcut function fs->read_inode() and fs->write_inode().
+ Added inode_cache to reduce CPU time spent in doing
+ byte swapping.
+
+ * swapfs.c (ext2fs_swap_super): Swap the new fields in a V2
+ superblock.
+
+ * namei.c (ext2fs_follow_link): New function.
+ (ext2fs_namei): Extended to have support for chasing
+ symbolic links. ext2fs_namei() still returns an inode
+ which is a symbolic link. Symbolic links are only chased
+ while resolving the containing directory. To chase
+ symbolic links of the final result, use
+ ext2fs_follow_link().
+
+Mon Aug 26 23:46:07 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2_err.et.in: Added new error code EXT2_ET_SYMLINK_LOOP.
+
+ * bitops.h (ext2fs_set_bit, ext2fs_celar_bit): Use asm inlines
+ provided by Pete A. Zaitcev (zaitcev@lab.sun.mcst.ru).
+
+Thu Aug 22 00:40:18 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c (ext2fs_initialize): On systems where the byte
+ order is not i386 compatible, set the swap_byte flag.
+
+ * inode.c (inocpy_with_swap): Check to see if inode contains a
+ fast symlink before swapping the inode block fields. This
+ required adding a new argument to inocpy_with_swap to
+ determine whether the mode field is in host order or not.
+
+Wed Aug 21 00:45:42 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * bitops.h (ext2fs_set_bit, ext2fs_clear_bit, ext2fs_test_bit): On
+ the sparc, if EXT2_STD_BITOPS set, use the standard
+ i386-compatible bitmask operations, instead on the
+ non-standard native bitmask operators.
+
+Fri Aug 9 11:11:35 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * block.c (ext2fs_block_iterate): Cause block iterator to return
+ the HURD translator block (along with everything else).
+ If the flag BLOCK_FLAG_DATA_ONLY is passed to the block
+ iterator, then don't return any meta data blocks
+ (including the HURD translator).
+
+Wed Jul 17 17:13:34 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * gen_uuid.c: New file, which generates DCE-compatible UUIDs.
+
+ * uuid.c: New file, containing UUID utility functions.
+
+Tue Jul 16 10:19:16 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: Add a definition of the "real" ext2 superblock.
+
+Fri May 24 14:54:55 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: Fix erroneous ino_t type used in block_bitmap type.
+
+Sun May 19 15:39:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * openfs.c (ext2fs_open): If the blocksize in the superblock is
+ zero, return the error EXT2_ET_CORRUPT_SUPERBLOCK, since
+ that's a basic value that must be correct for the rest of
+ the library to work.
+
+ * ext2_err.et.in (EXT2_ET_CORRUPT_SUPERBLOCK): Added new error
+ code.
+
+Thu May 16 11:12:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.04
+
+Wed Mar 27 00:33:40 1996 <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.03
+
+Tue Mar 26 12:06:32 1996 <tytso@rsts-11.mit.edu>
+
+ * bitops.h (ext2fs_set_bit, ext2fs_clear_bit, ext2fs_test_bit):
+ Change the m68k bit numbering for bitmasks to match with
+ the bit numbering used by all other ext2 implementations.
+
+Thu Mar 7 03:37:00 1996 <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_get_next_inode, ext2fs_close_inode_scan,
+ ext2fs_open_inode_scan): Support dynamically-sized inodes.
+
+Wed Mar 6 12:26:29 1996 <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_read_inode, ext2fs_write_inode): Support
+ dynamically-sized inodes.
+
+ * openfs.c (ext2fs_open): Allow dynamic revision filesystem to be
+ loaded.
+
+Tue Mar 5 03:49:37 1996 <tytso@rsts-11.mit.edu>
+
+ * initialize.c (ext2fs_initialize): Catch an error condition where
+ the passed in size is *really* too small.
+
+ * alloc.c (ext2fs_new_inode):
+ * ext2fs.h (EXT2_FIRST_INODE): Add support for dynamic revision to
+ get first inode.
+
+Wed Feb 21 15:56:17 1996 <tytso@rsts-11.mit.edu>
+
+ * getsize.c (ext2fs_get_device_size): Open the device read-only
+ when trying to determine its size.
+
+Wed Jan 31 11:06:08 1996 <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.02
+
+Sat Dec 9 09:57:50 1995 <tytso@rsts-11.mit.edu>
+
+ * rw_bitops.c (ext2fs_write_block_bitmap):
+ * bitops.c (ext2fs_test_bit, ext2fs_clear_bit, ext2fs_set_bit):
+ * bitops.h (ext2fs_test_bit, ext2fs_clear_bit, ext2fs_set_bit):
+ Rename {test,set,clear}_bit to ext2fs_{test,set,clear}_bit,
+ to avoid conflicts with with kernel include files. Also
+ rename ADDR and CONST_ADDR to EXT2FS_ADDR and
+ EXT2FS_CONST_ADDR.
+
+Thu Oct 26 12:09:16 1995 <tytso@rsts-11.mit.edu>
+
+ * ext2_err.et: Updated message in EXT2_ET_BASE to say version 0.5c
+
+ * swapfs.c (ext2fs_swap_super): Put an #ifdef check around
+ s_def_resuid and s_def_resgid for backwards compatibility.
+
+Fri Oct 20 23:33:31 1995 <tytso@rsts-11.mit.edu>
+
+ * bitops.h: Added #ifdef's for Sparc.
+
+Wed Sep 6 22:14:46 1995 <tytso@rsts-11.mit.edu>
+
+ * getsize.c: #include <sys/ioctl.h> under Linux to pick up ioctl()
+ declaration
+
+ * closefs.c: #include <string.h> to pick up memset() declaration
+
+Mon Sep 4 21:45:29 1995 Remy Card <card@bbj>
+
+ * Makefile.in: Added support for BSD shared libraries.
+
+ * initialize.c (ext2fs_initialize): Correctly set the s_creator_os
+ flag.
+
+Mon Sep 4 09:55:30 1995 <tytso@rsts-11.mit.edu>
+
+ * unix_io.c (unix_open): Add a double check; if the passed in name
+ is NULL, return EXT2_ET_BAD_DEVICE_NAME.
+
+ * ext2_err.et (EXT2_ET_BAD_DEVICE_NAME): Added new error code
+
+Wed Aug 16 15:44:10 1995 <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_check_directory): Use LINUX_S_ISDIR instead of
+ S_ISDIR.
+
+Tue Aug 15 13:08:36 1995 <tytso@rsts-11.mit.edu>
+
+ * getsize.c (ext2fs_get_device_size): Add support for reading the
+ partition size from a BSD disk label.
+
+Thu Aug 10 09:33:26 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
+
+ * getsize.c (ext2fs_get_device_size): New function that determins
+ the size of a device. Used by mke2fs and e2fsck.
+
+Sat Aug 12 03:09:54 1995 Remy Card <card@bbj>
+
+ * Makefile.in (install): Install static libraries in $(ulibdir)
+ (/usr/lib on Linux) instead of $(libdir) (/lib on Linux).
+
+Wed Aug 9 17:04:23 1995 Theodore Y. Ts'o <tytso@dcl>
+
+ * bitmaps.c (ext2fs_free_inode_bitmap, ext2fs_free_block_bitmap):
+ Move these functions to freefs.c.
+
+ * closefs.c (ext2fs_flush): If swapping blocks, clear the group
+ descriptors shadow memory to keep purify quiet. (This
+ also has the nice benefit that the unused portion of the
+ shadow descriptors are zeroed out.)
+
+ * dirblock.c (ext2fs_write_dir_block): We need to use
+ dirent->rec_len *before* it's byteswapped to find the
+ location of the next directory structure!
+
+ * alloc.c (ext2fs_new_inode): Fix bug which could potentially
+ cause ext2fs_new_inode to loop infinitely if we're trying
+ to allocate an inode in group #0 and there are no free
+ inodes at all in the system.
+
+ * closefs.c: #include <errno.h> if it exists.
+
+Sun Aug 6 13:27:50 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
+
+ * ext2fs.h (BLOCK_FLAG_HOLE): Added new definition for
+ BLOCK_FLAG_APPEND. Added documentation for the block
+ interator flags.
+
+Sat Aug 5 11:44:05 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
+
+ * Makefile.in (DLL_INSTALL_DIR, ELF_INSTALL_DIR): Set the
+ installation directories correctly.
+
+Tue Jul 18 09:27:38 1995 <tytso@rsx-11.mit.edu>
+
+ * namei.c (process_dir_block):
+ * mkdir.c (ext2fs_mkdir):
+ * expanddir.c (expand_dir_proc): Use ext2fs_{read,write}_dir_block
+ to read/write the directory block.
+
+ * dirblock.c (ext2fs_read_dir_block), ext2fs_write_dir_block): New
+ file containing functions for reading and writing
+ directory blocks (byte swapping if necesssary)
+
+ * block.c (block_iterate_ind, block_iterate_dind,
+ block_iterate_tind): Byte swap the block addresses if
+ EXT2_SWAP_BYTES is set (and swap them back before writing
+ them out.)
+
+ * inode.c (inocpy_with_swap): New function.
+ (ext2fs_get_next_inode, ext2fs_read_inode, ext2fs_write_inode):
+ Call inocpy_with_swap if EXT2_SWAP_BYTES if set.
+
+ * closefs.c (ext2fs_flush): If EXT2_SWAP_BYTES is set, then swap
+ the superblock and group descriptors before writing it out.
+
+ * openfs.c (ext2fs_open): If the magic number is byte-swapped,
+ then set the EXT2_SWAP_BYTES and byte-swap the superblock
+ and group descriptors.
+
+ * swapfs.c (ext2fs_swap_super, ext2fs_swap_group_desc): New functions
+ to desp ext2 filesystem structures.
+
+ * bitops.c (set_bit, clear_bit, test_bit): Use modifications
+ supplied by Pete A. Zaitcev so that the C language
+ versions of these functions are more portable. They will
+ now work on both little and big endian systems, and the
+ assumption that 32-bit integers are used is gone.
+
+ * bitops.h (ext2_swab16, ext2_swab32): Added new functions for
+ doing byte swapping.
+
+ * ext2fs.h (EXT2_SWAP_BYTES): Add new flag which indicates that
+ byte swapping should take place.
+
+Sun Jul 16 06:21:43 1995 <tytso@rsx-11.mit.edu>
+
+ * Makefile.in, cmp_bitmaps.c (ext2fs_compare_block_bitmap_end,
+ ext2fs_compare_inode_bitmap_end): Added new file
+ containing routines to compare bitmaps.
+
+ * ext2_err.et (EXT2_ET_NEQ_BLOCK_BITMAP, EXT2_ET_NEQ_INODE_BITMAP):
+ Added new error codes.
+
+Sat Jul 15 04:23:37 1995 <tytso@rsx-11.mit.edu>
+
+ * inode.c (ext2fs_get_next_inode): Don't check scan->inode_buffer;
+ if the magic number is correct, it will be allocated.
+
+Fri Jul 14 19:02:59 1995 <tytso@rsx-11.mit.edu>
+
+ * block.c (block_iterate_ind, block_iterate_dind,
+ block_iterate_tind): Don't recompute block_nr each loop;
+ just increment it! Factor check of BLOCK_FLAG_APPEND out
+ of the loop. Factor mask of BLOCK_CHANGED into changed
+ variable out of the loop. (block_iterate_ind, in
+ particular, gets called a lot, so every little
+ optimization helps.)
+
+Thu Jul 13 08:02:45 1995 <tytso@rsx-11.mit.edu>
+
+ * block.c (block_iterate_ind, block_iterate_dind,
+ block_iterate_tind): Precompute limit of loop to speed up
+ block_iterate_ind and company.
+
+ * bitops.h (ext2fs_fast_mark_block_bitmap,
+ ext2fs_fast_unmark_block_bitmap, ext2fs_fast_test_block_bitmap,
+ ext2fs_fast_mark_inode_bitmap, ext2fs_fast_unmark_inode_bitmap,
+ ext2fs_fast_test_inode_bitmap): Add fast version of these
+ functions, which don't do range checking.
+
+ * bitops.h (ext2fs_get_block_bitmap_start,
+ ext2fs_get_inode_bitmap_start, ext2fs_get_block_bitmap_end,
+ ext2fs_get_inode_bitmap_end): Add new accessor functions
+ which return the start and end points of the bitmaps.
+
+Tue Jul 11 18:59:41 1995 <tytso@rsx-11.mit.edu>
+
+ * llseek.c (ext2_llseek): If the offset is small enough, use lseek
+ instead of llseek. The errno if the offset is too large
+ and lseek is not supported should be EINVAL, not -EINVAL.
+
+Thu Jun 15 23:43:02 1995 Remy Card <card@bbj>
+
+ * Makefile.in: Added support for ELF shared libraries.
+ Fixed typos in the compilation rules.
+ (distclean): Added Makefile.
+
+ * llseek.c (llseek): New function, if llseek() does not exist in the
+ C library.
+ (ext2_llseek): Changed to call llseek().
+
+Mon Jun 12 08:29:07 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
+
+ * ext2fs.h: Use __u32 to define blk_t, instead of unsigned long.
+
+Sun Jun 11 15:02:54 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
+
+ * mkdir.c (ext2fs_mkdir): Use LINUX_S_IFDIR instead of S_IFDIR.
+
+ * ext2fs.h (LINUX_S_IFDIR): Define a linux specific versions of
+ the S_*, which are normally defined in <sys/stat.h>. This
+ allows us to compile e2fsprogs on a non-Linux system,
+ which may have a different value for S_IFDIR.
+
+Sat Jun 10 23:47:05 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
+
+ * bitops.c (clear_bit, set_bit): Remove calls to cli() and sti();
+ this is a user-mode application!
+
+Thu Jun 8 13:13:22 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
+
+ * llseek.c: Put the include of <linux/unistd.h> inside the #ifdef
+ __linux__ so that non-linux systems won't see it.
+
+ * alloc.c: Include <errno.h> if possible.
+ * badblocks.c: Ditto.
+ * bb_inode.c: Ditto.
+ * bitmaps.c: Ditto.
+ * block.c: Ditto.
+ * expanddir.c: Ditto.
+ * get_pathname.c: Ditto.
+ * initialize.c: Ditto.
+ * inode.c: Ditto.
+ * llseek.c: Ditto.
+ * mkdir.c: Ditto.
+ * namei.c: Ditto.
+ * newdir.c: Ditto.
+ * openfs.c: Ditto.
+ * rw_bitmaps.c: Ditto.
+ * unix_io.c: Ditto.
+
+ * Makefile.in: Rewritten to conform to GNU coding standards and
+ support separate compilation directories.
+
+Thu May 11 04:13:12 1995 <tytso@rsx-11.mit.edu>
+
+ * initialize.c (ext2fs_initialize): Don't allow more than one
+ bitmaps's worth of inodes in a group.
+
+Sat Mar 11 14:07:11 1995 Theodore Y. Ts'o <tytso@localhost>
+
+ * llseek.c (ext2_llseek): Added error checking to the llseek()
+ compat code to protect against overflow. This only
+ applies to 1.0 and early 1.1 kernels, which don't support
+ the llseek() system call.
+
+Thu Nov 24 16:29:00 1994 Theodore Y. Ts'o (tytso@rt-11)
+
+ * unix_io.c (unix_open): Initialize the read_error and write_error
+ io_channel pointers to be null.
+
+ * bb_inode.c (clear_bad_block_proc): If an illegal block number is
+ found, clear it but don't try to update the filesystem
+ accounting information, since that's hopeless anyway.
+
+ * block.c (bloblock_iterate_ind, bloblock_iterate_dind,
+ bloblock_iterate_tind): Check to see if the indirect blocks are
+ valid before trying to read them.
+
+ * ext2_err.et (EXT2_ET_BAD_IND_BLOCK, EX2_ET_BAD_DIND_BLOCK,
+ EXT2_ET_BAD_TIND_BLOCK): Add new error codes.
+
+ * bitops.h (ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
+ ext2fs_test_block_bitmap, ext2fs_mark_inode_bitmap,
+ ext2fs_unmark_inode_bitmap, ext2fs_test_inode_bitmap): If an
+ illegal block or inode number is passed in, return instead
+ of trying to test, set, or clear the bit.
+
+Mon Nov 7 21:32:33 1994 Remy Card <card@bbj>
+
+ * Makefile: Added a dummy install target in case shared libraries
+ are not built.
+
+Mon Oct 24 14:11:44 1994 (tytso@rsx-11)
+
+ * bitmaps.c (ext2fs_allocate_block_bitmap): Fix calculation of how
+ the real last block of the bitmap should be calculated.
+
+Wed Sep 7 10:05:36 1994 (tytso@rsx-11)
+
+ * bitmaps.c (ext2fs_fudge_inode_bitmap_end,
+ ext2fs_fudge_block_bitmap_end, ext2fs_clear_inode_bitmap,
+ ext2fs_clear_block_bitmap, ext2fs_free_inode_bitmap,
+ ext2fs_free_block_bitmap): Add magic number checking for
+ the inode and block bitmaps.
+
+ * bitmaps.c (ext2fs_allocate_block_bitmap): Fix to set the correct
+ magic number for a block bitmap instead of an inode bitmap.
+
+ * inode.c (ext2fs_close_inode_scan, ext2fs_get_next_inode): Add
+ magic number checking for the inode_scan structure.
+
+ * badblocks.c (badblocks_list_free, badblocks_list_add,
+ badblocks_list_test, badblocks_list_iterate_begin,
+ badblocks_list_iterate, badblocks_list_iterate_end): Add
+ magic number checking for the badblocks_list and
+ badblocks_iterate structures.
+
+ * ext2_err.et (EXT2_ET_MAGIC_UNIX_IO_CHANNEL):
+ * unix_io.c (unix_open, unix_close, unix_set_blksize, unix_read_blk,
+ unix_write_blk, unix_flush): Add magic number checking
+ both for io_channel structure and unix_private_data
+ structure.
+
+ * openfs.c (ext2fs_open): Add check for io_manager structure's
+ magic number.
+
+ * rw_bitmaps.c (ext2fs_write_inode_bitmap, ext2fs_write_block_bitmap,
+ ext2fs_read_inode_bitmap, ext2fs_read_block_bitmap,
+ ext2fs_read_bitmaps, ext2fs_write_bitmaps):
+ * read_bb.c (ext2fs_read_bb_inode):
+ * read_bb_file.c (ext2fs_read_bb_FILE):
+ * newdir.c (ext2fs_new_dir_block):
+ * namei.c (ext2fs_dir_iterate, ext2fs_lookup, ext2fs_namei):
+ * link.c (ext2fs_link, ext2fs_unlink):
+ * inode.c (ext2fs_open_inode_scan, ext2fs_read_inode,
+ ext2fs_write_inode, ext2fs_get_blocks,
+ ext2fs_check_directory):
+ * get_pathname.c (ext2fs_get_pathname):
+ * expanddir.c (ext2fs_expand_dir):
+ * block.c (ext2fs_block_iterate):
+ * bitmaps.c (ext2fs_allocate_inode_bitmap,
+ ext2fs_allocate_block_bitmap):
+ * bb_inode.c (ext2fs_update_bb_inode):
+ * alloc.c (ext2fs_new_inode,ext2fs_new_block,ext2fs_get_free_blocks):
+ * check_desc.c (ext2fs_check_desc):
+ * closefs.c (ext2fs_close, ext2fs_flush):
+ * freefs.c (ext2fs_free): Add check for ext2_filsys magic number.
+
+ * Makefile:
+ * ext2fs.h:
+ * openfs.c:
+ * check_desc.c (ext2fs_check_desc): Move ext2fs_check_desc from
+ openfs.c into its own file.
+
+ * ext2fs.h (EXT2_CHECK_MAGIC): Added macro for checking for
+ structure magic numbers.
+
+ * closefs.c (ext2fs_flush): Folded in Remy Card's changes to clear
+ the EXT2_VALID_FS flag in the backup superblock blocks, so that if
+ someone uses the -b option to specify the use of the backup
+ superblock --- this usually means that the main superblock is
+ toast. :-)
+
+ * ext2fs.h:
+ * ext2_err.et (EXT2_ET_REV_TOO_HIGH):
+ * openfs.c (ext2fs_open): Folded in Remy Card's changes to add a
+ revision level to the superblock.
+
+Sun Aug 21 00:50:08 1994 Theodore Y. Ts'o (tytso@rt-11)
+
+ * ext2fs.h:
+ * bitmaps.c:
+ * bitops.c
+ * bitops.h:
+ * openfs.c:
+ * initialize.c: Completely revamped the inode and block bitmap
+ structures, so that they can be better chance of being extensible
+ in a shared library. They are now their own type, instead of
+ being a char *. Also, the function signatures of
+ ext2fs_test_block_bitmap, ext2fs_mark_block_bitmap,
+ ext2fs_unmark_block_bitmap, ext2fs_test_inode_bitmap,
+ ext2fs_mark_inode_bitmap, and ext2fs_unmark_inode_bitmap were
+ changed to eliminate the ext2_filsys argument, since it is no
+ longer necessary.
+
+Wed Aug 17 21:46:44 1994 Remy Card (card@bbj)
+
+ * unix_io.c (unix_read_blk and unix_write_blk): use the llseek
+ system call if available.
+
+ * llseek.c: new file. This is the stub calling the llseek system
+ call which allows supports for 2GB+ file systems.
+
+ * initialize.c (ext2fs_initialize): Ext2fs_initialize now stores
+ the creator operating system.
+
+Wed Aug 17 10:03:24 1994 Theodore Y. Ts'o (tytso@rt-11)
+
+ * initialize.c (ext2fs_initialize): Ext2fs_initialize now sets up
+ the group descriptor statistics in addition to everything else.
+ This relieves mke2fs of the responsibility of doing it.
+
+ * bitops.c, bitops.h: Add assembly inline functions for the 68000.
+ Added a new #define, _EXT2_HAVE_ASM_BITOPS_ to control whether or
+ not the generic C function equivalents should be included or not.
+
+ * openfs.c (ext2fs_open): If a superblock is specified, then use
+ the backup group descriptors that go along with this superblock,
+ instead of using the primary group descriptors. This allows
+ e2fsck to recover filesystems where the primary group descriptors
+ have been trashed.
+
+
diff --git a/e2fslib/MCONFIG b/e2fslib/MCONFIG
new file mode 100644
index 0000000..5fde38f
--- /dev/null
+++ b/e2fslib/MCONFIG
@@ -0,0 +1,199 @@
+# Beginning of file MCONFIG
+
+all::
+
+check::
+
+SHELL = /bin/sh
+
+prefix = /usr
+root_prefix =
+exec_prefix = ${prefix}
+root_bindir = $(root_prefix)/bin
+root_sbindir = $(root_prefix)/sbin
+root_libdir = $(root_prefix)/lib
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libdir = ${exec_prefix}/lib
+includedir = ${prefix}/include
+mandir = ${prefix}/man
+man1dir = $(mandir)/man1
+man3dir = $(mandir)/man3
+man8dir = $(mandir)/man8
+infodir = ${prefix}/info
+datadir = ${prefix}/share
+
+
+
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+CC = cc
+BUILD_CC = cc
+DEFS = -DENABLE_SWAPFS=1 -DPACKAGE=\"e2fsprogs\" -DVERSION=\"1.25\" -DSTDC_HEADERS=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_ARGZ_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1 -DHAVE_NL_TYPES_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_GETCWD=1 -DHAVE_MUNMAP=1 -DHAVE_PUTENV=1 -DHAVE_SETENV=1 -DHAVE_SETLOCALE=1 -DHAVE_STRCHR=1 -DHAVE_STRCASECMP=1 -DHAVE_STRDUP=1 -DHAVE___ARGZ_COUNT=1 -DHAVE___ARGZ_STRINGIFY=1 -DHAVE___ARGZ_NEXT=1 -DHAVE_STPCPY=1 -DHAVE_STPCPY=1 -DHAVE_LC_MESSAGES=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1 -DHAVE_ERRNO_H=1 -DHAVE_MALLOC_H=1 -DHAVE_MNTENT_H=1 -DHAVE_PATHS_H=1 -DHAVE_DIRENT_H=1 -DHAVE_GETOPT_H=1 -DHAVE_SETJMP_H=1 -DHAVE_SIGNAL_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_LINUX_FD_H=1 -DHAVE_LINUX_MAJOR_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_MOUNT_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_NET_IF_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_VPRINTF=1 -DHAVE_LSEEK64_PROTOTYPE=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DWORDS_BIGENDIAN=1 -DHAVE_GETRUSAGE=1 -DHAVE_LLSEEK=1 -DHAVE_LSEEK64=1 -DHAVE_OPEN64=1 -DHAVE_STRCASECMP=1 -DHAVE_SRANDOM=1 -DHAVE_FCHOWN=1 -DHAVE_MALLINFO=1 -DHAVE_FDATASYNC=1 -DHAVE_STRNLEN=1 -DHAVE_EXT2_IOCTLS=1
+CFLAGS = -g -O2
+CPPFLAGS =
+ALL_CFLAGS = $(CPPFLAGS) $(DEFS) $(USE_WFLAGS) $(CFLAGS) $(XTRA_CFLAGS) \
+ -I$(top_builddir)/lib -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/include $(LINUX_INCLUDE)
+LDFLAGS =
+ALL_LDFLAGS = $(LDFLAGS)
+RM = /bin/rm
+LN = /bin/ln
+LN_S = ln -s
+MV = /bin/mv
+CP = /bin/cp
+CHMOD = /bin/chmod
+AR = ar
+AWK = /usr/bin/awk
+SED = /bin/sed
+PERL = /usr/bin/perl
+RANLIB = ranlib
+STRIP = strip
+LD = $(PURE) cc
+ARUPD = $(AR) r
+LDCONFIG = :
+
+#
+# Library definitions
+#
+LIB = $(top_builddir)/lib
+LIBSS = $(LIB)/libss.a
+LIBCOM_ERR = $(LIB)/libcom_err.a
+LIBE2P = $(LIB)/libe2p.a
+LIBEXT2FS = $(LIB)/libext2fs.a
+LIBUUID = $(LIB)/libuuid.a
+DEPLIBUUID = $(LIB)/libuuid.a
+
+STATIC_LIBSS = $(LIB)/libss.a
+STATIC_LIBCOM_ERR = $(LIB)/libcom_err.a
+STATIC_LIBE2P = $(LIB)/libe2p.a
+STATIC_LIBEXT2FS = $(LIB)/libext2fs.a
+STATIC_LIBUUID = $(LIB)/libuuid.a
+DEPSTATIC_LIBUUID = $(LIB)/libuuid.a
+
+PROFILED_LIBSS = $(LIB)/libss
+PROFILED_LIBCOM_ERR = $(LIB)/libcom_err
+PROFILED_LIBE2P = $(LIB)/libe2p
+PROFILED_LIBEXT2FS = $(LIB)/libext2fs
+PROFILED_LIBUUID = $(LIB)/libuuid
+DEPPROFILED_LIBUUID = $(LIB)/libuuid
+
+#
+# Use these definitions is you use tools 2.x, x < 16
+#
+#DLL_BIN=/usr/dll/bin
+#JUMP_PREFIX=/usr/dll/jump/
+
+#
+# Use these definitions if you use tools 2.16 or above
+#
+DLL_BIN=/usr/bin
+JUMP_PREFIX=/usr/bin/jump
+
+# An include directive pointing to a directory holding enough linux-like
+# include files to satisfy some programs here
+LINUX_INCLUDE=
+
+#
+# A fast substitution command for fixing up man pages, shell scripts, etc.
+#
+SUBST_CONF=$(top_builddir)/util/subst.conf
+SUBSTITUTE= $(top_builddir)/util/subst -f $(SUBST_CONF)
+DEP_SUBSTITUTE= $(top_builddir)/util/subst $(SUBST_CONF)
+
+$(top_builddir)/util/subst:
+ cd $(top_builddir)/util ; $(MAKE) subst
+
+#
+# Warning flags
+#
+# Run make gcc-wall to do a build with warning messages.
+#
+#
+WFLAGS= -ansi -D_POSIX_SOURCE -pedantic \
+ -Wall -Wwrite-strings -Wpointer-arith \
+ -Wcast-qual -Wcast-align -Wtraditional \
+ -Wstrict-prototypes -Wmissing-prototypes \
+ -Wnested-externs -Winline -DNO_INLINE_FUNCS -Wshadow
+
+gcc-wall-new:
+ (make USE_WFLAGS="$(WFLAGS)" > /dev/null) 2>&1 | sed -f $(top_srcdir)/util/gcc-wall-cleanup
+
+gcc-wall:
+ make clean > /dev/null
+ make gcc-wall-new
+
+#
+# Installation user and groups
+#
+BINGRP= bin
+BINOWN= bin
+BINMODE= 555
+INCGRP= bin
+INCOWN= bin
+INCMODE= 444
+LIBOWN= bin
+LIBGRP= bin
+LIBMODE= 444
+MANGRP= bin
+MANOWN= bin
+MANMODE= 444
+
+#
+# Autoconf magic...
+#
+
+DEP_LIB_MAKEFILES = $(top_srcdir)/lib/Makefile.elf-lib \
+ $(top_srcdir)/lib/Makefile.dll-lib $(top_srcdir)/lib/Makefile.bsd-lib \
+ $(top_srcdir)/lib/Makefile.checker $(top_srcdir)/lib/Makefile.profile
+
+$(top_builddir)/config.status: $(top_srcdir)/configure
+ cd $(top_builddir); ./config.status --recheck
+
+$(top_builddir)/MCONFIG: $(top_srcdir)/MCONFIG.in $(top_builddir)/config.status
+ cd $(top_builddir); CONFIG_FILES=MCONFIG ./config.status
+
+$(top_builddir)/lib/substitute_sh: $(top_srcdir)/lib/substitute_sh.in \
+ $(top_builddir)/config.status
+ cd $(top_builddir); CONFIG_FILES=lib/substitute_sh ./config.status
+
+$(top_builddir)/util/subst.conf: $(top_srcdir)/util/subst.conf.in \
+ $(top_builddir)/config.status
+ cd $(top_builddir); CONFIG_FILES=util/subst.conf ./config.status
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/MCONFIG \
+ $(DEP_MAKEFILE) $(top_builddir)/config.status
+ cd $(top_builddir); CONFIG_FILES=$(my_dir)/Makefile ./config.status
+
+$(top_srcdir)/configure: $(top_srcdir)/configure.in
+ cd $(top_srcdir) && autoconf
+
+#
+# Make depend magic...
+#
+
+.depend: Makefile $(SRCS) $(top_srcdir)/depfix.sed $(top_srcdir)/wordwrap.pl
+ if test -n "$(SRCS)" ; then \
+ $(CC) -M $(ALL_CFLAGS) $(SRCS) | \
+ $(SED) -f $(top_srcdir)/depfix.sed \
+ -e 's; $(srcdir)/; $$(srcdir)/;g' \
+ -e 's; $(top_srcdir)/; $$(top_srcdir)/;g' \
+ -e 's; $(top_builddir)/; $$(top_builddir)/;g' \
+ -e 's; \./; ;g' \
+ -e '/^ *\\$$/d' | \
+ $(PERL) $(top_srcdir)/wordwrap.pl > .depend; \
+ else :; fi
+
+depend:: .depend
+ if test -n "$(SRCS)" ; then \
+ sed -e '/^# +++ Dependency line eater +++/,$$d' \
+ < $(srcdir)/Makefile.in | cat - .depend \
+ > $(srcdir)/Makefile.in.new; \
+ if cmp -s $(srcdir)/Makefile.in $(srcdir)/Makefile.in.new ; then \
+ $(RM) $(srcdir)/Makefile.in.new ; \
+ else \
+ $(MV) $(srcdir)/Makefile.in $(srcdir)/Makefile.in.old; \
+ $(MV) $(srcdir)/Makefile.in.new $(srcdir)/Makefile.in; \
+ fi ; else :; fi
+
+# End of file MCONFIG
diff --git a/e2fslib/Makefile b/e2fslib/Makefile
new file mode 100644
index 0000000..dd3f6cf
--- /dev/null
+++ b/e2fslib/Makefile
@@ -0,0 +1,642 @@
+# Generated automatically from Makefile.in by configure.
+srcdir = .
+top_srcdir = ../..
+top_builddir = ../..
+my_dir = lib/ext2fs
+INSTALL = /usr/bin/install -c
+
+
+# Beginning of file MCONFIG
+
+all::
+
+check::
+
+SHELL = /bin/sh
+
+prefix = /usr
+root_prefix =
+exec_prefix = ${prefix}
+root_bindir = $(root_prefix)/bin
+root_sbindir = $(root_prefix)/sbin
+root_libdir = $(root_prefix)/lib
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libdir = ${exec_prefix}/lib
+includedir = ${prefix}/include
+mandir = ${prefix}/man
+man1dir = $(mandir)/man1
+man3dir = $(mandir)/man3
+man8dir = $(mandir)/man8
+infodir = ${prefix}/info
+datadir = ${prefix}/share
+
+
+
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+CC = cc
+BUILD_CC = cc
+DEFS = -DENABLE_SWAPFS=1 -DPACKAGE=\"e2fsprogs\" -DVERSION=\"1.25\" -DSTDC_HEADERS=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_ARGZ_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1 -DHAVE_NL_TYPES_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_GETCWD=1 -DHAVE_MUNMAP=1 -DHAVE_PUTENV=1 -DHAVE_SETENV=1 -DHAVE_SETLOCALE=1 -DHAVE_STRCHR=1 -DHAVE_STRCASECMP=1 -DHAVE_STRDUP=1 -DHAVE___ARGZ_COUNT=1 -DHAVE___ARGZ_STRINGIFY=1 -DHAVE___ARGZ_NEXT=1 -DHAVE_STPCPY=1 -DHAVE_STPCPY=1 -DHAVE_LC_MESSAGES=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1 -DHAVE_ERRNO_H=1 -DHAVE_MALLOC_H=1 -DHAVE_MNTENT_H=1 -DHAVE_PATHS_H=1 -DHAVE_DIRENT_H=1 -DHAVE_GETOPT_H=1 -DHAVE_SETJMP_H=1 -DHAVE_SIGNAL_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_LINUX_FD_H=1 -DHAVE_LINUX_MAJOR_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_MOUNT_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_NET_IF_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_VPRINTF=1 -DHAVE_LSEEK64_PROTOTYPE=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DWORDS_BIGENDIAN=1 -DHAVE_GETRUSAGE=1 -DHAVE_LLSEEK=1 -DHAVE_LSEEK64=1 -DHAVE_OPEN64=1 -DHAVE_STRCASECMP=1 -DHAVE_SRANDOM=1 -DHAVE_FCHOWN=1 -DHAVE_MALLINFO=1 -DHAVE_FDATASYNC=1 -DHAVE_STRNLEN=1 -DHAVE_EXT2_IOCTLS=1
+CFLAGS = -g -O -G 0 -fno-pic -mno-abicalls
+CPPFLAGS =
+ALL_CFLAGS = $(CPPFLAGS) $(DEFS) $(USE_WFLAGS) $(CFLAGS) $(XTRA_CFLAGS) \
+ -I. $(LINUX_INCLUDE)
+LDFLAGS =
+ALL_LDFLAGS = $(LDFLAGS)
+RM = /bin/rm
+LN = /bin/ln
+LN_S = ln -s
+MV = /bin/mv
+CP = /bin/cp
+CHMOD = /bin/chmod
+AR = ar
+AWK = /usr/bin/awk
+SED = /bin/sed
+PERL = /usr/bin/perl
+RANLIB = ranlib
+STRIP = strip
+LD = $(PURE) cc
+ARUPD = $(AR) r
+LDCONFIG = :
+
+#
+# Library definitions
+#
+LIB = $(top_builddir)/lib
+LIBSS = $(LIB)/libss.a
+LIBCOM_ERR = $(LIB)/libcom_err.a
+LIBE2P = $(LIB)/libe2p.a
+LIBEXT2FS = $(LIB)/libext2fs.a
+LIBUUID = $(LIB)/libuuid.a
+DEPLIBUUID = $(LIB)/libuuid.a
+
+STATIC_LIBSS = $(LIB)/libss.a
+STATIC_LIBCOM_ERR = $(LIB)/libcom_err.a
+STATIC_LIBE2P = $(LIB)/libe2p.a
+STATIC_LIBEXT2FS = $(LIB)/libext2fs.a
+STATIC_LIBUUID = $(LIB)/libuuid.a
+DEPSTATIC_LIBUUID = $(LIB)/libuuid.a
+
+PROFILED_LIBSS = $(LIB)/libss
+PROFILED_LIBCOM_ERR = $(LIB)/libcom_err
+PROFILED_LIBE2P = $(LIB)/libe2p
+PROFILED_LIBEXT2FS = $(LIB)/libext2fs
+PROFILED_LIBUUID = $(LIB)/libuuid
+DEPPROFILED_LIBUUID = $(LIB)/libuuid
+
+#
+# Use these definitions if you use tools 2.16 or above
+#
+DLL_BIN=/usr/bin
+JUMP_PREFIX=/usr/bin/jump
+
+# An include directive pointing to a directory holding enough linux-like
+# include files to satisfy some programs here
+LINUX_INCLUDE=
+
+#
+# A fast substitution command for fixing up man pages, shell scripts, etc.
+#
+SUBST_CONF=util/subst.conf
+SUBSTITUTE=util/subst -f $(SUBST_CONF)
+DEP_SUBSTITUTE=util/subst $(SUBST_CONF)
+
+$(top_builddir)/util/subst:
+ cd $(top_builddir)/util ; $(MAKE) subst
+
+#
+# Warning flags
+#
+# Run make gcc-wall to do a build with warning messages.
+#
+#
+WFLAGS= -ansi -D_POSIX_SOURCE -pedantic \
+ -Wall -Wwrite-strings -Wpointer-arith \
+ -Wcast-qual -Wcast-align -Wtraditional \
+ -Wstrict-prototypes -Wmissing-prototypes \
+ -Wnested-externs -Winline -DNO_INLINE_FUNCS -Wshadow
+
+gcc-wall-new:
+ (make USE_WFLAGS="$(WFLAGS)" > /dev/null) 2>&1 | sed -f $(top_srcdir)/util/gcc-wall-cleanup
+
+gcc-wall:
+ make clean > /dev/null
+ make gcc-wall-new
+
+#
+# Installation user and groups
+#
+BINGRP= bin
+BINOWN= bin
+BINMODE= 555
+INCGRP= bin
+INCOWN= bin
+INCMODE= 444
+LIBOWN= bin
+LIBGRP= bin
+LIBMODE= 444
+MANGRP= bin
+MANOWN= bin
+MANMODE= 444
+
+#
+# Autoconf magic...
+#
+
+DEP_LIB_MAKEFILES = $(top_srcdir)/lib/Makefile.elf-lib \
+ $(top_srcdir)/lib/Makefile.dll-lib $(top_srcdir)/lib/Makefile.bsd-lib \
+ $(top_srcdir)/lib/Makefile.checker $(top_srcdir)/lib/Makefile.profile
+
+$(top_builddir)/config.status: $(top_srcdir)/configure
+ cd $(top_builddir); ./config.status --recheck
+
+$(top_builddir)/lib/substitute_sh: $(top_srcdir)/lib/substitute_sh.in \
+ $(top_builddir)/config.status
+ cd $(top_builddir); CONFIG_FILES=lib/substitute_sh ./config.status
+
+$(top_builddir)/util/subst.conf: $(top_srcdir)/util/subst.conf.in \
+ $(top_builddir)/config.status
+ cd $(top_builddir); CONFIG_FILES=util/subst.conf ./config.status
+
+$(top_srcdir)/configure: $(top_srcdir)/configure.in
+ cd $(top_srcdir) && autoconf
+
+#
+# Make depend magic...
+#
+
+.depend: Makefile $(SRCS) $(top_srcdir)/depfix.sed $(top_srcdir)/wordwrap.pl
+ if test -n "$(SRCS)" ; then \
+ $(CC) -M $(ALL_CFLAGS) $(SRCS) | \
+ $(SED) -f $(top_srcdir)/depfix.sed \
+ -e 's; $(srcdir)/; $$(srcdir)/;g' \
+ -e 's; $(top_srcdir)/; $$(top_srcdir)/;g' \
+ -e 's; $(top_builddir)/; $$(top_builddir)/;g' \
+ -e 's; \./; ;g' \
+ -e '/^ *\\$$/d' | \
+ $(PERL) $(top_srcdir)/wordwrap.pl > .depend; \
+ else :; fi
+
+depend:: .depend
+ if test -n "$(SRCS)" ; then \
+ sed -e '/^# +++ Dependency line eater +++/,$$d' \
+ < $(srcdir)/Makefile.in | cat - .depend \
+ > $(srcdir)/Makefile.in.new; \
+ if cmp -s $(srcdir)/Makefile.in $(srcdir)/Makefile.in.new ; then \
+ $(RM) $(srcdir)/Makefile.in.new ; \
+ else \
+ $(MV) $(srcdir)/Makefile.in $(srcdir)/Makefile.in.old; \
+ $(MV) $(srcdir)/Makefile.in.new $(srcdir)/Makefile.in; \
+ fi ; else :; fi
+
+# End of file MCONFIG
+
+DEBUGFS_LIB_OBJS = bb_compat.o cmp_bitmaps.o dupfs.o fileio.o \
+ namei.o test_io.o write_bb_file.o
+
+RESIZE_LIB_OBJS = rs_bitmap.o
+
+E2IMAGE_LIB_OBJS = imager.o
+
+OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
+ ext2_err.o \
+ alloc.o \
+ alloc_tables.o \
+ badblocks.o \
+ bb_inode.o \
+ bitmaps.o \
+ bitops.o \
+ block.o \
+ bmap.o \
+ check_desc.o \
+ closefs.o \
+ dblist.o \
+ dblist_dir.o \
+ dirblock.o \
+ dir_iterate.o \
+ expanddir.o \
+ ext_attr.o \
+ finddev.o \
+ flushb.o \
+ freefs.o \
+ gen_bitmap.o \
+ get_pathname.o \
+ getsize.o \
+ icount.o \
+ initialize.o \
+ inline.o \
+ inode.o \
+ ismounted.o \
+ link.o \
+ llseek.o \
+ lookup.o \
+ mkdir.o \
+ mkjournal.o \
+ native.o \
+ newdir.o \
+ openfs.o \
+ read_bb.o \
+ read_bb_file.o \
+ rw_bitmaps.o \
+ swapfs.o \
+ unix_io.o \
+ unlink.o \
+ valid_blk.o \
+ version.o
+
+SRCS= ext2_err.c \
+ $(srcdir)/alloc.c \
+ $(srcdir)/alloc_tables.c \
+ $(srcdir)/badblocks.c \
+ $(srcdir)/bb_compat.c \
+ $(srcdir)/bb_inode.c \
+ $(srcdir)/bitmaps.c \
+ $(srcdir)/bitops.c \
+ $(srcdir)/block.c \
+ $(srcdir)/bmap.c \
+ $(srcdir)/check_desc.c \
+ $(srcdir)/closefs.c \
+ $(srcdir)/cmp_bitmaps.c \
+ $(srcdir)/dblist.c \
+ $(srcdir)/dblist_dir.c \
+ $(srcdir)/dirblock.c \
+ $(srcdir)/dir_iterate.c \
+ $(srcdir)/dupfs.c \
+ $(srcdir)/expanddir.c \
+ $(srcdir)/ext_attr.c \
+ $(srcdir)/fileio.c \
+ $(srcdir)/finddev.c \
+ $(srcdir)/flushb.c \
+ $(srcdir)/freefs.c \
+ $(srcdir)/gen_bitmap.c \
+ $(srcdir)/get_pathname.c \
+ $(srcdir)/getsize.c \
+ $(srcdir)/icount.c \
+ $(srcdir)/imager.c \
+ $(srcdir)/initialize.c \
+ $(srcdir)/inline.c \
+ $(srcdir)/inode.c \
+ $(srcdir)/ismounted.c \
+ $(srcdir)/link.c \
+ $(srcdir)/llseek.c \
+ $(srcdir)/lookup.c \
+ $(srcdir)/mkdir.c \
+ $(srcdir)/mkjournal.c \
+ $(srcdir)/namei.c \
+ $(srcdir)/native.c \
+ $(srcdir)/newdir.c \
+ $(srcdir)/openfs.c \
+ $(srcdir)/read_bb.c \
+ $(srcdir)/read_bb_file.c \
+ $(srcdir)/rs_bitmap.c \
+ $(srcdir)/rw_bitmaps.c \
+ $(srcdir)/swapfs.c \
+ $(srcdir)/test_io.c \
+ $(srcdir)/unix_io.c \
+ $(srcdir)/unlink.c \
+ $(srcdir)/valid_blk.c \
+ $(srcdir)/version.c \
+ $(srcdir)/write_bb_file.c \
+ $(srcdir)/tst_badblocks.c \
+ $(srcdir)/tst_bitops.c \
+ $(srcdir)/tst_byteswap.c \
+ $(srcdir)/tst_getsize.c \
+ $(srcdir)/tst_iscan.c
+
+HFILES= bitops.h ext2fs.h ext2_io.h ext2_fs.h ext2_ext_attr.h
+HFILES_IN= ext2_err.h ext2_types.h
+
+LIBRARY= libext2fs
+LIBDIR= ext2fs
+
+DLL_ADDRESS = 0x66900000
+DLL_JUMPSIZE = 0x1000
+DLL_GOTSIZE = 0x1000
+DLL_VERSION = 1.2
+DLL_IMAGE = libe2fs
+DLL_STUB = libext2fs
+DLL_LIBS = -L../.. -lcom_err
+DLL_MYDIR = ext2fs
+DLL_INSTALL_DIR = $(root_libdir)
+
+ELF_VERSION = 2.4
+ELF_SO_VERSION = 2
+ELF_IMAGE = libext2fs
+ELF_MYDIR = ext2fs
+ELF_INSTALL_DIR = $(root_libdir)
+ELF_OTHER_LIBS = -L../.. -lcom_err
+
+BSDLIB_VERSION = 2.1
+BSDLIB_IMAGE = libext2fs
+BSDLIB_MYDIR = ext2fs
+BSDLIB_INSTALL_DIR = $(root_libdir)
+
+
+all:: subdirs $(LIBRARY).a
+
+install-shlibs::
+
+subdirs::
+
+$(LIBRARY).a: $(OBJS)
+ (if test -r $@; then $(RM) -f $@.bak && $(MV) $@ $@.bak; fi)
+ $(ARUPD) $@ $(OBJS)
+ -$(RANLIB) $@
+
+.c.o:
+ $(CC) $(ALL_CFLAGS) -c $< -o $@
+# $(CC) $(ALL_CFLAGS) -g -pg -o profiled/$*.o -c $<
+# $(CC) $(ALL_CFLAGS) -checker -g -o checker/$*.o -c $<
+# (export JUMP_DIR=`pwd`/jump; $(CC) -B$(JUMP_PREFIX) $(ALL_CFLAGS) \
+# -o jump/$*.o -c $<)
+# $(CC) $(ALL_CFLAGS) -fPIC -o elfshared/$*.o -c $<
+# $(CC) $(ALL_CFLAGS) -fpic -o pic/$*.o -c $<
+
+COMPILE_ET=et/compile_et
+
+DISTFILES= Makefile *.c *.h image
+
+ext2_err.et: $(DEP_SUBSTITUTE) $(srcdir)/ext2_err.et.in
+ $(SUBSTITUTE) $(srcdir)/ext2_err.et.in ext2_err.et
+
+ext2_err.c ext2_err.h: ext2_err.et
+ $(COMPILE_ET) ext2_err.et
+
+tst_badblocks: tst_badblocks.o freefs.o \
+ read_bb_file.o write_bb_file.o badblocks.o
+ $(CC) -o tst_badblocks tst_badblocks.o freefs.o \
+ read_bb_file.o write_bb_file.o badblocks.o $(LIBCOM_ERR)
+
+tst_iscan: tst_iscan.o inode.o badblocks.o test_io.o $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_iscan tst_iscan.o inode.o badblocks.o test_io.o \
+ $(STATIC_LIBEXT2FS) $(LIBCOM_ERR)
+
+tst_getsize: tst_getsize.o getsize.o $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_getsize tst_getsize.o getsize.o $(STATIC_LIBEXT2FS) \
+ $(LIBCOM_ERR)
+
+tst_ismounted: $(srcdir)/ismounted.c $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_ismounted $(srcdir)/ismounted.c -DDEBUG $(ALL_CFLAGS) $(LIBCOM_ERR)
+
+tst_byteswap: tst_byteswap.o bitops.o $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_byteswap tst_byteswap.o bitops.o $(STATIC_LIBEXT2FS) \
+ $(LIBCOM_ERR)
+
+tst_bitops: tst_bitops.o inline.o $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_bitops tst_bitops.o inline.o \
+ $(STATIC_LIBEXT2FS) $(LIBCOM_ERR)
+
+mkjournal: mkjournal.c $(STATIC_LIBEXT2FS)
+ $(CC) -o mkjournal $(srcdir)/mkjournal.c -DDEBUG $(STATIC_LIBEXT2FS) $(LIBCOM_ERR) $(ALL_CFLAGS)
+
+check:: tst_badblocks tst_iscan tst_byteswap
+ ./tst_badblocks
+ ./tst_iscan
+ ./tst_byteswap
+
+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 mkjournal \
+ ../libext2fs.a ../libext2fs_p.a ../libext2fs_chk.a
+#
+# Hack to parallel makes recognize dependencies correctly.
+#
+$(top_builddir)/lib/ext2fs/ext2_err.h: ext2_err.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 $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+alloc_tables.o: $(srcdir)/alloc_tables.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+badblocks.o: $(srcdir)/badblocks.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+bb_compat.o: $(srcdir)/bb_compat.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+bb_inode.o: $(srcdir)/bb_inode.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+bitmaps.o: $(srcdir)/bitmaps.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+bitops.o: $(srcdir)/bitops.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+block.o: $(srcdir)/block.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+bmap.o: $(srcdir)/bmap.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+check_desc.o: $(srcdir)/check_desc.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+closefs.o: $(srcdir)/closefs.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+cmp_bitmaps.o: $(srcdir)/cmp_bitmaps.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+dblist.o: $(srcdir)/dblist.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+dblist_dir.o: $(srcdir)/dblist_dir.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+dirblock.o: $(srcdir)/dirblock.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+dir_iterate.o: $(srcdir)/dir_iterate.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+dupfs.o: $(srcdir)/dupfs.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+expanddir.o: $(srcdir)/expanddir.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+ext_attr.o: $(srcdir)/ext_attr.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+fileio.o: $(srcdir)/fileio.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+finddev.o: $(srcdir)/finddev.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+flushb.o: $(srcdir)/flushb.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+freefs.o: $(srcdir)/freefs.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+gen_bitmap.o: $(srcdir)/gen_bitmap.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+get_pathname.o: $(srcdir)/get_pathname.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+getsize.o: $(srcdir)/getsize.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+icount.o: $(srcdir)/icount.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+imager.o: $(srcdir)/imager.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+initialize.o: $(srcdir)/initialize.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+inline.o: $(srcdir)/inline.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+inode.o: $(srcdir)/inode.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h $(srcdir)/e2image.h
+ismounted.o: $(srcdir)/ismounted.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+link.o: $(srcdir)/link.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+llseek.o: $(srcdir)/llseek.c com_err.h \
+ $(srcdir)/ext2_io.h
+lookup.o: $(srcdir)/lookup.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+mkdir.o: $(srcdir)/mkdir.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+mkjournal.o: $(srcdir)/mkjournal.c $(srcdir)/ext2_fs.h \
+ ext2_types.h e2p/e2p.h \
+ $(srcdir)/ext2fs.h com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h \
+ $(srcdir)/jfs_user.h linux/jfs.h \
+ linux/jfs_compat.h linux/list.h
+namei.o: $(srcdir)/namei.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+native.o: $(srcdir)/native.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+newdir.o: $(srcdir)/newdir.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+openfs.o: $(srcdir)/openfs.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h $(srcdir)/e2image.h
+read_bb.o: $(srcdir)/read_bb.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+read_bb_file.o: $(srcdir)/read_bb_file.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+rs_bitmap.o: $(srcdir)/rs_bitmap.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+rw_bitmaps.o: $(srcdir)/rw_bitmaps.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h $(srcdir)/e2image.h
+swapfs.o: $(srcdir)/swapfs.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+test_io.o: $(srcdir)/test_io.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+unix_io.o: $(srcdir)/unix_io.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+unlink.o: $(srcdir)/unlink.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+valid_blk.o: $(srcdir)/valid_blk.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+version.o: $(srcdir)/version.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h \
+ version.h
+write_bb_file.o: $(srcdir)/write_bb_file.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+tst_badblocks.o: $(srcdir)/tst_badblocks.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+tst_bitops.o: $(srcdir)/tst_bitops.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+tst_byteswap.o: $(srcdir)/tst_byteswap.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+tst_getsize.o: $(srcdir)/tst_getsize.c $(srcdir)/ext2_fs.h \
+ ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ ext2_err.h $(srcdir)/bitops.h
+tst_iscan.o: $(srcdir)/tst_iscan.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
diff --git a/e2fslib/Makefile.in b/e2fslib/Makefile.in
new file mode 100644
index 0000000..d301d98
--- /dev/null
+++ b/e2fslib/Makefile.in
@@ -0,0 +1,477 @@
+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 cmp_bitmaps.o dupfs.o fileio.o \
+@DEBUGFS_CMT@ namei.o test_io.o write_bb_file.o
+
+@RESIZER_CMT@RESIZE_LIB_OBJS = rs_bitmap.o
+
+@IMAGER_CMT@E2IMAGE_LIB_OBJS = imager.o
+
+OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
+ ext2_err.o \
+ alloc.o \
+ alloc_tables.o \
+ badblocks.o \
+ bb_inode.o \
+ bitmaps.o \
+ bitops.o \
+ block.o \
+ bmap.o \
+ check_desc.o \
+ closefs.o \
+ dblist.o \
+ dblist_dir.o \
+ dirblock.o \
+ dir_iterate.o \
+ expanddir.o \
+ ext_attr.o \
+ finddev.o \
+ flushb.o \
+ freefs.o \
+ gen_bitmap.o \
+ get_pathname.o \
+ getsize.o \
+ icount.o \
+ initialize.o \
+ inline.o \
+ inode.o \
+ ismounted.o \
+ link.o \
+ llseek.o \
+ lookup.o \
+ mkdir.o \
+ mkjournal.o \
+ native.o \
+ newdir.o \
+ openfs.o \
+ read_bb.o \
+ read_bb_file.o \
+ rw_bitmaps.o \
+ swapfs.o \
+ unix_io.o \
+ unlink.o \
+ valid_blk.o \
+ version.o
+
+SRCS= ext2_err.c \
+ $(srcdir)/alloc.c \
+ $(srcdir)/alloc_tables.c \
+ $(srcdir)/badblocks.c \
+ $(srcdir)/bb_compat.c \
+ $(srcdir)/bb_inode.c \
+ $(srcdir)/bitmaps.c \
+ $(srcdir)/bitops.c \
+ $(srcdir)/block.c \
+ $(srcdir)/bmap.c \
+ $(srcdir)/check_desc.c \
+ $(srcdir)/closefs.c \
+ $(srcdir)/cmp_bitmaps.c \
+ $(srcdir)/dblist.c \
+ $(srcdir)/dblist_dir.c \
+ $(srcdir)/dirblock.c \
+ $(srcdir)/dir_iterate.c \
+ $(srcdir)/dupfs.c \
+ $(srcdir)/expanddir.c \
+ $(srcdir)/ext_attr.c \
+ $(srcdir)/fileio.c \
+ $(srcdir)/finddev.c \
+ $(srcdir)/flushb.c \
+ $(srcdir)/freefs.c \
+ $(srcdir)/gen_bitmap.c \
+ $(srcdir)/get_pathname.c \
+ $(srcdir)/getsize.c \
+ $(srcdir)/icount.c \
+ $(srcdir)/imager.c \
+ $(srcdir)/initialize.c \
+ $(srcdir)/inline.c \
+ $(srcdir)/inode.c \
+ $(srcdir)/ismounted.c \
+ $(srcdir)/link.c \
+ $(srcdir)/llseek.c \
+ $(srcdir)/lookup.c \
+ $(srcdir)/mkdir.c \
+ $(srcdir)/mkjournal.c \
+ $(srcdir)/namei.c \
+ $(srcdir)/native.c \
+ $(srcdir)/newdir.c \
+ $(srcdir)/openfs.c \
+ $(srcdir)/read_bb.c \
+ $(srcdir)/read_bb_file.c \
+ $(srcdir)/rs_bitmap.c \
+ $(srcdir)/rw_bitmaps.c \
+ $(srcdir)/swapfs.c \
+ $(srcdir)/test_io.c \
+ $(srcdir)/unix_io.c \
+ $(srcdir)/unlink.c \
+ $(srcdir)/valid_blk.c \
+ $(srcdir)/version.c \
+ $(srcdir)/write_bb_file.c \
+ $(srcdir)/tst_badblocks.c \
+ $(srcdir)/tst_bitops.c \
+ $(srcdir)/tst_byteswap.c \
+ $(srcdir)/tst_getsize.c \
+ $(srcdir)/tst_iscan.c
+
+HFILES= bitops.h ext2fs.h ext2_io.h ext2_fs.h ext2_ext_attr.h
+HFILES_IN= ext2_err.h ext2_types.h
+
+LIBRARY= libext2fs
+LIBDIR= ext2fs
+
+DLL_ADDRESS = 0x66900000
+DLL_JUMPSIZE = 0x1000
+DLL_GOTSIZE = 0x1000
+DLL_VERSION = 1.2
+DLL_IMAGE = libe2fs
+DLL_STUB = libext2fs
+DLL_LIBS = -L../.. -lcom_err
+DLL_MYDIR = ext2fs
+DLL_INSTALL_DIR = $(root_libdir)
+
+ELF_VERSION = 2.4
+ELF_SO_VERSION = 2
+ELF_IMAGE = libext2fs
+ELF_MYDIR = ext2fs
+ELF_INSTALL_DIR = $(root_libdir)
+ELF_OTHER_LIBS = -L../.. -lcom_err
+
+BSDLIB_VERSION = 2.1
+BSDLIB_IMAGE = libext2fs
+BSDLIB_MYDIR = ext2fs
+BSDLIB_INSTALL_DIR = $(root_libdir)
+
+@MAKEFILE_LIBRARY@
+@MAKEFILE_DLL@
+@MAKEFILE_ELF@
+@MAKEFILE_BSDLIB@
+@MAKEFILE_PROFILE@
+@MAKEFILE_CHECKER@
+
+.c.o:
+ $(CC) $(ALL_CFLAGS) -c $< -o $@
+@PROFILE_CMT@ $(CC) $(ALL_CFLAGS) -g -pg -o profiled/$*.o -c $<
+@CHECKER_CMT@ $(CC) $(ALL_CFLAGS) -checker -g -o checker/$*.o -c $<
+@DLL_CMT@ (export JUMP_DIR=`pwd`/jump; $(CC) -B$(JUMP_PREFIX) $(ALL_CFLAGS) \
+@DLL_CMT@ -o jump/$*.o -c $<)
+@ELF_CMT@ $(CC) $(ALL_CFLAGS) -fPIC -o elfshared/$*.o -c $<
+@BSDLIB_CMT@ $(CC) $(ALL_CFLAGS) -fpic -o pic/$*.o -c $<
+
+COMPILE_ET=../et/compile_et
+
+DISTFILES= Makefile *.c *.h image
+
+ext2_err.et: $(DEP_SUBSTITUTE) $(srcdir)/ext2_err.et.in
+ $(SUBSTITUTE) $(srcdir)/ext2_err.et.in ext2_err.et
+
+ext2_err.c ext2_err.h: ext2_err.et
+ $(COMPILE_ET) ext2_err.et
+
+tst_badblocks: tst_badblocks.o freefs.o \
+ read_bb_file.o write_bb_file.o badblocks.o
+ $(CC) -o tst_badblocks tst_badblocks.o freefs.o \
+ read_bb_file.o write_bb_file.o badblocks.o $(LIBCOM_ERR)
+
+tst_iscan: tst_iscan.o inode.o badblocks.o test_io.o $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_iscan tst_iscan.o inode.o badblocks.o test_io.o \
+ $(STATIC_LIBEXT2FS) $(LIBCOM_ERR)
+
+tst_getsize: tst_getsize.o getsize.o $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_getsize tst_getsize.o getsize.o $(STATIC_LIBEXT2FS) \
+ $(LIBCOM_ERR)
+
+tst_ismounted: $(srcdir)/ismounted.c $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_ismounted $(srcdir)/ismounted.c -DDEBUG $(ALL_CFLAGS) $(LIBCOM_ERR)
+
+tst_byteswap: tst_byteswap.o bitops.o $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_byteswap tst_byteswap.o bitops.o $(STATIC_LIBEXT2FS) \
+ $(LIBCOM_ERR)
+
+tst_bitops: tst_bitops.o inline.o $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_bitops tst_bitops.o inline.o \
+ $(STATIC_LIBEXT2FS) $(LIBCOM_ERR)
+
+mkjournal: mkjournal.c $(STATIC_LIBEXT2FS)
+ $(CC) -o mkjournal $(srcdir)/mkjournal.c -DDEBUG $(STATIC_LIBEXT2FS) $(LIBCOM_ERR) $(ALL_CFLAGS)
+
+check:: tst_badblocks tst_iscan tst_byteswap
+ ./tst_badblocks
+ ./tst_iscan
+ ./tst_byteswap
+
+installdirs::
+ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(libdir) \
+ $(DESTDIR)$(includedir)/ext2fs
+
+install:: all $(HFILES) $(HFILES_IN) installdirs
+ $(INSTALL_DATA) libext2fs.a $(DESTDIR)$(libdir)/libext2fs.a
+ $(CHMOD) 644 $(DESTDIR)$(libdir)/libext2fs.a
+ -$(RANLIB) $(DESTDIR)$(libdir)/libext2fs.a
+ $(CHMOD) $(LIBMODE) $(DESTDIR)$(libdir)/libext2fs.a
+ for i in $(HFILES); do \
+ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir)/ext2fs/$$i; \
+ done
+ for i in $(HFILES_IN); do \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(includedir)/ext2fs/$$i; \
+ done
+
+uninstall::
+ $(RM) -f $(DESTDIR)$(libdir)/libext2fs.a
+ $(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 mkjournal \
+ ../libext2fs.a ../libext2fs_p.a ../libext2fs_chk.a
+
+mostlyclean:: clean
+distclean:: clean
+ $(RM) -f .depend ext2_err.c ext2_err.h Makefile \
+ $(srcdir)/TAGS $(srcdir)/Makefile.in.old
+#
+# Hack to parallel makes recognize dependencies correctly.
+#
+$(top_builddir)/lib/ext2fs/ext2_err.h: ext2_err.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 $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+alloc_tables.o: $(srcdir)/alloc_tables.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+badblocks.o: $(srcdir)/badblocks.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+bb_compat.o: $(srcdir)/bb_compat.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+bb_inode.o: $(srcdir)/bb_inode.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+bitmaps.o: $(srcdir)/bitmaps.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+bitops.o: $(srcdir)/bitops.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+block.o: $(srcdir)/block.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+bmap.o: $(srcdir)/bmap.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+check_desc.o: $(srcdir)/check_desc.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+closefs.o: $(srcdir)/closefs.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+cmp_bitmaps.o: $(srcdir)/cmp_bitmaps.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+dblist.o: $(srcdir)/dblist.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+dblist_dir.o: $(srcdir)/dblist_dir.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+dirblock.o: $(srcdir)/dirblock.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+dir_iterate.o: $(srcdir)/dir_iterate.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+dupfs.o: $(srcdir)/dupfs.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+expanddir.o: $(srcdir)/expanddir.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ext_attr.o: $(srcdir)/ext_attr.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+fileio.o: $(srcdir)/fileio.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+finddev.o: $(srcdir)/finddev.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+flushb.o: $(srcdir)/flushb.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+freefs.o: $(srcdir)/freefs.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+gen_bitmap.o: $(srcdir)/gen_bitmap.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+get_pathname.o: $(srcdir)/get_pathname.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+getsize.o: $(srcdir)/getsize.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+icount.o: $(srcdir)/icount.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+imager.o: $(srcdir)/imager.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+initialize.o: $(srcdir)/initialize.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+inline.o: $(srcdir)/inline.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+inode.o: $(srcdir)/inode.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h $(srcdir)/e2image.h
+ismounted.o: $(srcdir)/ismounted.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+link.o: $(srcdir)/link.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+llseek.o: $(srcdir)/llseek.c $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h
+lookup.o: $(srcdir)/lookup.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+mkdir.o: $(srcdir)/mkdir.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+mkjournal.o: $(srcdir)/mkjournal.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/e2p/e2p.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h \
+ $(srcdir)/jfs_user.h $(top_srcdir)/include/linux/jfs.h \
+ $(top_srcdir)/include/linux/jfs_compat.h $(top_srcdir)/include/linux/list.h
+namei.o: $(srcdir)/namei.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+native.o: $(srcdir)/native.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+newdir.o: $(srcdir)/newdir.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+openfs.o: $(srcdir)/openfs.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h $(srcdir)/e2image.h
+read_bb.o: $(srcdir)/read_bb.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+read_bb_file.o: $(srcdir)/read_bb_file.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+rs_bitmap.o: $(srcdir)/rs_bitmap.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+rw_bitmaps.o: $(srcdir)/rw_bitmaps.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h $(srcdir)/e2image.h
+swapfs.o: $(srcdir)/swapfs.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+test_io.o: $(srcdir)/test_io.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+unix_io.o: $(srcdir)/unix_io.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+unlink.o: $(srcdir)/unlink.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+valid_blk.o: $(srcdir)/valid_blk.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+version.o: $(srcdir)/version.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h \
+ $(top_srcdir)/version.h
+write_bb_file.o: $(srcdir)/write_bb_file.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+tst_badblocks.o: $(srcdir)/tst_badblocks.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+tst_bitops.o: $(srcdir)/tst_bitops.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+tst_byteswap.o: $(srcdir)/tst_byteswap.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+tst_getsize.o: $(srcdir)/tst_getsize.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+tst_iscan.o: $(srcdir)/tst_iscan.c $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
diff --git a/e2fslib/alloc.c b/e2fslib/alloc.c
new file mode 100644
index 0000000..2de05bc
--- /dev/null
+++ b/e2fslib/alloc.c
@@ -0,0 +1,178 @@
+/*
+ * alloc.c --- allocate new inodes, blocks for ext2fs
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ *
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <time.h>
+#include <string.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+/*
+ * Right now, just search forward from the parent directory's block
+ * group to find the next free inode.
+ *
+ * Should have a special policy for directories.
+ */
+errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, int mode,
+ ext2fs_inode_bitmap map, ext2_ino_t *ret)
+{
+ ext2_ino_t dir_group = 0;
+ ext2_ino_t i;
+ ext2_ino_t start_inode;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ if (!map)
+ map = fs->inode_map;
+ if (!map)
+ return EXT2_ET_NO_INODE_BITMAP;
+
+ if (dir > 0)
+ dir_group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super);
+
+ start_inode = (dir_group * EXT2_INODES_PER_GROUP(fs->super)) + 1;
+ if (start_inode < EXT2_FIRST_INODE(fs->super))
+ start_inode = EXT2_FIRST_INODE(fs->super);
+ i = start_inode;
+
+ do {
+ if (!ext2fs_fast_test_inode_bitmap(map, i))
+ break;
+ i++;
+ if (i > fs->super->s_inodes_count)
+ i = EXT2_FIRST_INODE(fs->super);
+ } while (i != start_inode);
+
+ if (ext2fs_test_inode_bitmap(map, i))
+ return EXT2_ET_INODE_ALLOC_FAIL;
+ *ret = i;
+ return 0;
+}
+
+/*
+ * Stupid algorithm --- we now just search forward starting from the
+ * goal. Should put in a smarter one someday....
+ */
+errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
+ ext2fs_block_bitmap map, blk_t *ret)
+{
+ blk_t i;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ if (!map)
+ map = fs->block_map;
+ if (!map)
+ return EXT2_ET_NO_BLOCK_BITMAP;
+ if (!goal || (goal >= fs->super->s_blocks_count))
+ goal = fs->super->s_first_data_block;
+ i = goal;
+ do {
+ if (!ext2fs_fast_test_block_bitmap(map, i)) {
+ *ret = i;
+ return 0;
+ }
+ i++;
+ if (i >= fs->super->s_blocks_count)
+ i = fs->super->s_first_data_block;
+ } while (i != goal);
+ return EXT2_ET_BLOCK_ALLOC_FAIL;
+}
+
+/*
+ * This function zeros out the allocated block, and updates all of the
+ * appropriate filesystem records.
+ */
+errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
+ char *block_buf, blk_t *ret)
+{
+ errcode_t retval;
+ blk_t block;
+ int group;
+ char *buf = 0;
+
+ if (!block_buf) {
+ retval = ext2fs_get_mem(fs->blocksize, (void **) &buf);
+ if (retval)
+ return retval;
+ block_buf = buf;
+ }
+ memset(block_buf, 0, fs->blocksize);
+
+ if (!fs->block_map) {
+ retval = ext2fs_read_block_bitmap(fs);
+ if (retval)
+ goto fail;
+ }
+
+ retval = ext2fs_new_block(fs, goal, 0, &block);
+ if (retval)
+ goto fail;
+
+ retval = io_channel_write_blk(fs->io, block, 1, block_buf);
+ if (retval)
+ goto fail;
+
+ fs->super->s_free_blocks_count--;
+ group = ext2fs_group_of_blk(fs, block);
+ fs->group_desc[group].bg_free_blocks_count--;
+ ext2fs_mark_block_bitmap(fs->block_map, block);
+ ext2fs_mark_super_dirty(fs);
+ ext2fs_mark_bb_dirty(fs);
+ *ret = block;
+ return 0;
+
+fail:
+ if (buf)
+ ext2fs_free_mem((void **) &buf);
+ return retval;
+}
+
+errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
+ int num, ext2fs_block_bitmap map, blk_t *ret)
+{
+ blk_t b = start;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ if (!map)
+ map = fs->block_map;
+ if (!map)
+ return EXT2_ET_NO_BLOCK_BITMAP;
+ if (!b)
+ b = fs->super->s_first_data_block;
+ if (!finish)
+ finish = start;
+ if (!num)
+ num = 1;
+ do {
+ if (b+num-1 > fs->super->s_blocks_count)
+ b = fs->super->s_first_data_block;
+ if (ext2fs_fast_test_block_bitmap_range(map, b, num)) {
+ *ret = b;
+ return 0;
+ }
+ b++;
+ } while (b != finish);
+ return EXT2_ET_BLOCK_ALLOC_FAIL;
+}
+
diff --git a/e2fslib/alloc.o b/e2fslib/alloc.o
new file mode 100644
index 0000000..93c31d6
--- /dev/null
+++ b/e2fslib/alloc.o
Binary files differ
diff --git a/e2fslib/alloc_tables.c b/e2fslib/alloc_tables.c
new file mode 100644
index 0000000..ca274cc
--- /dev/null
+++ b/e2fslib/alloc_tables.c
@@ -0,0 +1,120 @@
+/*
+ * alloc_tables.c --- Allocate tables for a newly initialized
+ * filesystem. Used by mke2fs when initializing a filesystem
+ *
+ * Copyright (C) 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
+ ext2fs_block_bitmap bmap)
+{
+ errcode_t retval;
+ blk_t group_blk, start_blk, last_blk, new_blk, blk;
+ int j;
+
+ group_blk = fs->super->s_first_data_block +
+ (group * fs->super->s_blocks_per_group);
+
+ last_blk = group_blk + fs->super->s_blocks_per_group;
+ if (last_blk >= fs->super->s_blocks_count)
+ last_blk = fs->super->s_blocks_count - 1;
+
+ start_blk = group_blk + 3 + fs->desc_blocks;
+ if (start_blk > last_blk)
+ start_blk = group_blk;
+
+ if (!bmap)
+ bmap = fs->block_map;
+
+ /*
+ * Allocate the inode table
+ */
+ if (!fs->group_desc[group].bg_inode_table) {
+ retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
+ fs->inode_blocks_per_group,
+ bmap, &new_blk);
+ if (retval)
+ return retval;
+ for (j=0, blk = new_blk;
+ j < fs->inode_blocks_per_group;
+ j++, blk++)
+ ext2fs_mark_block_bitmap(bmap, blk);
+ fs->group_desc[group].bg_inode_table = new_blk;
+ }
+
+ /*
+ * Allocate the block and inode bitmaps, if necessary
+ */
+ if (fs->stride) {
+ start_blk += fs->inode_blocks_per_group;
+ start_blk += ((fs->stride * group) %
+ (last_blk - start_blk));
+ if (start_blk > last_blk)
+ /* should never happen */
+ start_blk = group_blk;
+ } else
+ start_blk = group_blk;
+
+ if (!fs->group_desc[group].bg_block_bitmap) {
+ retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
+ 1, bmap, &new_blk);
+ if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
+ retval = ext2fs_get_free_blocks(fs, group_blk,
+ last_blk, 1, bmap, &new_blk);
+ if (retval)
+ return retval;
+ ext2fs_mark_block_bitmap(bmap, new_blk);
+ fs->group_desc[group].bg_block_bitmap = new_blk;
+ }
+
+ if (!fs->group_desc[group].bg_inode_bitmap) {
+ retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
+ 1, bmap, &new_blk);
+ if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
+ retval = ext2fs_get_free_blocks(fs, group_blk,
+ last_blk, 1, bmap, &new_blk);
+ if (retval)
+ return retval;
+ ext2fs_mark_block_bitmap(bmap, new_blk);
+ fs->group_desc[group].bg_inode_bitmap = new_blk;
+ }
+ return 0;
+}
+
+
+
+errcode_t ext2fs_allocate_tables(ext2_filsys fs)
+{
+ errcode_t retval;
+ dgrp_t i;
+
+ for (i = 0; i < fs->group_desc_count; i++) {
+ retval = ext2fs_allocate_group_table(fs, i, fs->block_map);
+ if (retval)
+ return retval;
+ }
+ return 0;
+}
+
diff --git a/e2fslib/alloc_tables.o b/e2fslib/alloc_tables.o
new file mode 100644
index 0000000..ef79962
--- /dev/null
+++ b/e2fslib/alloc_tables.o
Binary files differ
diff --git a/e2fslib/badblocks.c b/e2fslib/badblocks.c
new file mode 100644
index 0000000..4e94e8c
--- /dev/null
+++ b/e2fslib/badblocks.c
@@ -0,0 +1,236 @@
+/*
+ * badblocks.c --- routines to manipulate the bad block structure
+ *
+ * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+
+/*
+ * Helper function for making a badblocks list
+ */
+static errcode_t make_badblocks_list(int size, int num, blk_t *list,
+ ext2_badblocks_list *ret)
+{
+ ext2_badblocks_list bb;
+ errcode_t retval;
+
+ retval = ext2fs_get_mem(sizeof(struct ext2_struct_badblocks_list),
+ (void **) &bb);
+ if (retval)
+ return retval;
+ memset(bb, 0, sizeof(struct ext2_struct_badblocks_list));
+ bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
+ bb->size = size ? size : 10;
+ bb->num = num;
+ retval = ext2fs_get_mem(bb->size * sizeof(blk_t), (void **) &bb->list);
+ if (!bb->list) {
+ ext2fs_free_mem((void **) &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 badblocks list.
+ */
+errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
+{
+ return make_badblocks_list(size, 0, 0, ret);
+}
+
+/*
+ * This procedure copies a badblocks list
+ */
+errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
+ ext2_badblocks_list *dest)
+{
+ errcode_t retval;
+
+ retval = make_badblocks_list(src->size, src->num, src->list,
+ dest);
+ if (retval)
+ return retval;
+ (*dest)->badblocks_flags = src->badblocks_flags;
+ return 0;
+}
+
+
+/*
+ * This procedure frees a badblocks list.
+ *
+ * (note: moved to closefs.c)
+ */
+
+
+/*
+ * This procedure adds a block to a badblocks list.
+ */
+errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t 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(blk_t);
+ bb->size += 100;
+ retval = ext2fs_resize_mem(old_size, bb->size * sizeof(blk_t),
+ (void **) &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;
+}
+
+/*
+ * This procedure tests to see if a particular block is on a badblocks
+ * list.
+ */
+int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
+{
+ int low, high, mid;
+
+ if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
+ return 0;
+
+ if (bb->num == 0)
+ return 0;
+
+ low = 0;
+ high = bb->num-1;
+ if (blk == bb->list[low])
+ return 1;
+ if (blk == bb->list[high])
+ return 1;
+
+ while (low < high) {
+ mid = (low+high)/2;
+ if (mid == low || mid == high)
+ break;
+ if (blk == bb->list[mid])
+ return 1;
+ if (blk < bb->list[mid])
+ high = mid;
+ else
+ low = mid;
+ }
+ return 0;
+}
+
+errcode_t ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
+ ext2_badblocks_iterate *ret)
+{
+ ext2_badblocks_iterate iter;
+ errcode_t retval;
+
+ EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
+
+ retval = ext2fs_get_mem(sizeof(struct ext2_struct_badblocks_iterate),
+ (void **) &iter);
+ if (retval)
+ return retval;
+
+ iter->magic = EXT2_ET_MAGIC_BADBLOCKS_ITERATE;
+ iter->bb = bb;
+ iter->ptr = 0;
+ *ret = iter;
+ return 0;
+}
+
+int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk)
+{
+ ext2_badblocks_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;
+}
+
+void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter)
+{
+ if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE))
+ return;
+
+ iter->bb = 0;
+ ext2fs_free_mem((void **) &iter);
+}
+
+int ext2fs_badblocks_equal(ext2_badblocks_list bb1, ext2_badblocks_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;
+}
diff --git a/e2fslib/badblocks.o b/e2fslib/badblocks.o
new file mode 100644
index 0000000..6da4c25
--- /dev/null
+++ b/e2fslib/badblocks.o
Binary files differ
diff --git a/e2fslib/bb_compat.c b/e2fslib/bb_compat.c
new file mode 100644
index 0000000..40f7343
--- /dev/null
+++ b/e2fslib/bb_compat.c
@@ -0,0 +1,63 @@
+/*
+ * bb_compat.c --- compatibility badblocks routines
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+
+errcode_t badblocks_list_create(badblocks_list *ret, int size)
+{
+ return ext2fs_badblocks_list_create(ret, size);
+}
+
+void badblocks_list_free(badblocks_list bb)
+{
+ ext2fs_badblocks_list_free(bb);
+}
+
+errcode_t badblocks_list_add(badblocks_list bb, blk_t blk)
+{
+ return ext2fs_badblocks_list_add(bb, blk);
+}
+
+int badblocks_list_test(badblocks_list bb, blk_t blk)
+{
+ return ext2fs_badblocks_list_test(bb, blk);
+}
+
+errcode_t badblocks_list_iterate_begin(badblocks_list bb,
+ badblocks_iterate *ret)
+{
+ return ext2fs_badblocks_list_iterate_begin(bb, ret);
+}
+
+int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk)
+{
+ return ext2fs_badblocks_list_iterate(iter, blk);
+}
+
+void badblocks_list_iterate_end(badblocks_iterate iter)
+{
+ ext2fs_badblocks_list_iterate_end(iter);
+}
diff --git a/e2fslib/bb_compat.o b/e2fslib/bb_compat.o
new file mode 100644
index 0000000..579ca8c
--- /dev/null
+++ b/e2fslib/bb_compat.o
Binary files differ
diff --git a/e2fslib/bb_inode.c b/e2fslib/bb_inode.c
new file mode 100644
index 0000000..34c4955
--- /dev/null
+++ b/e2fslib/bb_inode.c
@@ -0,0 +1,287 @@
+/*
+ * bb_inode.c --- routines to update the bad block inode.
+ *
+ * WARNING: This routine modifies a lot of state in the filesystem; if
+ * this routine returns an error, the bad block inode may be in an
+ * inconsistent state.
+ *
+ * Copyright (C) 1994, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+struct set_badblock_record {
+ ext2_badblocks_iterate bb_iter;
+ int bad_block_count;
+ blk_t *ind_blocks;
+ int max_ind_blocks;
+ int ind_blocks_size;
+ int ind_blocks_ptr;
+ char *block_buf;
+ errcode_t err;
+};
+
+static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
+ e2_blkcnt_t blockcnt,
+ blk_t ref_block, int ref_offset,
+ void *priv_data);
+static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
+ e2_blkcnt_t blockcnt,
+ blk_t ref_block, int ref_offset,
+ void *priv_data);
+
+/*
+ * Given a bad blocks bitmap, update the bad blocks inode to reflect
+ * the map.
+ */
+errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
+{
+ errcode_t retval;
+ struct set_badblock_record rec;
+ struct ext2_inode inode;
+ blk_t blk;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ if (!fs->block_map)
+ return EXT2_ET_NO_BLOCK_BITMAP;
+
+ rec.bad_block_count = 0;
+ rec.ind_blocks_size = rec.ind_blocks_ptr = 0;
+ rec.max_ind_blocks = 10;
+ retval = ext2fs_get_mem(rec.max_ind_blocks * sizeof(blk_t),
+ (void **) &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, (void **) &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;
+ while (ext2fs_badblocks_list_iterate(rec.bb_iter, &blk)) {
+ ext2fs_mark_block_bitmap(fs->block_map, blk);
+ }
+ ext2fs_badblocks_list_iterate_end(rec.bb_iter);
+ ext2fs_mark_bb_dirty(fs);
+
+ retval = ext2fs_badblocks_list_iterate_begin(bb_list,
+ &rec.bb_iter);
+ if (retval)
+ goto cleanup;
+ retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO,
+ BLOCK_FLAG_APPEND, 0,
+ set_bad_block_proc, &rec);
+ ext2fs_badblocks_list_iterate_end(rec.bb_iter);
+ if (retval)
+ goto cleanup;
+ if (rec.err) {
+ retval = rec.err;
+ goto cleanup;
+ }
+ }
+
+ /*
+ * Update the bad block inode's mod time and block count
+ * field.
+ */
+ retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
+ if (retval)
+ goto cleanup;
+
+ inode.i_atime = inode.i_mtime = time(0);
+ if (!inode.i_ctime)
+ inode.i_ctime = time(0);
+ inode.i_blocks = rec.bad_block_count * (fs->blocksize / 512);
+ inode.i_size = rec.bad_block_count * fs->blocksize;
+
+ retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
+ if (retval)
+ goto cleanup;
+
+cleanup:
+ ext2fs_free_mem((void **) &rec.ind_blocks);
+ ext2fs_free_mem((void **) &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, int ref_offset,
+ void *priv_data)
+{
+ struct set_badblock_record *rec = (struct set_badblock_record *)
+ priv_data;
+ errcode_t retval;
+ int group;
+ unsigned long old_size;
+
+ if (!*block_nr)
+ return 0;
+
+ /*
+ * If the block number is outrageous, clear it and ignore it.
+ */
+ if (*block_nr >= fs->super->s_blocks_count ||
+ *block_nr < fs->super->s_first_data_block) {
+ *block_nr = 0;
+ return BLOCK_CHANGED;
+ }
+
+ if (blockcnt < 0) {
+ if (rec->ind_blocks_size >= rec->max_ind_blocks) {
+ old_size = rec->max_ind_blocks * sizeof(blk_t);
+ rec->max_ind_blocks += 10;
+ retval = ext2fs_resize_mem(old_size,
+ rec->max_ind_blocks * sizeof(blk_t),
+ (void **) &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_unmark_block_bitmap(fs->block_map, *block_nr);
+ ext2fs_mark_bb_dirty(fs);
+ group = ext2fs_group_of_blk(fs, *block_nr);
+ fs->group_desc[group].bg_free_blocks_count++;
+ fs->super->s_free_blocks_count++;
+ ext2fs_mark_super_dirty(fs);
+
+ *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,
+ int ref_offset, void *priv_data)
+{
+ struct set_badblock_record *rec = (struct set_badblock_record *)
+ priv_data;
+ errcode_t retval;
+ blk_t blk;
+ int group;
+
+ if (blockcnt >= 0) {
+ /*
+ * Get the next bad block.
+ */
+ if (!ext2fs_badblocks_list_iterate(rec->bb_iter, &blk))
+ return BLOCK_ABORT;
+ rec->bad_block_count++;
+ } else {
+ /*
+ * An indirect block; fetch a block from the
+ * previously used indirect block list. The block
+ * most be not marked as used; if so, get another one.
+ * If we run out of reserved indirect blocks, allocate
+ * a new one.
+ */
+ retry:
+ if (rec->ind_blocks_ptr < rec->ind_blocks_size) {
+ blk = rec->ind_blocks[rec->ind_blocks_ptr++];
+ if (ext2fs_test_block_bitmap(fs->block_map, blk))
+ goto retry;
+ } else {
+ retval = ext2fs_new_block(fs, 0, 0, &blk);
+ if (retval) {
+ rec->err = retval;
+ return BLOCK_ABORT;
+ }
+ }
+ retval = io_channel_write_blk(fs->io, blk, 1, rec->block_buf);
+ if (retval) {
+ rec->err = retval;
+ return BLOCK_ABORT;
+ }
+ ext2fs_mark_block_bitmap(fs->block_map, blk);
+ ext2fs_mark_bb_dirty(fs);
+ }
+
+ /*
+ * Update block counts
+ */
+ group = ext2fs_group_of_blk(fs, blk);
+ fs->group_desc[group].bg_free_blocks_count--;
+ fs->super->s_free_blocks_count--;
+ ext2fs_mark_super_dirty(fs);
+
+ *block_nr = blk;
+ return BLOCK_CHANGED;
+}
+
+
+
+
+
+
diff --git a/e2fslib/bb_inode.o b/e2fslib/bb_inode.o
new file mode 100644
index 0000000..f053cfa
--- /dev/null
+++ b/e2fslib/bb_inode.o
Binary files differ
diff --git a/e2fslib/bitmaps.c b/e2fslib/bitmaps.c
new file mode 100644
index 0000000..44f16a9
--- /dev/null
+++ b/e2fslib/bitmaps.c
@@ -0,0 +1,213 @@
+/*
+ * bitmaps.c --- routines to read, write, and manipulate the inode and
+ * block bitmaps.
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+static errcode_t make_bitmap(__u32 start, __u32 end, __u32 real_end,
+ const char *descr, char *init_map,
+ ext2fs_generic_bitmap *ret)
+{
+ ext2fs_generic_bitmap bitmap;
+ errcode_t retval;
+ size_t size;
+
+ retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap),
+ (void **) &bitmap);
+ if (retval)
+ return retval;
+
+ bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ bitmap->fs = NULL;
+ bitmap->start = start;
+ bitmap->end = end;
+ bitmap->real_end = real_end;
+ bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
+ if (descr) {
+ retval = ext2fs_get_mem(strlen(descr)+1,
+ (void **) &bitmap->description);
+ if (retval) {
+ ext2fs_free_mem((void **) &bitmap);
+ return retval;
+ }
+ strcpy(bitmap->description, descr);
+ } else
+ bitmap->description = 0;
+
+ size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
+ retval = ext2fs_get_mem(size, (void **) &bitmap->bitmap);
+ if (retval) {
+ ext2fs_free_mem((void **) &bitmap->description);
+ ext2fs_free_mem((void **) &bitmap);
+ return retval;
+ }
+
+ if (init_map)
+ memcpy(bitmap->bitmap, init_map, size);
+ else
+ memset(bitmap->bitmap, 0, size);
+ *ret = bitmap;
+ return 0;
+}
+
+errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+ __u32 end,
+ __u32 real_end,
+ const char *descr,
+ ext2fs_generic_bitmap *ret)
+{
+ return make_bitmap(start, end, real_end, descr, 0, ret);
+}
+
+errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
+ ext2fs_generic_bitmap *dest)
+{
+ errcode_t retval;
+ ext2fs_generic_bitmap new_map;
+
+ retval = make_bitmap(src->start, src->end, src->real_end,
+ src->description, src->bitmap, &new_map);
+ if (retval)
+ return retval;
+ new_map->magic = src->magic;
+ new_map->fs = src->fs;
+ new_map->base_error_code = src->base_error_code;
+ *dest = new_map;
+ return 0;
+}
+
+void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map)
+{
+ __u32 i, j;
+
+ for (i=map->end+1, j = i - map->start; i <= map->real_end; i++, j++)
+ ext2fs_set_bit(j, map->bitmap);
+
+ return;
+}
+
+errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
+ const char *descr,
+ ext2fs_inode_bitmap *ret)
+{
+ ext2fs_inode_bitmap bitmap;
+ errcode_t retval;
+ __u32 start, end, real_end;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ fs->write_bitmaps = ext2fs_write_bitmaps;
+
+ start = 1;
+ end = fs->super->s_inodes_count;
+ real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count);
+
+ retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+ descr, &bitmap);
+ if (retval)
+ return retval;
+
+ bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
+ bitmap->fs = fs;
+ bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
+
+ *ret = bitmap;
+ return 0;
+}
+
+errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
+ const char *descr,
+ ext2fs_block_bitmap *ret)
+{
+ ext2fs_block_bitmap bitmap;
+ errcode_t retval;
+ __u32 start, end, real_end;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ fs->write_bitmaps = ext2fs_write_bitmaps;
+
+ start = fs->super->s_first_data_block;
+ end = fs->super->s_blocks_count-1;
+ real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)
+ * fs->group_desc_count)-1 + start;
+
+ retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+ descr, &bitmap);
+ if (retval)
+ return retval;
+
+ bitmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
+ bitmap->fs = fs;
+ bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
+
+ *ret = bitmap;
+ return 0;
+}
+
+errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t end, ext2_ino_t *oend)
+{
+ EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
+
+ if (end > bitmap->real_end)
+ return EXT2_ET_FUDGE_INODE_BITMAP_END;
+ if (oend)
+ *oend = bitmap->end;
+ bitmap->end = end;
+ return 0;
+}
+
+errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
+ blk_t end, blk_t *oend)
+{
+ EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
+
+ if (end > bitmap->real_end)
+ return EXT2_ET_FUDGE_BLOCK_BITMAP_END;
+ if (oend)
+ *oend = bitmap->end;
+ bitmap->end = end;
+ return 0;
+}
+
+void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap)
+{
+ if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
+ return;
+
+ memset(bitmap->bitmap, 0,
+ (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
+}
+
+void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap)
+{
+ if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
+ return;
+
+ memset(bitmap->bitmap, 0,
+ (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
+}
diff --git a/e2fslib/bitmaps.o b/e2fslib/bitmaps.o
new file mode 100644
index 0000000..7d03127
--- /dev/null
+++ b/e2fslib/bitmaps.o
Binary files differ
diff --git a/e2fslib/bitops.c b/e2fslib/bitops.c
new file mode 100644
index 0000000..e27c5a0
--- /dev/null
+++ b/e2fslib/bitops.c
@@ -0,0 +1,91 @@
+/*
+ * bitops.c --- Bitmap frobbing code. See bitops.h for the inlined
+ * routines.
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+#ifndef _EXT2_HAVE_ASM_BITOPS_
+
+/*
+ * For the benefit of those who are trying to port Linux to another
+ * architecture, here are some C-language equivalents. You should
+ * recode these in the native assmebly language, if at all possible.
+ *
+ * C language equivalents written by Theodore Ts'o, 9/26/92.
+ * Modified by Pete A. Zaitcev 7/14/95 to be portable to big endian
+ * systems, as well as non-32 bit systems.
+ */
+
+int ext2fs_set_bit(int nr,void * addr)
+{
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ retval = (mask & *ADDR) != 0;
+ *ADDR |= mask;
+ return retval;
+}
+
+int ext2fs_clear_bit(int nr, void * addr)
+{
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ retval = (mask & *ADDR) != 0;
+ *ADDR &= ~mask;
+ return retval;
+}
+
+int ext2fs_test_bit(int nr, const void * addr)
+{
+ int mask;
+ const unsigned char *ADDR = (const unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ return ((mask & *ADDR) != 0);
+}
+
+#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, "#%u for %s", arg, description);
+ else
+ com_err(0, errcode, "#%u", arg);
+#endif
+}
+
+void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+ int code, unsigned long arg)
+{
+#ifndef OMIT_COM_ERR
+ if (bitmap->description)
+ com_err(0, bitmap->base_error_code+code,
+ "#%u for %s", arg, bitmap->description);
+ else
+ com_err(0, bitmap->base_error_code + code, "#%u", arg);
+#endif
+}
+
diff --git a/e2fslib/bitops.h b/e2fslib/bitops.h
new file mode 100644
index 0000000..58a64d1
--- /dev/null
+++ b/e2fslib/bitops.h
@@ -0,0 +1,718 @@
+/*
+ * bitops.h --- Bitmap frobbing code. The byte swapping routines are
+ * also included here.
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ *
+ * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
+ * Linus Torvalds.
+ */
+
+
+extern int ext2fs_set_bit(int nr,void * addr);
+extern int ext2fs_clear_bit(int nr, void * addr);
+extern int ext2fs_test_bit(int nr, const void * addr);
+extern __u16 ext2fs_swab16(__u16 val);
+extern __u32 ext2fs_swab32(__u32 val);
+
+/*
+ * EXT2FS bitmap manipulation routines.
+ */
+
+/* Support for sending warning messages from the inline subroutines */
+extern const char *ext2fs_block_string;
+extern const char *ext2fs_inode_string;
+extern const char *ext2fs_mark_string;
+extern const char *ext2fs_unmark_string;
+extern const char *ext2fs_test_string;
+extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
+ const char *description);
+extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+ int code, unsigned long arg);
+
+extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
+extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block);
+extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
+
+extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
+extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t inode);
+extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
+
+extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block);
+extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block);
+extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block);
+
+extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t inode);
+extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t inode);
+extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t inode);
+extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
+extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
+extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
+extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
+
+extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
+
+/*
+ * The inline routines themselves...
+ *
+ * If NO_INLINE_FUNCS is defined, then we won't try to do inline
+ * functions at all; they will be included as normal functions in
+ * inline.c
+ */
+#ifdef NO_INLINE_FUNCS
+#if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
+ defined(__i586__) || defined(__mc68000__) || \
+ defined(__sparc__)))
+ /* This prevents bitops.c from trying to include the C */
+ /* function version of these functions */
+#define _EXT2_HAVE_ASM_BITOPS_
+#endif
+#endif /* NO_INLINE_FUNCS */
+
+#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
+#ifdef INCLUDE_INLINE_FUNCS
+#define _INLINE_ extern
+#else
+#ifdef __GNUC__
+#define _INLINE_ extern __inline__
+#else /* For Watcom C */
+#define _INLINE_ extern inline
+#endif
+#endif
+
+#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
+ (defined(__i386__) || defined(__i486__) || defined(__i586__)))
+
+#define _EXT2_HAVE_ASM_BITOPS_
+#define _EXT2_HAVE_ASM_SWAB_
+#define _EXT2_HAVE_ASM_FINDBIT_
+
+/*
+ * These are done by inline assembly for speed reasons.....
+ *
+ * All bitoperations return 0 if the bit was cleared before the
+ * operation and != 0 if it was not. Bit 0 is the LSB of addr; bit 32
+ * is the LSB of (addr+1).
+ */
+
+/*
+ * Some hacks to defeat gcc over-optimizations..
+ */
+struct __dummy_h { unsigned long a[100]; };
+#define EXT2FS_ADDR (*(struct __dummy_h *) addr)
+#define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)
+
+_INLINE_ int ext2fs_set_bit(int nr, void * addr)
+{
+ int oldbit;
+
+ __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit),"=m" (EXT2FS_ADDR)
+ :"r" (nr));
+ return oldbit;
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+ int oldbit;
+
+ __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit),"=m" (EXT2FS_ADDR)
+ :"r" (nr));
+ return oldbit;
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+ int oldbit;
+
+ __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit)
+ :"m" (EXT2FS_CONST_ADDR),"r" (nr));
+ return oldbit;
+}
+
+#if 0
+_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
+{
+ int d0, d1, d2;
+ int res;
+
+ if (!size)
+ return 0;
+ /* This looks at memory. Mark it volatile to tell gcc not to move it around */
+ __asm__ __volatile__(
+ "cld\n\t"
+ "xorl %%eax,%%eax\n\t"
+ "xorl %%edx,%%edx\n\t"
+ "repe; scasl\n\t"
+ "je 1f\n\t"
+ "movl -4(%%edi),%%eax\n\t"
+ "subl $4,%%edi\n\t"
+ "bsfl %%eax,%%edx\n"
+ "1:\tsubl %%esi,%%edi\n\t"
+ "shll $3,%%edi\n\t"
+ "addl %%edi,%%edx"
+ :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
+ :"1" ((size + 31) >> 5), "2" (addr), "S" (addr));
+ return res;
+}
+
+_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
+{
+ unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
+ int set = 0, bit = offset & 31, res;
+
+ if (bit) {
+ /*
+ * Look for zero in first byte
+ */
+ __asm__("bsfl %1,%0\n\t"
+ "jne 1f\n\t"
+ "movl $32, %0\n"
+ "1:"
+ : "=r" (set)
+ : "r" (*p >> bit));
+ if (set < (32 - bit))
+ return set + offset;
+ set = 32 - bit;
+ p++;
+ }
+ /*
+ * No bit found yet, search remaining full bytes for a bit
+ */
+ res = ext2fs_find_first_bit_set(p, size - 32 * (p - (unsigned long *) addr));
+ return (offset + set + res);
+}
+#endif
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+_INLINE_ __u32 ext2fs_swab32(__u32 val)
+{
+#ifdef EXT2FS_REQUIRE_486
+ __asm__("bswap %0" : "=r" (val) : "0" (val));
+#else
+ __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
+ "rorl $16,%0\n\t" /* swap words */
+ "xchgb %b0,%h0" /* swap higher bytes */
+ :"=q" (val)
+ : "0" (val));
+#endif
+ return val;
+}
+
+_INLINE_ __u16 ext2fs_swab16(__u16 val)
+{
+ __asm__("xchgb %b0,%h0" /* swap bytes */ \
+ : "=q" (val) \
+ : "0" (val)); \
+ return val;
+}
+#endif
+
+#undef EXT2FS_ADDR
+
+#endif /* i386 */
+
+#ifdef __mc68000__
+
+#define _EXT2_HAVE_ASM_BITOPS_
+
+_INLINE_ int ext2fs_set_bit(int nr,void * addr)
+{
+ char retval;
+
+ __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
+ : "=d" (retval) : "d" (nr^7), "a" (addr));
+
+ return retval;
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+ char retval;
+
+ __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
+ : "=d" (retval) : "d" (nr^7), "a" (addr));
+
+ return retval;
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+ char retval;
+
+ __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
+ : "=d" (retval) : "d" (nr^7), "a" (addr));
+
+ return retval;
+}
+
+#endif /* __mc68000__ */
+
+#ifdef __sparc__
+
+#define _EXT2_HAVE_ASM_BITOPS_
+
+#ifndef EXT2_OLD_BITOPS
+
+/*
+ * Do the bitops so that we are compatible with the standard i386
+ * convention.
+ */
+
+_INLINE_ int ext2fs_set_bit(int nr,void * addr)
+{
+#if 1
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("ldub [%0], %%g6\n\t"
+ "or %%g6, %2, %%g5\n\t"
+ "stb %%g5, [%0]\n\t"
+ "and %%g6, %2, %0\n"
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g5", "g6");
+ return (int) ADDR;
+#else
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ retval = (mask & *ADDR) != 0;
+ *ADDR |= mask;
+ return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+#if 1
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("ldub [%0], %%g6\n\t"
+ "andn %%g6, %2, %%g5\n\t"
+ "stb %%g5, [%0]\n\t"
+ "and %%g6, %2, %0\n"
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g5", "g6");
+ return (int) ADDR;
+
+#else
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ retval = (mask & *ADDR) != 0;
+ *ADDR &= ~mask;
+ return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+ int mask;
+ const unsigned char *ADDR = (const unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ return ((mask & *ADDR) != 0);
+}
+
+#else
+
+/* Do things the old, unplesant way. */
+
+_INLINE_ int ext2fs_set_bit(int nr, void *addr)
+{
+ int mask, retval;
+ unsigned long *ADDR = (unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ retval = ((mask & *ADDR) != 0);
+ *ADDR |= mask;
+ return retval;
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void *addr)
+{
+ int mask, retval;
+ unsigned long *ADDR = (unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ retval = ((mask & *ADDR) != 0);
+ *ADDR &= ~mask;
+ return retval;
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void *addr)
+{
+ int mask;
+ const unsigned long *ADDR = (const unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ return ((mask & *ADDR) != 0);
+}
+#endif
+
+#endif /* __sparc__ */
+
+#if !defined(_EXT2_HAVE_ASM_SWAB_) && defined(EXT2FS_ENABLE_SWAPFS)
+
+_INLINE_ __u16 ext2fs_swab16(__u16 val)
+{
+ return (val >> 8) | (val << 8);
+}
+
+_INLINE_ __u32 ext2fs_swab32(__u32 val)
+{
+ return ((val>>24) | ((val>>8)&0xFF00) |
+ ((val<<8)&0xFF0000) | (val<<24));
+}
+
+#endif /* !_EXT2_HAVE_ASM_SWAB */
+
+#if !defined(_EXT2_HAVE_ASM_FINDBIT_)
+
+extern int ffs(int);
+
+_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
+{
+ char *cp = (unsigned char *) addr;
+ int res = 0, d0;
+
+ if (!size)
+ return 0;
+
+ while ((size > res) && (*cp == 0)) {
+ cp++;
+ res += 8;
+ }
+ d0 = ffs(*cp);
+ if (d0 == 0)
+ return size;
+
+ return res + d0 - 1;
+}
+
+_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
+{
+ unsigned char * p;
+ int set = 0, bit = offset & 7, res = 0, d0;
+
+ res = offset >> 3;
+ p = ((unsigned char *) addr) + res;
+
+ if (bit) {
+ set = ffs(*p & ~((1 << bit) - 1));
+ if (set)
+ return (offset & ~7) + set - 1;
+ p++;
+ res += 8;
+ }
+ while ((size > res) && (*p == 0)) {
+ p++;
+ res += 8;
+ }
+ d0 = ffs(*p);
+ if (d0 == 0)
+ return size;
+
+ return (res + d0 - 1);
+}
+#endif
+
+/* These two routines moved to gen_bitmap.c */
+extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ __u32 bitno);
+extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno);
+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno);
+
+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
+ return 0;
+ }
+ return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+ return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
+ bitmap,
+ block);
+}
+
+_INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+ return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ block);
+}
+
+_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+ return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ block);
+}
+
+_INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t inode)
+{
+ return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ inode);
+}
+
+_INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t inode)
+{
+ return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ inode);
+}
+
+_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t inode)
+{
+ return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ inode);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
+ bitmap->description);
+ return;
+ }
+#endif
+ ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
+ block, bitmap->description);
+ return;
+ }
+#endif
+ ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+ block, bitmap->description);
+ return 0;
+ }
+#endif
+ return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t inode)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((inode < bitmap->start) || (inode > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
+ inode, bitmap->description);
+ return;
+ }
+#endif
+ ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t inode)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((inode < bitmap->start) || (inode > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
+ inode, bitmap->description);
+ return;
+ }
+#endif
+ ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t inode)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((inode < bitmap->start) || (inode > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
+ inode, bitmap->description);
+ return 0;
+ }
+#endif
+ return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
+{
+ return bitmap->start;
+}
+
+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
+{
+ return bitmap->start;
+}
+
+_INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
+{
+ return bitmap->end;
+}
+
+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
+{
+ return bitmap->end;
+}
+
+_INLINE_ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+ block, bitmap->description);
+ return 0;
+ }
+ for (i=0; i < num; i++) {
+ if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
+ return 0;
+ }
+ return 1;
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+ block, bitmap->description);
+ return 0;
+ }
+#endif
+ for (i=0; i < num; i++) {
+ if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
+ return 0;
+ }
+ return 1;
+}
+
+_INLINE_ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
+ bitmap->description);
+ return;
+ }
+ for (i=0; i < num; i++)
+ ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
+ bitmap->description);
+ return;
+ }
+#endif
+ for (i=0; i < num; i++)
+ ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
+ bitmap->description);
+ return;
+ }
+ for (i=0; i < num; i++)
+ ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
+ bitmap->description);
+ return;
+ }
+#endif
+ for (i=0; i < num; i++)
+ ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+#undef _INLINE_
+#endif
+
diff --git a/e2fslib/bitops.o b/e2fslib/bitops.o
new file mode 100644
index 0000000..42f78cb
--- /dev/null
+++ b/e2fslib/bitops.o
Binary files differ
diff --git a/e2fslib/block.c b/e2fslib/block.c
new file mode 100644
index 0000000..a0bf738
--- /dev/null
+++ b/e2fslib/block.c
@@ -0,0 +1,496 @@
+/*
+ * block.c --- iterate over all blocks in an inode
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+struct block_context {
+ ext2_filsys fs;
+ int (*func)(ext2_filsys fs,
+ blk_t *blocknr,
+ e2_blkcnt_t bcount,
+ blk_t ref_blk,
+ int ref_offset,
+ void *priv_data);
+ e2_blkcnt_t bcount;
+ int bsize;
+ int flags;
+ errcode_t errcode;
+ char *ind_buf;
+ char *dind_buf;
+ char *tind_buf;
+ void *priv_data;
+};
+
+static int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
+ int ref_offset, struct block_context *ctx)
+{
+ int ret = 0, changed = 0;
+ int i, flags, limit, offset;
+ blk_t *block_nr;
+
+ limit = ctx->fs->blocksize >> 2;
+ if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
+ ret = (*ctx->func)(ctx->fs, ind_block,
+ BLOCK_COUNT_IND, ref_block,
+ ref_offset, ctx->priv_data);
+ if (!*ind_block || (ret & BLOCK_ABORT)) {
+ ctx->bcount += limit;
+ return ret;
+ }
+ if (*ind_block >= ctx->fs->super->s_blocks_count ||
+ *ind_block < ctx->fs->super->s_first_data_block) {
+ ctx->errcode = EXT2_ET_BAD_IND_BLOCK;
+ ret |= BLOCK_ERROR;
+ return ret;
+ }
+ if (ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) {
+ ctx->errcode = 0;
+ memset(ctx->ind_buf, 0, ctx->fs->blocksize);
+ } else
+ ctx->errcode = io_channel_read_blk(ctx->fs->io, *ind_block,
+ 1, ctx->ind_buf);
+ if (ctx->errcode) {
+ ret |= BLOCK_ERROR;
+ return ret;
+ }
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
+ EXT2_FLAG_SWAP_BYTES_READ)) {
+ block_nr = (blk_t *) ctx->ind_buf;
+ for (i = 0; i < limit; i++, block_nr++)
+ *block_nr = ext2fs_swab32(*block_nr);
+ }
+#endif
+ block_nr = (blk_t *) ctx->ind_buf;
+ offset = 0;
+ if (ctx->flags & BLOCK_FLAG_APPEND) {
+ for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) {
+ flags = (*ctx->func)(ctx->fs, block_nr, ctx->bcount,
+ *ind_block, offset,
+ ctx->priv_data);
+ changed |= flags;
+ if (flags & BLOCK_ABORT) {
+ ret |= BLOCK_ABORT;
+ break;
+ }
+ offset += sizeof(blk_t);
+ }
+ } else {
+ for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) {
+ if (*block_nr == 0)
+ continue;
+ flags = (*ctx->func)(ctx->fs, block_nr, ctx->bcount,
+ *ind_block, offset,
+ ctx->priv_data);
+ changed |= flags;
+ if (flags & BLOCK_ABORT) {
+ ret |= BLOCK_ABORT;
+ break;
+ }
+ offset += sizeof(blk_t);
+ }
+ }
+ if (!(ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
+ (changed & BLOCK_CHANGED)) {
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
+ EXT2_FLAG_SWAP_BYTES_WRITE)) {
+ block_nr = (blk_t *) ctx->ind_buf;
+ for (i = 0; i < limit; i++, block_nr++)
+ *block_nr = ext2fs_swab32(*block_nr);
+ }
+#endif
+ ctx->errcode = io_channel_write_blk(ctx->fs->io, *ind_block,
+ 1, ctx->ind_buf);
+ if (ctx->errcode)
+ ret |= BLOCK_ERROR | BLOCK_ABORT;
+ }
+ if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
+ !(ret & BLOCK_ABORT))
+ ret |= (*ctx->func)(ctx->fs, ind_block,
+ BLOCK_COUNT_IND, ref_block,
+ ref_offset, ctx->priv_data);
+ return ret;
+}
+
+static int block_iterate_dind(blk_t *dind_block, blk_t ref_block,
+ int ref_offset, struct block_context *ctx)
+{
+ int ret = 0, changed = 0;
+ int i, flags, limit, offset;
+ blk_t *block_nr;
+
+ limit = ctx->fs->blocksize >> 2;
+ if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
+ BLOCK_FLAG_DATA_ONLY)))
+ ret = (*ctx->func)(ctx->fs, dind_block,
+ BLOCK_COUNT_DIND, ref_block,
+ ref_offset, ctx->priv_data);
+ if (!*dind_block || (ret & BLOCK_ABORT)) {
+ ctx->bcount += limit*limit;
+ return ret;
+ }
+ if (*dind_block >= ctx->fs->super->s_blocks_count ||
+ *dind_block < ctx->fs->super->s_first_data_block) {
+ ctx->errcode = EXT2_ET_BAD_DIND_BLOCK;
+ ret |= BLOCK_ERROR;
+ return ret;
+ }
+ if (ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) {
+ ctx->errcode = 0;
+ memset(ctx->dind_buf, 0, ctx->fs->blocksize);
+ } else
+ ctx->errcode = io_channel_read_blk(ctx->fs->io, *dind_block,
+ 1, ctx->dind_buf);
+ if (ctx->errcode) {
+ ret |= BLOCK_ERROR;
+ return ret;
+ }
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
+ EXT2_FLAG_SWAP_BYTES_READ)) {
+ block_nr = (blk_t *) ctx->dind_buf;
+ for (i = 0; i < limit; i++, block_nr++)
+ *block_nr = ext2fs_swab32(*block_nr);
+ }
+#endif
+ block_nr = (blk_t *) ctx->dind_buf;
+ offset = 0;
+ if (ctx->flags & BLOCK_FLAG_APPEND) {
+ for (i = 0; i < limit; i++, block_nr++) {
+ flags = block_iterate_ind(block_nr,
+ *dind_block, offset,
+ ctx);
+ changed |= flags;
+ if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
+ ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
+ break;
+ }
+ offset += sizeof(blk_t);
+ }
+ } else {
+ for (i = 0; i < limit; i++, block_nr++) {
+ if (*block_nr == 0) {
+ ctx->bcount += limit;
+ continue;
+ }
+ flags = block_iterate_ind(block_nr,
+ *dind_block, offset,
+ ctx);
+ changed |= flags;
+ if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
+ ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
+ break;
+ }
+ offset += sizeof(blk_t);
+ }
+ }
+ if (!(ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
+ (changed & BLOCK_CHANGED)) {
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
+ EXT2_FLAG_SWAP_BYTES_WRITE)) {
+ block_nr = (blk_t *) ctx->dind_buf;
+ for (i = 0; i < limit; i++, block_nr++)
+ *block_nr = ext2fs_swab32(*block_nr);
+ }
+#endif
+ ctx->errcode = io_channel_write_blk(ctx->fs->io, *dind_block,
+ 1, ctx->dind_buf);
+ if (ctx->errcode)
+ ret |= BLOCK_ERROR | BLOCK_ABORT;
+ }
+ if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
+ !(ret & BLOCK_ABORT))
+ ret |= (*ctx->func)(ctx->fs, dind_block,
+ BLOCK_COUNT_DIND, ref_block,
+ ref_offset, ctx->priv_data);
+ return ret;
+}
+
+static int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
+ int ref_offset, struct block_context *ctx)
+{
+ int ret = 0, changed = 0;
+ int i, flags, limit, offset;
+ blk_t *block_nr;
+
+ limit = ctx->fs->blocksize >> 2;
+ if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
+ BLOCK_FLAG_DATA_ONLY)))
+ ret = (*ctx->func)(ctx->fs, tind_block,
+ BLOCK_COUNT_TIND, ref_block,
+ ref_offset, ctx->priv_data);
+ if (!*tind_block || (ret & BLOCK_ABORT)) {
+ ctx->bcount += limit*limit*limit;
+ return ret;
+ }
+ if (*tind_block >= ctx->fs->super->s_blocks_count ||
+ *tind_block < ctx->fs->super->s_first_data_block) {
+ ctx->errcode = EXT2_ET_BAD_TIND_BLOCK;
+ ret |= BLOCK_ERROR;
+ return ret;
+ }
+ if (ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) {
+ ctx->errcode = 0;
+ memset(ctx->tind_buf, 0, ctx->fs->blocksize);
+ } else
+ ctx->errcode = io_channel_read_blk(ctx->fs->io, *tind_block,
+ 1, ctx->tind_buf);
+ if (ctx->errcode) {
+ ret |= BLOCK_ERROR;
+ return ret;
+ }
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
+ EXT2_FLAG_SWAP_BYTES_READ)) {
+ block_nr = (blk_t *) ctx->tind_buf;
+ for (i = 0; i < limit; i++, block_nr++)
+ *block_nr = ext2fs_swab32(*block_nr);
+ }
+#endif
+ block_nr = (blk_t *) ctx->tind_buf;
+ offset = 0;
+ if (ctx->flags & BLOCK_FLAG_APPEND) {
+ for (i = 0; i < limit; i++, block_nr++) {
+ flags = block_iterate_dind(block_nr,
+ *tind_block,
+ offset, ctx);
+ changed |= flags;
+ if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
+ ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
+ break;
+ }
+ offset += sizeof(blk_t);
+ }
+ } else {
+ for (i = 0; i < limit; i++, block_nr++) {
+ if (*block_nr == 0) {
+ ctx->bcount += limit*limit;
+ continue;
+ }
+ flags = block_iterate_dind(block_nr,
+ *tind_block,
+ offset, ctx);
+ changed |= flags;
+ if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
+ ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
+ break;
+ }
+ offset += sizeof(blk_t);
+ }
+ }
+ if (!(ctx->fs->flags & EXT2_FLAG_IMAGE_FILE) &&
+ (changed & BLOCK_CHANGED)) {
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (ctx->fs->flags & (EXT2_FLAG_SWAP_BYTES |
+ EXT2_FLAG_SWAP_BYTES_WRITE)) {
+ block_nr = (blk_t *) ctx->tind_buf;
+ for (i = 0; i < limit; i++, block_nr++)
+ *block_nr = ext2fs_swab32(*block_nr);
+ }
+#endif
+ ctx->errcode = io_channel_write_blk(ctx->fs->io, *tind_block,
+ 1, ctx->tind_buf);
+ if (ctx->errcode)
+ ret |= BLOCK_ERROR | BLOCK_ABORT;
+ }
+ if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
+ !(ret & BLOCK_ABORT))
+ ret |= (*ctx->func)(ctx->fs, tind_block,
+ BLOCK_COUNT_TIND, ref_block,
+ ref_offset, ctx->priv_data);
+
+ return ret;
+}
+
+errcode_t ext2fs_block_iterate2(ext2_filsys fs,
+ ext2_ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_filsys fs,
+ blk_t *blocknr,
+ e2_blkcnt_t blockcnt,
+ blk_t ref_blk,
+ int ref_offset,
+ void *priv_data),
+ void *priv_data)
+{
+ int i;
+ int got_inode = 0;
+ int ret = 0;
+ blk_t blocks[EXT2_N_BLOCKS]; /* directory data blocks */
+ struct ext2_inode inode;
+ errcode_t retval;
+ struct block_context ctx;
+ int limit;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ /*
+ * Check to see if we need to limit large files
+ */
+ if (flags & BLOCK_FLAG_NO_LARGE) {
+ ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
+ if (ctx.errcode)
+ return ctx.errcode;
+ got_inode = 1;
+ if (!LINUX_S_ISDIR(inode.i_mode) &&
+ (inode.i_size_high != 0))
+ return EXT2_ET_FILE_TOO_BIG;
+ }
+
+ retval = ext2fs_get_blocks(fs, ino, blocks);
+ if (retval)
+ return retval;
+
+ limit = fs->blocksize >> 2;
+
+ ctx.fs = fs;
+ ctx.func = func;
+ ctx.priv_data = priv_data;
+ ctx.flags = flags;
+ ctx.bcount = 0;
+ if (block_buf) {
+ ctx.ind_buf = block_buf;
+ } else {
+ retval = ext2fs_get_mem(fs->blocksize * 3,
+ (void **) &ctx.ind_buf);
+ if (retval)
+ return retval;
+ }
+ ctx.dind_buf = ctx.ind_buf + fs->blocksize;
+ ctx.tind_buf = ctx.dind_buf + fs->blocksize;
+
+ /*
+ * Iterate over the HURD translator block (if present)
+ */
+ if ((fs->super->s_creator_os == EXT2_OS_HURD) &&
+ !(flags & BLOCK_FLAG_DATA_ONLY)) {
+ ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
+ if (ctx.errcode)
+ goto abort_exit;
+ got_inode = 1;
+ if (inode.osd1.hurd1.h_i_translator) {
+ ret |= (*ctx.func)(fs,
+ &inode.osd1.hurd1.h_i_translator,
+ BLOCK_COUNT_TRANSLATOR,
+ 0, 0, priv_data);
+ if (ret & BLOCK_ABORT)
+ goto abort_exit;
+ }
+ }
+
+ /*
+ * Iterate over normal data blocks
+ */
+ for (i = 0; i < EXT2_NDIR_BLOCKS ; i++, ctx.bcount++) {
+ if (blocks[i] || (flags & BLOCK_FLAG_APPEND)) {
+ ret |= (*ctx.func)(fs, &blocks[i],
+ ctx.bcount, 0, i, priv_data);
+ if (ret & BLOCK_ABORT)
+ goto abort_exit;
+ }
+ }
+ if (*(blocks + EXT2_IND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
+ ret |= block_iterate_ind(blocks + EXT2_IND_BLOCK,
+ 0, EXT2_IND_BLOCK, &ctx);
+ if (ret & BLOCK_ABORT)
+ goto abort_exit;
+ } else
+ ctx.bcount += limit;
+ if (*(blocks + EXT2_DIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
+ ret |= block_iterate_dind(blocks + EXT2_DIND_BLOCK,
+ 0, EXT2_DIND_BLOCK, &ctx);
+ if (ret & BLOCK_ABORT)
+ goto abort_exit;
+ } else
+ ctx.bcount += limit * limit;
+ if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
+ ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK,
+ 0, EXT2_TIND_BLOCK, &ctx);
+ if (ret & BLOCK_ABORT)
+ goto abort_exit;
+ }
+
+abort_exit:
+ if (ret & BLOCK_CHANGED) {
+ if (!got_inode) {
+ retval = ext2fs_read_inode(fs, ino, &inode);
+ if (retval)
+ return retval;
+ }
+ for (i=0; i < EXT2_N_BLOCKS; i++)
+ inode.i_block[i] = blocks[i];
+ retval = ext2fs_write_inode(fs, ino, &inode);
+ if (retval)
+ return retval;
+ }
+
+ if (!block_buf)
+ ext2fs_free_mem((void **) &ctx.ind_buf);
+
+ return (ret & BLOCK_ERROR) ? ctx.errcode : 0;
+}
+
+/*
+ * Emulate the old ext2fs_block_iterate function!
+ */
+
+struct xlate {
+ int (*func)(ext2_filsys fs,
+ blk_t *blocknr,
+ int bcount,
+ void *priv_data);
+ void *real_private;
+};
+
+#ifdef __TURBOC__
+ #pragma argsused
+#endif
+static int xlate_func(ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t blockcnt,
+ blk_t ref_block, int ref_offset, 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/e2fslib/block.o b/e2fslib/block.o
new file mode 100644
index 0000000..3ec71ce
--- /dev/null
+++ b/e2fslib/block.o
Binary files differ
diff --git a/e2fslib/bmap.c b/e2fslib/bmap.c
new file mode 100644
index 0000000..25ba695
--- /dev/null
+++ b/e2fslib/bmap.c
@@ -0,0 +1,237 @@
+/*
+ * bmap.c --- logical to physical block mapping
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+#if defined(__GNUC__) && !defined(NO_INLINE_FUNCS)
+#define _BMAP_INLINE_ __inline__
+#else
+#define _BMAP_INLINE_
+#endif
+
+extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode,
+ char *block_buf, int bmap_flags,
+ blk_t block, blk_t *phys_blk);
+
+#define BMAP_ALLOC 1
+
+#define inode_bmap(inode, nr) ((inode)->i_block[(nr)])
+
+static errcode_t _BMAP_INLINE_ 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) {
+ *ret_blk = 0;
+ return 0;
+ }
+ retval = io_channel_read_blk(fs->io, ind, 1, block_buf);
+ if (retval)
+ return retval;
+
+ b = ((blk_t *) block_buf)[nr];
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+ (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
+ b = ext2fs_swab32(b);
+#endif
+
+ if (!b && (flags & BMAP_ALLOC)) {
+ b = nr ? ((blk_t *) block_buf)[nr-1] : 0;
+ retval = ext2fs_alloc_block(fs, b,
+ block_buf + fs->blocksize, &b);
+ if (retval)
+ return retval;
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+ (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
+ ((blk_t *) block_buf)[nr] = ext2fs_swab32(b);
+ else
+#endif
+ ((blk_t *) block_buf)[nr] = b;
+
+ retval = io_channel_write_blk(fs->io, ind, 1, block_buf);
+ if (retval)
+ return retval;
+
+ (*blocks_alloc)++;
+ }
+
+ *ret_blk = b;
+ return 0;
+}
+
+static errcode_t _BMAP_INLINE_ block_dind_bmap(ext2_filsys fs, int flags,
+ blk_t dind, char *block_buf,
+ int *blocks_alloc,
+ blk_t nr, blk_t *ret_blk)
+{
+ blk_t b;
+ errcode_t retval;
+ blk_t addr_per_block;
+
+ addr_per_block = (blk_t) fs->blocksize >> 2;
+
+ retval = block_ind_bmap(fs, flags, 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 errcode_t _BMAP_INLINE_ block_tind_bmap(ext2_filsys fs, int flags,
+ blk_t tind, char *block_buf,
+ int *blocks_alloc,
+ blk_t nr, blk_t *ret_blk)
+{
+ blk_t b;
+ errcode_t retval;
+ blk_t addr_per_block;
+
+ addr_per_block = (blk_t) fs->blocksize >> 2;
+
+ retval = block_dind_bmap(fs, flags, tind, block_buf, blocks_alloc,
+ nr / addr_per_block, &b);
+ if (retval)
+ return retval;
+ retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc,
+ nr % addr_per_block, ret_blk);
+ return retval;
+}
+
+errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
+ char *block_buf, int bmap_flags, blk_t block,
+ blk_t *phys_blk)
+{
+ struct ext2_inode inode_buf;
+ blk_t addr_per_block;
+ blk_t b;
+ char *buf = 0;
+ errcode_t retval = 0;
+ int blocks_alloc = 0;
+
+ *phys_blk = 0;
+
+ /* Read inode structure if necessary */
+ if (!inode) {
+ retval = ext2fs_read_inode(fs, ino, &inode_buf);
+ if (!retval)
+ return retval;
+ inode = &inode_buf;
+ }
+ addr_per_block = (blk_t) fs->blocksize >> 2;
+
+ if (!block_buf) {
+ retval = ext2fs_get_mem(fs->blocksize * 2, (void **) &buf);
+ if (retval)
+ return retval;
+ block_buf = buf;
+ }
+
+ if (block < EXT2_NDIR_BLOCKS) {
+ *phys_blk = inode_bmap(inode, block);
+ b = block ? inode_bmap(inode, block-1) : 0;
+
+ if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) {
+ retval = ext2fs_alloc_block(fs, b, block_buf, &b);
+ if (retval)
+ goto done;
+ inode_bmap(inode, block) = b;
+ blocks_alloc++;
+ *phys_blk = b;
+ }
+ goto done;
+ }
+
+ /* Indirect block */
+ block -= EXT2_NDIR_BLOCKS;
+ if (block < addr_per_block) {
+ b = inode_bmap(inode, EXT2_IND_BLOCK);
+ if (!b) {
+ if (!(bmap_flags & BMAP_ALLOC))
+ goto done;
+
+ b = inode_bmap(inode, EXT2_IND_BLOCK-1);
+ retval = ext2fs_alloc_block(fs, b, block_buf, &b);
+ if (retval)
+ goto done;
+ inode_bmap(inode, EXT2_IND_BLOCK) = b;
+ blocks_alloc++;
+ }
+ retval = block_ind_bmap(fs, bmap_flags, b, block_buf,
+ &blocks_alloc, block, phys_blk);
+ goto done;
+ }
+
+ /* Doubly indirect block */
+ block -= addr_per_block;
+ if (block < addr_per_block * addr_per_block) {
+ b = inode_bmap(inode, EXT2_DIND_BLOCK);
+ if (!b) {
+ if (!(bmap_flags & BMAP_ALLOC))
+ goto done;
+
+ b = inode_bmap(inode, EXT2_IND_BLOCK);
+ retval = ext2fs_alloc_block(fs, b, block_buf, &b);
+ if (retval)
+ goto done;
+ inode_bmap(inode, EXT2_DIND_BLOCK) = b;
+ blocks_alloc++;
+ }
+ retval = block_dind_bmap(fs, bmap_flags, b, block_buf,
+ &blocks_alloc, block, phys_blk);
+ goto done;
+ }
+
+ /* Triply indirect block */
+ block -= addr_per_block * addr_per_block;
+ b = inode_bmap(inode, EXT2_TIND_BLOCK);
+ if (!b) {
+ if (!(bmap_flags & BMAP_ALLOC))
+ goto done;
+
+ b = inode_bmap(inode, EXT2_DIND_BLOCK);
+ retval = ext2fs_alloc_block(fs, b, block_buf, &b);
+ if (retval)
+ goto done;
+ inode_bmap(inode, EXT2_TIND_BLOCK) = b;
+ blocks_alloc++;
+ }
+ retval = block_tind_bmap(fs, bmap_flags, b, block_buf,
+ &blocks_alloc, block, phys_blk);
+done:
+ if (buf)
+ ext2fs_free_mem((void **) &buf);
+ if ((retval == 0) && blocks_alloc) {
+ inode->i_blocks += (blocks_alloc * fs->blocksize) / 512;
+ retval = ext2fs_write_inode(fs, ino, inode);
+ }
+ return retval;
+}
+
+
+
diff --git a/e2fslib/bmap.o b/e2fslib/bmap.o
new file mode 100644
index 0000000..288700c
--- /dev/null
+++ b/e2fslib/bmap.o
Binary files differ
diff --git a/e2fslib/bmove.c b/e2fslib/bmove.c
new file mode 100644
index 0000000..c0205ca
--- /dev/null
+++ b/e2fslib/bmove.c
@@ -0,0 +1,160 @@
+/*
+ * bmove.c --- Move blocks around to make way for a particular
+ * filesystem structure.
+ *
+ * Copyright (C) 1997 Theodore Ts'o. This file may be redistributed
+ * under the terms of the GNU Public License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+
+struct process_block_struct {
+ ext2_ino_t ino;
+ struct ext2_inode * inode;
+ ext2fs_block_bitmap reserve;
+ ext2fs_block_bitmap alloc_map;
+ errcode_t error;
+ char *buf;
+ int add_dir;
+ int flags;
+};
+
+static int process_block(ext2_filsys fs, blk_t *block_nr,
+ e2_blkcnt_t blockcnt, blk_t ref_block,
+ int ref_offset, void *priv_data)
+{
+ struct process_block_struct *pb;
+ errcode_t retval;
+ int ret;
+ blk_t block, orig;
+
+ pb = (struct process_block_struct *) priv_data;
+ block = orig = *block_nr;
+ ret = 0;
+
+ /*
+ * Let's see if this is one which we need to relocate
+ */
+ if (ext2fs_test_block_bitmap(pb->reserve, block)) {
+ do {
+ if (++block >= fs->super->s_blocks_count)
+ block = fs->super->s_first_data_block;
+ if (block == orig) {
+ pb->error = EXT2_ET_BLOCK_ALLOC_FAIL;
+ return BLOCK_ABORT;
+ }
+ } while (ext2fs_test_block_bitmap(pb->reserve, block) ||
+ ext2fs_test_block_bitmap(pb->alloc_map, block));
+
+ retval = io_channel_read_blk(fs->io, orig, 1, pb->buf);
+ if (retval) {
+ pb->error = retval;
+ return BLOCK_ABORT;
+ }
+ retval = io_channel_write_blk(fs->io, block, 1, pb->buf);
+ if (retval) {
+ pb->error = retval;
+ return BLOCK_ABORT;
+ }
+ *block_nr = block;
+ ext2fs_mark_block_bitmap(pb->alloc_map, block);
+ ret = BLOCK_CHANGED;
+ if (pb->flags & EXT2_BMOVE_DEBUG)
+ printf("ino=%ld, blockcnt=%lld, %d->%d\n", pb->ino,
+ blockcnt, orig, block);
+ }
+ if (pb->add_dir) {
+ retval = ext2fs_add_dir_block(fs->dblist, pb->ino,
+ block, (int) blockcnt);
+ if (retval) {
+ pb->error = retval;
+ ret |= BLOCK_ABORT;
+ }
+ }
+ return ret;
+}
+
+errcode_t ext2fs_move_blocks(ext2_filsys fs,
+ ext2fs_block_bitmap reserve,
+ ext2fs_block_bitmap alloc_map,
+ int flags)
+{
+ ext2_ino_t ino;
+ struct ext2_inode inode;
+ errcode_t retval;
+ struct process_block_struct pb;
+ ext2_inode_scan scan;
+ char *block_buf;
+
+ retval = ext2fs_open_inode_scan(fs, 0, &scan);
+ if (retval)
+ return retval;
+
+ pb.reserve = reserve;
+ pb.error = 0;
+ pb.alloc_map = alloc_map ? alloc_map : fs->block_map;
+ pb.flags = flags;
+
+ retval = ext2fs_get_mem(fs->blocksize * 4, (void **) &block_buf);
+ if (retval)
+ return retval;
+ pb.buf = block_buf + fs->blocksize * 3;
+
+ /*
+ * If GET_DBLIST is set in the flags field, then we should
+ * gather directory block information while we're doing the
+ * block move.
+ */
+ if (flags & EXT2_BMOVE_GET_DBLIST) {
+ if (fs->dblist) {
+ ext2fs_free_dblist(fs->dblist);
+ fs->dblist = NULL;
+ }
+ retval = ext2fs_init_dblist(fs, 0);
+ if (retval)
+ return retval;
+ }
+
+ retval = ext2fs_get_next_inode(scan, &ino, &inode);
+ if (retval)
+ return retval;
+
+ while (ino) {
+ if ((inode.i_links_count == 0) ||
+ !ext2fs_inode_has_valid_blocks(&inode))
+ goto next;
+
+ pb.ino = ino;
+ pb.inode = &inode;
+
+ pb.add_dir = (LINUX_S_ISDIR(inode.i_mode) &&
+ flags & EXT2_BMOVE_GET_DBLIST);
+
+ retval = ext2fs_block_iterate2(fs, ino, 0, block_buf,
+ process_block, &pb);
+ if (retval)
+ return retval;
+ if (pb.error)
+ return pb.error;
+
+ next:
+ retval = ext2fs_get_next_inode(scan, &ino, &inode);
+ if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
+ goto next;
+ }
+ return 0;
+}
+
diff --git a/e2fslib/brel.h b/e2fslib/brel.h
new file mode 100644
index 0000000..be97243
--- /dev/null
+++ b/e2fslib/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 Public
+ * License.
+ * %End-Header%
+ */
+
+struct ext2_block_relocate_entry {
+ blk_t new;
+ __s16 offset;
+ __u16 flags;
+ union {
+ blk_t block_ref;
+ ext2_ino_t inode_ref;
+ } owner;
+};
+
+#define RELOCATE_TYPE_REF 0x0007
+#define RELOCATE_BLOCK_REF 0x0001
+#define RELOCATE_INODE_REF 0x0002
+
+typedef struct ext2_block_relocation_table *ext2_brel;
+
+struct ext2_block_relocation_table {
+ __u32 magic;
+ char *name;
+ blk_t current;
+ void *priv_data;
+
+ /*
+ * Add a block relocation entry.
+ */
+ errcode_t (*put)(ext2_brel brel, blk_t old,
+ struct ext2_block_relocate_entry *ent);
+
+ /*
+ * Get a block relocation entry.
+ */
+ errcode_t (*get)(ext2_brel brel, blk_t old,
+ struct ext2_block_relocate_entry *ent);
+
+ /*
+ * Initialize for iterating over the block relocation entries.
+ */
+ errcode_t (*start_iter)(ext2_brel brel);
+
+ /*
+ * The iterator function for the inode relocation entries.
+ * Returns an inode number of 0 when out of entries.
+ */
+ errcode_t (*next)(ext2_brel brel, blk_t *old,
+ struct ext2_block_relocate_entry *ent);
+
+ /*
+ * Move the inode relocation table from one block number to
+ * another.
+ */
+ errcode_t (*move)(ext2_brel brel, blk_t old, blk_t new);
+
+ /*
+ * Remove a block relocation entry.
+ */
+ errcode_t (*delete)(ext2_brel brel, blk_t old);
+
+
+ /*
+ * Free the block relocation table.
+ */
+ errcode_t (*free)(ext2_brel brel);
+};
+
+errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block,
+ ext2_brel *brel);
+
+#define ext2fs_brel_put(brel, old, ent) ((brel)->put((brel), old, ent))
+#define ext2fs_brel_get(brel, old, ent) ((brel)->get((brel), old, ent))
+#define ext2fs_brel_start_iter(brel) ((brel)->start_iter((brel)))
+#define ext2fs_brel_next(brel, old, ent) ((brel)->next((brel), old, ent))
+#define ext2fs_brel_move(brel, old, new) ((brel)->move((brel), old, new))
+#define ext2fs_brel_delete(brel, old) ((brel)->delete((brel), old))
+#define ext2fs_brel_free(brel) ((brel)->free((brel)))
+
diff --git a/e2fslib/brel_ma.c b/e2fslib/brel_ma.c
new file mode 100644
index 0000000..8ad8e9f
--- /dev/null
+++ b/e2fslib/brel_ma.c
@@ -0,0 +1,197 @@
+/*
+ * brel_ma.c
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * TODO: rewrite to not use a direct array!!! (Fortunately this
+ * module isn't really used yet.)
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+#include "brel.h"
+
+static errcode_t bma_put(ext2_brel brel, blk_t old,
+ struct ext2_block_relocate_entry *ent);
+static errcode_t bma_get(ext2_brel brel, blk_t old,
+ struct ext2_block_relocate_entry *ent);
+static errcode_t bma_start_iter(ext2_brel brel);
+static errcode_t bma_next(ext2_brel brel, blk_t *old,
+ struct ext2_block_relocate_entry *ent);
+static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new);
+static errcode_t bma_delete(ext2_brel brel, blk_t old);
+static errcode_t bma_free(ext2_brel brel);
+
+struct brel_ma {
+ __u32 magic;
+ blk_t max_block;
+ struct ext2_block_relocate_entry *entries;
+};
+
+errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block,
+ ext2_brel *new_brel)
+{
+ ext2_brel brel = 0;
+ errcode_t retval;
+ struct brel_ma *ma = 0;
+ size_t size;
+
+ *new_brel = 0;
+
+ /*
+ * Allocate memory structures
+ */
+ retval = ext2fs_get_mem(sizeof(struct ext2_block_relocation_table),
+ (void **) &brel);
+ if (retval)
+ goto errout;
+ memset(brel, 0, sizeof(struct ext2_block_relocation_table));
+
+ retval = ext2fs_get_mem(strlen(name)+1, (void **) &brel->name);
+ if (retval)
+ goto errout;
+ strcpy(brel->name, name);
+
+ retval = ext2fs_get_mem(sizeof(struct brel_ma), (void **) &ma);
+ if (retval)
+ goto errout;
+ memset(ma, 0, sizeof(struct brel_ma));
+ brel->priv_data = ma;
+
+ size = (size_t) (sizeof(struct ext2_block_relocate_entry) *
+ (max_block+1));
+ retval = ext2fs_get_mem(size, (void **) &ma->entries);
+ if (retval)
+ goto errout;
+ memset(ma->entries, 0, size);
+ ma->max_block = max_block;
+
+ /*
+ * Fill in the brel data structure
+ */
+ brel->put = bma_put;
+ brel->get = bma_get;
+ brel->start_iter = bma_start_iter;
+ brel->next = bma_next;
+ brel->move = bma_move;
+ brel->delete = bma_delete;
+ brel->free = bma_free;
+
+ *new_brel = brel;
+ return 0;
+
+errout:
+ bma_free(brel);
+ return retval;
+}
+
+static errcode_t bma_put(ext2_brel brel, blk_t old,
+ struct ext2_block_relocate_entry *ent)
+{
+ struct brel_ma *ma;
+
+ ma = brel->priv_data;
+ if (old > ma->max_block)
+ return EXT2_ET_INVALID_ARGUMENT;
+ ma->entries[(unsigned)old] = *ent;
+ return 0;
+}
+
+static errcode_t bma_get(ext2_brel brel, blk_t old,
+ struct ext2_block_relocate_entry *ent)
+{
+ struct brel_ma *ma;
+
+ ma = brel->priv_data;
+ if (old > ma->max_block)
+ return EXT2_ET_INVALID_ARGUMENT;
+ if (ma->entries[(unsigned)old].new == 0)
+ return ENOENT;
+ *ent = ma->entries[old];
+ return 0;
+}
+
+static errcode_t bma_start_iter(ext2_brel brel)
+{
+ brel->current = 0;
+ return 0;
+}
+
+static errcode_t bma_next(ext2_brel brel, blk_t *old,
+ struct ext2_block_relocate_entry *ent)
+{
+ struct brel_ma *ma;
+
+ ma = brel->priv_data;
+ while (++brel->current < ma->max_block) {
+ if (ma->entries[(unsigned)brel->current].new == 0)
+ continue;
+ *old = brel->current;
+ *ent = ma->entries[(unsigned)brel->current];
+ return 0;
+ }
+ *old = 0;
+ return 0;
+}
+
+static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new)
+{
+ struct brel_ma *ma;
+
+ ma = brel->priv_data;
+ if ((old > ma->max_block) || (new > ma->max_block))
+ return EXT2_ET_INVALID_ARGUMENT;
+ if (ma->entries[(unsigned)old].new == 0)
+ return ENOENT;
+ ma->entries[(unsigned)new] = ma->entries[old];
+ ma->entries[(unsigned)old].new = 0;
+ return 0;
+}
+
+static errcode_t bma_delete(ext2_brel brel, blk_t old)
+{
+ struct brel_ma *ma;
+
+ ma = brel->priv_data;
+ if (old > ma->max_block)
+ return EXT2_ET_INVALID_ARGUMENT;
+ if (ma->entries[(unsigned)old].new == 0)
+ return ENOENT;
+ ma->entries[(unsigned)old].new = 0;
+ return 0;
+}
+
+static errcode_t bma_free(ext2_brel brel)
+{
+ struct brel_ma *ma;
+
+ if (!brel)
+ return 0;
+
+ ma = brel->priv_data;
+
+ if (ma) {
+ if (ma->entries)
+ ext2fs_free_mem((void **) &ma->entries);
+ ext2fs_free_mem((void **) &ma);
+ }
+ if (brel->name)
+ ext2fs_free_mem((void **) &brel->name);
+ ext2fs_free_mem((void **) &brel);
+ return 0;
+}
diff --git a/e2fslib/check_desc.c b/e2fslib/check_desc.c
new file mode 100644
index 0000000..902c4b6
--- /dev/null
+++ b/e2fslib/check_desc.c
@@ -0,0 +1,68 @@
+/*
+ * check_desc.c --- Check the group descriptors of an ext2 filesystem
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+/*
+ * This routine sanity checks the group descriptors
+ */
+errcode_t ext2fs_check_desc(ext2_filsys fs)
+{
+ int i;
+ blk_t block = fs->super->s_first_data_block;
+ blk_t next;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ for (i = 0; i < fs->group_desc_count; i++) {
+ next = block + fs->super->s_blocks_per_group;
+ /*
+ * Check to make sure block bitmap for group is
+ * located within the group.
+ */
+ if (fs->group_desc[i].bg_block_bitmap < block ||
+ fs->group_desc[i].bg_block_bitmap >= next)
+ return EXT2_ET_GDESC_BAD_BLOCK_MAP;
+ /*
+ * Check to make sure inode bitmap for group is
+ * located within the group
+ */
+ if (fs->group_desc[i].bg_inode_bitmap < block ||
+ fs->group_desc[i].bg_inode_bitmap >= next)
+ return EXT2_ET_GDESC_BAD_INODE_MAP;
+ /*
+ * Check to make sure inode table for group is located
+ * within the group
+ */
+ if (fs->group_desc[i].bg_inode_table < block ||
+ ((fs->group_desc[i].bg_inode_table +
+ fs->inode_blocks_per_group) >= next))
+ return EXT2_ET_GDESC_BAD_INODE_TABLE;
+
+ block = next;
+ }
+ return 0;
+}
diff --git a/e2fslib/check_desc.o b/e2fslib/check_desc.o
new file mode 100644
index 0000000..86571de
--- /dev/null
+++ b/e2fslib/check_desc.o
Binary files differ
diff --git a/e2fslib/closefs.c b/e2fslib/closefs.c
new file mode 100644
index 0000000..f52c343
--- /dev/null
+++ b/e2fslib/closefs.c
@@ -0,0 +1,291 @@
+/*
+ * closefs.c --- close an ext2 filesystem
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <time.h>
+#include <string.h>
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+
+static int test_root(int a, int b)
+{
+ if (a == 0)
+ return 1;
+ while (1) {
+ if (a == 1)
+ return 1;
+ if (a % b)
+ return 0;
+ a = a / b;
+ }
+}
+
+int ext2fs_bg_has_super(ext2_filsys fs, int group_block)
+{
+ if (!(fs->super->s_feature_ro_compat &
+ EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
+ return 1;
+
+ if (test_root(group_block, 3) || (test_root(group_block, 5)) ||
+ test_root(group_block, 7))
+ return 1;
+
+ return 0;
+}
+
+/*
+ * This function forces out the primary superblock. We need to only
+ * write out those fields which we have changed, since if the
+ * filesystem is mounted, it may have changed some of the other
+ * fields.
+ *
+ * It takes as input a superblock which has already been byte swapped
+ * (if necessary).
+ *
+ */
+static errcode_t write_primary_superblock(ext2_filsys fs,
+ struct ext2_super_block *super)
+{
+ __u16 *old_super, *new_super;
+ int check_idx, write_idx, size;
+ errcode_t retval;
+
+ if (!fs->io->manager->write_byte || !fs->orig_super) {
+ io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET);
+ retval = io_channel_write_blk(fs->io, 1, -SUPERBLOCK_SIZE,
+ super);
+ io_channel_set_blksize(fs->io, fs->blocksize);
+ return retval;
+ }
+
+ old_super = (__u16 *) fs->orig_super;
+ new_super = (__u16 *) super;
+
+ for (check_idx = 0; check_idx < SUPERBLOCK_SIZE/2; check_idx++) {
+ if (old_super[check_idx] == new_super[check_idx])
+ continue;
+ write_idx = check_idx;
+ for (check_idx++; check_idx < SUPERBLOCK_SIZE/2; check_idx++)
+ if (old_super[check_idx] == new_super[check_idx])
+ break;
+ size = 2 * (check_idx - write_idx);
+#if 0
+ printf("Writing %d bytes starting at %d\n",
+ size, write_idx*2);
+#endif
+ retval = io_channel_write_byte(fs->io,
+ SUPERBLOCK_OFFSET + (2 * write_idx), size,
+ new_super + write_idx);
+ if (retval)
+ return retval;
+ }
+ memcpy(fs->orig_super, super, SUPERBLOCK_SIZE);
+ return 0;
+}
+
+
+/*
+ * Updates the revision to EXT2_DYNAMIC_REV
+ */
+void ext2fs_update_dynamic_rev(ext2_filsys fs)
+{
+ struct ext2_super_block *sb = fs->super;
+
+ if (sb->s_rev_level > EXT2_GOOD_OLD_REV)
+ return;
+
+ sb->s_rev_level = EXT2_DYNAMIC_REV;
+ sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
+ sb->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
+ /* s_uuid is handled by e2fsck already */
+ /* other fields should be left alone */
+}
+
+errcode_t ext2fs_flush(ext2_filsys fs)
+{
+ dgrp_t i,j,maxgroup,sgrp;
+ blk_t group_block;
+ errcode_t retval;
+ char *group_ptr;
+ unsigned long fs_state;
+ struct ext2_super_block *super_shadow = 0;
+ struct ext2_group_desc *group_shadow = 0;
+ struct ext2_group_desc *s, *t;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ fs_state = fs->super->s_state;
+
+ fs->super->s_wtime = time(NULL);
+ fs->super->s_block_group_nr = 0;
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
+ retval = EXT2_ET_NO_MEMORY;
+ retval = ext2fs_get_mem(SUPERBLOCK_SIZE,
+ (void **) &super_shadow);
+ if (retval)
+ goto errout;
+ retval = ext2fs_get_mem((size_t)(fs->blocksize *
+ fs->desc_blocks),
+ (void **) &group_shadow);
+ if (retval)
+ goto errout;
+ memset(group_shadow, 0, (size_t) fs->blocksize *
+ fs->desc_blocks);
+
+ /* swap the superblock */
+ *super_shadow = *fs->super;
+ ext2fs_swap_super(super_shadow);
+
+ /* swap the group descriptors */
+ for (j=0, s=fs->group_desc, t=group_shadow;
+ j < fs->group_desc_count; j++, t++, s++) {
+ *t = *s;
+ ext2fs_swap_group_desc(t);
+ }
+ } else {
+ super_shadow = fs->super;
+ group_shadow = fs->group_desc;
+ }
+#else
+ super_shadow = fs->super;
+ group_shadow = fs->group_desc;
+#endif
+
+ /*
+ * Write out master superblock. This has to be done
+ * separately, since it is located at a fixed location
+ * (SUPERBLOCK_OFFSET).
+ */
+ retval = write_primary_superblock(fs, super_shadow);
+ if (retval)
+ goto errout;
+
+ /*
+ * 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) {
+ retval = 0;
+ goto errout;
+ }
+
+ /*
+ * Set the state of the FS to be non-valid. (The state has
+ * already been backed up earlier, and will be restored when
+ * we exit.)
+ */
+ fs->super->s_state &= ~EXT2_VALID_FS;
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
+ *super_shadow = *fs->super;
+ ext2fs_swap_super(super_shadow);
+ }
+#endif
+
+ /*
+ * Write out the master group descriptors, and the backup
+ * superblocks and group descriptors.
+ */
+ group_block = fs->super->s_first_data_block;
+ maxgroup = (fs->flags & EXT2_FLAG_MASTER_SB_ONLY) ? 1 :
+ fs->group_desc_count;
+ for (i = 0; i < maxgroup; i++) {
+ if (!ext2fs_bg_has_super(fs, i))
+ goto next_group;
+
+ sgrp = i;
+ if (sgrp > ((1 << 16) - 1))
+ sgrp = (1 << 16) - 1;
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES)
+ super_shadow->s_block_group_nr = ext2fs_swab16(sgrp);
+ else
+#endif
+ fs->super->s_block_group_nr = sgrp;
+
+ if (i !=0 ) {
+ retval = io_channel_write_blk(fs->io, group_block,
+ -SUPERBLOCK_SIZE,
+ super_shadow);
+ if (retval)
+ goto errout;
+ }
+ if (fs->flags & EXT2_FLAG_SUPER_ONLY)
+ goto next_group;
+ group_ptr = (char *) group_shadow;
+ for (j=0; j < fs->desc_blocks; j++) {
+ retval = io_channel_write_blk(fs->io,
+ group_block+1+j, 1,
+ group_ptr);
+ if (retval)
+ goto errout;
+ group_ptr += fs->blocksize;
+ }
+ next_group:
+ group_block += EXT2_BLOCKS_PER_GROUP(fs->super);
+ }
+ fs->super->s_block_group_nr = 0;
+
+ /*
+ * 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;
+ }
+
+ fs->flags &= ~EXT2_FLAG_DIRTY;
+
+ /*
+ * Flush the blocks out to disk
+ */
+ retval = io_channel_flush(fs->io);
+errout:
+ fs->super->s_state = fs_state;
+ if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
+ if (super_shadow)
+ ext2fs_free_mem((void **) &super_shadow);
+ if (group_shadow)
+ ext2fs_free_mem((void **) &group_shadow);
+ }
+ return retval;
+}
+
+errcode_t ext2fs_close(ext2_filsys fs)
+{
+ errcode_t retval;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ if (fs->flags & EXT2_FLAG_DIRTY) {
+ retval = ext2fs_flush(fs);
+ if (retval)
+ return retval;
+ }
+ if (fs->write_bitmaps) {
+ retval = fs->write_bitmaps(fs);
+ if (retval)
+ return retval;
+ }
+ ext2fs_free(fs);
+ return 0;
+}
+
diff --git a/e2fslib/closefs.o b/e2fslib/closefs.o
new file mode 100644
index 0000000..b62baf1
--- /dev/null
+++ b/e2fslib/closefs.o
Binary files differ
diff --git a/e2fslib/cmp_bitmaps.c b/e2fslib/cmp_bitmaps.c
new file mode 100644
index 0000000..51cc3d0
--- /dev/null
+++ b/e2fslib/cmp_bitmaps.c
@@ -0,0 +1,72 @@
+/*
+ * cmp_bitmaps.c --- routines to compare inode and block bitmaps.
+ *
+ * Copyright (C) 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
+ ext2fs_block_bitmap bm2)
+{
+ blk_t i;
+
+ EXT2_CHECK_MAGIC(bm1, EXT2_ET_MAGIC_BLOCK_BITMAP);
+ EXT2_CHECK_MAGIC(bm2, EXT2_ET_MAGIC_BLOCK_BITMAP);
+
+ if ((bm1->start != bm2->start) ||
+ (bm1->end != bm2->end) ||
+ (memcmp(bm1->bitmap, bm2->bitmap,
+ (size_t) (bm1->end - bm1->start)/8)))
+ return EXT2_ET_NEQ_BLOCK_BITMAP;
+
+ for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
+ if (ext2fs_fast_test_block_bitmap(bm1, i) !=
+ ext2fs_fast_test_block_bitmap(bm2, i))
+ return EXT2_ET_NEQ_BLOCK_BITMAP;
+
+ return 0;
+}
+
+errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
+ ext2fs_inode_bitmap bm2)
+{
+ ext2_ino_t i;
+
+ EXT2_CHECK_MAGIC(bm1, EXT2_ET_MAGIC_INODE_BITMAP);
+ EXT2_CHECK_MAGIC(bm2, EXT2_ET_MAGIC_INODE_BITMAP);
+
+ if ((bm1->start != bm2->start) ||
+ (bm1->end != bm2->end) ||
+ (memcmp(bm1->bitmap, bm2->bitmap,
+ (size_t) (bm1->end - bm1->start)/8)))
+ return EXT2_ET_NEQ_INODE_BITMAP;
+
+ for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
+ if (ext2fs_fast_test_inode_bitmap(bm1, i) !=
+ ext2fs_fast_test_inode_bitmap(bm2, i))
+ return EXT2_ET_NEQ_INODE_BITMAP;
+
+ return 0;
+}
+
diff --git a/e2fslib/cmp_bitmaps.o b/e2fslib/cmp_bitmaps.o
new file mode 100644
index 0000000..21c8386
--- /dev/null
+++ b/e2fslib/cmp_bitmaps.o
Binary files differ
diff --git a/e2fslib/com_err.h b/e2fslib/com_err.h
new file mode 100644
index 0000000..f28dce8
--- /dev/null
+++ b/e2fslib/com_err.h
@@ -0,0 +1,40 @@
+/*
+ * Header file for common error description library.
+ *
+ * Copyright 1988, Student Information Processing Board of the
+ * Massachusetts Institute of Technology.
+ *
+ * For copyright and distribution info, see the documentation supplied
+ * with this package.
+ */
+
+#ifndef __COM_ERR_H
+
+typedef long errcode_t;
+
+#ifdef __STDC__
+#include <stdarg.h>
+
+/* ANSI C -- use prototypes etc */
+void com_err (const char *, long, const char *, ...);
+void com_err_va (const char *whoami, errcode_t code, const char *fmt,
+ va_list args);
+char const *error_message (long);
+extern void (*com_err_hook) (const char *, long, const char *, va_list);
+void (*set_com_err_hook (void (*) (const char *, long, const char *, va_list)))
+ (const char *, long, const char *, va_list);
+void (*reset_com_err_hook (void)) (const char *, long, const char *, va_list);
+int init_error_table(const char * const *msgs, int base, int count);
+#else
+/* no prototypes */
+void com_err ();
+void com_err_va ();
+char *error_message ();
+extern void (*com_err_hook) ();
+void (*set_com_err_hook ()) ();
+void (*reset_com_err_hook ()) ();
+int init_error_table();
+#endif
+
+#define __COM_ERR_H
+#endif /* ! defined(__COM_ERR_H) */
diff --git a/e2fslib/dblist.c b/e2fslib/dblist.c
new file mode 100644
index 0000000..a195b5b
--- /dev/null
+++ b/e2fslib/dblist.c
@@ -0,0 +1,254 @@
+/*
+ * dblist.c -- directory block list functions
+ *
+ * Copyright 1997 by Theodore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ *
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <time.h>
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+
+static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b);
+
+/*
+ * Returns the number of directories in the filesystem as reported by
+ * the group descriptors. Of course, the group descriptors could be
+ * wrong!
+ */
+errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs)
+{
+ dgrp_t i;
+ ext2_ino_t num_dirs, max_dirs;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ num_dirs = 0;
+ max_dirs = fs->super->s_inodes_per_group;
+ for (i = 0; i < fs->group_desc_count; i++) {
+ if (fs->group_desc[i].bg_used_dirs_count > max_dirs)
+ num_dirs += max_dirs / 8;
+ else
+ num_dirs += fs->group_desc[i].bg_used_dirs_count;
+ }
+ if (num_dirs > fs->super->s_inodes_count)
+ num_dirs = fs->super->s_inodes_count;
+
+ *ret_num_dirs = num_dirs;
+
+ return 0;
+}
+
+/*
+ * helper function for making a new directory block list (for
+ * initialize and copy).
+ */
+static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, ext2_ino_t count,
+ struct ext2_db_entry *list,
+ ext2_dblist *ret_dblist)
+{
+ ext2_dblist dblist;
+ errcode_t retval;
+ size_t len;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ if ((ret_dblist == 0) && fs->dblist &&
+ (fs->dblist->magic == EXT2_ET_MAGIC_DBLIST))
+ return 0;
+
+ retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist),
+ (void **) &dblist);
+ if (retval)
+ return retval;
+ memset(dblist, 0, sizeof(struct ext2_struct_dblist));
+
+ dblist->magic = EXT2_ET_MAGIC_DBLIST;
+ dblist->fs = fs;
+ if (size)
+ dblist->size = size;
+ else {
+ retval = ext2fs_get_num_dirs(fs, &dblist->size);
+ if (retval)
+ goto cleanup;
+ dblist->size = (dblist->size * 2) + 12;
+ }
+ len = (size_t) sizeof(struct ext2_db_entry) * dblist->size;
+ dblist->count = count;
+ retval = ext2fs_get_mem(len, (void **) &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((void **) &dblist);
+ return retval;
+}
+
+/*
+ * Initialize a directory block list
+ */
+errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist)
+{
+ ext2_dblist dblist;
+ errcode_t retval;
+
+ retval = make_dblist(fs, 0, 0, 0, &dblist);
+ if (retval)
+ return retval;
+
+ dblist->sorted = 1;
+ if (ret_dblist)
+ *ret_dblist = dblist;
+ else
+ fs->dblist = dblist;
+
+ return 0;
+}
+
+/*
+ * Copy a directory block list
+ */
+errcode_t ext2fs_copy_dblist(ext2_dblist src, ext2_dblist *dest)
+{
+ ext2_dblist dblist;
+ errcode_t retval;
+
+ retval = make_dblist(src->fs, src->size, src->count, src->list,
+ &dblist);
+ if (retval)
+ return retval;
+ dblist->sorted = src->sorted;
+ *dest = dblist;
+ return 0;
+}
+
+/*
+ * Close a directory block list
+ *
+ * (moved to closefs.c)
+ */
+
+
+/*
+ * Add a directory block to the directory block list
+ */
+errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk,
+ int blockcnt)
+{
+ struct ext2_db_entry *new_entry;
+ errcode_t retval;
+ unsigned long old_size;
+
+ EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+
+ if (dblist->count >= dblist->size) {
+ old_size = dblist->size * sizeof(struct ext2_db_entry);
+ dblist->size += 100;
+ retval = ext2fs_resize_mem(old_size, (size_t) dblist->size *
+ sizeof(struct ext2_db_entry),
+ (void **) &dblist->list);
+ if (retval) {
+ dblist->size -= 100;
+ return retval;
+ }
+ }
+ new_entry = dblist->list + ( (int) dblist->count++);
+ new_entry->blk = blk;
+ new_entry->ino = ino;
+ new_entry->blockcnt = blockcnt;
+
+ dblist->sorted = 0;
+
+ return 0;
+}
+
+/*
+ * Change the directory block to the directory block list
+ */
+errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk,
+ int blockcnt)
+{
+ dgrp_t i;
+
+ EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+
+ for (i=0; i < dblist->count; i++) {
+ if ((dblist->list[i].ino != ino) ||
+ (dblist->list[i].blockcnt != blockcnt))
+ continue;
+ dblist->list[i].blk = blk;
+ dblist->sorted = 0;
+ return 0;
+ }
+ return EXT2_ET_DB_NOT_FOUND;
+}
+
+/*
+ * This function iterates over the directory block list
+ */
+errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
+ int (*func)(ext2_filsys fs,
+ struct ext2_db_entry *db_info,
+ void *priv_data),
+ void *priv_data)
+{
+ ext2_ino_t i;
+ int ret;
+
+ EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+
+ if (!dblist->sorted) {
+ qsort(dblist->list, (size_t) dblist->count,
+ sizeof(struct ext2_db_entry), dir_block_cmp);
+ dblist->sorted = 1;
+ }
+ for (i=0; i < dblist->count; i++) {
+ ret = (*func)(dblist->fs, &dblist->list[(int)i], priv_data);
+ if (ret & DBLIST_ABORT)
+ return 0;
+ }
+ return 0;
+}
+
+
+static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b)
+{
+ const struct ext2_db_entry *db_a =
+ (const struct ext2_db_entry *) a;
+ const struct ext2_db_entry *db_b =
+ (const struct ext2_db_entry *) b;
+
+ if (db_a->blk != db_b->blk)
+ return (int) (db_a->blk - db_b->blk);
+
+ if (db_a->ino != db_b->ino)
+ return (int) (db_a->ino - db_b->ino);
+
+ return (int) (db_a->blockcnt - db_b->blockcnt);
+}
+
+int ext2fs_dblist_count(ext2_dblist dblist)
+{
+ return (int) dblist->count;
+}
diff --git a/e2fslib/dblist.o b/e2fslib/dblist.o
new file mode 100644
index 0000000..6ca5fc4
--- /dev/null
+++ b/e2fslib/dblist.o
Binary files differ
diff --git a/e2fslib/dblist_dir.c b/e2fslib/dblist_dir.c
new file mode 100644
index 0000000..c4ea584
--- /dev/null
+++ b/e2fslib/dblist_dir.c
@@ -0,0 +1,77 @@
+/*
+ * dblist_dir.c --- iterate by directory entry
+ *
+ * Copyright 1997 by Theodore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ *
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <time.h>
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+
+static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info,
+ void *priv_data);
+
+errcode_t ext2fs_dblist_dir_iterate(ext2_dblist dblist,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_ino_t dir,
+ int entry,
+ struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data)
+{
+ errcode_t retval;
+ struct dir_context ctx;
+
+ EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+
+ ctx.dir = 0;
+ ctx.flags = flags;
+ if (block_buf)
+ ctx.buf = block_buf;
+ else {
+ retval = ext2fs_get_mem(dblist->fs->blocksize,
+ (void **) &ctx.buf);
+ if (retval)
+ return retval;
+ }
+ ctx.func = 0;
+ ctx.func2 = func;
+ ctx.priv_data = priv_data;
+ ctx.errcode = 0;
+
+ retval = ext2fs_dblist_iterate(dblist, db_dir_proc, &ctx);
+
+ if (!block_buf)
+ ext2fs_free_mem((void **) &ctx.buf);
+ if (retval)
+ return retval;
+ return ctx.errcode;
+}
+
+static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info,
+ void *priv_data)
+{
+ struct dir_context *ctx;
+
+ ctx = (struct dir_context *) priv_data;
+ ctx->dir = db_info->ino;
+
+ return ext2fs_process_dir_block(fs, &db_info->blk,
+ db_info->blockcnt, 0, 0, priv_data);
+}
diff --git a/e2fslib/dblist_dir.o b/e2fslib/dblist_dir.o
new file mode 100644
index 0000000..40f1c71
--- /dev/null
+++ b/e2fslib/dblist_dir.o
Binary files differ
diff --git a/e2fslib/dir_iterate.c b/e2fslib/dir_iterate.c
new file mode 100644
index 0000000..ae97d82
--- /dev/null
+++ b/e2fslib/dir_iterate.c
@@ -0,0 +1,137 @@
+/*
+ * dir_iterate.c --- ext2fs directory iteration operations
+ *
+ * Copyright (C) 1993, 1994, 1994, 1995, 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+
+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 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, (void **) &ctx.buf);
+ if (retval)
+ return retval;
+ }
+ ctx.func = func;
+ ctx.func2 = 0;
+ ctx.priv_data = priv_data;
+ ctx.errcode = 0;
+ retval = ext2fs_block_iterate2(fs, dir, 0, 0,
+ ext2fs_process_dir_block, &ctx);
+ if (!block_buf)
+ ext2fs_free_mem((void **) &ctx.buf);
+ if (retval)
+ return retval;
+ return ctx.errcode;
+}
+
+/*
+ * Helper function which is private to this module. Used by
+ * ext2fs_dir_iterate() and ext2fs_dblist_dir_iterate()
+ */
+int ext2fs_process_dir_block(ext2_filsys fs,
+ blk_t *blocknr,
+ e2_blkcnt_t blockcnt,
+ blk_t ref_block,
+ int ref_offset,
+ void *priv_data)
+{
+ struct dir_context *ctx = (struct dir_context *) priv_data;
+ int offset = 0;
+ int ret = 0;
+ int changed = 0;
+ int do_abort = 0;
+ 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_block(fs, *blocknr, ctx->buf);
+ if (ctx->errcode)
+ return BLOCK_ABORT;
+
+ while (offset < fs->blocksize) {
+ dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
+ if (((offset + dirent->rec_len) > fs->blocksize) ||
+ (dirent->rec_len < 8) ||
+ ((dirent->rec_len % 4) != 0) ||
+ (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
+ ctx->errcode = EXT2_ET_DIR_CORRUPTED;
+ return BLOCK_ABORT;
+ }
+ if (!dirent->inode &&
+ !(ctx->flags & DIRENT_FLAG_INCLUDE_EMPTY))
+ goto next;
+
+ if (ctx->func)
+ ret = (ctx->func)(dirent, offset, fs->blocksize,
+ ctx->buf, ctx->priv_data);
+ else if (ctx->func2) {
+ ret = (ctx->func2)(ctx->dir, entry, dirent, offset,
+ fs->blocksize, ctx->buf,
+ ctx->priv_data);
+ if (entry < DIRENT_OTHER_FILE)
+ entry++;
+ }
+
+ if (ret & DIRENT_CHANGED)
+ changed++;
+ if (ret & DIRENT_ABORT) {
+ do_abort++;
+ break;
+ }
+next:
+ offset += dirent->rec_len;
+ }
+
+ if (changed) {
+ ctx->errcode = ext2fs_write_dir_block(fs, *blocknr, ctx->buf);
+ if (ctx->errcode)
+ return BLOCK_ABORT;
+ }
+ if (do_abort)
+ return BLOCK_ABORT;
+ return 0;
+}
+
diff --git a/e2fslib/dir_iterate.o b/e2fslib/dir_iterate.o
new file mode 100644
index 0000000..36f8330
--- /dev/null
+++ b/e2fslib/dir_iterate.o
Binary files differ
diff --git a/e2fslib/dirblock.c b/e2fslib/dirblock.c
new file mode 100644
index 0000000..9efbceb
--- /dev/null
+++ b/e2fslib/dirblock.c
@@ -0,0 +1,100 @@
+/*
+ * dirblock.c --- directory block routines.
+ *
+ * Copyright (C) 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <time.h>
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
+ void *buf)
+{
+ errcode_t retval;
+ char *p, *end;
+ struct ext2_dir_entry *dirent;
+ unsigned int rec_len, do_swap;
+
+ retval = io_channel_read_blk(fs->io, block, 1, buf);
+ if (retval)
+ return retval;
+#ifdef EXT2FS_ENABLE_SWAPFS
+ do_swap = (fs->flags & (EXT2_FLAG_SWAP_BYTES|
+ EXT2_FLAG_SWAP_BYTES_READ)) != 0;
+#endif
+ p = (char *) buf;
+ end = (char *) buf + fs->blocksize;
+ while (p < end-8) {
+ dirent = (struct ext2_dir_entry *) p;
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if (do_swap) {
+ dirent->inode = ext2fs_swab32(dirent->inode);
+ dirent->rec_len = ext2fs_swab16(dirent->rec_len);
+ dirent->name_len = ext2fs_swab16(dirent->name_len);
+ }
+#endif
+ rec_len = dirent->rec_len;
+ if ((rec_len < 8) || (rec_len % 4)) {
+ rec_len = 8;
+ retval = EXT2_ET_DIR_CORRUPTED;
+ }
+ if (((dirent->name_len & 0xFF) + 8) > dirent->rec_len)
+ retval = EXT2_ET_DIR_CORRUPTED;
+ p += rec_len;
+ }
+ return retval;
+}
+
+errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
+ void *inbuf)
+{
+ errcode_t retval;
+ char *p, *end, *write_buf;
+ char *buf = 0;
+ struct ext2_dir_entry *dirent;
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+ (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) {
+ retval = ext2fs_get_mem(fs->blocksize, (void **) &buf);
+ if (retval)
+ return retval;
+ write_buf = buf;
+ memcpy(buf, inbuf, fs->blocksize);
+ p = buf;
+ end = buf + fs->blocksize;
+ while (p < end) {
+ dirent = (struct ext2_dir_entry *) p;
+ if ((dirent->rec_len < 8) ||
+ (dirent->rec_len % 4)) {
+ retval = EXT2_ET_DIR_CORRUPTED;
+ goto errout;
+ }
+ p += dirent->rec_len;
+ dirent->inode = ext2fs_swab32(dirent->inode);
+ dirent->rec_len = ext2fs_swab16(dirent->rec_len);
+ dirent->name_len = ext2fs_swab16(dirent->name_len);
+ }
+ } else
+#endif
+ write_buf = (char *) inbuf;
+ retval = io_channel_write_blk(fs->io, block, 1, write_buf);
+errout:
+ if (buf)
+ ext2fs_free_mem((void **) &buf);
+ return retval;
+}
+
+
diff --git a/e2fslib/dirblock.o b/e2fslib/dirblock.o
new file mode 100644
index 0000000..e79011f
--- /dev/null
+++ b/e2fslib/dirblock.o
Binary files differ
diff --git a/e2fslib/dll/jump.funcs b/e2fslib/dll/jump.funcs
new file mode 100644
index 0000000..7498b03
--- /dev/null
+++ b/e2fslib/dll/jump.funcs
@@ -0,0 +1,178 @@
+00000000 T _ext2fs_open libext2fs openfs
+00000000 T _ext2fs_check_desc libext2fs openfs
+00000000 T _ext2fs_free libext2fs freefs
+00000000 T _ext2fs_flush libext2fs closefs
+00000000 T _ext2fs_close libext2fs closefs
+00000000 T _ext2fs_allocate_inode_bitmap libext2fs bitmaps
+00000000 T _ext2fs_allocate_block_bitmap libext2fs bitmaps
+00000000 T _ext2fs_free_inode_bitmap libext2fs bitmaps
+00000000 T _ext2fs_free_block_bitmap libext2fs bitmaps
+00000000 T _ext2fs_fudge_inode_bitmap_end libext2fs bitmaps
+00000000 T _ext2fs_fudge_block_bitmap_end libext2fs bitmaps
+00000000 T _ext2fs_clear_inode_bitmap libext2fs bitmaps
+00000000 T _ext2fs_clear_block_bitmap libext2fs bitmaps
+00000000 T _ext2fs_write_inode_bitmap libext2fs rw_bitmaps
+00000000 T _ext2fs_write_block_bitmap libext2fs rw_bitmaps
+00000000 T _ext2fs_read_inode_bitmap libext2fs rw_bitmaps
+00000000 T _ext2fs_read_block_bitmap libext2fs rw_bitmaps
+00000000 T _ext2fs_read_bitmaps libext2fs rw_bitmaps
+00000000 T _ext2fs_write_bitmaps libext2fs rw_bitmaps
+00000000 T _ext2fs_open_inode_scan libext2fs inode
+00000000 T _ext2fs_close_inode_scan libext2fs inode
+00000000 T _ext2fs_get_next_inode libext2fs inode
+00000000 T _ext2fs_read_inode libext2fs inode
+00000000 T _ext2fs_write_inode libext2fs inode
+00000000 T _ext2fs_get_blocks libext2fs inode
+00000000 T _ext2fs_check_directory libext2fs inode
+00000000 T _ext2fs_block_iterate libext2fs block
+00000000 T _ext2fs_dir_iterate libext2fs namei
+00000000 T _ext2fs_lookup libext2fs namei
+00000000 T _ext2fs_namei libext2fs namei
+00000000 T _ext2fs_new_dir_block libext2fs newdir
+00000000 T _ext2fs_mkdir libext2fs mkdir
+00000000 T _ext2fs_get_pathname libext2fs get_pathname
+00000000 T _ext2fs_warn_bitmap libext2fs bitops
+00000000 T _ext2fs_link libext2fs link
+00000000 T _ext2fs_unlink libext2fs link
+00000000 T _ext2fs_new_inode libext2fs alloc
+00000000 T _ext2fs_new_block libext2fs alloc
+00000000 T _ext2fs_get_free_blocks libext2fs alloc
+00000000 T _ext2fs_expand_dir libext2fs expanddir
+00000000 T _ext2fs_set_bit libext2fs inline
+00000000 T _ext2fs_clear_bit libext2fs inline
+00000000 T _ext2fs_test_bit libext2fs inline
+00000000 T _ext2fs_mark_block_bitmap libext2fs inline
+00000000 T _ext2fs_unmark_block_bitmap libext2fs inline
+00000000 T _ext2fs_test_block_bitmap libext2fs inline
+00000000 T _ext2fs_mark_inode_bitmap libext2fs inline
+00000000 T _ext2fs_unmark_inode_bitmap libext2fs inline
+00000000 T _ext2fs_test_inode_bitmap libext2fs inline
+00000000 T _ext2fs_mark_super_dirty libext2fs inline
+00000000 T _ext2fs_mark_changed libext2fs inline
+00000000 T _ext2fs_test_changed libext2fs inline
+00000000 T _ext2fs_mark_valid libext2fs inline
+00000000 T _ext2fs_unmark_valid libext2fs inline
+00000000 T _ext2fs_test_valid libext2fs inline
+00000000 T _ext2fs_mark_ib_dirty libext2fs inline
+00000000 T _ext2fs_mark_bb_dirty libext2fs inline
+00000000 T _ext2fs_test_ib_dirty libext2fs inline
+00000000 T _ext2fs_test_bb_dirty libext2fs inline
+00000000 T _ext2fs_group_of_blk libext2fs inline
+00000000 T _ext2fs_group_of_ino libext2fs inline
+00000000 T _ext2fs_initialize libext2fs initialize
+00000000 T _badblocks_list_create libext2fs badblocks
+00000000 T _badblocks_list_free libext2fs badblocks
+00000000 T _badblocks_list_add libext2fs badblocks
+00000000 T _badblocks_list_test libext2fs badblocks
+00000000 T _badblocks_list_iterate_begin libext2fs badblocks
+00000000 T _badblocks_list_iterate libext2fs badblocks
+00000000 T _badblocks_list_iterate_end libext2fs badblocks
+00000000 T _ext2fs_read_bb_inode libext2fs read_bb
+00000000 T _ext2fs_update_bb_inode libext2fs bb_inode
+00000000 T _ext2fs_read_bb_FILE libext2fs read_bb_file
+00000000 T _initialize_ext2_error_table libext2fs ext2_err
+00000000 T _ext2fs_llseek libext2fs llseek
+00000000 T _ext2fs_set_inode_callback libext2fs inode
+00000000 T _ext2fs_compare_block_bitmap libext2fs cmp_bitmaps
+00000000 T _ext2fs_compare_inode_bitmap libext2fs cmp_bitmaps
+00000000 T _ext2fs_read_dir_block libext2fs dirblock
+00000000 T _ext2fs_write_dir_block libext2fs dirblock
+00000000 T _ext2fs_swab16 libext2fs inline
+00000000 T _ext2fs_swab32 libext2fs inline
+00000000 T _ext2fs_fast_mark_block_bitmap libext2fs inline
+00000000 T _ext2fs_fast_unmark_block_bitmap libext2fs inline
+00000000 T _ext2fs_fast_test_block_bitmap libext2fs inline
+00000000 T _ext2fs_fast_mark_inode_bitmap libext2fs inline
+00000000 T _ext2fs_fast_unmark_inode_bitmap libext2fs inline
+00000000 T _ext2fs_fast_test_inode_bitmap libext2fs inline
+00000000 T _ext2fs_get_block_bitmap_start libext2fs inline
+00000000 T _ext2fs_get_inode_bitmap_start libext2fs inline
+00000000 T _ext2fs_get_block_bitmap_end libext2fs inline
+00000000 T _ext2fs_get_inode_bitmap_end libext2fs inline
+00000000 T _ext2fs_swap_super libext2fs swapfs
+00000000 T _ext2fs_swap_group_desc libext2fs swapfs
+00000000 T _ext2fs_get_device_size libext2fs getsize
+00000000 T _ext2fs_check_if_mounted libext2fs ismounted
+00000000 T _ext2fs_allocate_tables libext2fs alloc_tables
+00000000 T _ext2fs_allocate_generic_bitmap libext2fs bitmaps
+00000000 T _ext2fs_warn_bitmap2 libext2fs bitops
+00000000 T _ext2fs_free_generic_bitmap libext2fs freefs
+00000000 T _ext2fs_mark_generic_bitmap libext2fs inline
+00000000 T _ext2fs_unmark_generic_bitmap libext2fs inline
+00000000 T _ext2fs_test_generic_bitmap libext2fs inline
+00000000 T _ext2fs_namei_follow libext2fs namei
+00000000 T _ext2fs_follow_link libext2fs namei
+00000000 T _ext2fs_native_flag libext2fs native
+00000000 T _ext2fs_swap_inode libext2fs swapfs
+00000000 T _ext2fs_block_iterate2 libext2fs block
+00000000 T _ext2fs_inode_scan_goto_blockgroup libext2fs inode
+00000000 T _ext2fs_badblocks_list_create libext2fs badblocks
+00000000 T _ext2fs_badblocks_list_add libext2fs badblocks
+00000000 T _ext2fs_badblocks_list_test libext2fs badblocks
+00000000 T _ext2fs_badblocks_list_iterate_begin libext2fs badblocks
+00000000 T _ext2fs_badblocks_list_iterate libext2fs badblocks
+00000000 T _ext2fs_badblocks_list_iterate_end libext2fs badblocks
+#00000000 U _ext2fs_brel_memarray_create libext2fs brel_ma
+00000000 T __DUMMY__ libext2fs brel_ma
+00000000 T _ext2fs_badblocks_list_free libext2fs closefs
+00000000 T _ext2fs_free_dblist libext2fs closefs
+00000000 T _ext2fs_get_num_dirs libext2fs dblist
+00000000 T _ext2fs_init_dblist libext2fs dblist
+00000000 T _ext2fs_add_dir_block libext2fs dblist
+00000000 T _ext2fs_dblist_iterate libext2fs dblist
+00000000 T _ext2fs_dblist_dir_iterate libext2fs dblist_dir
+00000000 T _ext2fs_process_dir_block libext2fs dir_iterate
+00000000 T _ext2fs_test_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_fast_test_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_mark_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_fast_mark_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_unmark_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_fast_unmark_block_bitmap_range libext2fs inline
+00000000 T _ext2fs_inode_scan_flags libext2fs inode
+#00000000 U _ext2fs_irel_memarray_create libext2fs irel_ma
+00000000 U __DUMMY__ libext2fs irel_ma
+00000000 T _ext2fs_resize_generic_bitmap libext2fs rs_bitmap
+00000000 T _ext2fs_inode_has_valid_blocks libext2fs valid_blk
+00000000 T _ext2fs_free_icount libext2fs icount
+00000000 T _ext2fs_create_icount libext2fs icount
+00000000 T _ext2fs_icount_fetch libext2fs icount
+00000000 T _ext2fs_icount_increment libext2fs icount
+00000000 T _ext2fs_icount_decrement libext2fs icount
+00000000 T _ext2fs_icount_store libext2fs icount
+00000000 T _ext2fs_get_icount_size libext2fs icount
+00000000 T _ext2fs_create_icount2 libext2fs icount
+00000000 T _ext2fs_get_library_version libext2fs version
+00000000 T _ext2fs_parse_version_string libext2fs version
+00000000 T _ext2fs_set_dir_block libext2fs dblist
+00000000 T _ext2fs_badblocks_copy libext2fs badblocks
+00000000 T _ext2fs_copy_bitmap libext2fs bitmaps
+00000000 T _ext2fs_bg_has_super libext2fs closefs
+00000000 T _ext2fs_copy_dblist libext2fs dblist
+00000000 T _ext2fs_dup_handle libext2fs dupfs
+00000000 T _ext2fs_icount_validate libext2fs icount
+00000000 T _ext2fs_resize_inode_bitmap libext2fs rs_bitmap
+00000000 T _ext2fs_resize_block_bitmap libext2fs rs_bitmap
+00000000 T _ext2fs_dblist_count libext2fs dblist
+00000000 T _ext2fs_alloc_block libext2fs alloc
+00000000 T _ext2fs_allocate_group_table libext2fs alloc_tables
+00000000 T _ext2fs_set_bitmap_padding libext2fs bitmaps
+00000000 T _ext2fs_bmap libext2fs bmap
+#00000000 T _ext2fs_move_blocks libext2fs bmove
+00000000 T __DUMMY__ libext2fs bmove
+00000000 T _ext2fs_file_open libext2fs fileio
+00000000 T _ext2fs_file_get_fs libext2fs fileio
+00000000 T _ext2fs_file_close libext2fs fileio
+00000000 T _ext2fs_file_read libext2fs fileio
+00000000 T _ext2fs_file_write libext2fs fileio
+00000000 T _ext2fs_file_lseek libext2fs fileio
+00000000 T _ext2fs_file_get_size libext2fs fileio
+00000000 T _ext2fs_file_set_size libext2fs fileio
+00000000 T _ext2fs_get_mem libext2fs inline
+00000000 T _ext2fs_free_mem libext2fs inline
+00000000 T _ext2fs_resize_mem libext2fs inline
+00000000 T _ext2fs_read_bb_FILE2 libext2fs read_bb_file
+00000000 T _ext2fs_write_bb_FILE libext2fs write_bb_file
+00000000 T _ext2fs_badblocks_equal libext2fs badblocks
+00000000 T _ext2fs_update_dynamic_rev libext2fs closefs
+00000000 T _ext2fs_sync_device libext2fs flushb
+
diff --git a/e2fslib/dll/jump.import b/e2fslib/dll/jump.import
new file mode 100644
index 0000000..53208d5
--- /dev/null
+++ b/e2fslib/dll/jump.import
@@ -0,0 +1,166 @@
+00000004 D __et_list libcom_err jump/error_message
+00000004 D _com_err_hook libcom_err jump/com_err
+/usr/lib/libc.sa(__libc.o):00001000 a __GOT_SIZE
+/usr/lib/libc.sa(__libc.o):6008f0b0 A _AL
+/usr/lib/libc.sa(__libc.o):6008f198 A _AL_PARM
+/usr/lib/libc.sa(__libc.o):6008f060 A _AM
+/usr/lib/libc.sa(__libc.o):6008f0b4 A _BC
+/usr/lib/libc.sa(__libc.o):6008f064 A _BS
+/usr/lib/libc.sa(__libc.o):6008f0bc A _BT
+/usr/lib/libc.sa(__libc.o):6008f068 A _CA
+/usr/lib/libc.sa(__libc.o):6008f0c0 A _CD
+/usr/lib/libc.sa(__libc.o):6008f0c4 A _CE
+/usr/lib/libc.sa(__libc.o):6008f0c8 A _CL
+/usr/lib/libc.sa(__libc.o):6008f0cc A _CM
+/usr/lib/libc.sa(__libc.o):6008f048 A _COLS
+/usr/lib/libc.sa(__libc.o):6008f0d0 A _CR
+/usr/lib/libc.sa(__libc.o):6008f0d4 A _CS
+/usr/lib/libc.sa(__libc.o):6008f06c A _DA
+/usr/lib/libc.sa(__libc.o):6008f070 A _DB
+/usr/lib/libc.sa(__libc.o):6008f0d8 A _DC
+/usr/lib/libc.sa(__libc.o):6008f0dc A _DL
+/usr/lib/libc.sa(__libc.o):6008f19c A _DL_PARM
+/usr/lib/libc.sa(__libc.o):6008f0e0 A _DM
+/usr/lib/libc.sa(__libc.o):6008f0e4 A _DO
+/usr/lib/libc.sa(__libc.o):6008f1a4 A _DOWN_PARM
+/usr/lib/libc.sa(__libc.o):6008f03c A _Def_term
+/usr/lib/libc.sa(__libc.o):6008f0e8 A _ED
+/usr/lib/libc.sa(__libc.o):6008f0ec A _EI
+/usr/lib/libc.sa(__libc.o):6008f074 A _EO
+/usr/lib/libc.sa(__libc.o):6008f1b8 A _GT
+/usr/lib/libc.sa(__libc.o):6008f078 A _HC
+/usr/lib/libc.sa(__libc.o):6008f118 A _HO
+/usr/lib/libc.sa(__libc.o):6008f07c A _HZ
+/usr/lib/libc.sa(__libc.o):6008f11c A _IC
+/usr/lib/libc.sa(__libc.o):6008f120 A _IM
+/usr/lib/libc.sa(__libc.o):6008f080 A _IN
+/usr/lib/libc.sa(__libc.o):6008f124 A _IP
+/usr/lib/libc.sa(__libc.o):6008f0f0 A _K0
+/usr/lib/libc.sa(__libc.o):6008f0f4 A _K1
+/usr/lib/libc.sa(__libc.o):6008f0f8 A _K2
+/usr/lib/libc.sa(__libc.o):6008f0fc A _K3
+/usr/lib/libc.sa(__libc.o):6008f100 A _K4
+/usr/lib/libc.sa(__libc.o):6008f104 A _K5
+/usr/lib/libc.sa(__libc.o):6008f108 A _K6
+/usr/lib/libc.sa(__libc.o):6008f10c A _K7
+/usr/lib/libc.sa(__libc.o):6008f110 A _K8
+/usr/lib/libc.sa(__libc.o):6008f114 A _K9
+/usr/lib/libc.sa(__libc.o):6008f128 A _KD
+/usr/lib/libc.sa(__libc.o):6008f12c A _KE
+/usr/lib/libc.sa(__libc.o):6008f130 A _KH
+/usr/lib/libc.sa(__libc.o):6008f134 A _KL
+/usr/lib/libc.sa(__libc.o):6008f138 A _KR
+/usr/lib/libc.sa(__libc.o):6008f13c A _KS
+/usr/lib/libc.sa(__libc.o):6008f140 A _KU
+/usr/lib/libc.sa(__libc.o):6008f1a8 A _LEFT_PARM
+/usr/lib/libc.sa(__libc.o):6008f044 A _LINES
+/usr/lib/libc.sa(__libc.o):6008f144 A _LL
+/usr/lib/libc.sa(__libc.o):6008f148 A _MA
+/usr/lib/libc.sa(__libc.o):6008f300 A _MCAppPath
+/usr/lib/libc.sa(__libc.o):6008f084 A _MI
+/usr/lib/libc.sa(__libc.o):6008f088 A _MS
+/usr/lib/libc.sa(__libc.o):6008f030 A _My_term
+/usr/lib/libc.sa(__libc.o):6008f08c A _NC
+/usr/lib/libc.sa(__libc.o):6008f14c A _ND
+/usr/lib/libc.sa(__libc.o):6008f150 A _NL
+/usr/lib/libc.sa(__libc.o):6008f1bc A _NONL
+/usr/lib/libc.sa(__libc.o):6008f090 A _NS
+/usr/lib/libc.sa(__libc.o):6008f094 A _OS
+/usr/lib/libc.sa(__libc.o):6008f1b0 A _PC
+/usr/lib/libc.sa(__libc.o):6008f154 A _RC
+/usr/lib/libc.sa(__libc.o):6008f1ac A _RIGHT_PARM
+/usr/lib/libc.sa(__libc.o):6008f158 A _SC
+/usr/lib/libc.sa(__libc.o):6008f15c A _SE
+/usr/lib/libc.sa(__libc.o):6008f160 A _SF
+/usr/lib/libc.sa(__libc.o):6008f164 A _SO
+/usr/lib/libc.sa(__libc.o):6008f168 A _SR
+/usr/lib/libc.sa(__libc.o):6008f16c A _TA
+/usr/lib/libc.sa(__libc.o):6008f170 A _TE
+/usr/lib/libc.sa(__libc.o):6008f174 A _TI
+/usr/lib/libc.sa(__libc.o):6008f178 A _UC
+/usr/lib/libc.sa(__libc.o):6008f17c A _UE
+/usr/lib/libc.sa(__libc.o):6008f098 A _UL
+/usr/lib/libc.sa(__libc.o):6008f180 A _UP
+/usr/lib/libc.sa(__libc.o):6008f1c0 A _UPPERCASE
+/usr/lib/libc.sa(__libc.o):6008f1a0 A _UP_PARM
+/usr/lib/libc.sa(__libc.o):6008f188 A _US
+/usr/lib/libc.sa(__libc.o):6008f18c A _VB
+/usr/lib/libc.sa(__libc.o):6008f194 A _VE
+/usr/lib/libc.sa(__libc.o):6008f190 A _VS
+/usr/lib/libc.sa(__libc.o):6008f09c A _XB
+/usr/lib/libc.sa(__libc.o):6008f0a0 A _XN
+/usr/lib/libc.sa(__libc.o):6008f0a8 A _XS
+/usr/lib/libc.sa(__libc.o):6008f0a4 A _XT
+/usr/lib/libc.sa(__libc.o):6008f0ac A _XX
+/usr/lib/libc.sa(__libc.o):6008f2a4 A __IO_file_jumps
+/usr/lib/libc.sa(__libc.o):6008f1f4 A __IO_list_all
+/usr/lib/libc.sa(__libc.o):6008f2a8 A __IO_proc_jumps
+/usr/lib/libc.sa(__libc.o):6008f1ec A __IO_stderr_
+/usr/lib/libc.sa(__libc.o):6008f1e4 A __IO_stdin_
+/usr/lib/libc.sa(__libc.o):6008f1e8 A __IO_stdout_
+/usr/lib/libc.sa(__libc.o):6008f2ac A __IO_str_jumps
+/usr/lib/libc.sa(__libc.o):6008f214 A ____brk_addr
+/usr/lib/libc.sa(__libc.o):6008f01c A ___ctype_b
+/usr/lib/libc.sa(__libc.o):6008f020 A ___ctype_tolower
+/usr/lib/libc.sa(__libc.o):6008f024 A ___ctype_toupper
+/usr/lib/libc.sa(__libc.o):6008f1fc A ___environ
+/usr/lib/libc.sa(__libc.o):6008f250 A ___exit_funcs
+/usr/lib/libc.sa(__libc.o):6008f2f0 A ___glob_closedir_hook
+/usr/lib/libc.sa(__libc.o):6008f2f4 A ___glob_opendir_hook
+/usr/lib/libc.sa(__libc.o):6008f2f8 A ___glob_readdir_hook
+/usr/lib/libc.sa(__libc.o):6008f278 A ___ttyname
+/usr/lib/libc.sa(__libc.o):6008f238 A __collate_info
+/usr/lib/libc.sa(__libc.o):6008f23c A __ctype_info
+/usr/lib/libc.sa(__libc.o):6008f028 A __echoit
+/usr/lib/libc.sa(__libc.o):6008f034 A __endwin
+/usr/lib/libc.sa(__libc.o):6008f288 A __gdbm_fetch_val
+/usr/lib/libc.sa(__libc.o):6008f280 A __gdbm_file
+/usr/lib/libc.sa(__libc.o):6008f284 A __gdbm_memory
+/usr/lib/libc.sa(__libc.o):6008f240 A __monetary_info
+/usr/lib/libc.sa(__libc.o):6008f234 A __null_auth
+/usr/lib/libc.sa(__libc.o):6008f244 A __numeric_info
+/usr/lib/libc.sa(__libc.o):6008f2ec A __obstack
+/usr/lib/libc.sa(__libc.o):6008f1c8 A __pfast
+/usr/lib/libc.sa(__libc.o):6008f02c A __rawmode
+/usr/lib/libc.sa(__libc.o):6008f1dc A __res
+/usr/lib/libc.sa(__libc.o):6008f04c A __res_iflg
+/usr/lib/libc.sa(__libc.o):6008f050 A __res_lflg
+/usr/lib/libc.sa(__libc.o):6008f270 A __res_opcodes
+/usr/lib/libc.sa(__libc.o):6008f274 A __res_resultcodes
+/usr/lib/libc.sa(__libc.o):6008f248 A __response_info
+/usr/lib/libc.sa(__libc.o):6008f2fc A __sigintr
+/usr/lib/libc.sa(__libc.o):6008f00c A __sys_errlist
+/usr/lib/libc.sa(__libc.o):6008f010 A __sys_nerr
+/usr/lib/libc.sa(__libc.o):6008f014 A __sys_siglist
+/usr/lib/libc.sa(__libc.o):6008f24c A __time_info
+/usr/lib/libc.sa(__libc.o):6008f05c A __tty
+/usr/lib/libc.sa(__libc.o):6008f040 A __tty_ch
+/usr/lib/libc.sa(__libc.o):6008f1cc A __unctrl
+/usr/lib/libc.sa(__libc.o):6008f27c A __win
+/usr/lib/libc.sa(__libc.o):6008f058 A _curscr
+/usr/lib/libc.sa(__libc.o):6008f228 A _daylight
+/usr/lib/libc.sa(__libc.o):6008f200 A _errno
+/usr/lib/libc.sa(__libc.o):6008f1d0 A _gdbm_errno
+/usr/lib/libc.sa(__libc.o):6008f28c A _gdbm_version
+/usr/lib/libc.sa(__libc.o):6008f008 A _h_errlist
+/usr/lib/libc.sa(__libc.o):6008f1d8 A _h_errno
+/usr/lib/libc.sa(__libc.o):6008f2a0 A _h_nerr
+/usr/lib/libc.sa(__libc.o):6008f1c4 A _normtty
+/usr/lib/libc.sa(__libc.o):6008f204 A _optarg
+/usr/lib/libc.sa(__libc.o):6008f20c A _opterr
+/usr/lib/libc.sa(__libc.o):6008f208 A _optind
+/usr/lib/libc.sa(__libc.o):6008f2e4 A _optopt
+/usr/lib/libc.sa(__libc.o):6008f218 A _ospeed
+/usr/lib/libc.sa(__libc.o):6008f26c A _re_max_failures
+/usr/lib/libc.sa(__libc.o):6008f210 A _re_syntax_options
+/usr/lib/libc.sa(__libc.o):6008f1e0 A _rexecoptions
+/usr/lib/libc.sa(__libc.o):6008f230 A _rpc_createerr
+/usr/lib/libc.sa(__libc.o):6008f25c A _stderr
+/usr/lib/libc.sa(__libc.o):6008f254 A _stdin
+/usr/lib/libc.sa(__libc.o):6008f258 A _stdout
+/usr/lib/libc.sa(__libc.o):6008f054 A _stdscr
+/usr/lib/libc.sa(__libc.o):6008f2e8 A _svc_fdset
+/usr/lib/libc.sa(__libc.o):6008f224 A _timezone
+/usr/lib/libc.sa(__libc.o):6008f21c A _tputs_baud_rate
+/usr/lib/libc.sa(__libc.o):6008f038 A _ttytype
+/usr/lib/libc.sa(__libc.o):6008f220 A _tzname
diff --git a/e2fslib/dll/jump.params b/e2fslib/dll/jump.params
new file mode 100644
index 0000000..d4d1b33
--- /dev/null
+++ b/e2fslib/dll/jump.params
@@ -0,0 +1,6 @@
+Name=libe2fs
+Text=0x66900000
+Data=0x00000000
+Jump=0x00001000
+GOT=0x00001000
+Version=1.2.0
diff --git a/e2fslib/dll/jump.undefs b/e2fslib/dll/jump.undefs
new file mode 100644
index 0000000..294a0b7
--- /dev/null
+++ b/e2fslib/dll/jump.undefs
@@ -0,0 +1,2 @@
+6690b080 D __NEEDS_SHRLIB_libc_4
+6690b098 D __NEEDS_SHRLIB_libet_1
diff --git a/e2fslib/dll/jump.vars b/e2fslib/dll/jump.vars
new file mode 100644
index 0000000..5f219d3
--- /dev/null
+++ b/e2fslib/dll/jump.vars
@@ -0,0 +1,6 @@
+00000004 D _unix_io_manager libext2fs unix_io
+00000004 D _test_io_manager libext2fs test_io
+00000004 D _test_io_backing_manager libext2fs test_io
+00000004 D _test_io_cb_read_blk libext2fs test_io
+00000004 D _test_io_cb_write_blk libext2fs test_io
+00000004 D _test_io_cb_set_blksize libext2fs test_io
diff --git a/e2fslib/dosio.c b/e2fslib/dosio.c
new file mode 100644
index 0000000..d695b18
--- /dev/null
+++ b/e2fslib/dosio.c
@@ -0,0 +1,456 @@
+/*
+ * dosio.c -- Disk I/O module for the ext2fs/DOS library.
+ *
+ * Copyright (c) 1997 by Theodore Ts'o.
+ *
+ * Copyright (c) 1997 Mark Habersack
+ * This file may be distributed under the terms of the GNU Public License.
+ *
+ */
+
+#include <stdio.h>
+#include <bios.h>
+#include <string.h>
+#include <ctype.h>
+#include <io.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <ext2fs/ext2_types.h>
+#include "utils.h"
+#include "dosio.h"
+#include "et/com_err.h"
+#include "ext2_err.h"
+#include "ext2fs/io.h"
+
+/*
+ * Some helper macros
+ */
+#define LINUX_EXT2FS 0x83
+#define LINUX_SWAP 0x82
+#define WRITE_ERR(_msg_) write(2, _msg_, strlen(_msg_))
+#define WRITE_ERR_S(_msg_) write(2, _msg_, sizeof(_msg_))
+
+/*
+ * Exported variables
+ */
+unsigned long _dio_error;
+unsigned long _dio_hw_error;
+
+/*
+ * Array of all opened partitions
+ */
+static PARTITION **partitions = NULL;
+static unsigned short npart = 0; /* Number of mapped partitions */
+static PARTITION *active = NULL;
+
+/*
+ * I/O Manager routine prototypes
+ */
+static errcode_t dos_open(const char *dev, int flags, io_channel *channel);
+static errcode_t dos_close(io_channel channel);
+static errcode_t dos_set_blksize(io_channel channel, int blksize);
+static errcode_t dos_read_blk(io_channel channel, unsigned long block,
+ int count, void *buf);
+static errcode_t dos_write_blk(io_channel channel, unsigned long block,
+ int count, const void *buf);
+static errcode_t dos_flush(io_channel channel);
+
+static struct struct_io_manager struct_dos_manager = {
+ EXT2_ET_MAGIC_IO_MANAGER,
+ "DOS I/O Manager",
+ dos_open,
+ dos_close,
+ dos_set_blksize,
+ dos_read_blk,
+ dos_write_blk,
+ dos_flush
+};
+io_manager dos_io_manager = &struct_dos_manager;
+
+/*
+ * Macro taken from unix_io.c
+ */
+/*
+ * For checking structure magic numbers...
+ */
+
+#define EXT2_CHECK_MAGIC(struct, code) \
+ if ((struct)->magic != (code)) return (code)
+
+/*
+ * Calculates a CHS address of a sector from its LBA
+ * offset for the given partition.
+ */
+static void lba2chs(unsigned long lba_addr, CHS *chs, PARTITION *part)
+{
+ unsigned long abss;
+
+ chs->offset = lba_addr & 0x000001FF;
+ abss = (lba_addr >> 9) + part->start;
+ chs->cyl = abss / (part->sects * part->heads);
+ chs->head = (abss / part->sects) % part->heads;
+ chs->sector = (abss % part->sects) + 1;
+}
+
+#ifdef __TURBOC__
+#pragma argsused
+#endif
+/*
+ * Scans the passed partition table looking for *pno partition
+ * that has LINUX_EXT2FS type.
+ *
+ * TODO:
+ * For partition numbers >5 Linux uses DOS extended partitions -
+ * dive into them an return an appropriate entry. Also dive into
+ * extended partitions when scanning for a first Linux/ext2fs.
+ */
+static PTABLE_ENTRY *scan_partition_table(PTABLE_ENTRY *pentry,
+ unsigned short phys,
+ unsigned char *pno)
+{
+ unsigned i;
+
+ if(*pno != 0xFF && *pno >= 5)
+ return NULL; /* We don't support extended partitions for now */
+
+ if(*pno != 0xFF)
+ {
+ if(pentry[*pno].type == LINUX_EXT2FS)
+ return &pentry[*pno];
+ else
+ {
+ if(!pentry[*pno].type)
+ *pno = 0xFE;
+ else if(pentry[*pno].type == LINUX_SWAP)
+ *pno = 0xFD;
+ return NULL;
+ }
+ }
+
+ for(i = 0; i < 4; i++)
+ if(pentry[i].type == LINUX_EXT2FS)
+ {
+ *pno = i;
+ return &pentry[i];
+ }
+
+ return NULL;
+}
+
+/*
+ * Allocate libext2fs structures associated with I/O manager
+ */
+static io_channel alloc_io_channel(PARTITION *part)
+{
+ io_channel ioch;
+
+ ioch = (io_channel)malloc(sizeof(struct struct_io_channel));
+ if (!ioch)
+ return NULL;
+ memset(ioch, 0, sizeof(struct struct_io_channel));
+ ioch->magic = EXT2_ET_MAGIC_IO_CHANNEL;
+ ioch->manager = dos_io_manager;
+ ioch->name = (char *)malloc(strlen(part->dev)+1);
+ if (!ioch->name) {
+ free(ioch);
+ return NULL;
+ }
+ strcpy(ioch->name, part->dev);
+ ioch->private_data = part;
+ ioch->block_size = 1024; /* The smallest ext2fs block size */
+ ioch->read_error = 0;
+ ioch->write_error = 0;
+
+ return ioch;
+}
+
+#ifdef __TURBOC__
+#pragma argsused
+#endif
+/*
+ * Open the 'name' partition, initialize all information structures
+ * we need to keep and create libext2fs I/O manager.
+ */
+static errcode_t dos_open(const char *dev, int flags, io_channel *channel)
+{
+ unsigned char *tmp, sec[512];
+ PARTITION *part;
+ PTABLE_ENTRY *pent;
+ PARTITION **newparts;
+
+ if(!dev)
+ {
+ _dio_error = ERR_BADDEV;
+ return EXT2_ET_BAD_DEVICE_NAME;
+ }
+
+ /*
+ * First check whether the dev name is OK
+ */
+ tmp = (unsigned char*)strrchr(dev, '/');
+ if(!tmp)
+ {
+ _dio_error = ERR_BADDEV;
+ return EXT2_ET_BAD_DEVICE_NAME;
+ }
+ *tmp = 0;
+ if(strcmp(dev, "/dev"))
+ {
+ _dio_error = ERR_BADDEV;
+ return EXT2_ET_BAD_DEVICE_NAME;
+ }
+ *tmp++ = '/';
+
+ /*
+ * Check whether the partition data is already in cache
+ */
+
+ part = (PARTITION*)malloc(sizeof(PARTITION));
+ if (!part)
+ return ENOMEM;
+ {
+ int i = 0;
+
+ for(;i < npart; i++)
+ if(!strcmp(partitions[i]->dev, dev))
+ {
+ /* Found it! Make it the active one */
+ active = partitions[i];
+ *channel = alloc_io_channel(active);
+ if (!*channel)
+ return ENOMEM;
+ return 0;
+ }
+ }
+
+ /*
+ * Drive number & optionally partn number
+ */
+ switch(tmp[0])
+ {
+ case 'h':
+ case 's':
+ part->phys = 0x80;
+ part->phys += toupper(tmp[2]) - 'A';
+ /*
+ * Do we have the partition number?
+ */
+ if(tmp[3])
+ part->pno = isdigit((int)tmp[3]) ? tmp[3] - '0' - 1: 0;
+ else
+ part->pno = 0xFF;
+ break;
+
+ case 'f':
+ if(tmp[2])
+ part->phys = isdigit((int)tmp[2]) ? tmp[2] - '0' : 0;
+ else
+ part->phys = 0x00; /* We'll assume /dev/fd0 */
+ break;
+
+ default:
+ _dio_error = ERR_BADDEV;
+ return ENODEV;
+ }
+
+ if(part->phys < 0x80)
+ {
+ /* We don't support floppies for now */
+ _dio_error = ERR_NOTSUPP;
+ return EINVAL;
+ }
+
+ part->dev = strdup(dev);
+
+ /*
+ * Get drive's geometry
+ */
+ _dio_hw_error = biosdisk(DISK_GET_GEOMETRY,
+ part->phys,
+ 0, /* head */
+ 0, /* cylinder */
+ 1, /* sector */
+ 1, /* just one sector */
+ sec);
+
+ if(!HW_OK())
+ {
+ _dio_error = ERR_HARDWARE;
+ if (part)
+ free(part);
+ return EFAULT;
+ }
+
+ /*
+ * Calculate the geometry
+ */
+ part->cyls = (unsigned short)(((sec[0] >> 6) << 8) + sec[1] + 1);
+ part->heads = sec[3] + 1;
+ part->sects = sec[0] & 0x3F;
+
+ /*
+ * Now that we know all we need, let's look for the partition
+ */
+ _dio_hw_error = biosdisk(DISK_READ, part->phys, 0, 0, 1, 1, sec);
+
+ if(!HW_OK())
+ {
+ _dio_error = ERR_HARDWARE;
+ if (part)
+ free(part);
+ return EFAULT;
+ }
+
+ pent = (PTABLE_ENTRY*)&sec[0x1BE];
+ pent = scan_partition_table(pent, part->phys, &part->pno);
+
+ if(!pent)
+ {
+ _dio_error = part->pno == 0xFE ? ERR_EMPTYPART :
+ part->pno == 0xFD ? ERR_LINUXSWAP : ERR_NOTEXT2FS;
+ if (part)
+ free(part);
+ return ENODEV;
+ }
+
+ /*
+ * Calculate the remaining figures
+ */
+ {
+ unsigned long fsec, fhead, fcyl;
+
+ fsec = (unsigned long)(pent->start_sec & 0x3F);
+ fhead = (unsigned long)pent->start_head;
+ fcyl = ((pent->start_sec >> 6) << 8) + pent->start_cyl;
+ part->start = fsec + fhead * part->sects + fcyl *
+ (part->heads * part->sects) - 1;
+ part->len = pent->size;
+ }
+
+ /*
+ * Add the partition to the table
+ */
+ newparts = (PARTITION**)realloc(partitions, sizeof(PARTITION) * npart);
+ if (!newparts) {
+ free(part);
+ return ENOMEM;
+ }
+ partitions = newparts;
+ partitions[npart++] = active = part;
+
+ /*
+ * Now alloc all libe2fs structures
+ */
+ *channel = alloc_io_channel(active);
+ if (!*channel)
+ return ENOMEM;
+
+ return 0;
+}
+
+static errcode_t dos_close(io_channel channel)
+{
+ if (channel->name)
+ free(channel->name);
+ if (channel)
+ free(channel);
+
+ return 0;
+}
+
+static errcode_t dos_set_blksize(io_channel channel, int blksize)
+{
+ channel->block_size = blksize;
+
+ return 0;
+}
+
+static errcode_t dos_read_blk(io_channel channel, unsigned long block,
+ int count, void *buf)
+{
+ PARTITION *part;
+ size_t size;
+ ext2_loff_t loc;
+ CHS chs;
+
+ EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+ part = (PARTITION*)channel->private_data;
+
+ size = (size_t)((count < 0) ? -count : count * channel->block_size);
+ loc = (ext2_loff_t) block * channel->block_size;
+
+ lba2chs(loc, &chs, part);
+ /*
+ * Potential bug here:
+ * If DJGPP is used then reads of >18 sectors will fail!
+ * Have to rewrite biosdisk.
+ */
+ _dio_hw_error = biosdisk(DISK_READ,
+ part->phys,
+ chs.head,
+ chs.cyl,
+ chs.sector,
+ size < 512 ? 1 : size/512,
+ buf);
+
+ if(!HW_OK())
+ {
+ _dio_error = ERR_HARDWARE;
+ return EFAULT;
+ }
+
+ return 0;
+}
+
+static errcode_t dos_write_blk(io_channel channel, unsigned long block,
+ int count, const void *buf)
+{
+ PARTITION *part;
+ size_t size;
+ ext2_loff_t loc;
+ CHS chs;
+
+ EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
+ part = (PARTITION*)channel->private_data;
+
+ if(count == 1)
+ size = (size_t)channel->block_size;
+ else
+ {
+ if (count < 0)
+ size = (size_t)-count;
+ else
+ size = (size_t)(count * channel->block_size);
+ }
+
+ loc = (ext2_loff_t)block * channel->block_size;
+ lba2chs(loc, &chs, part);
+ _dio_hw_error = biosdisk(DISK_WRITE,
+ part->phys,
+ chs.head,
+ chs.cyl,
+ chs.sector,
+ size < 512 ? 1 : size/512,
+ (void*)buf);
+
+ if(!HW_OK())
+ {
+ _dio_error = ERR_HARDWARE;
+ return EFAULT;
+ }
+
+ return 0;
+}
+
+#ifdef __TURBOC__
+#pragma argsused
+#endif
+static errcode_t dos_flush(io_channel channel)
+{
+ /*
+ * No buffers, no flush...
+ */
+ return 0;
+}
diff --git a/e2fslib/dosio.h b/e2fslib/dosio.h
new file mode 100644
index 0000000..a0d652d
--- /dev/null
+++ b/e2fslib/dosio.h
@@ -0,0 +1,153 @@
+/*
+ * v1.0
+ *
+ * Disk I/O include file for the ext2fs/DOS library.
+ *
+ * Copyright (c) 1997 Mark Habersack
+ * This file may be distributed under the terms of the GNU Public License.
+ *
+ */
+#ifndef __diskio_h
+#define __diskio_h
+#ifdef __TURBOC__
+#ifndef __LARGE__
+# error "ext2fs/DOS library requires LARGE model!"
+#endif
+#endif
+
+#ifdef __TURBOC__
+#include "msdos.h"
+#endif
+
+/*
+ * A helper structure used in LBA => CHS conversion
+ */
+typedef struct
+{
+ unsigned short cyl; /* Cylinder (or track) */
+ unsigned short head;
+ unsigned short sector;
+ unsigned short offset; /* Offset of byte within the sector */
+} CHS;
+
+/*
+ * All partition data we need is here
+ */
+typedef struct
+{
+ char *dev; /* _Linux_ device name (like "/dev/hda1") */
+ unsigned char phys; /* Physical DOS drive number */
+ unsigned long start; /* LBA address of partition start */
+ unsigned long len; /* length of partition in sectors */
+ unsigned char pno; /* Partition number (read from *dev) */
+
+ /* This partition's drive geometry */
+ unsigned short cyls;
+ unsigned short heads;
+ unsigned short sects;
+} PARTITION;
+
+/*
+ * PC partition table entry format
+ */
+#ifdef __DJGPP__
+#pragma pack(1)
+#endif
+typedef struct
+{
+ unsigned char active;
+ unsigned char start_head;
+ unsigned char start_sec;
+ unsigned char start_cyl;
+ unsigned char type;
+ unsigned char end_head;
+ unsigned char end_sec;
+ unsigned char end_cyl;
+ unsigned long first_sec_rel;
+ unsigned long size;
+} PTABLE_ENTRY;
+#ifdef __DJGPP__
+#pragma pack()
+#endif
+
+/*
+ * INT 0x13 operation codes
+ */
+#define DISK_READ 0x02
+#define DISK_WRITE 0x03
+#define DISK_GET_GEOMETRY 0x08
+#define DISK_READY 0x10
+
+/*
+ * Errors to put in _dio_error
+ */
+#define ERR_BADDEV 0x00000001L
+#define ERR_HARDWARE 0x00000002L
+#define ERR_NOTSUPP 0x00000003L
+#define ERR_NOTEXT2FS 0x00000004L
+#define ERR_EMPTYPART 0x00000005L
+#define ERR_LINUXSWAP 0x00000006L
+
+/*
+ * Functions in diskio.c
+ */
+
+/*
+ * Variable contains last module's error
+ */
+extern unsigned long _dio_error;
+
+/*
+ * This one contains last hardware error (if _dio_error == ERR_HARDWARE)
+ */
+extern unsigned long _dio_hw_error;
+
+/*
+ * Macros to check for disk hardware errors
+ */
+#define HW_OK() ((unsigned char)_dio_hw_error == 0x00)
+#define HW_BAD_CMD() ((unsigned char)_dio_hw_error == 0x01)
+#define HW_NO_ADDR_MARK() ((unsigned char)_dio_hw_error == 0x02)
+#define HW_WRITE_PROT() ((unsigned char)_dio_hw_error == 0x03)
+#define HW_NO_SECTOR() ((unsigned char)_dio_hw_error == 0x04)
+#define HW_RESET_FAIL() ((unsigned char)_dio_hw_error == 0x05)
+#define HW_DISK_CHANGED() ((unsigned char)_dio_hw_error == 0x06)
+#define HW_DRIVE_FAIL() ((unsigned char)_dio_hw_error == 0x07)
+#define HW_DMA_OVERRUN() ((unsigned char)_dio_hw_error == 0x08)
+#define HW_DMA_BOUNDARY() ((unsigned char)_dio_hw_error == 0x09)
+#define HW_BAD_SECTOR() ((unsigned char)_dio_hw_error == 0x0A)
+#define HW_BAD_TRACK() ((unsigned char)_dio_hw_error == 0x0B)
+#define HW_UNSUPP_TRACK() ((unsigned char)_dio_hw_error == 0x0C)
+#define HW_BAD_CRC_ECC() ((unsigned char)_dio_hw_error == 0x10)
+#define HW_CRC_ECC_CORR() ((unsigned char)_dio_hw_error == 0x11)
+#define HW_CONTR_FAIL() ((unsigned char)_dio_hw_error == 0x20)
+#define HW_SEEK_FAIL() ((unsigned char)_dio_hw_error == 0x40)
+#define HW_ATTACH_FAIL() ((unsigned char)_dio_hw_error == 0x80)
+#define HW_DRIVE_NREADY() ((unsigned char)_dio_hw_error == 0xAA)
+#define HW_UNDEF_ERROR() ((unsigned char)_dio_hw_error == 0xBB)
+#define HW_WRITE_FAULT() ((unsigned char)_dio_hw_error == 0xCC)
+#define HW_STATUS_ERROR() ((unsigned char)_dio_hw_error == 0xE0)
+#define HW_SENSE_FAIL() ((unsigned char)_dio_hw_error == 0xFF)
+
+
+/*
+ * Open the specified partition.
+ * String 'dev' must have a format:
+ *
+ * /dev/{sd|hd|fd}[X]
+ *
+ * where,
+ *
+ * only one of the option in curly braces can be used and X is an optional
+ * partition number for the given device. If X is not specified, function
+ * scans the drive's partition table in search for the first Linux ext2fs
+ * partition (signature 0x83). Along the way it dives into every extended
+ * partition encountered.
+ * Scan ends if either (a) there are no more used partition entries, or
+ * (b) there is no Xth partition.
+ *
+ * Routine returns 0 on success and !=0 otherwise.
+ */
+int open_partition(char *dev);
+
+#endif /* __diskio_h */
diff --git a/e2fslib/dupfs.c b/e2fslib/dupfs.c
new file mode 100644
index 0000000..31579a4
--- /dev/null
+++ b/e2fslib/dupfs.c
@@ -0,0 +1,92 @@
+/*
+ * dupfs.c --- duplicate a ext2 filesystem handle
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#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),
+ (void **) &fs);
+ if (retval)
+ return retval;
+
+ *fs = *src;
+ fs->device_name = 0;
+ fs->super = 0;
+ fs->group_desc = 0;
+ fs->inode_map = 0;
+ fs->block_map = 0;
+ fs->badblocks = 0;
+ fs->dblist = 0;
+
+ io_channel_bumpcount(fs->io);
+ if (fs->icache)
+ fs->icache->refcount++;
+
+ retval = ext2fs_get_mem(strlen(src->device_name)+1,
+ (void **) &fs->device_name);
+ if (retval)
+ goto errout;
+ strcpy(fs->device_name, src->device_name);
+
+ retval = ext2fs_get_mem(SUPERBLOCK_SIZE, (void **) &fs->super);
+ if (retval)
+ goto errout;
+ memcpy(fs->super, src->super, SUPERBLOCK_SIZE);
+
+ retval = ext2fs_get_mem((size_t) fs->desc_blocks * fs->blocksize,
+ (void **) &fs->group_desc);
+ if (retval)
+ goto errout;
+ memcpy(fs->group_desc, src->group_desc,
+ (size_t) fs->desc_blocks * fs->blocksize);
+
+ if (src->inode_map) {
+ retval = ext2fs_copy_bitmap(src->inode_map, &fs->inode_map);
+ if (retval)
+ goto errout;
+ }
+ if (src->block_map) {
+ retval = ext2fs_copy_bitmap(src->block_map, &fs->block_map);
+ if (retval)
+ goto errout;
+ }
+ if (src->badblocks) {
+ retval = ext2fs_badblocks_copy(src->badblocks, &fs->badblocks);
+ if (retval)
+ goto errout;
+ }
+ if (src->dblist) {
+ retval = ext2fs_copy_dblist(src->dblist, &fs->dblist);
+ if (retval)
+ goto errout;
+ }
+ *dest = fs;
+ return 0;
+errout:
+ ext2fs_free(fs);
+ return retval;
+
+}
+
diff --git a/e2fslib/dupfs.o b/e2fslib/dupfs.o
new file mode 100644
index 0000000..e0e2738
--- /dev/null
+++ b/e2fslib/dupfs.o
Binary files differ
diff --git a/e2fslib/e2image.h b/e2fslib/e2image.h
new file mode 100644
index 0000000..e12b7d6
--- /dev/null
+++ b/e2fslib/e2image.h
@@ -0,0 +1,51 @@
+/*
+ * e2image.h --- header file describing the ext2 image format
+ *
+ * Copyright (C) 2000 Theodore Ts'o.
+ *
+ * Note: this uses the POSIX IO interfaces, unlike most of the other
+ * functions in this library. So sue me.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+
+struct ext2_image_hdr {
+ __u32 magic_number; /* This must be EXT2_ET_MAGIC_E2IMAGE */
+ char magic_descriptor[16]; /* "Ext2 Image 1.0", w/ null padding */
+ char fs_hostname[64];/* Hostname of machine of image */
+ char fs_netaddr[32]; /* Network address */
+ __u32 fs_netaddr_type;/* 0 = IPV4, 1 = IPV6, etc. */
+ __u32 fs_device; /* Device number of image */
+ char fs_device_name[64]; /* Device name */
+ char fs_uuid[16]; /* UUID of filesystem */
+ __u32 fs_blocksize; /* Block size of the filesystem */
+ __u32 fs_reserved[8];
+
+ __u32 image_device; /* Device number of image file */
+ __u32 image_inode; /* Inode number of image file */
+ __u32 image_time; /* Time of image creation */
+ __u32 image_reserved[8];
+
+ __u32 offset_super; /* Byte offset of the sb and descriptors */
+ __u32 offset_inode; /* Byte offset of the inode table */
+ __u32 offset_inodemap; /* Byte offset of the inode bitmaps */
+ __u32 offset_blockmap; /* Byte offset of the inode bitmaps */
+ __u32 offset_reserved[8];
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/e2fslib/e2p/e2p.h b/e2fslib/e2p/e2p.h
new file mode 100644
index 0000000..61d05f7
--- /dev/null
+++ b/e2fslib/e2p/e2p.h
@@ -0,0 +1,39 @@
+#include <sys/types.h> /* Needed by dirent.h on netbsd */
+#include <stdio.h>
+#include <dirent.h>
+
+#include <ext2_fs.h>
+
+#define E2P_FEATURE_COMPAT 0
+#define E2P_FEATURE_INCOMPAT 1
+#define E2P_FEATURE_RO_INCOMPAT 2
+
+
+/* `options' for print_flags() */
+
+#define PFOPT_LONG 1 /* Must be 1 for compatibility with `int long_format'. */
+
+
+int fgetflags (const char * name, unsigned long * flags);
+int fgetversion (const char * name, unsigned long * version);
+int fsetflags (const char * name, unsigned long flags);
+int fsetversion (const char * name, unsigned long version);
+int getflags (int fd, unsigned long * flags);
+int getversion (int fd, unsigned long * version);
+int iterate_on_dir (const char * dir_name,
+ int (*func) (const char *, struct dirent *, void *),
+ void * private);
+void list_super(struct ext2_super_block * s);
+void list_super2(struct ext2_super_block * s, FILE *f);
+void print_fs_errors (FILE * f, unsigned short errors);
+void print_flags (FILE * f, unsigned long flags, unsigned options);
+void print_fs_state (FILE * f, unsigned short state);
+int setflags (int fd, unsigned long flags);
+int setversion (int fd, unsigned long version);
+
+const char *e2p_feature2string(int compat, unsigned int mask);
+int e2p_string2feature(char *string, int *compat, unsigned int *mask);
+int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array);
+
+int e2p_is_null_uuid(void *uu);
+void e2p_uuid_to_str(void *uu, char *out);
diff --git a/e2fslib/et/.cvsignore b/e2fslib/et/.cvsignore
new file mode 100644
index 0000000..8526e03
--- /dev/null
+++ b/e2fslib/et/.cvsignore
@@ -0,0 +1 @@
+compile_et
diff --git a/e2fslib/et/ChangeLog b/e2fslib/et/ChangeLog
new file mode 100644
index 0000000..a8fec3c
--- /dev/null
+++ b/e2fslib/et/ChangeLog
@@ -0,0 +1,210 @@
+2001-09-20 Theodore Tso <tytso@thunk.org>
+
+ * Release of E2fsprogs 1.25
+
+2001-09-16 Theodore Tso <tytso@valinux.com>
+
+ * compile_et.sh.in: Make the shell script safe from directory
+ pathnames with spaces.
+
+2001-09-10 Theodore Tso <tytso@valinux.com>
+
+ * com_err.texinfo: Add appropriate @node and @menu lines so that
+ the a valid .info file can be made. Use @deftypefun to
+ define functions. Change the e-mail address where bug
+ reports to be sent to be is the e2fsprogs maintainer.
+
+2001-09-02 Theodore Tso <tytso@thunk.org>
+
+ * Release of E2fsprogs 1.24a
+
+2001-08-30 Theodore Tso <tytso@thunk.org>
+
+ * Release of E2fsprogs 1.24
+
+2001-08-15 Theodore Tso <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.23
+
+2001-06-23 Theodore Tso <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.22
+
+2001-06-15 Theodore Tso <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.21
+
+2001-05-25 Theodore Tso <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.20
+
+2000-12-04 <tytso@snap.thunk.org>
+
+ * compile_et.1: Fix simple typo in the man page.
+
+2000-07-13 <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.19
+
+2000-07-04 Theodore Ts'o <tytso@valinux.com>
+
+ * Makefile.in: Remove explicit link of -lc in the shared library.
+ (It shouldn't be necessary, and is harmful in some cases).
+
+1999-11-19 <tytso@valinux.com>
+
+ * Makefile.in (distclean): Remove TAGS and Makefile.in.old from
+ the source directory.
+
+1999-11-10 <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.18
+
+1999-10-26 <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.17
+
+1999-10-22 <tytso@valinux.com>
+
+ * Release of E2fsprogs 1.16
+
+1999-10-22 <tytso@valinux.com>
+
+ * com_err.3: Fix to have correct #include path for com_err.h
+
+1999-09-07 <tytso@rsts-11.mit.edu>
+
+ * Updated copyright statements with permission of the original
+ authors.
+
+1999-07-18 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs 1.15
+
+1999-01-09 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs 1.14
+
+1998-12-15 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs 1.13
+
+1998-07-09 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs 1.12
+
+1998-06-27 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * et_h.awk, et_c.awk: Work around libm bug on the ARM.
+
+1998-03-30 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.in: Fix bug where my_dir was set incorrectly. Install
+ the et_c.awk and et_h.awk files in $(datadir)/et (i.e.,
+ /usr/share/et) directory. Change to use new
+ installation directory variables convention. Fix
+ uninstall rules to take $(DESTDIR) into account.
+
+ * compile_et.1: Change man page to reflect the fact that
+ compile_et is now a awk/sed script, not a yacc script.
+
+ * compile_et.sh.in: Look in $(datadir)/et for et_c.awk and
+ et_h.awk; if not found, look in the build directory. Add
+ error checking for non-existent input file.
+
+Fri Oct 31 01:14:41 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * et_c.awk, et_h.awk: Remove support for non STDC compilers, since
+ the workarounds caused problems with the header file.
+
+Sun Aug 10 09:40:54 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * error_table.h:
+ * et_name.c (error_table_name):
+ * error_message.c (error_message.c): Make code be 16-bit safe.
+
+Tue Jun 17 01:33:20 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs 1.11
+
+Thu Apr 24 12:16:42 1997 Theodre Ts'o <tytso@localhost.mit.edu>
+
+ * Release of E2fsprogs version 1.10
+
+Thu Apr 17 12:23:38 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.09
+
+Fri Apr 11 18:56:26 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.08
+
+Wed Mar 12 13:32:05 1997 Theodore Y. Ts'o <tytso@mit.edu>
+
+ * Release of E2fsprogs version 1.07
+
+Tue Oct 8 02:02:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.06
+
+Thu Sep 12 15:23:07 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.05
+
+Thu May 16 11:12:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.04
+
+Wed Mar 27 00:33:40 1996 <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.03
+
+Wed Jan 31 11:06:08 1996 <tytso@rsts-11.mit.edu>
+
+ * Release of E2fsprogs version 1.02
+
+Mon Sep 4 21:44:47 1995 Remy Card <card@bbj>
+
+ * Makefile.in: Added support for BSD shared libraries.
+
+Sat Aug 12 03:11:28 1995 Remy Card <card@bbj>
+
+ * Makefile.in (install): Install static libraries in $(ulibdir)
+ (/usr/lib on Linux) instead of $(libdir) (/lib on Linux).
+
+Sat Aug 5 11:44:17 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
+
+ * Makefile.in (DLL_INSTALL_DIR, ELF_INSTALL_DIR): Set the
+ installation directories correctly.
+
+Thu Jun 15 23:39:51 1995 Remy Card <card@bbj>
+
+ * Makefile.in: Added support for ELF shared libraries.
+ Fixed typos in the compilation rules.
+ (distclean): Added compile_et.sh.
+
+Sat Jun 10 19:56:13 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
+
+ * compile_et.sh.in: Use ET_DIR instead of srcdir to determine the
+ location of the et directory.
+
+Thu Jun 8 12:45:41 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
+
+ * vfprintf.c (vfprintf): Only compile this function if vfprintf
+ doesn't already exist and _doprnt does.
+
+ * compile_et.sh: Moved to compile_et.sh.in.
+
+ * Makefile.in: Rewritten to conform to GNU coding standards and
+ support separate compilation directories.
+ Don't preprocess compile_et.sh, as this is now done by configure.
+
+Mon Nov 7 21:17:48 1994 Remy Card <card@bbj>
+
+ * Makefile: Added a dummy install target in case shared libraries
+ are not built.
+
+Thu Sep 8 22:33:33 1994 (tytso@rsx-11)
+
+ * com_err.c (default_com_err_proc): Reversed order of \n\r to make
+ jik happy.
diff --git a/e2fslib/et/Makefile b/e2fslib/et/Makefile
new file mode 100644
index 0000000..79b6ca7
--- /dev/null
+++ b/e2fslib/et/Makefile
@@ -0,0 +1,334 @@
+# Generated automatically from Makefile.in by configure.
+#
+# Makefile for lib/et
+#
+
+srcdir = .
+top_srcdir = ../..
+top_builddir = ../..
+my_dir = lib/et
+INSTALL = /usr/bin/install -c
+
+DEP_MAKEFILE = $(DEP_LIB_MAKEFILES)
+
+
+# Beginning of file MCONFIG
+
+all::
+
+check::
+
+SHELL = /bin/sh
+
+prefix = /usr
+root_prefix =
+exec_prefix = ${prefix}
+root_bindir = $(root_prefix)/bin
+root_sbindir = $(root_prefix)/sbin
+root_libdir = $(root_prefix)/lib
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libdir = ${exec_prefix}/lib
+includedir = ${prefix}/include
+mandir = ${prefix}/man
+man1dir = $(mandir)/man1
+man3dir = $(mandir)/man3
+man8dir = $(mandir)/man8
+infodir = ${prefix}/info
+datadir = ${prefix}/share
+
+
+
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+CC = cc
+BUILD_CC = cc
+DEFS = -DENABLE_SWAPFS=1 -DPACKAGE=\"e2fsprogs\" -DVERSION=\"1.25\" -DSTDC_HEADERS=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_ARGZ_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1 -DHAVE_NL_TYPES_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_GETCWD=1 -DHAVE_MUNMAP=1 -DHAVE_PUTENV=1 -DHAVE_SETENV=1 -DHAVE_SETLOCALE=1 -DHAVE_STRCHR=1 -DHAVE_STRCASECMP=1 -DHAVE_STRDUP=1 -DHAVE___ARGZ_COUNT=1 -DHAVE___ARGZ_STRINGIFY=1 -DHAVE___ARGZ_NEXT=1 -DHAVE_STPCPY=1 -DHAVE_STPCPY=1 -DHAVE_LC_MESSAGES=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1 -DHAVE_ERRNO_H=1 -DHAVE_MALLOC_H=1 -DHAVE_MNTENT_H=1 -DHAVE_PATHS_H=1 -DHAVE_DIRENT_H=1 -DHAVE_GETOPT_H=1 -DHAVE_SETJMP_H=1 -DHAVE_SIGNAL_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_LINUX_FD_H=1 -DHAVE_LINUX_MAJOR_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_MOUNT_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_NET_IF_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_VPRINTF=1 -DHAVE_LSEEK64_PROTOTYPE=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DWORDS_BIGENDIAN=1 -DHAVE_GETRUSAGE=1 -DHAVE_LLSEEK=1 -DHAVE_LSEEK64=1 -DHAVE_OPEN64=1 -DHAVE_STRCASECMP=1 -DHAVE_SRANDOM=1 -DHAVE_FCHOWN=1 -DHAVE_MALLINFO=1 -DHAVE_FDATASYNC=1 -DHAVE_STRNLEN=1 -DHAVE_EXT2_IOCTLS=1
+CFLAGS = -g -O2
+CPPFLAGS =
+ALL_CFLAGS = $(CPPFLAGS) $(DEFS) $(USE_WFLAGS) $(CFLAGS) $(XTRA_CFLAGS) \
+ -I$(top_builddir)/lib -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/include $(LINUX_INCLUDE)
+LDFLAGS =
+ALL_LDFLAGS = $(LDFLAGS)
+RM = /bin/rm
+LN = /bin/ln
+LN_S = ln -s
+MV = /bin/mv
+CP = /bin/cp
+CHMOD = /bin/chmod
+AR = ar
+AWK = /usr/bin/awk
+SED = /bin/sed
+PERL = /usr/bin/perl
+RANLIB = ranlib
+STRIP = strip
+LD = $(PURE) cc
+ARUPD = $(AR) r
+LDCONFIG = :
+
+#
+# Library definitions
+#
+LIB = $(top_builddir)/lib
+LIBSS = $(LIB)/libss.a
+LIBCOM_ERR = $(LIB)/libcom_err.a
+LIBE2P = $(LIB)/libe2p.a
+LIBEXT2FS = $(LIB)/libext2fs.a
+LIBUUID = $(LIB)/libuuid.a
+DEPLIBUUID = $(LIB)/libuuid.a
+
+STATIC_LIBSS = $(LIB)/libss.a
+STATIC_LIBCOM_ERR = $(LIB)/libcom_err.a
+STATIC_LIBE2P = $(LIB)/libe2p.a
+STATIC_LIBEXT2FS = $(LIB)/libext2fs.a
+STATIC_LIBUUID = $(LIB)/libuuid.a
+DEPSTATIC_LIBUUID = $(LIB)/libuuid.a
+
+PROFILED_LIBSS = $(LIB)/libss
+PROFILED_LIBCOM_ERR = $(LIB)/libcom_err
+PROFILED_LIBE2P = $(LIB)/libe2p
+PROFILED_LIBEXT2FS = $(LIB)/libext2fs
+PROFILED_LIBUUID = $(LIB)/libuuid
+DEPPROFILED_LIBUUID = $(LIB)/libuuid
+
+#
+# Use these definitions is you use tools 2.x, x < 16
+#
+#DLL_BIN=/usr/dll/bin
+#JUMP_PREFIX=/usr/dll/jump/
+
+#
+# Use these definitions if you use tools 2.16 or above
+#
+DLL_BIN=/usr/bin
+JUMP_PREFIX=/usr/bin/jump
+
+# An include directive pointing to a directory holding enough linux-like
+# include files to satisfy some programs here
+LINUX_INCLUDE=
+
+#
+# A fast substitution command for fixing up man pages, shell scripts, etc.
+#
+SUBST_CONF=../util/subst.conf
+SUBSTITUTE= ../util/subst -f $(SUBST_CONF)
+DEP_SUBSTITUTE= ../util/subst $(SUBST_CONF)
+
+$(top_builddir)/util/subst:
+ cd $(top_builddir)/util ; $(MAKE) subst
+
+#
+# Warning flags
+#
+# Run make gcc-wall to do a build with warning messages.
+#
+#
+WFLAGS= -ansi -D_POSIX_SOURCE -pedantic \
+ -Wall -Wwrite-strings -Wpointer-arith \
+ -Wcast-qual -Wcast-align -Wtraditional \
+ -Wstrict-prototypes -Wmissing-prototypes \
+ -Wnested-externs -Winline -DNO_INLINE_FUNCS -Wshadow
+
+gcc-wall-new:
+ (make USE_WFLAGS="$(WFLAGS)" > /dev/null) 2>&1 | sed -f $(top_srcdir)/util/gcc-wall-cleanup
+
+gcc-wall:
+ make clean > /dev/null
+ make gcc-wall-new
+
+#
+# Installation user and groups
+#
+BINGRP= bin
+BINOWN= bin
+BINMODE= 555
+INCGRP= bin
+INCOWN= bin
+INCMODE= 444
+LIBOWN= bin
+LIBGRP= bin
+LIBMODE= 444
+MANGRP= bin
+MANOWN= bin
+MANMODE= 444
+
+#
+# Autoconf magic...
+#
+
+DEP_LIB_MAKEFILES = $(top_srcdir)/lib/Makefile.elf-lib \
+ $(top_srcdir)/lib/Makefile.dll-lib $(top_srcdir)/lib/Makefile.bsd-lib \
+ $(top_srcdir)/lib/Makefile.checker $(top_srcdir)/lib/Makefile.profile
+
+$(top_builddir)/config.status: $(top_srcdir)/configure
+ cd $(top_builddir); ./config.status --recheck
+
+$(top_builddir)/lib/substitute_sh: $(top_srcdir)/lib/substitute_sh.in \
+ $(top_builddir)/config.status
+ cd $(top_builddir); CONFIG_FILES=lib/substitute_sh ./config.status
+
+$(top_builddir)/util/subst.conf: $(top_srcdir)/util/subst.conf.in \
+ $(top_builddir)/config.status
+ cd $(top_builddir); CONFIG_FILES=util/subst.conf ./config.status
+
+$(top_srcdir)/configure: $(top_srcdir)/configure.in
+ cd $(top_srcdir) && autoconf
+
+#
+# Make depend magic...
+#
+
+.depend: Makefile $(SRCS) $(top_srcdir)/depfix.sed $(top_srcdir)/wordwrap.pl
+ if test -n "$(SRCS)" ; then \
+ $(CC) -M $(ALL_CFLAGS) $(SRCS) | \
+ $(SED) -f $(top_srcdir)/depfix.sed \
+ -e 's; $(srcdir)/; $$(srcdir)/;g' \
+ -e 's; $(top_srcdir)/; $$(top_srcdir)/;g' \
+ -e 's; $(top_builddir)/; $$(top_builddir)/;g' \
+ -e 's; \./; ;g' \
+ -e '/^ *\\$$/d' | \
+ $(PERL) $(top_srcdir)/wordwrap.pl > .depend; \
+ else :; fi
+
+depend:: .depend
+ if test -n "$(SRCS)" ; then \
+ sed -e '/^# +++ Dependency line eater +++/,$$d' \
+ < $(srcdir)/Makefile.in | cat - .depend \
+ > $(srcdir)/Makefile.in.new; \
+ if cmp -s $(srcdir)/Makefile.in $(srcdir)/Makefile.in.new ; then \
+ $(RM) $(srcdir)/Makefile.in.new ; \
+ else \
+ $(MV) $(srcdir)/Makefile.in $(srcdir)/Makefile.in.old; \
+ $(MV) $(srcdir)/Makefile.in.new $(srcdir)/Makefile.in; \
+ fi ; else :; fi
+
+# End of file MCONFIG
+
+all:: compile_et
+
+OBJS= error_message.o et_name.o init_et.o com_err.o
+SRCS = $(srcdir)/error_message.c $(srcdir)/et_name.c $(srcdir)/init_et.c \
+ $(srcdir)/com_err.c
+
+HFILES= com_err.h
+SHARE_FILES= et_c.awk et_h.awk
+
+LIBRARY= libcom_err
+LIBDIR= et
+
+DLL_ADDRESS = 0x66800000
+DLL_JUMPSIZE = 0x1000
+DLL_GOTSIZE = 0x1000
+DLL_VERSION = 1.0
+DLL_IMAGE = libet
+DLL_STUB = libcom_err
+DLL_MYDIR = et
+DLL_INSTALL_DIR = $(root_libdir)
+
+ELF_VERSION = 2.0
+ELF_SO_VERSION = 2
+ELF_IMAGE = libcom_err
+ELF_MYDIR = et
+ELF_INSTALL_DIR = $(root_libdir)
+ELF_OTHER_LIBS =
+
+BSDLIB_VERSION = 1.0
+BSDLIB_IMAGE = libcom_err
+BSDLIB_MYDIR = et
+BSDLIB_INSTALL_DIR = $(root_libdir)
+
+#
+# what to build...
+#
+.c.o:
+ $(CC) $(ALL_CFLAGS) -c $< -o $@
+# $(CC) $(ALL_CFLAGS) -g -pg -o profiled/$*.o -c $<
+# $(CC) $(ALL_CFLAGS) -checker -g -o checker/$*.o -c $<
+# (export JUMP_DIR=`pwd`/jump; $(CC) -B$(JUMP_PREFIX) $(ALL_CFLAGS) \
+# -o jump/$*.o -c $<)
+# $(CC) $(ALL_CFLAGS) -fPIC -o elfshared/$*.o -c $<
+# $(CC) $(ALL_CFLAGS) -fpic -o pic/$*.o -c $<
+
+
+all:: subdirs $(LIBRARY).a
+
+install-shlibs::
+
+subdirs::
+
+$(LIBRARY).a: $(OBJS)
+ (if test -r $@; then $(RM) -f $@.bak && $(MV) $@ $@.bak; fi)
+ $(ARUPD) $@ $(OBJS)
+ -$(RANLIB) $@
+ $(RM) -f ../$@
+ $(LN) $@ ../$@
+
+
+
+
+
+
+
+compile_et: $(DEP_SUBSTITUTE) $(srcdir)/compile_et.sh.in
+ $(SUBSTITUTE) $(srcdir)/compile_et.sh.in compile_et
+ $(CHMOD) +x compile_et
+
+com_err.ps : com_err.dvi
+com_err.dvi: com_err.texinfo
+
+#libcom_err.o: $(LIBOBJS)
+# $(LD) -r -s -o libcom_err.o $(LIBOBJS)
+# chmod -x libcom_err.o
+
+TAGS: $(SRCS)
+ $(TAGS) $(SRCS)
+
+installdirs::
+ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(libdir) \
+ $(DESTDIR)$(includedir)/et $(DESTDIR)$(datadir)/et \
+ $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir) \
+ $(DESTDIR)$(man3dir)
+
+install:: compile_et libcom_err.a $(HFILES) installdirs
+ $(INSTALL_DATA) libcom_err.a $(DESTDIR)$(libdir)/libcom_err.a
+ $(CHMOD) 644 $(DESTDIR)$(libdir)/libcom_err.a
+ -$(RANLIB) $(DESTDIR)$(libdir)/libcom_err.a
+ $(CHMOD) $(LIBMODE) $(DESTDIR)$(libdir)/libcom_err.a
+ for i in $(HFILES); do \
+ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir)/et/$$i; \
+ done
+ for i in $(SHARE_FILES); do \
+ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(datadir)/et/$$i; \
+ done
+ $(INSTALL) compile_et $(DESTDIR)$(bindir)/compile_et
+ $(INSTALL_DATA) $(srcdir)/com_err.3 $(DESTDIR)$(man3dir)/com_err.3
+ $(INSTALL_DATA) $(srcdir)/compile_et.1 \
+ $(DESTDIR)$(man1dir)/compile_et.1
+
+uninstall::
+ $(RM) -f $(DESTDIR)$(libdir)/libcom_err.a \
+ $(DESTDIR)$(bindir)/compile_et
+ $(RM) -rf $(DESTDIR)$(includedir)/et $(DESTDIR)$(datadir)/et
+
+clean::
+ $(RM) -f compile_et libcom_err.a libcom_err_p.a
+ $(RM) -f $(OBJS) profiled/*
+ $(RM) -f *~ \#* *.bak *.otl *.aux *.toc *.PS *.dvi *.ps TAGS *.ln
+ $(RM) -f ../libcom_err.a ../libcom_err_p.a
+mostlyclean:: clean
+distclean:: clean
+ $(RM) -f .depend Makefile $(srcdir)/TAGS $(srcdir)/Makefile.in.old
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+error_message.o: $(srcdir)/error_message.c $(srcdir)/com_err.h \
+ $(srcdir)/error_table.h $(srcdir)/internal.h
+et_name.o: $(srcdir)/et_name.c $(srcdir)/com_err.h $(srcdir)/error_table.h \
+ $(srcdir)/internal.h
+init_et.o: $(srcdir)/init_et.c $(srcdir)/com_err.h $(srcdir)/error_table.h
+com_err.o: $(srcdir)/com_err.c $(srcdir)/com_err.h $(srcdir)/error_table.h \
+ $(srcdir)/internal.h
diff --git a/e2fslib/et/Makefile.in b/e2fslib/et/Makefile.in
new file mode 100644
index 0000000..4a9e538
--- /dev/null
+++ b/e2fslib/et/Makefile.in
@@ -0,0 +1,129 @@
+#
+# Makefile for lib/et
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+top_builddir = ../..
+my_dir = lib/et
+INSTALL = @INSTALL@
+
+DEP_MAKEFILE = $(DEP_LIB_MAKEFILES)
+
+@MCONFIG@
+
+all:: compile_et
+
+OBJS= error_message.o et_name.o init_et.o com_err.o
+SRCS = $(srcdir)/error_message.c $(srcdir)/et_name.c $(srcdir)/init_et.c \
+ $(srcdir)/com_err.c
+
+HFILES= com_err.h
+SHARE_FILES= et_c.awk et_h.awk
+
+LIBRARY= libcom_err
+LIBDIR= et
+
+DLL_ADDRESS = 0x66800000
+DLL_JUMPSIZE = 0x1000
+DLL_GOTSIZE = 0x1000
+DLL_VERSION = 1.0
+DLL_IMAGE = libet
+DLL_STUB = libcom_err
+DLL_MYDIR = et
+DLL_INSTALL_DIR = $(root_libdir)
+
+ELF_VERSION = 2.0
+ELF_SO_VERSION = 2
+ELF_IMAGE = libcom_err
+ELF_MYDIR = et
+ELF_INSTALL_DIR = $(root_libdir)
+ELF_OTHER_LIBS =
+
+BSDLIB_VERSION = 1.0
+BSDLIB_IMAGE = libcom_err
+BSDLIB_MYDIR = et
+BSDLIB_INSTALL_DIR = $(root_libdir)
+
+#
+# what to build...
+#
+.c.o:
+ $(CC) $(ALL_CFLAGS) -c $< -o $@
+@PROFILE_CMT@ $(CC) $(ALL_CFLAGS) -g -pg -o profiled/$*.o -c $<
+@CHECKER_CMT@ $(CC) $(ALL_CFLAGS) -checker -g -o checker/$*.o -c $<
+@DLL_CMT@ (export JUMP_DIR=`pwd`/jump; $(CC) -B$(JUMP_PREFIX) $(ALL_CFLAGS) \
+@DLL_CMT@ -o jump/$*.o -c $<)
+@ELF_CMT@ $(CC) $(ALL_CFLAGS) -fPIC -o elfshared/$*.o -c $<
+@BSDLIB_CMT@ $(CC) $(ALL_CFLAGS) -fpic -o pic/$*.o -c $<
+
+@MAKEFILE_LIBRARY@
+@MAKEFILE_DLL@
+@MAKEFILE_ELF@
+@MAKEFILE_BSDLIB@
+@MAKEFILE_PROFILE@
+@MAKEFILE_CHECKER@
+
+compile_et: $(DEP_SUBSTITUTE) $(srcdir)/compile_et.sh.in
+ $(SUBSTITUTE) $(srcdir)/compile_et.sh.in compile_et
+ $(CHMOD) +x compile_et
+
+com_err.ps : com_err.dvi
+com_err.dvi: com_err.texinfo
+
+#libcom_err.o: $(LIBOBJS)
+# $(LD) -r -s -o libcom_err.o $(LIBOBJS)
+# chmod -x libcom_err.o
+
+TAGS: $(SRCS)
+ $(TAGS) $(SRCS)
+
+installdirs::
+ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(libdir) \
+ $(DESTDIR)$(includedir)/et $(DESTDIR)$(datadir)/et \
+ $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir) \
+ $(DESTDIR)$(man3dir)
+
+install:: compile_et libcom_err.a $(HFILES) installdirs
+ $(INSTALL_DATA) libcom_err.a $(DESTDIR)$(libdir)/libcom_err.a
+ $(CHMOD) 644 $(DESTDIR)$(libdir)/libcom_err.a
+ -$(RANLIB) $(DESTDIR)$(libdir)/libcom_err.a
+ $(CHMOD) $(LIBMODE) $(DESTDIR)$(libdir)/libcom_err.a
+ for i in $(HFILES); do \
+ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir)/et/$$i; \
+ done
+ for i in $(SHARE_FILES); do \
+ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(datadir)/et/$$i; \
+ done
+ $(INSTALL) compile_et $(DESTDIR)$(bindir)/compile_et
+ $(INSTALL_DATA) $(srcdir)/com_err.3 $(DESTDIR)$(man3dir)/com_err.3
+ $(INSTALL_DATA) $(srcdir)/compile_et.1 \
+ $(DESTDIR)$(man1dir)/compile_et.1
+
+uninstall::
+ $(RM) -f $(DESTDIR)$(libdir)/libcom_err.a \
+ $(DESTDIR)$(bindir)/compile_et
+ $(RM) -rf $(DESTDIR)$(includedir)/et $(DESTDIR)$(datadir)/et
+
+clean::
+ $(RM) -f compile_et libcom_err.a libcom_err_p.a
+ $(RM) -f $(OBJS) profiled/*
+ $(RM) -f *~ \#* *.bak *.otl *.aux *.toc *.PS *.dvi *.ps TAGS *.ln
+ $(RM) -f ../libcom_err.a ../libcom_err_p.a
+mostlyclean:: clean
+distclean:: clean
+ $(RM) -f .depend Makefile $(srcdir)/TAGS $(srcdir)/Makefile.in.old
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+error_message.o: $(srcdir)/error_message.c $(srcdir)/com_err.h \
+ $(srcdir)/error_table.h $(srcdir)/internal.h
+et_name.o: $(srcdir)/et_name.c $(srcdir)/com_err.h $(srcdir)/error_table.h \
+ $(srcdir)/internal.h
+init_et.o: $(srcdir)/init_et.c $(srcdir)/com_err.h $(srcdir)/error_table.h
+com_err.o: $(srcdir)/com_err.c $(srcdir)/com_err.h $(srcdir)/error_table.h \
+ $(srcdir)/internal.h
diff --git a/e2fslib/et/com_err.c b/e2fslib/et/com_err.c
new file mode 100644
index 0000000..81a70cf
--- /dev/null
+++ b/e2fslib/et/com_err.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1987, 1988 by MIT Student Information Processing Board.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose is hereby granted, provided that
+ * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. M.I.T. and the
+ * M.I.T. S.I.P.B. make no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+#include <stdio.h>
+#include "com_err.h"
+#include "error_table.h"
+#include "internal.h"
+
+#if !defined(__STDC__) && !defined(STDARG_PROTOTYPES)
+#include <varargs.h>
+#define VARARGS
+#endif
+
+static void
+#ifdef __STDC__
+ default_com_err_proc (const char *whoami, errcode_t code, const
+ char *fmt, va_list args)
+#else
+ default_com_err_proc (whoami, code, fmt, args)
+ const char *whoami;
+ errcode_t code;
+ const char *fmt;
+ va_list args;
+#endif
+{
+ if (whoami) {
+ fputs(whoami, stderr);
+ fputs(": ", stderr);
+ }
+ if (code) {
+ fputs(error_message(code), stderr);
+ fputs(" ", stderr);
+ }
+ if (fmt) {
+ vfprintf (stderr, fmt, args);
+ }
+ /* should do this only on a tty in raw mode */
+ putc('\r', stderr);
+ putc('\n', stderr);
+ fflush(stderr);
+}
+
+#ifdef __STDC__
+typedef void (*errf) (const char *, errcode_t, const char *, va_list);
+#else
+typedef void (*errf) ();
+#endif
+
+errf com_err_hook = default_com_err_proc;
+
+#ifdef __STDC__
+void com_err_va (const char *whoami, errcode_t code, const char *fmt,
+ va_list args)
+#else
+void com_err_va (whoami, code, fmt, args)
+ const char *whoami;
+ errcode_t code;
+ const char *fmt;
+ va_list args;
+#endif
+{
+ (*com_err_hook) (whoami, code, fmt, args);
+}
+
+#ifndef VARARGS
+void com_err (const char *whoami,
+ errcode_t code,
+ const char *fmt, ...)
+{
+#else
+void com_err (va_alist)
+ va_dcl
+{
+ const char *whoami, *fmt;
+ errcode_t code;
+#endif
+ va_list pvar;
+
+ if (!com_err_hook)
+ com_err_hook = default_com_err_proc;
+#ifdef VARARGS
+ va_start (pvar);
+ whoami = va_arg (pvar, const char *);
+ code = va_arg (pvar, errcode_t);
+ fmt = va_arg (pvar, const char *);
+#else
+ va_start(pvar, fmt);
+#endif
+ com_err_va (whoami, code, fmt, pvar);
+ va_end(pvar);
+}
+
+errf set_com_err_hook (new_proc)
+ errf new_proc;
+{
+ errf x = com_err_hook;
+
+ if (new_proc)
+ com_err_hook = new_proc;
+ else
+ com_err_hook = default_com_err_proc;
+
+ return x;
+}
+
+errf reset_com_err_hook () {
+ errf x = com_err_hook;
+ com_err_hook = default_com_err_proc;
+ return x;
+}
diff --git a/e2fslib/et/com_err.h b/e2fslib/et/com_err.h
new file mode 100644
index 0000000..f28dce8
--- /dev/null
+++ b/e2fslib/et/com_err.h
@@ -0,0 +1,40 @@
+/*
+ * Header file for common error description library.
+ *
+ * Copyright 1988, Student Information Processing Board of the
+ * Massachusetts Institute of Technology.
+ *
+ * For copyright and distribution info, see the documentation supplied
+ * with this package.
+ */
+
+#ifndef __COM_ERR_H
+
+typedef long errcode_t;
+
+#ifdef __STDC__
+#include <stdarg.h>
+
+/* ANSI C -- use prototypes etc */
+void com_err (const char *, long, const char *, ...);
+void com_err_va (const char *whoami, errcode_t code, const char *fmt,
+ va_list args);
+char const *error_message (long);
+extern void (*com_err_hook) (const char *, long, const char *, va_list);
+void (*set_com_err_hook (void (*) (const char *, long, const char *, va_list)))
+ (const char *, long, const char *, va_list);
+void (*reset_com_err_hook (void)) (const char *, long, const char *, va_list);
+int init_error_table(const char * const *msgs, int base, int count);
+#else
+/* no prototypes */
+void com_err ();
+void com_err_va ();
+char *error_message ();
+extern void (*com_err_hook) ();
+void (*set_com_err_hook ()) ();
+void (*reset_com_err_hook ()) ();
+int init_error_table();
+#endif
+
+#define __COM_ERR_H
+#endif /* ! defined(__COM_ERR_H) */
diff --git a/e2fslib/et/com_err.o b/e2fslib/et/com_err.o
new file mode 100644
index 0000000..f851d2d
--- /dev/null
+++ b/e2fslib/et/com_err.o
Binary files differ
diff --git a/e2fslib/et/com_err.texinfo b/e2fslib/et/com_err.texinfo
new file mode 100644
index 0000000..6ca745d
--- /dev/null
+++ b/e2fslib/et/com_err.texinfo
@@ -0,0 +1,579 @@
+\input texinfo @c -*-texinfo-*-
+
+@c $Header: /home/cvs/arcboot/e2fslib/et/com_err.texinfo,v 1.1 2004/11/29 10:39:38 ladis Exp $
+@c $Source: /home/cvs/arcboot/e2fslib/et/com_err.texinfo,v $
+@c $Locker: $
+
+@c Note that although this source file is in texinfo format (more
+@c or less), it is not yet suitable for turning into an ``info''
+@c file. Sorry, maybe next time.
+@c
+@c In order to produce hardcopy documentation from a texinfo file,
+@c run ``tex com_err.texinfo'' which will load in texinfo.tex,
+@c provided in this distribution. (texinfo.tex is from the Free
+@c Software Foundation, and is under different copyright restrictions
+@c from the rest of this package.)
+
+@setfilename com_err
+@settitle A Common Error Description Library for UNIX
+
+@ifinfo
+@dircategory Development
+@format
+START-INFO-DIR-ENTRY
+* com_err: (com_err.info). A Common Error Description Library for UNIX.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@iftex
+@tolerance 10000
+
+@c Mutate section headers...
+@begingroup
+ @catcode#=6
+ @gdef@secheading#1#2#3{@secheadingi {#3@enspace #1}}
+@endgroup
+@end iftex
+
+@ifinfo
+This file documents the use of the Common Error Description library.
+
+Copyright (C) 1987, 1988 Student Information Processing Board of the
+Massachusetts Institute of Technology.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution of the software
+without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
+make no representations about the suitability of this software for any
+purpose. It is provided "as is" without express or implied warranty.
+
+Note that the file texinfo.tex, provided with this distribution, is from
+the Free Software Foundation, and is under different copyright restrictions
+from the remainder of this package.
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+
+@setchapternewpage odd
+
+@titlepage
+@center @titlefont{A Common Error Description}
+@center @titlefont{Library for UNIX}
+@sp 2
+@center Ken Raeburn
+@center Bill Sommerfeld
+@sp 1
+@center MIT Student Information Processing Board
+@sp 3
+@center last updated 1 January 1989
+@center for version 1.2
+@center ***DRAFT COPY ONLY***
+
+@vskip 2in
+
+@center @b{Abstract}
+
+UNIX has always had a clean and simple system call interface, with a
+standard set of error codes passed between the kernel and user
+programs. Unfortunately, the same cannot be said of many of the
+libraries layered on top of the primitives provided by the kernel.
+Typically, each one has used a different style of indicating errors to
+their callers, leading to a total hodgepodge of error handling, and
+considerable amounts of work for the programmer. This paper describes
+a library and associated utilities which allows a more uniform way for
+libraries to return errors to their callers, and for programs to
+describe errors and exceptional conditions to their users.
+
+@page
+@vskip 0pt plus 1filll
+
+Copyright @copyright{} 1987, 1988 by the Student Information Processing
+Board of the Massachusetts Institute of Technology.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution of the software
+without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
+make no representations about the suitability of this software for any
+purpose. It is provided "as is" without express or implied warranty.
+
+Note that the file texinfo.tex, provided with this distribution, is from
+the Free Software Foundation, and is under different copyright restrictions
+from the remainder of this package.
+
+@end titlepage
+
+
+@node Top, Why com_err?, (dir), (dir)
+
+@top A Common Error Description Library for UNIX
+
+This manual documents the com_err library.
+
+@menu
+* Why com_err?::
+* Error codes::
+* Error table source file::
+* The error-table compiler::
+* Run-time support routines::
+* Coding Conventions::
+* Building and Installation::
+* Bug Reports::
+* Acknowledgements::
+@end menu
+
+@end ifinfo
+
+@page
+
+@node Why com_err?, Error codes, Top, Top
+@section Why com_err?
+
+In building application software packages, a programmer often has to
+deal with a number of libraries, each of which can use a different
+error-reporting mechanism. Sometimes one of two values is returned,
+indicating simply SUCCESS or FAILURE, with no description of errors
+encountered. Sometimes it is an index into a table of text strings,
+where the name of the table used is dependent on the library being
+used when the error is generated; since each table starts numbering at
+0 or 1, additional information as to the source of the error code is
+needed to determine which table to look at. Sometimes no text messages are
+supplied at all, and the programmer must supply them at any point at which
+he may wish to report error conditions.
+Often, a global variable is assigned some value describing the error, but
+the programmer has to know in each case whether to look at @code{errno},
+@code{h_errno}, the return value from @code{hes_err()}, or whatever other
+variables or routines are specified.
+And what happens if something
+in the procedure of
+examining or reporting the error changes the same variable?
+
+The package we have developed is an attempt to present a common
+error-handling mechanism to manipulate the most common form of error code
+in a fashion that does not have the problems listed above.
+
+A list of up to 256 text messages is supplied to a translator we have
+written, along with the three- to four-character ``name'' of the error
+table. The library using this error table need only call a routine
+generated from this error-table source to make the table ``known'' to the
+com_err library, and any error code the library generates can be converted
+to the corresponding error message. There is also a default format for
+error codes accidentally returned before making the table known, which is
+of the form @samp{unknown code foo 32}, where @samp{foo} would be the name
+of the table.
+
+@node Error codes, Error table source file, Why com_err?, Top
+@section Error codes
+
+Error codes themselves are 32 bit (signed) integers, of which the high
+order 24 bits are an identifier of which error table the error code is
+from, and the low order 8 bits are a sequential error number within
+the table. An error code may thus be easily decomposed into its component
+parts. Only the lowest 32 bits of an error code are considered significant
+on systems which support wider values.
+
+Error table 0 is defined to match the UNIX system call error table
+(@code{sys_errlist}); this allows @code{errno} values to be used directly
+in the library (assuming that @code{errno} is of a type with the same width
+as @t{long}). Other error table numbers are formed by compacting together
+the first four characters of the error table name. The mapping between
+characters in the name and numeric values in the error code are defined in
+a system-independent fashion, so that two systems that can pass integral
+values between them can reliably pass error codes without loss of meaning;
+this should work even if the character sets used are not the same.
+(However, if this is to be done, error table 0 should be avoided, since the
+local system call error tables may differ.)
+
+Any variable which is to contain an error code should be declared @t{long}.
+The draft proposed American National Standard for C (as of May, 1988)
+requires that @t{long} variables be at least 32 bits; any system which does
+not support 32-bit @t{long} values cannot make use of this package (nor
+much other software that assumes an ANSI-C environment base) without
+significant effort.
+
+@node Error table source file, The error-table compiler, Error codes, Top
+@section Error table source file
+
+The error table source file begins with the declaration of the table name,
+as
+
+@example
+error_table @var{tablename}
+@end example
+
+Individual error codes are
+specified with
+
+@example
+error_code @var{ERROR_NAME}, @var{"text message"}
+@end example
+
+where @samp{ec} can also be used as a short form of @samp{error_code}. To
+indicate the end of the table, use @samp{end}. Thus, a (short) sample
+error table might be:
+
+@example
+
+ error_table dsc
+
+ error_code DSC_DUP_MTG_NAME,
+ "Meeting already exists"
+
+ ec DSC_BAD_PATH,
+ "A bad meeting pathname was given"
+
+ ec DSC_BAD_MODES,
+ "Invalid mode for this access control list"
+
+ end
+
+@end example
+
+@node The error-table compiler, Run-time support routines, Error table source file, Top
+@section The error-table compiler
+
+The error table compiler is named @code{compile_et}. It takes one
+argument, the pathname of a file (ending in @samp{.et}, e.g.,
+@samp{dsc_err.et}) containing an error table source file. It parses the
+error table, and generates two output files -- a C header file
+(@samp{discuss_err.h}) which contains definitions of the numerical values
+of the error codes defined in the error table, and a C source file which
+should be compiled and linked with the executable. The header file must be
+included in the source of a module which wishes to reference the error
+codes defined; the object module generated from the C code may be linked in
+to a program which wishes to use the printed forms of the error codes.
+
+This translator accepts a @kbd{-language @var{lang}} argument, which
+determines for which language (or language variant) the output should be
+written. At the moment, @var{lang} is currently limited to @kbd{ANSI-C}
+and @kbd{K&R-C}, and some abbreviated forms of each. Eventually, this will
+be extended to include some support for C++. The default is currently
+@kbd{K&R-C}, though the generated sources will have ANSI-C code
+conditionalized on the symbol @t{__STDC__}.
+
+@node Run-time support routines, Coding Conventions, The error-table compiler, Top
+@section Run-time support routines
+
+Any source file which uses the routines supplied with or produced by the
+com_err package should include the header file @file{<com_err.h>}. It
+contains declarations and definitions which may be needed on some systems.
+(Some functions cannot be referenced properly without the return type
+declarations in this file. Some functions may work properly on most
+architectures even without the header file, but relying on this is not
+recommended.)
+
+The run-time support routines and variables provided via this package
+include the following:
+
+@example
+void initialize_@var{xxxx}_error_table (void);
+@end example
+
+One of these routines is built by the error compiler for each error table.
+It makes the @var{xxxx} error table ``known'' to the error reporting
+system. By convention, this routine should be called in the initialization
+routine of the @var{xxxx} library. If the library has no initialization
+routine, some combination of routines which form the core of the library
+should ensure that this routine is called. It is not advised to leave it
+the caller to make this call.
+
+There is no harm in calling this routine more than once.
+
+@example
+#define ERROR_TABLE_BASE_@var{xxxx} @var{nnnnn}L
+@end example
+
+This symbol contains the value of the first error code entry in the
+specified table.
+This rarely needs be used by the
+programmer.
+
+@deftypefun const char *error_message (long @var{code});
+
+This routine returns the character string error message associated
+with @code{code}; if this is associated with an unknown error table, or
+if the code is associated with a known error table but the code is not
+in the table, a string of the form @samp{Unknown code @var{xxxx nn}} is
+returned, where @var{xxxx} is the error table name produced by
+reversing the compaction performed on the error table number implied
+by that error code, and @var{nn} is the offset from that base value.
+
+Although this routine is available for use when needed, its use should be
+left to circumstances which render @code{com_err} (below) unusable.
+
+@end deftypefun
+
+@deftypefun
+void com_err (const char *@var{whoami}, long @var{error_code},
+ const char *@var{format}, ...);
+
+This routine provides an alternate way to print error messages to
+standard error; it allows the error message to be passed in as a
+parameter, rather than in an external variable. @emph{Provide grammatical
+context for ``message.''}
+
+The module reporting the error should be passed in via @var{whoami}.
+If @var{format} is @code{(char *)NULL}, the formatted message will not be
+printed. @var{format} may not be omitted.
+
+@end deftypefun
+
+@deftypefun
+void com_err_va (const char *@var{whoami}, long @var{error_code}, const char *@var{format}, va_list @var{args});
+
+This routine provides an interface, equivalent to @code{com_err} above,
+which may be used by higher-level variadic functions (functions which
+accept variable numbers of arguments).
+
+@end deftypefun
+
+@deftypefun void (*set_com_err_hook (void (*@var{proc}) (const char *@var{whoami}, long @var{error_code}, va_list @var{args}))) (const char *@var{whoami}, long @var{error_code}, va_list @var{args});
+
+@deftypefunx void reset_com_err_hook ();
+
+These two routines allow a routine to be dynamically substituted for
+@samp{com_err}. After @samp{set_com_err_hook} has been called,
+calls to @samp{com_err} will turn into calls to the new hook routine.
+@samp{reset_com_err_hook} turns off this hook. This may intended to
+be used in daemons (to use a routine which calls @cite{syslog(3)}), or
+in a window system application (which could pop up a dialogue box).
+
+If a program is to be used in an environment in which simply printing
+messages to the @code{stderr} stream would be inappropriate (such as in a
+daemon program which runs without a terminal attached),
+@code{set_com_err_hook} may be used to redirect output from @code{com_err}.
+The following is an example of an error handler which uses @cite{syslog(3)}
+as supplied in BSD 4.3:
+
+@example
+#include <stdio.h>
+#include <stdarg.h>
+#include <syslog.h>
+
+/* extern openlog (const char * name, int logopt, int facility); */
+/* extern syslog (int priority, char * message, ...); */
+
+void hook (const char * whoami, long code,
+ const char * format, va_list args)
+@{
+ char buffer[BUFSIZ];
+ static int initialized = 0;
+ if (!initialized) @{
+ openlog (whoami,
+ LOG_NOWAIT|LOG_CONS|LOG_PID|LOG_NDELAY,
+ LOG_DAEMON);
+ initialized = 1;
+ @}
+ vsprintf (buffer, format, args);
+ syslog (LOG_ERR, "%s %s", error_message (code), buffer);
+@}
+@end example
+
+After making the call
+@code{set_com_err_hook (hook);},
+any calls to @code{com_err} will result in messages being sent to the
+@var{syslogd} daemon for logging.
+The name of the program, @samp{whoami}, is supplied to the
+@samp{openlog()} call, and the message is formatted into a buffer and
+passed to @code{syslog}.
+
+Note that since the extra arguments to @code{com_err} are passed by
+reference via the @code{va_list} value @code{args}, the hook routine may
+place any form of interpretation on them, including ignoring them. For
+consistency, @code{printf}-style interpretation is suggested, via
+@code{vsprintf} (or @code{_doprnt} on BSD systems without full support for
+the ANSI C library).
+
+@end deftypefun
+
+@node Coding Conventions, Building and Installation, Run-time support routines, Top
+@section Coding Conventions
+
+The following conventions are just some general stylistic conventions
+to follow when writing robust libraries and programs. Conventions
+similar to this are generally followed inside the UNIX kernel and most
+routines in the Multics operating system. In general, a routine
+either succeeds (returning a zero error code, and doing some side
+effects in the process), or it fails, doing minimal side effects; in
+any event, any invariant which the library assumes must be maintained.
+
+In general, it is not in the domain of non user-interface library
+routines to write error messages to the user's terminal, or halt the
+process. Such forms of ``error handling'' should be reserved for
+failures of internal invariants and consistancy checks only, as it
+provides the user of the library no way to clean up for himself in the
+event of total failure.
+
+Library routines which can fail should be set up to return an error
+code. This should usually be done as the return value of the
+function; if this is not acceptable, the routine should return a
+``null'' value, and put the error code into a parameter passed by
+reference.
+
+Routines which use the first style of interface can be used from
+user-interface levels of a program as follows:
+
+@example
+@{
+ if ((code = initialize_world(getuid(), random())) != 0) @{
+ com_err("demo", code,
+ "when trying to initialize world");
+ exit(1);
+ @}
+ if ((database = open_database("my_secrets", &code))==NULL) @{
+ com_err("demo", code,
+ "while opening my_secrets");
+ exit(1);
+ @}
+@}
+@end example
+
+A caller which fails to check the return status is in error. It is
+possible to look for code which ignores error returns by using lint;
+look for error messages of the form ``foobar returns value which is
+sometimes ignored'' or ``foobar returns value which is always
+ignored.''
+
+Since libraries may be built out of other libraries, it is often necessary
+for the success of one routine to depend on another. When a lower level
+routine returns an error code, the middle level routine has a few possible
+options. It can simply return the error code to its caller after doing
+some form of cleanup, it can substitute one of its own, or it can take
+corrective action of its own and continue normally. For instance, a
+library routine which makes a ``connect'' system call to make a network
+connection may reflect the system error code @code{ECONNREFUSED}
+(Connection refused) to its caller, or it may return a ``server not
+available, try again later,'' or it may try a different server.
+
+Cleanup which is typically necessary may include, but not be limited
+to, freeing allocated memory which will not be needed any more,
+unlocking concurrancy locks, dropping reference counts, closing file
+descriptors, or otherwise undoing anything which the procedure did up
+to this point. When there are a lot of things which can go wrong, it
+is generally good to write one block of error-handling code which is
+branched to, using a goto, in the event of failure. A common source
+of errors in UNIX programs is failing to close file descriptors on
+error returns; this leaves a number of ``zombied'' file descriptors
+open, which eventually causes the process to run out of file
+descriptors and fall over.
+
+@example
+@{
+ FILE *f1=NULL, *f2=NULL, *f3=NULL;
+ int status = 0;
+
+ if ( (f1 = fopen(FILE1, "r")) == NULL) @{
+ status = errno;
+ goto error;
+ @}
+
+ /*
+ * Crunch for a while
+ */
+
+ if ( (f2 = fopen(FILE2, "w")) == NULL) @{
+ status = errno;
+ goto error;
+ @}
+
+ if ( (f3 = fopen(FILE3, "a+")) == NULL) @{
+ status = errno;
+ goto error;
+ @}
+
+ /*
+ * Do more processing.
+ */
+ fclose(f1);
+ fclose(f2);
+ fclose(f3);
+ return 0;
+
+error:
+ if (f1) fclose(f1);
+ if (f2) fclose(f2);
+ if (f3) fclose(f3);
+ return status;
+@}
+@end example
+
+@node Building and Installation, Bug Reports, Coding Conventions, Top
+@section Building and Installation
+
+The distribution of this package will probably be done as a compressed
+``tar''-format file available via anonymous FTP from SIPB.MIT.EDU.
+Retrieve @samp{pub/com_err.tar.Z} and extract the contents. A subdirectory
+@t{profiled} should be created to hold objects compiled for profiling.
+Running ``make all'' should then be sufficient to build the library and
+error-table compiler. The files @samp{libcom_err.a},
+@samp{libcom_err_p.a}, @samp{com_err.h}, and @samp{compile_et} should be
+installed for use; @samp{com_err.3} and @samp{compile_et.1} can also be
+installed as manual pages.
+
+Potential problems:
+
+@itemize @bullet
+
+@item Use of @code{strcasecmp}, a routine provided in BSD for
+case-insensitive string comparisons. If an equivalent routine is
+available, you can modify @code{CFLAGS} in the makefile to define
+@code{strcasecmp} to the name of that routine.
+
+@item Compilers that defined @code{__STDC__} without providing the header
+file @code{<stdarg.h>}. One such example is Metaware's High ``C''
+compiler, as provided at Project Athena on the IBM RT/PC workstation; if
+@code{__HIGHC__} is defined, it is assumed that @code{<stdarg.h>} is not
+available, and therefore @code{<varargs.h>} must be used. If the symbol
+@code{VARARGS} is defined (e.g., in the makefile), @code{<varargs.h>} will
+be used.
+
+@item If your linker rejects symbols that are simultaneously defined in two
+library files, edit @samp{Makefile} to remove @samp{perror.c} from the
+library. This file contains a version of @cite{perror(3)} which calls
+@code{com_err} instead of calling @code{write} directly.
+
+@end itemize
+
+As I do not have access to non-BSD systems, there are probably
+bugs present that may interfere with building or using this package on
+other systems. If they are reported to me, they can probably be fixed for
+the next version.
+
+@node Bug Reports, Acknowledgements, Building and Installation, Top
+@section Bug Reports
+
+The principal author of this library is: Ken
+Raeburn, @t{raeburn@@MIT.EDU}.
+
+This version of the com_err library is being maintained by Theodore
+Ts'o, and so bugs and comments should be sent to @t{tytso@@thunk.org}.
+
+
+@node Acknowledgements, , Bug Reports, Top
+@section Acknowledgements
+
+I would like to thank: Bill Sommerfeld, for his help with some of this
+documentation, and catching some of the bugs the first time around;
+Honeywell Information Systems, for not killing off the @emph{Multics}
+operating system before I had an opportunity to use it; Honeywell's
+customers, who persuaded them not to do so, for a while; Ted Anderson of
+CMU, for catching some problems before version 1.2 left the nest; Stan
+Zanarotti and several others of MIT's Student Information Processing Board,
+for getting us started with ``discuss,'' for which this package was
+originally written; and everyone I've talked into --- I mean, asked to read
+this document and the ``man'' pages.
+
+@bye
diff --git a/e2fslib/et/compile_et b/e2fslib/et/compile_et
new file mode 100755
index 0000000..ca19559
--- /dev/null
+++ b/e2fslib/et/compile_et
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+#
+AWK=/usr/bin/awk
+DIR="${DIR-/usr/share/et}"
+ET_DIR="et"
+
+if test "x$1" = x ; then
+ echo "Usage: compile_et file"
+ exit 1
+fi
+
+if test ! -f "$DIR/et_h.awk" -o ! -f "$DIR/et_c.awk" ; then
+ DIR="$ET_DIR"
+# echo "Falling back to $DIR..."
+ if test ! -f "$DIR/et_h.awk" -o ! -f "$DIR/et_c.awk" ; then
+ echo "compile_et: Couldn't find compile_et's template files."
+ exit 1
+ fi
+fi
+
+ROOT=`echo $1 | sed -e s/.et$//`
+BASE=`basename $ROOT`
+
+if test ! -f "$ROOT.et" ; then
+ echo "compile_et: $ROOT.et: File not found"
+ exit 1;
+fi
+
+$AWK -f "${DIR}/et_h.awk" "outfile=${BASE}.h" "$ROOT.et"
+$AWK -f "${DIR}/et_c.awk" "outfile=${BASE}.c" "$ROOT.et"
diff --git a/e2fslib/et/compile_et.sh.in b/e2fslib/et/compile_et.sh.in
new file mode 100644
index 0000000..ad445fa
--- /dev/null
+++ b/e2fslib/et/compile_et.sh.in
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+#
+AWK=@AWK@
+DIR="${DIR-@datadir@/et}"
+ET_DIR="@ET_DIR@"
+
+if test "x$1" = x ; then
+ echo "Usage: compile_et file"
+ exit 1
+fi
+
+if test ! -f "$DIR/et_h.awk" -o ! -f "$DIR/et_c.awk" ; then
+ DIR="$ET_DIR"
+# echo "Falling back to $DIR..."
+ if test ! -f "$DIR/et_h.awk" -o ! -f "$DIR/et_c.awk" ; then
+ echo "compile_et: Couldn't find compile_et's template files."
+ exit 1
+ fi
+fi
+
+ROOT=`echo $1 | sed -e s/.et$//`
+BASE=`basename $ROOT`
+
+if test ! -f "$ROOT.et" ; then
+ echo "compile_et: $ROOT.et: File not found"
+ exit 1;
+fi
+
+$AWK -f "${DIR}/et_h.awk" "outfile=${BASE}.h" "$ROOT.et"
+$AWK -f "${DIR}/et_c.awk" "outfile=${BASE}.c" "$ROOT.et"
diff --git a/e2fslib/et/error_message.c b/e2fslib/et/error_message.c
new file mode 100644
index 0000000..b9e3628
--- /dev/null
+++ b/e2fslib/et/error_message.c
@@ -0,0 +1,88 @@
+/*
+ * $ Header: lib/et/SCCS/s.error_message.c 1.16 99/10/23 01:16:05-00:00 tytso@mit.edu $
+ * $ Source: /usr/src/e2fsprogs/BK/e2fsprogs/lib/et/SCCS/s.error_message.c $
+ * $ Locker: <Not implemented> $
+ *
+ * Copyright 1987 by the Student Information Processing Board
+ * of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose is hereby granted, provided that
+ * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. M.I.T. and the
+ * M.I.T. S.I.P.B. make no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "com_err.h"
+#include "error_table.h"
+#include "internal.h"
+
+static char buffer[25];
+
+struct et_list * _et_list = (struct et_list *) NULL;
+
+
+#ifdef __STDC__
+const char * error_message (errcode_t code)
+#else
+const char * error_message (code)
+ errcode_t code;
+#endif
+{
+ int offset;
+ struct et_list *et;
+ errcode_t table_num;
+ int started = 0;
+ char *cp;
+
+ offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
+ table_num = code - offset;
+ if (!table_num) {
+#ifdef HAS_SYS_ERRLIST
+ if (offset < sys_nerr)
+ return(sys_errlist[offset]);
+ else
+ goto oops;
+#else
+ cp = strerror(offset);
+ if (cp)
+ return(cp);
+ else
+ goto oops;
+#endif
+ }
+ for (et = _et_list; et; et = et->next) {
+ if (et->table->base == table_num) {
+ /* This is the right table */
+ if (et->table->n_msgs <= offset)
+ goto oops;
+ return(et->table->msgs[offset]);
+ }
+ }
+oops:
+ strcpy (buffer, "Unknown code ");
+ if (table_num) {
+ strcat (buffer, error_table_name (table_num));
+ strcat (buffer, " ");
+ }
+ for (cp = buffer; *cp; cp++)
+ ;
+ if (offset >= 100) {
+ *cp++ = '0' + offset / 100;
+ offset %= 100;
+ started++;
+ }
+ if (started || offset >= 10) {
+ *cp++ = '0' + offset / 10;
+ offset %= 10;
+ }
+ *cp++ = '0' + offset;
+ *cp = '\0';
+ return(buffer);
+}
diff --git a/e2fslib/et/error_message.o b/e2fslib/et/error_message.o
new file mode 100644
index 0000000..9223eb8
--- /dev/null
+++ b/e2fslib/et/error_message.o
Binary files differ
diff --git a/e2fslib/et/error_table.h b/e2fslib/et/error_table.h
new file mode 100644
index 0000000..d9a7b4b
--- /dev/null
+++ b/e2fslib/et/error_table.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1988 by the Student Information Processing Board of the
+ * Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose is hereby granted, provided that
+ * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. M.I.T. and the
+ * M.I.T. S.I.P.B. make no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+#ifndef _ET_H
+/* Are we using ANSI C? */
+#ifndef __STDC__
+#define const
+#endif
+
+struct error_table {
+ char const * const * msgs;
+ long base;
+ int n_msgs;
+};
+struct et_list {
+ struct et_list *next;
+ const struct error_table *table;
+};
+extern struct et_list * _et_list;
+
+#define ERRCODE_RANGE 8 /* # of bits to shift table number */
+#define BITS_PER_CHAR 6 /* # bits to shift per character in name */
+
+#ifdef __STDC__
+extern const char *error_table_name(errcode_t num);
+#else
+extern const char *error_table_name();
+#endif
+
+#define _ET_H
+#endif
diff --git a/e2fslib/et/et_c.awk b/e2fslib/et/et_c.awk
new file mode 100644
index 0000000..5f95b55
--- /dev/null
+++ b/e2fslib/et/et_c.awk
@@ -0,0 +1,187 @@
+BEGIN {
+char_shift=64
+## "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
+c2n["A"]=1
+c2n["B"]=2
+c2n["C"]=3
+c2n["D"]=4
+c2n["E"]=5
+c2n["F"]=6
+c2n["G"]=7
+c2n["H"]=8
+c2n["I"]=9
+c2n["J"]=10
+c2n["K"]=11
+c2n["L"]=12
+c2n["M"]=13
+c2n["N"]=14
+c2n["O"]=15
+c2n["P"]=16
+c2n["Q"]=17
+c2n["R"]=18
+c2n["S"]=19
+c2n["T"]=20
+c2n["U"]=21
+c2n["V"]=22
+c2n["W"]=23
+c2n["X"]=24
+c2n["Y"]=25
+c2n["Z"]=26
+c2n["a"]=27
+c2n["b"]=28
+c2n["c"]=29
+c2n["d"]=30
+c2n["e"]=31
+c2n["f"]=32
+c2n["g"]=33
+c2n["h"]=34
+c2n["i"]=35
+c2n["j"]=36
+c2n["k"]=37
+c2n["l"]=38
+c2n["m"]=39
+c2n["n"]=40
+c2n["o"]=41
+c2n["p"]=42
+c2n["q"]=43
+c2n["r"]=44
+c2n["s"]=45
+c2n["t"]=46
+c2n["u"]=47
+c2n["v"]=48
+c2n["w"]=49
+c2n["x"]=50
+c2n["y"]=51
+c2n["z"]=52
+c2n["0"]=53
+c2n["1"]=54
+c2n["2"]=55
+c2n["3"]=56
+c2n["4"]=57
+c2n["5"]=58
+c2n["6"]=59
+c2n["7"]=60
+c2n["8"]=61
+c2n["9"]=62
+c2n["_"]=63
+}
+/^#/ { next }
+/^[ \t]*(error_table|et)[ \t]+[a-zA-Z][a-zA-Z0-9_]+/ {
+ table_number = 0
+ table_name = $2
+ mod_base = 1000000
+ for(i=1; i<=length(table_name); i++) {
+ table_number=(table_number*char_shift)+c2n[substr(table_name,i,1)]
+ }
+
+ # We start playing *_high, *low games here because the some
+ # awk programs do not have the necessary precision (sigh)
+ tab_base_low = table_number % mod_base
+ if (tab_base_low < 0) {
+ # Work around stupid bug in the ARM libm
+ tab_base_low = tab_base_low + mod_base
+ }
+ tab_base_high = int(table_number / mod_base)
+ tab_base_sign = 1;
+
+ # figure out: table_number_base=table_number*256
+ tab_base_low = tab_base_low * 256
+ tab_base_high = (tab_base_high * 256) + \
+ int(tab_base_low / mod_base)
+ tab_base_low = tab_base_low % mod_base
+ if (tab_base_low < 0) {
+ # Work around stupid bug in the ARM libm
+ tab_base_low = tab_base_low + mod_base
+ }
+
+ if (table_number > 128*256*256) {
+ # figure out: table_number_base -= 256*256*256*256
+ # sub_high, sub_low is 256*256*256*256
+ sub_low = 256*256*256 % mod_base
+ sub_high = int(256*256*256 / mod_base)
+
+ sub_low = sub_low * 256
+ sub_high = (sub_high * 256) + int(sub_low / mod_base)
+ sub_low = sub_low % mod_base
+
+ tab_base_low = sub_low - tab_base_low;
+ tab_base_high = sub_high - tab_base_high;
+ tab_base_sign = -1;
+ if (tab_base_low < 0) {
+ tab_base_low = tab_base_low + mod_base
+ tab_base_high--
+ }
+ }
+ print "/*" > outfile
+ print " * " outfile ":" > outfile
+ print " * This file is automatically generated; please do not edit it." > outfile
+ print " */" > outfile
+
+ print "" > outfile
+ print "static const char * const text[] = {" > outfile
+ table_item_count = 0
+}
+
+/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*$/ {
+ skipone=1
+ next
+}
+
+/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*"[ \t]*$/ {
+ text=""
+ for (i=3; i<=NF; i++) {
+ text = text FS $i
+ }
+ text=substr(text,2,length(text)-1);
+ printf "\t%s,\n", text > outfile
+ table_item_count++
+}
+
+{
+ if (skipone) {
+ printf "\t%s,\n", $0 > outfile
+ table_item_count++
+ }
+ skipone=0
+}
+END {
+
+
+ print " 0" > outfile
+ print "};" > outfile
+ print "" > outfile
+ print "struct error_table {" > outfile
+ print " char const * const * msgs;" > outfile
+ print " long base;" > outfile
+ print " int n_msgs;" > outfile
+ print "};" > outfile
+ print "struct et_list {" > outfile
+ print " struct et_list *next;" > outfile
+ print " const struct error_table * table;" > outfile
+ print "};" > outfile
+ print "extern struct et_list *_et_list;" > outfile
+ print "" > outfile
+ if (tab_base_high == 0) {
+ print "static const struct error_table et = { text, " \
+ sprintf("%dL, %d };", tab_base_sign*tab_base_low, \
+ table_item_count) > outfile
+ } else {
+ print "static const struct error_table et = { text, " \
+ sprintf("%d%06dL, %d };", tab_base_sign*tab_base_high, \
+ tab_base_low, table_item_count) > outfile
+ }
+ print "" > outfile
+ print "static struct et_list link = { 0, 0 };" > outfile
+ print "" > outfile
+ print "void initialize_" table_name "_error_table(void);" > outfile
+ print "" > outfile
+ print "void initialize_" table_name "_error_table(void) {" > outfile
+ print " if (!link.table) {" > outfile
+ print " link.next = _et_list;" > outfile
+ print " link.table = &et;" > outfile
+ print " _et_list = &link;" > outfile
+ print " }" > outfile
+ print "}" > outfile
+
+
+}
diff --git a/e2fslib/et/et_h.awk b/e2fslib/et/et_h.awk
new file mode 100644
index 0000000..8b83a21
--- /dev/null
+++ b/e2fslib/et/et_h.awk
@@ -0,0 +1,159 @@
+BEGIN {
+char_shift=64
+## "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
+c2n["A"]=1
+c2n["B"]=2
+c2n["C"]=3
+c2n["D"]=4
+c2n["E"]=5
+c2n["F"]=6
+c2n["G"]=7
+c2n["H"]=8
+c2n["I"]=9
+c2n["J"]=10
+c2n["K"]=11
+c2n["L"]=12
+c2n["M"]=13
+c2n["N"]=14
+c2n["O"]=15
+c2n["P"]=16
+c2n["Q"]=17
+c2n["R"]=18
+c2n["S"]=19
+c2n["T"]=20
+c2n["U"]=21
+c2n["V"]=22
+c2n["W"]=23
+c2n["X"]=24
+c2n["Y"]=25
+c2n["Z"]=26
+c2n["a"]=27
+c2n["b"]=28
+c2n["c"]=29
+c2n["d"]=30
+c2n["e"]=31
+c2n["f"]=32
+c2n["g"]=33
+c2n["h"]=34
+c2n["i"]=35
+c2n["j"]=36
+c2n["k"]=37
+c2n["l"]=38
+c2n["m"]=39
+c2n["n"]=40
+c2n["o"]=41
+c2n["p"]=42
+c2n["q"]=43
+c2n["r"]=44
+c2n["s"]=45
+c2n["t"]=46
+c2n["u"]=47
+c2n["v"]=48
+c2n["w"]=49
+c2n["x"]=50
+c2n["y"]=51
+c2n["z"]=52
+c2n["0"]=53
+c2n["1"]=54
+c2n["2"]=55
+c2n["3"]=56
+c2n["4"]=57
+c2n["5"]=58
+c2n["6"]=59
+c2n["7"]=60
+c2n["8"]=61
+c2n["9"]=62
+c2n["_"]=63
+}
+/^#/ { next }
+/^[ \t]*(error_table|et)[ \t]+[a-zA-Z][a-zA-Z0-9_]+/ {
+ table_number = 0
+ table_name = $2
+ mod_base = 1000000
+ for(i=1; i<=length(table_name); i++) {
+ table_number=(table_number*char_shift)+c2n[substr(table_name,i,1)]
+ }
+ # We start playing *_high, *low games here because the some
+ # awk programs do not have the necessary precision (sigh)
+ tab_base_low = table_number % mod_base
+ if (tab_base_low < 0) {
+ # Work around stupid bug in the ARM libm
+ tab_base_low = tab_base_low + mod_base
+ }
+ tab_base_high = int(table_number / mod_base)
+ tab_base_sign = 1;
+
+ # figure out: table_number_base=table_number*256
+ tab_base_low = tab_base_low * 256
+ tab_base_high = (tab_base_high * 256) + \
+ int(tab_base_low / mod_base)
+ tab_base_low = tab_base_low % mod_base
+ if (tab_base_low < 0) {
+ # Work around stupid bug in the ARM libm
+ tab_base_low = tab_base_low + mod_base
+ }
+
+ if (table_number > 128*256*256) {
+ # figure out: table_number_base -= 256*256*256*256
+ # sub_high, sub_low is 256*256*256*256
+ sub_low = 256*256*256 % mod_base
+ sub_high = int(256*256*256 / mod_base)
+
+ sub_low = sub_low * 256
+ sub_high = (sub_high * 256) + int(sub_low / mod_base)
+ sub_low = sub_low % mod_base
+
+ tab_base_low = sub_low - tab_base_low;
+ tab_base_high = sub_high - tab_base_high;
+ tab_base_sign = -1;
+ if (tab_base_low < 0) {
+ tab_base_low = tab_base_low + mod_base
+ tab_base_high--
+ }
+ }
+ curr_low = tab_base_low
+ curr_high = tab_base_high
+ curr_sign = tab_base_sign
+ print "/*" > outfile
+ print " * " outfile ":" > outfile
+ print " * This file is automatically generated; please do not edit it." > outfile
+ print " */" > outfile
+ print "" > outfile
+}
+
+/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,/ {
+ tag=substr($2,1,length($2)-1)
+ if (curr_high == 0) {
+ printf "#define %-40s (%dL)\n", tag, \
+ curr_sign*curr_low > outfile
+ } else {
+ printf "#define %-40s (%d%06dL)\n", tag, curr_high*curr_sign, \
+ curr_low > outfile
+ }
+ curr_low += curr_sign;
+ if (curr_low >= mod_base) {
+ curr_low -= mod_base;
+ curr_high++
+ }
+ if (curr_low < 0) {
+ cur_low += mod_base
+ cur_high--
+ }
+}
+
+END {
+ print "extern void initialize_" table_name "_error_table(void);" > outfile
+ if (tab_base_high == 0) {
+ print "#define ERROR_TABLE_BASE_" table_name " (" \
+ sprintf("%d", tab_base_sign*tab_base_low) \
+ "L)" > outfile
+ } else {
+ print "#define ERROR_TABLE_BASE_" table_name " (" \
+ sprintf("%d%06d", tab_base_sign*tab_base_high, \
+ tab_base_low) "L)" > outfile
+ }
+ print "" > outfile
+ print "/* for compatibility with older versions... */" > outfile
+ print "#define init_" table_name "_err_tbl initialize_" table_name "_error_table" > outfile
+ print "#define " table_name "_err_base ERROR_TABLE_BASE_" table_name > outfile
+}
diff --git a/e2fslib/et/et_name.c b/e2fslib/et/et_name.c
new file mode 100644
index 0000000..1888326
--- /dev/null
+++ b/e2fslib/et/et_name.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1987 by MIT Student Information Processing Board
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose is hereby granted, provided that
+ * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. M.I.T. and the
+ * M.I.T. S.I.P.B. make no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+#include "com_err.h"
+#include "error_table.h"
+#include "internal.h"
+
+static const char char_set[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
+
+static char buf[6];
+
+const char * error_table_name(num)
+ errcode_t num;
+{
+ int ch;
+ int i;
+ char *p;
+
+ /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
+ p = buf;
+ num >>= ERRCODE_RANGE;
+ /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
+ num &= 077777777L;
+ /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
+ for (i = 4; i >= 0; i--) {
+ ch = (int)((num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1));
+ if (ch != 0)
+ *p++ = char_set[ch-1];
+ }
+ *p = '\0';
+ return(buf);
+}
diff --git a/e2fslib/et/et_name.o b/e2fslib/et/et_name.o
new file mode 100644
index 0000000..c2510b2
--- /dev/null
+++ b/e2fslib/et/et_name.o
Binary files differ
diff --git a/e2fslib/et/init_et.c b/e2fslib/et/init_et.c
new file mode 100644
index 0000000..bfdb73d
--- /dev/null
+++ b/e2fslib/et/init_et.c
@@ -0,0 +1,63 @@
+/*
+ * $ Header: lib/et/SCCS/s.init_et.c 1.15 99/10/23 01:16:06-00:00 tytso@mit.edu $
+ * $ Source: /usr/src/e2fsprogs/BK/e2fsprogs/lib/et/SCCS/s.init_et.c $
+ * $ Locker: <Not implemented> $
+ *
+ * Copyright 1986, 1987, 1988 by MIT Information Systems and
+ * the MIT Student Information Processing Board.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose is hereby granted, provided that
+ * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. M.I.T. and the
+ * M.I.T. S.I.P.B. make no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "com_err.h"
+#include "error_table.h"
+
+#ifndef __STDC__
+#define const
+#endif
+
+struct foobar {
+ struct et_list etl;
+ struct error_table et;
+};
+
+extern struct et_list * _et_list;
+
+#ifdef __STDC__
+int init_error_table(const char * const *msgs, int base, int count)
+#else
+int init_error_table(msgs, base, count)
+ const char * const * msgs;
+ int base;
+ int count;
+#endif
+{
+ struct foobar * new_et;
+
+ if (!base || !count || !msgs)
+ return 0;
+
+ new_et = (struct foobar *) malloc(sizeof(struct foobar));
+ if (!new_et)
+ return ENOMEM; /* oops */
+ new_et->etl.table = &new_et->et;
+ new_et->et.msgs = msgs;
+ new_et->et.base = base;
+ new_et->et.n_msgs= count;
+
+ new_et->etl.next = _et_list;
+ _et_list = &new_et->etl;
+ return 0;
+}
diff --git a/e2fslib/et/init_et.o b/e2fslib/et/init_et.o
new file mode 100644
index 0000000..9a7698a
--- /dev/null
+++ b/e2fslib/et/init_et.o
Binary files differ
diff --git a/e2fslib/et/internal.h b/e2fslib/et/internal.h
new file mode 100644
index 0000000..30b1921
--- /dev/null
+++ b/e2fslib/et/internal.h
@@ -0,0 +1,30 @@
+/*
+ * internal include file for com_err package
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose is hereby granted, provided that
+ * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. M.I.T. and the
+ * M.I.T. S.I.P.B. make no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+#ifndef __STDC__
+#undef const
+#define const
+#endif
+
+#include <errno.h>
+
+#ifdef NEED_SYS_ERRLIST
+extern char const * const sys_errlist[];
+extern const int sys_nerr;
+#endif
+
+/* AIX and Ultrix have standard conforming header files. */
+#if !defined(ultrix) && !defined(_AIX)
+#ifdef __STDC__
+void perror (const char *);
+#endif
+#endif
diff --git a/e2fslib/et/libcom_err.a b/e2fslib/et/libcom_err.a
new file mode 100644
index 0000000..4c848dc
--- /dev/null
+++ b/e2fslib/et/libcom_err.a
Binary files differ
diff --git a/e2fslib/et/vfprintf.c b/e2fslib/et/vfprintf.c
new file mode 100644
index 0000000..a1dc1e8
--- /dev/null
+++ b/e2fslib/et/vfprintf.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)vfprintf.c 5.2 (Berkeley) 6/27/88";
+#endif /* LIBC_SCCS and not lint */
+
+#if !HAVE_VPRINTF && HAVE_DOPRNT
+#include <stdio.h>
+#include <varargs.h>
+
+int
+vfprintf(iop, fmt, ap)
+ FILE *iop;
+ char *fmt;
+ va_list ap;
+{
+ int len;
+ char localbuf[BUFSIZ];
+
+ if (iop->_flag & _IONBF) {
+ iop->_flag &= ~_IONBF;
+ iop->_ptr = iop->_base = localbuf;
+ len = _doprnt(fmt, ap, iop);
+ (void) fflush(iop);
+ iop->_flag |= _IONBF;
+ iop->_base = NULL;
+ iop->_bufsiz = 0;
+ iop->_cnt = 0;
+ } else
+ len = _doprnt(fmt, ap, iop);
+
+ return (ferror(iop) ? EOF : len);
+}
+#endif /* !HAVE_VPRINTF */
diff --git a/e2fslib/expanddir.c b/e2fslib/expanddir.c
new file mode 100644
index 0000000..112dedc
--- /dev/null
+++ b/e2fslib/expanddir.c
@@ -0,0 +1,132 @@
+/*
+ * expand.c --- expand an ext2fs directory
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+struct expand_dir_struct {
+ int done;
+ int newblocks;
+ errcode_t err;
+};
+
+static int expand_dir_proc(ext2_filsys fs,
+ blk_t *blocknr,
+ e2_blkcnt_t blockcnt,
+ blk_t ref_block,
+ int ref_offset,
+ void *priv_data)
+{
+ struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
+ blk_t new_blk;
+ static blk_t last_blk = 0;
+ char *block;
+ errcode_t retval;
+ int group;
+
+ if (*blocknr) {
+ last_blk = *blocknr;
+ return 0;
+ }
+ retval = ext2fs_new_block(fs, last_blk, 0, &new_blk);
+ if (retval) {
+ es->err = retval;
+ return BLOCK_ABORT;
+ }
+ if (blockcnt > 0) {
+ retval = ext2fs_new_dir_block(fs, 0, 0, &block);
+ if (retval) {
+ es->err = retval;
+ return BLOCK_ABORT;
+ }
+ es->done = 1;
+ retval = ext2fs_write_dir_block(fs, new_blk, block);
+ } else {
+ retval = ext2fs_get_mem(fs->blocksize, (void **) &block);
+ if (retval) {
+ es->err = retval;
+ return BLOCK_ABORT;
+ }
+ memset(block, 0, fs->blocksize);
+ retval = io_channel_write_blk(fs->io, new_blk, 1, block);
+ }
+ if (retval) {
+ es->err = retval;
+ return BLOCK_ABORT;
+ }
+ ext2fs_free_mem((void **) &block);
+ *blocknr = new_blk;
+ ext2fs_mark_block_bitmap(fs->block_map, new_blk);
+ ext2fs_mark_bb_dirty(fs);
+ group = ext2fs_group_of_blk(fs, new_blk);
+ fs->group_desc[group].bg_free_blocks_count--;
+ fs->super->s_free_blocks_count--;
+ ext2fs_mark_super_dirty(fs);
+ es->newblocks++;
+
+ if (es->done)
+ return (BLOCK_CHANGED | BLOCK_ABORT);
+ else
+ return BLOCK_CHANGED;
+}
+
+errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir)
+{
+ errcode_t retval;
+ struct expand_dir_struct es;
+ struct ext2_inode inode;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ if (!(fs->flags & EXT2_FLAG_RW))
+ return EXT2_ET_RO_FILSYS;
+
+ if (!fs->block_map)
+ return EXT2_ET_NO_BLOCK_BITMAP;
+
+ retval = ext2fs_check_directory(fs, dir);
+ if (retval)
+ return retval;
+
+ es.done = 0;
+ es.err = 0;
+ es.newblocks = 0;
+
+ retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
+ 0, expand_dir_proc, &es);
+
+ if (es.err)
+ return es.err;
+ if (!es.done)
+ return EXT2_ET_EXPAND_DIR_ERR;
+
+ /*
+ * Update the size and block count fields in the inode.
+ */
+ retval = ext2fs_read_inode(fs, dir, &inode);
+ if (retval)
+ return retval;
+
+ inode.i_size += fs->blocksize;
+ inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
+
+ retval = ext2fs_write_inode(fs, dir, &inode);
+ if (retval)
+ return retval;
+
+ return 0;
+}
diff --git a/e2fslib/expanddir.o b/e2fslib/expanddir.o
new file mode 100644
index 0000000..5c02110
--- /dev/null
+++ b/e2fslib/expanddir.o
Binary files differ
diff --git a/e2fslib/ext2_err.c b/e2fslib/ext2_err.c
new file mode 100644
index 0000000..a8b5097
--- /dev/null
+++ b/e2fslib/ext2_err.c
@@ -0,0 +1,140 @@
+/*
+ * :
+ * This file is automatically generated; please do not edit it.
+ */
+
+#include <stdlib.h>
+
+static const char * const text[] = {
+ "EXT2FS Library version 1.25",
+ "Wrong magic number for ext2_filsys structure",
+ "Wrong magic number for badblocks_list structure",
+ "Wrong magic number for badblocks_iterate structure",
+ "Wrong magic number for inode_scan structure",
+ "Wrong magic number for io_channel structure",
+ "Wrong magic number for unix io_channel structure",
+ "Wrong magic number for io_manager structure",
+ "Wrong magic number for block_bitmap structure",
+ "Wrong magic number for inode_bitmap structure",
+ "Wrong magic number for generic_bitmap structure",
+ "Wrong magic number for test io_channel structure",
+ "Wrong magic number for directory block list structure",
+ "Wrong magic number for icount structure",
+ "Wrong magic number for Powerquest io_channel structure",
+ "Wrong magic number for ext2 file structure",
+ "Wrong magic number for Ext2 Image Header",
+ "Wrong magic number --- RESERVED_8",
+ "Wrong magic number --- RESERVED_9",
+ "Bad magic number in super-block",
+ "Filesystem revision too high",
+ "Attempt to write to filesystem opened read-only",
+ "Can't read group descriptors",
+ "Can't write group descriptors",
+ "Corrupt group descriptor: bad block for block bitmap",
+ "Corrupt group descriptor: bad block for inode bitmap",
+ "Corrupt group descriptor: bad block for inode table",
+ "Can't write an inode bitmap",
+ "Can't read an inode bitmap",
+ "Can't write an block bitmap",
+ "Can't read an block bitmap",
+ "Can't write an inode table",
+ "Can't read an inode table",
+ "Can't read next inode",
+ "Filesystem has unexpected block size",
+ "EXT2 directory corrupted",
+ "Attempt to read block from filesystem resulted in short read",
+ "Attempt to write block from filesystem resulted in short write",
+ "No free space in the directory",
+ "Inode bitmap not loaded",
+ "Block bitmap not loaded",
+ "Illegal inode number",
+ "Illegal block number",
+ "Internal error in ext2fs_expand_dir",
+ "Not enough space to build proposed filesystem",
+ "Illegal block number passed to ext2fs_mark_block_bitmap",
+ "Illegal block number passed to ext2fs_unmark_block_bitmap",
+ "Illegal block number passed to ext2fs_test_block_bitmap",
+ "Illegal inode number passed to ext2fs_mark_inode_bitmap",
+ "Illegal inode number passed to ext2fs_unmark_inode_bitmap",
+ "Illegal inode number passed to ext2fs_test_inode_bitmap",
+ "Attempt to fudge end of block bitmap past the real end",
+ "Attempt to fudge end of inode bitmap past the real end",
+ "Illegal indirect block found" ,
+ "Illegal doubly indirect block found" ,
+ "Illegal triply indirect block found" ,
+ "Block bitmaps are not the same",
+ "Inode bitmaps are not the same",
+ "Illegal or malformed device name",
+ "A block group is missing an inode table",
+ "The ext2 superblock is corrupt",
+ "Illegal generic bit number passed to ext2fs_mark_generic_bitmap",
+ "Illegal generic bit number passed to ext2fs_unmark_generic_bitmap",
+ "Illegal generic bit number passed to ext2fs_test_generic_bitmap",
+ "Too many symbolic links encountered.",
+ "The callback function will not handle this case",
+ "The inode is from a bad block in the inode table",
+ "Filesystem has unsupported feature(s)",
+ "Filesystem has unsupported read-only feature(s)",
+ "IO Channel failed to seek on read or write",
+ "Memory allocation failed",
+ "Invalid argument passed to ext2 library",
+ "Could not allocate block in ext2 filesystem",
+ "Could not allocate inode in ext2 filesystem",
+ "Ext2 inode is not a directory",
+ "Too many references in table",
+ "File not found by ext2_lookup",
+ "File open read-only",
+ "Ext2 directory block not found",
+ "Ext2 directory already exists",
+ "Unimplemented ext2 library function",
+ "User cancel requested",
+ "Ext2 file too big",
+ "Supplied journal device not a block device",
+ "Journal superblock not found",
+ "Journal must be at least 1024 blocks",
+ "Unsupported journal version",
+ "Error loading external journal",
+ 0
+};
+
+struct error_table {
+ char const * const * msgs;
+ long base;
+ int n_msgs;
+};
+struct et_list {
+ struct et_list *next;
+ const struct error_table * table;
+};
+extern struct et_list *_et_list;
+
+const struct error_table et_ext2_error_table = { text, 2133571328L, 88 };
+
+static struct et_list link = { 0, 0 };
+
+void initialize_ext2_error_table_r(struct et_list **list);
+void initialize_ext2_error_table(void);
+
+void initialize_ext2_error_table(void) {
+ initialize_ext2_error_table_r(&_et_list);
+}
+
+/* For Heimdal compatibility */
+void initialize_ext2_error_table_r(struct et_list **list)
+{
+ struct et_list *et, **end;
+
+ for (end = list, et = *list; et; end = &et->next, et = et->next)
+ if (et->table->msgs == text)
+ return;
+ et = malloc(sizeof(struct et_list));
+ if (et == 0) {
+ if (!link.table)
+ et = &link;
+ else
+ return;
+ }
+ et->table = &et_ext2_error_table;
+ et->next = 0;
+ *end = et;
+}
diff --git a/e2fslib/ext2_err.et b/e2fslib/ext2_err.et
new file mode 100644
index 0000000..d58ba4c
--- /dev/null
+++ b/e2fslib/ext2_err.et
@@ -0,0 +1,276 @@
+#
+# 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 1.25"
+
+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_RESERVED_8,
+ "Wrong magic number --- RESERVED_8"
+
+ec EXT2_ET_MAGIC_RESERVED_9,
+ "Wrong magic number --- RESERVED_9"
+
+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 an block bitmap"
+
+ec EXT2_ET_BLOCK_BITMAP_READ,
+ "Can't read an 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 from 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"
+
+ end
+
diff --git a/e2fslib/ext2_err.et.in b/e2fslib/ext2_err.et.in
new file mode 100644
index 0000000..235f75d
--- /dev/null
+++ b/e2fslib/ext2_err.et.in
@@ -0,0 +1,276 @@
+#
+# 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_RESERVED_8,
+ "Wrong magic number --- RESERVED_8"
+
+ec EXT2_ET_MAGIC_RESERVED_9,
+ "Wrong magic number --- RESERVED_9"
+
+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 an block bitmap"
+
+ec EXT2_ET_BLOCK_BITMAP_READ,
+ "Can't read an 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 from 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"
+
+ end
+
diff --git a/e2fslib/ext2_err.h b/e2fslib/ext2_err.h
new file mode 100644
index 0000000..5ff5afc
--- /dev/null
+++ b/e2fslib/ext2_err.h
@@ -0,0 +1,106 @@
+/*
+ * :
+ * This file is automatically generated; please do not edit it.
+ */
+
+#include <et/com_err.h>
+
+#define EXT2_ET_BASE (2133571328L)
+#define EXT2_ET_MAGIC_EXT2FS_FILSYS (2133571329L)
+#define EXT2_ET_MAGIC_BADBLOCKS_LIST (2133571330L)
+#define EXT2_ET_MAGIC_BADBLOCKS_ITERATE (2133571331L)
+#define EXT2_ET_MAGIC_INODE_SCAN (2133571332L)
+#define EXT2_ET_MAGIC_IO_CHANNEL (2133571333L)
+#define EXT2_ET_MAGIC_UNIX_IO_CHANNEL (2133571334L)
+#define EXT2_ET_MAGIC_IO_MANAGER (2133571335L)
+#define EXT2_ET_MAGIC_BLOCK_BITMAP (2133571336L)
+#define EXT2_ET_MAGIC_INODE_BITMAP (2133571337L)
+#define EXT2_ET_MAGIC_GENERIC_BITMAP (2133571338L)
+#define EXT2_ET_MAGIC_TEST_IO_CHANNEL (2133571339L)
+#define EXT2_ET_MAGIC_DBLIST (2133571340L)
+#define EXT2_ET_MAGIC_ICOUNT (2133571341L)
+#define EXT2_ET_MAGIC_PQ_IO_CHANNEL (2133571342L)
+#define EXT2_ET_MAGIC_EXT2_FILE (2133571343L)
+#define EXT2_ET_MAGIC_E2IMAGE (2133571344L)
+#define EXT2_ET_MAGIC_RESERVED_8 (2133571345L)
+#define EXT2_ET_MAGIC_RESERVED_9 (2133571346L)
+#define EXT2_ET_BAD_MAGIC (2133571347L)
+#define EXT2_ET_REV_TOO_HIGH (2133571348L)
+#define EXT2_ET_RO_FILSYS (2133571349L)
+#define EXT2_ET_GDESC_READ (2133571350L)
+#define EXT2_ET_GDESC_WRITE (2133571351L)
+#define EXT2_ET_GDESC_BAD_BLOCK_MAP (2133571352L)
+#define EXT2_ET_GDESC_BAD_INODE_MAP (2133571353L)
+#define EXT2_ET_GDESC_BAD_INODE_TABLE (2133571354L)
+#define EXT2_ET_INODE_BITMAP_WRITE (2133571355L)
+#define EXT2_ET_INODE_BITMAP_READ (2133571356L)
+#define EXT2_ET_BLOCK_BITMAP_WRITE (2133571357L)
+#define EXT2_ET_BLOCK_BITMAP_READ (2133571358L)
+#define EXT2_ET_INODE_TABLE_WRITE (2133571359L)
+#define EXT2_ET_INODE_TABLE_READ (2133571360L)
+#define EXT2_ET_NEXT_INODE_READ (2133571361L)
+#define EXT2_ET_UNEXPECTED_BLOCK_SIZE (2133571362L)
+#define EXT2_ET_DIR_CORRUPTED (2133571363L)
+#define EXT2_ET_SHORT_READ (2133571364L)
+#define EXT2_ET_SHORT_WRITE (2133571365L)
+#define EXT2_ET_DIR_NO_SPACE (2133571366L)
+#define EXT2_ET_NO_INODE_BITMAP (2133571367L)
+#define EXT2_ET_NO_BLOCK_BITMAP (2133571368L)
+#define EXT2_ET_BAD_INODE_NUM (2133571369L)
+#define EXT2_ET_BAD_BLOCK_NUM (2133571370L)
+#define EXT2_ET_EXPAND_DIR_ERR (2133571371L)
+#define EXT2_ET_TOOSMALL (2133571372L)
+#define EXT2_ET_BAD_BLOCK_MARK (2133571373L)
+#define EXT2_ET_BAD_BLOCK_UNMARK (2133571374L)
+#define EXT2_ET_BAD_BLOCK_TEST (2133571375L)
+#define EXT2_ET_BAD_INODE_MARK (2133571376L)
+#define EXT2_ET_BAD_INODE_UNMARK (2133571377L)
+#define EXT2_ET_BAD_INODE_TEST (2133571378L)
+#define EXT2_ET_FUDGE_BLOCK_BITMAP_END (2133571379L)
+#define EXT2_ET_FUDGE_INODE_BITMAP_END (2133571380L)
+#define EXT2_ET_BAD_IND_BLOCK (2133571381L)
+#define EXT2_ET_BAD_DIND_BLOCK (2133571382L)
+#define EXT2_ET_BAD_TIND_BLOCK (2133571383L)
+#define EXT2_ET_NEQ_BLOCK_BITMAP (2133571384L)
+#define EXT2_ET_NEQ_INODE_BITMAP (2133571385L)
+#define EXT2_ET_BAD_DEVICE_NAME (2133571386L)
+#define EXT2_ET_MISSING_INODE_TABLE (2133571387L)
+#define EXT2_ET_CORRUPT_SUPERBLOCK (2133571388L)
+#define EXT2_ET_BAD_GENERIC_MARK (2133571389L)
+#define EXT2_ET_BAD_GENERIC_UNMARK (2133571390L)
+#define EXT2_ET_BAD_GENERIC_TEST (2133571391L)
+#define EXT2_ET_SYMLINK_LOOP (2133571392L)
+#define EXT2_ET_CALLBACK_NOTHANDLED (2133571393L)
+#define EXT2_ET_BAD_BLOCK_IN_INODE_TABLE (2133571394L)
+#define EXT2_ET_UNSUPP_FEATURE (2133571395L)
+#define EXT2_ET_RO_UNSUPP_FEATURE (2133571396L)
+#define EXT2_ET_LLSEEK_FAILED (2133571397L)
+#define EXT2_ET_NO_MEMORY (2133571398L)
+#define EXT2_ET_INVALID_ARGUMENT (2133571399L)
+#define EXT2_ET_BLOCK_ALLOC_FAIL (2133571400L)
+#define EXT2_ET_INODE_ALLOC_FAIL (2133571401L)
+#define EXT2_ET_NO_DIRECTORY (2133571402L)
+#define EXT2_ET_TOO_MANY_REFS (2133571403L)
+#define EXT2_ET_FILE_NOT_FOUND (2133571404L)
+#define EXT2_ET_FILE_RO (2133571405L)
+#define EXT2_ET_DB_NOT_FOUND (2133571406L)
+#define EXT2_ET_DIR_EXISTS (2133571407L)
+#define EXT2_ET_UNIMPLEMENTED (2133571408L)
+#define EXT2_ET_CANCEL_REQUESTED (2133571409L)
+#define EXT2_ET_FILE_TOO_BIG (2133571410L)
+#define EXT2_ET_JOURNAL_NOT_BLOCK (2133571411L)
+#define EXT2_ET_NO_JOURNAL_SB (2133571412L)
+#define EXT2_ET_JOURNAL_TOO_SMALL (2133571413L)
+#define EXT2_ET_JOURNAL_UNSUPP_VERSION (2133571414L)
+#define EXT2_ET_LOAD_EXT_JOURNAL (2133571415L)
+extern const struct error_table et_ext2_error_table;
+extern void initialize_ext2_error_table(void);
+
+/* For compatibility with Heimdal */
+extern void initialize_ext2_error_table_r(struct et_list **list);
+
+#define ERROR_TABLE_BASE_ext2 (2133571328L)
+
+/* for compatibility with older versions... */
+#define init_ext2_err_tbl initialize_ext2_error_table
+#define ext2_err_base ERROR_TABLE_BASE_ext2
diff --git a/e2fslib/ext2_err.o b/e2fslib/ext2_err.o
new file mode 100644
index 0000000..282d74a
--- /dev/null
+++ b/e2fslib/ext2_err.o
Binary files differ
diff --git a/e2fslib/ext2_ext_attr.h b/e2fslib/ext2_ext_attr.h
new file mode 100644
index 0000000..504f747
--- /dev/null
+++ b/e2fslib/ext2_ext_attr.h
@@ -0,0 +1,58 @@
+/*
+ File: linux/ext2_ext_attr.h
+
+ On-disk format of extended attributes for the ext2 filesystem.
+
+ (C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+/* Magic value in attribute blocks */
+#define EXT2_EXT_ATTR_MAGIC 0xEA010000
+
+/* 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; /* index into table of names (n/i) */
+ __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 */
+ char e_name[0]; /* attribute name */
+};
+
+#define EXT2_EXT_ATTR_PAD_BITS 2
+#define EXT2_EXT_ATTR_PAD (1<<EXT2_EXT_ATTR_PAD_BITS)
+#define EXT2_EXT_ATTR_ROUND (EXT2_EXT_ATTR_PAD-1)
+#define EXT2_EXT_ATTR_LEN(name_len) \
+ (((name_len) + EXT2_EXT_ATTR_ROUND + \
+ sizeof(struct ext2_ext_attr_entry)) & ~EXT2_EXT_ATTR_ROUND)
+#define EXT2_EXT_ATTR_NEXT(entry) \
+ ( (struct ext2_ext_attr_entry *)( \
+ (char *)(entry) + EXT2_EXT_ATTR_LEN((entry)->e_name_len)) )
+#define EXT2_EXT_ATTR_SIZE(size) \
+ (((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND)
+
+#ifdef __KERNEL__
+# ifdef CONFIG_EXT2_FS_EXT_ATTR
+extern int ext2_get_ext_attr(struct inode *, const char *, char *, size_t, int);
+extern int ext2_set_ext_attr(struct inode *, const char *, char *, size_t, int);
+extern void ext2_ext_attr_free_inode(struct inode *inode);
+extern void ext2_ext_attr_put_super(struct super_block *sb);
+extern int ext2_ext_attr_init(void);
+extern void ext2_ext_attr_done(void);
+# else
+# define ext2_get_ext_attr NULL
+# define ext2_set_ext_attr NULL
+# endif
+#endif /* __KERNEL__ */
+
diff --git a/e2fslib/ext2_fs.h b/e2fslib/ext2_fs.h
new file mode 100644
index 0000000..25a9492
--- /dev/null
+++ b/e2fslib/ext2_fs.h
@@ -0,0 +1,624 @@
+/*
+ * 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 <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 inodes numbers
+ */
+#define EXT2_BAD_INO 1 /* Bad blocks inode */
+#define EXT2_ROOT_INO 2 /* Root inode */
+#define EXT2_ACL_IDX_INO 3 /* ACL inode */
+#define EXT2_ACL_DATA_INO 4 /* ACL inode */
+#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */
+#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */
+#define EXT2_RESIZE_INO 7 /* Reserved group descriptors inode */
+#define EXT2_JOURNAL_INO 8 /* Journal inode */
+
+/* First non-reserved inode for old ext2 filesystems */
+#define EXT2_GOOD_OLD_FIRST_INO 11
+
+/*
+ * The second extended file system magic number
+ */
+#define EXT2_SUPER_MAGIC 0xEF53
+
+/*
+ * Maximal count of links to a file
+ */
+#define EXT2_LINK_MAX 32000
+
+/*
+ * Macro-instructions used to manage several block sizes
+ */
+#define EXT2_MIN_BLOCK_SIZE 1024
+#define EXT2_MAX_BLOCK_SIZE 4096
+#define EXT2_MIN_BLOCK_LOG_SIZE 10
+#ifdef __KERNEL__
+# define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize)
+#else
+# define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+#endif
+#define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
+#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+#ifdef __KERNEL__
+# define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits)
+#else
+# define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
+#endif
+#ifdef __KERNEL__
+#define EXT2_ADDR_PER_BLOCK_BITS(s) ((s)->u.ext2_sb.s_addr_per_block_bits)
+#define EXT2_INODE_SIZE(s) ((s)->u.ext2_sb.s_inode_size)
+#define EXT2_FIRST_INO(s) ((s)->u.ext2_sb.s_first_ino)
+#else
+#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
+
+/*
+ * Macro-instructions used to manage fragments
+ */
+#define EXT2_MIN_FRAG_SIZE 1024
+#define EXT2_MAX_FRAG_SIZE 4096
+#define EXT2_MIN_FRAG_LOG_SIZE 10
+#ifdef __KERNEL__
+# define EXT2_FRAG_SIZE(s) ((s)->u.ext2_sb.s_frag_size)
+# define EXT2_FRAGS_PER_BLOCK(s) ((s)->u.ext2_sb.s_frags_per_block)
+#else
+# define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
+#endif
+
+/*
+ * ACL structures
+ */
+struct ext2_acl_header /* Header of Access Control Lists */
+{
+ __u32 aclh_size;
+ __u32 aclh_file_count;
+ __u32 aclh_acle_count;
+ __u32 aclh_first_acle;
+};
+
+struct ext2_acl_entry /* Access Control List Entry */
+{
+ __u32 acle_size;
+ __u16 acle_perms; /* Access permissions */
+ __u16 acle_type; /* Type of entry */
+ __u16 acle_tag; /* User or group identity */
+ __u16 acle_pad1;
+ __u32 acle_next; /* Pointer on next entry for the */
+ /* same inode or on next free entry */
+};
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext2_group_desc
+{
+ __u32 bg_block_bitmap; /* Blocks bitmap block */
+ __u32 bg_inode_bitmap; /* Inodes bitmap block */
+ __u32 bg_inode_table; /* Inodes table block */
+ __u16 bg_free_blocks_count; /* Free blocks count */
+ __u16 bg_free_inodes_count; /* Free inodes count */
+ __u16 bg_used_dirs_count; /* Directories count */
+ __u16 bg_pad;
+ __u32 bg_reserved[3];
+};
+
+/*
+ * Macro-instructions used to manage group descriptors
+ */
+#ifdef __KERNEL__
+# define EXT2_BLOCKS_PER_GROUP(s) ((s)->u.ext2_sb.s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s) ((s)->u.ext2_sb.s_desc_per_block)
+# define EXT2_INODES_PER_GROUP(s) ((s)->u.ext2_sb.s_inodes_per_group)
+# define EXT2_DESC_PER_BLOCK_BITS(s) ((s)->u.ext2_sb.s_desc_per_block_bits)
+#else
+# define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
+# define EXT2_INODES_PER_GROUP(s) ((s)->s_inodes_per_group)
+#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_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
+
+#define EXT2_FL_USER_VISIBLE 0x00005FFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */
+
+/*
+ * ioctl commands
+ */
+#define EXT2_IOC_GETFLAGS _IOR('f', 1, long)
+#define EXT2_IOC_SETFLAGS _IOW('f', 2, long)
+#define EXT2_IOC_GETVERSION _IOR('v', 1, long)
+#define EXT2_IOC_SETVERSION _IOW('v', 2, long)
+
+/*
+ * Structure of an inode on the disk
+ */
+struct ext2_inode {
+ __u16 i_mode; /* File mode */
+ __u16 i_uid; /* Low 16 bits of Owner Uid */
+ __u32 i_size; /* Size in bytes */
+ __u32 i_atime; /* Access time */
+ __u32 i_ctime; /* Creation time */
+ __u32 i_mtime; /* Modification time */
+ __u32 i_dtime; /* Deletion Time */
+ __u16 i_gid; /* Low 16 bits of Group Id */
+ __u16 i_links_count; /* Links count */
+ __u32 i_blocks; /* Blocks count */
+ __u32 i_flags; /* File flags */
+ union {
+ struct {
+ __u32 l_i_reserved1;
+ } linux1;
+ struct {
+ __u32 h_i_translator;
+ } hurd1;
+ struct {
+ __u32 m_i_reserved1;
+ } masix1;
+ } osd1; /* OS dependent 1 */
+ __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+ __u32 i_generation; /* File version (for NFS) */
+ __u32 i_file_acl; /* File ACL */
+ __u32 i_dir_acl; /* Directory ACL */
+ __u32 i_faddr; /* Fragment address */
+ union {
+ struct {
+ __u8 l_i_frag; /* Fragment number */
+ __u8 l_i_fsize; /* Fragment size */
+ __u16 i_pad1;
+ __u16 l_i_uid_high; /* these 2 fields */
+ __u16 l_i_gid_high; /* were reserved2[0] */
+ __u32 l_i_reserved2;
+ } linux2;
+ struct {
+ __u8 h_i_frag; /* Fragment number */
+ __u8 h_i_fsize; /* Fragment size */
+ __u16 h_i_mode_high;
+ __u16 h_i_uid_high;
+ __u16 h_i_gid_high;
+ __u32 h_i_author;
+ } hurd2;
+ struct {
+ __u8 m_i_frag; /* Fragment number */
+ __u8 m_i_fsize; /* Fragment size */
+ __u16 m_pad1;
+ __u32 m_i_reserved2[2];
+ } masix2;
+ } osd2; /* OS dependent 2 */
+};
+
+#define i_size_high i_dir_acl
+
+#if defined(__KERNEL__) || defined(__linux__)
+#define i_reserved1 osd1.linux1.l_i_reserved1
+#define i_frag osd2.linux2.l_i_frag
+#define i_fsize osd2.linux2.l_i_fsize
+#define i_uid_low i_uid
+#define i_gid_low i_gid
+#define i_uid_high osd2.linux2.l_i_uid_high
+#define i_gid_high osd2.linux2.l_i_gid_high
+#define i_reserved2 osd2.linux2.l_i_reserved2
+
+#elif 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
+
+#elif defined(__masix__)
+
+#define i_reserved1 osd1.masix1.m_i_reserved1
+#define i_frag osd2.masix2.m_i_frag
+#define i_fsize osd2.masix2.m_i_fsize
+#define i_reserved2 osd2.masix2.m_i_reserved2
+
+#endif /* defined(__KERNEL) || defined(__linux__) */
+
+/*
+ * File system states
+ */
+#define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */
+#define EXT2_ERROR_FS 0x0002 /* Errors detected */
+
+/*
+ * Mount flags
+ */
+#define EXT2_MOUNT_CHECK 0x0001 /* Do mount-time checks */
+#define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */
+#define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */
+#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */
+#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
+#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
+#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
+#define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */
+
+#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
+#define set_opt(o, opt) o |= EXT2_MOUNT_##opt
+#define test_opt(sb, opt) ((sb)->u.ext2_sb.s_mount_opt & \
+ EXT2_MOUNT_##opt)
+/*
+ * Maximal mount counts between two filesystem checks
+ */
+#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */
+#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */
+
+/*
+ * Behaviour when detecting errors
+ */
+#define EXT2_ERRORS_CONTINUE 1 /* Continue execution */
+#define EXT2_ERRORS_RO 2 /* Remount fs read-only */
+#define EXT2_ERRORS_PANIC 3 /* Panic */
+#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE
+
+/*
+ * Structure of the super block
+ */
+struct ext2_super_block {
+ __u32 s_inodes_count; /* Inodes count */
+ __u32 s_blocks_count; /* Blocks count */
+ __u32 s_r_blocks_count; /* Reserved blocks count */
+ __u32 s_free_blocks_count; /* Free blocks count */
+ __u32 s_free_inodes_count; /* Free inodes count */
+ __u32 s_first_data_block; /* First Data Block */
+ __u32 s_log_block_size; /* Block size */
+ __s32 s_log_frag_size; /* Fragment size */
+ __u32 s_blocks_per_group; /* # Blocks per group */
+ __u32 s_frags_per_group; /* # Fragments per group */
+ __u32 s_inodes_per_group; /* # Inodes per group */
+ __u32 s_mtime; /* Mount time */
+ __u32 s_wtime; /* Write time */
+ __u16 s_mnt_count; /* Mount count */
+ __s16 s_max_mnt_count; /* Maximal mount count */
+ __u16 s_magic; /* Magic signature */
+ __u16 s_state; /* File system state */
+ __u16 s_errors; /* Behaviour when detecting errors */
+ __u16 s_minor_rev_level; /* minor revision level */
+ __u32 s_lastcheck; /* time of last check */
+ __u32 s_checkinterval; /* max. time between checks */
+ __u32 s_creator_os; /* OS */
+ __u32 s_rev_level; /* Revision level */
+ __u16 s_def_resuid; /* Default uid for reserved blocks */
+ __u16 s_def_resgid; /* Default gid for reserved blocks */
+ /*
+ * These fields are for EXT2_DYNAMIC_REV superblocks only.
+ *
+ * Note: the difference between the compatible feature set and
+ * the incompatible feature set is that if there is a bit set
+ * in the incompatible feature set that the kernel doesn't
+ * know about, it should refuse to mount the filesystem.
+ *
+ * e2fsck's requirements are more strict; if it doesn't know
+ * about a feature in either the compatible or incompatible
+ * feature set, it must abort and not try to meddle with
+ * things it doesn't understand...
+ */
+ __u32 s_first_ino; /* First non-reserved inode */
+ __u16 s_inode_size; /* size of inode structure */
+ __u16 s_block_group_nr; /* block group # of this superblock */
+ __u32 s_feature_compat; /* compatible feature set */
+ __u32 s_feature_incompat; /* incompatible feature set */
+ __u32 s_feature_ro_compat; /* readonly-compatible feature set */
+ __u8 s_uuid[16]; /* 128-bit uuid for volume */
+ char s_volume_name[16]; /* volume name */
+ char s_last_mounted[64]; /* directory where last mounted */
+ __u32 s_algorithm_usage_bitmap; /* For compression */
+ /*
+ * Performance hints. Directory preallocation should only
+ * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
+ */
+ __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
+ __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
+ __u16 s_padding1;
+ /*
+ * 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_reserved[197]; /* Padding to the end of the block */
+};
+
+#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
+
+/*
+ * Codes for operating systems
+ */
+#define EXT2_OS_LINUX 0
+#define EXT2_OS_HURD 1
+#define EXT2_OS_MASIX 2
+#define EXT2_OS_FREEBSD 3
+#define EXT2_OS_LITES 4
+
+/*
+ * Revision levels
+ */
+#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
+#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
+
+#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
+#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
+
+#define EXT2_GOOD_OLD_INODE_SIZE 128
+
+/*
+ * Feature set definitions
+ */
+
+#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \
+ ( EXT2_SB(sb)->s_feature_compat & (mask) )
+#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \
+ ( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \
+ ( EXT2_SB(sb)->s_feature_incompat & (mask) )
+
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001
+#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
+#define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008
+#define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010
+#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020
+
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
+
+#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_COMPAT_SUPP 0
+#define EXT2_FEATURE_INCOMPAT_SUPP EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+ EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+
+/*
+ * Default values for user and/or group using reserved blocks
+ */
+#define EXT2_DEF_RESUID 0
+#define EXT2_DEF_RESGID 0
+
+/*
+ * 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)
+
+#ifdef __KERNEL__
+/*
+ * Function prototypes
+ */
+
+/*
+ * Ok, these declarations are also in <linux/kernel.h> but none of the
+ * ext2 source programs needs to include it so they are duplicated here.
+ */
+# define NORET_TYPE /**/
+# define ATTRIB_NORET __attribute__((noreturn))
+# define NORET_AND noreturn,
+
+/* acl.c */
+extern int ext2_permission (struct inode *, int);
+
+/* balloc.c */
+extern int ext2_bg_has_super(struct super_block *sb, int group);
+extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
+extern int ext2_new_block (const struct inode *, unsigned long,
+ __u32 *, __u32 *, int *);
+extern void ext2_free_blocks (const struct inode *, unsigned long,
+ unsigned long);
+extern unsigned long ext2_count_free_blocks (struct super_block *);
+extern void ext2_check_blocks_bitmap (struct super_block *);
+extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
+ unsigned int block_group,
+ struct buffer_head ** bh);
+
+/* bitmap.c */
+extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
+
+/* dir.c */
+extern int ext2_check_dir_entry (const char *, struct inode *,
+ struct ext2_dir_entry_2 *, struct buffer_head *,
+ unsigned long);
+
+/* file.c */
+extern int ext2_read (struct inode *, struct file *, char *, int);
+extern int ext2_write (struct inode *, struct file *, char *, int);
+
+/* fsync.c */
+extern int ext2_sync_file (struct file *, struct dentry *, int);
+extern int ext2_fsync_inode (struct inode *, int);
+
+/* ialloc.c */
+extern struct inode * ext2_new_inode (const struct inode *, int);
+extern void ext2_free_inode (struct inode *);
+extern unsigned long ext2_count_free_inodes (struct super_block *);
+extern void ext2_check_inodes_bitmap (struct super_block *);
+
+/* inode.c */
+
+extern struct buffer_head * ext2_getblk (struct inode *, long, int, int *);
+extern struct buffer_head * ext2_bread (struct inode *, int, int, int *);
+
+extern void ext2_read_inode (struct inode *);
+extern void ext2_write_inode (struct inode *, int);
+extern void ext2_put_inode (struct inode *);
+extern void ext2_delete_inode (struct inode *);
+extern int ext2_sync_inode (struct inode *);
+extern void ext2_discard_prealloc (struct inode *);
+
+/* ioctl.c */
+extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
+ unsigned long);
+
+/* namei.c */
+extern struct inode_operations ext2_dir_inode_operations;
+
+/* super.c */
+extern void ext2_error (struct super_block *, const char *, const char *, ...)
+ __attribute__ ((format (printf, 3, 4)));
+extern NORET_TYPE void ext2_panic (struct super_block *, const char *,
+ const char *, ...)
+ __attribute__ ((NORET_AND format (printf, 3, 4)));
+extern void ext2_warning (struct super_block *, const char *, const char *, ...)
+ __attribute__ ((format (printf, 3, 4)));
+extern void ext2_update_dynamic_rev (struct super_block *sb);
+extern void ext2_put_super (struct super_block *);
+extern void ext2_write_super (struct super_block *);
+extern int ext2_remount (struct super_block *, int *, char *);
+extern struct super_block * ext2_read_super (struct super_block *,void *,int);
+extern int ext2_statfs (struct super_block *, struct statfs *);
+
+/* truncate.c */
+extern void ext2_truncate (struct inode *);
+
+/*
+ * Inodes and files operations
+ */
+
+/* dir.c */
+extern struct file_operations ext2_dir_operations;
+
+/* file.c */
+extern struct inode_operations ext2_file_inode_operations;
+extern struct file_operations ext2_file_operations;
+
+/* symlink.c */
+extern struct inode_operations ext2_fast_symlink_inode_operations;
+
+extern struct address_space_operations ext2_aops;
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_EXT2_FS_H */
diff --git a/e2fslib/ext2_io.h b/e2fslib/ext2_io.h
new file mode 100644
index 0000000..b9ba0b6
--- /dev/null
+++ b/e2fslib/ext2_io.h
@@ -0,0 +1,100 @@
+/*
+ * io.h --- the I/O manager abstraction
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#ifndef _EXT2FS_EXT2_IO_H
+#define _EXT2FS_EXT2_IO_H
+
+/*
+ * ext2_loff_t is defined here since unix_io.c needs it.
+ */
+#if defined(__GNUC__) || defined(HAS_LONG_LONG)
+typedef long long ext2_loff_t;
+#else
+typedef long ext2_loff_t;
+#endif
+
+/* llseek.c */
+ext2_loff_t ext2fs_llseek (int, ext2_loff_t, int);
+
+typedef struct struct_io_manager *io_manager;
+typedef struct struct_io_channel *io_channel;
+
+#define CHANNEL_FLAGS_WRITETHROUGH 0x01
+
+struct struct_io_channel {
+ errcode_t magic;
+ io_manager manager;
+ char *name;
+ int block_size;
+ errcode_t (*read_error)(io_channel channel,
+ unsigned long block,
+ int count,
+ void *data,
+ size_t size,
+ int actual_bytes_read,
+ errcode_t error);
+ errcode_t (*write_error)(io_channel channel,
+ unsigned long block,
+ int count,
+ const void *data,
+ size_t size,
+ int actual_bytes_written,
+ errcode_t error);
+ int refcount;
+ int flags;
+ int reserved[14];
+ void *private_data;
+ void *app_data;
+};
+
+struct struct_io_manager {
+ errcode_t magic;
+ const char *name;
+ errcode_t (*open)(const char *name, int flags, io_channel *channel);
+ errcode_t (*close)(io_channel channel);
+ errcode_t (*set_blksize)(io_channel channel, int blksize);
+ errcode_t (*read_blk)(io_channel channel, unsigned long block,
+ int count, void *data);
+ errcode_t (*write_blk)(io_channel channel, unsigned long block,
+ int count, const void *data);
+ errcode_t (*flush)(io_channel channel);
+ errcode_t (*write_byte)(io_channel channel, unsigned long offset,
+ int count, const void *data);
+ int reserved[15];
+};
+
+#define IO_FLAG_RW 1
+
+/*
+ * Convenience functions....
+ */
+#define io_channel_close(c) ((c)->manager->close((c)))
+#define io_channel_set_blksize(c,s) ((c)->manager->set_blksize((c),s))
+#define io_channel_read_blk(c,b,n,d) ((c)->manager->read_blk((c),b,n,d))
+#define io_channel_write_blk(c,b,n,d) ((c)->manager->write_blk((c),b,n,d))
+#define io_channel_flush(c) ((c)->manager->flush((c)))
+#define io_channel_write_byte(c,b,n,d) ((c)->manager->write_byte((c),b,n,d))
+#define io_channel_bumpcount(c) ((c)->refcount++)
+
+/* unix_io.c */
+extern io_manager unix_io_manager;
+
+/* test_io.c */
+extern io_manager test_io_manager, test_io_backing_manager;
+extern void (*test_io_cb_read_blk)
+ (unsigned long block, int count, errcode_t err);
+extern void (*test_io_cb_write_blk)
+ (unsigned long block, int count, errcode_t err);
+extern void (*test_io_cb_set_blksize)
+ (int blksize, errcode_t err);
+
+#endif /* _EXT2FS_EXT2_IO_H */
+
diff --git a/e2fslib/ext2_types.h b/e2fslib/ext2_types.h
new file mode 100644
index 0000000..eff4a6b
--- /dev/null
+++ b/e2fslib/ext2_types.h
@@ -0,0 +1,53 @@
+#ifndef _EXT2_TYPES_H
+#define _EXT2_TYPES_H
+
+/*
+ * If linux/types.h is already been included, assume it has defined
+ * everything we need. (cross fingers)
+ */
+#ifndef _LINUX_TYPES_H
+
+typedef unsigned char __u8;
+typedef signed char __s8;
+
+#if (4 == 8)
+typedef int __s64;
+typedef unsigned int __u64;
+#elif (4 == 8)
+typedef long __s64;
+typedef unsigned long __u64;
+#elif (8 == 8)
+#if defined(__GNUC__)
+typedef __signed__ long long __s64;
+#else
+typedef signed long long __s64;
+#endif
+typedef unsigned long long __u64;
+#endif
+
+#if (4 == 2)
+typedef int __s16;
+typedef unsigned int __u16;
+#elif (2 == 2)
+typedef short __s16;
+typedef unsigned short __u16;
+#else
+ ?==error: undefined 16 bit type
+#endif
+
+#if (4 == 4)
+typedef int __s32;
+typedef unsigned int __u32;
+#elif (4 == 4)
+typedef long __s32;
+typedef unsigned long __u32;
+#elif (2 == 4)
+typedef short __s32;
+typedef unsigned short __u32;
+#else
+ ?== error: undefined 32 bit type
+#endif
+
+#endif /* LINUX_TYPES_H */
+
+#endif /* EXT2_TYPES_H */
diff --git a/e2fslib/ext2_types.h.in b/e2fslib/ext2_types.h.in
new file mode 100644
index 0000000..38f588f
--- /dev/null
+++ b/e2fslib/ext2_types.h.in
@@ -0,0 +1,53 @@
+#ifndef _EXT2_TYPES_H
+#define _EXT2_TYPES_H
+
+/*
+ * If linux/types.h is already been included, assume it has defined
+ * everything we need. (cross fingers)
+ */
+#ifndef _LINUX_TYPES_H
+
+typedef unsigned char __u8;
+typedef signed char __s8;
+
+#if (@SIZEOF_INT@ == 8)
+typedef int __s64;
+typedef unsigned int __u64;
+#elif (@SIZEOF_LONG@ == 8)
+typedef long __s64;
+typedef unsigned long __u64;
+#elif (@SIZEOF_LONG_LONG@ == 8)
+#if defined(__GNUC__)
+typedef __signed__ long long __s64;
+#else
+typedef signed long long __s64;
+#endif
+typedef unsigned long long __u64;
+#endif
+
+#if (@SIZEOF_INT@ == 2)
+typedef int __s16;
+typedef unsigned int __u16;
+#elif (@SIZEOF_SHORT@ == 2)
+typedef short __s16;
+typedef unsigned short __u16;
+#else
+ ?==error: undefined 16 bit type
+#endif
+
+#if (@SIZEOF_INT@ == 4)
+typedef int __s32;
+typedef unsigned int __u32;
+#elif (@SIZEOF_LONG@ == 4)
+typedef long __s32;
+typedef unsigned long __u32;
+#elif (@SIZEOF_SHORT@ == 4)
+typedef short __s32;
+typedef unsigned short __u32;
+#else
+ ?== error: undefined 32 bit type
+#endif
+
+#endif /* LINUX_TYPES_H */
+
+#endif /* EXT2_TYPES_H */
diff --git a/e2fslib/ext2fs.h b/e2fslib/ext2fs.h
new file mode 100644
index 0000000..bb3ae26
--- /dev/null
+++ b/e2fslib/ext2fs.h
@@ -0,0 +1,976 @@
+/*
+ * ext2fs.h --- ext2fs
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#ifndef _EXT2FS_EXT2FS_H
+#define _EXT2FS_EXT2FS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Non-GNU C compilers won't necessarily understand inline
+ */
+#if (!defined(__GNUC__) && !defined(__WATCOMC__))
+#define NO_INLINE_FUNCS
+#endif
+
+/*
+ * Build in support for byte-swapping filesystems if we the feature
+ * has been configured or if we're being built on a CPU architecture
+ * with a non-native byte order.
+ */
+#if defined(ENABLE_SWAPFS) || defined(WORDS_BIGENDIAN)
+#define EXT2FS_ENABLE_SWAPFS
+#endif
+
+/*
+ * Where the master copy of the superblock is located, and how big
+ * superblocks are supposed to be. We define SUPERBLOCK_SIZE because
+ * the size of the superblock structure is not necessarily trustworthy
+ * (some versions have the padding set up so that the superblock is
+ * 1032 bytes long).
+ */
+#define SUPERBLOCK_OFFSET 1024
+#define SUPERBLOCK_SIZE 1024
+
+/*
+ * The last ext2fs revision level that this version of the library is
+ * able to support.
+ */
+#define EXT2_LIB_CURRENT_REV EXT2_DYNAMIC_REV
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <stdlib.h>
+
+#if EXT2_FLAT_INCLUDES
+#include "e2_types.h"
+#else
+#include <ext2_types.h>
+#endif /* EXT2_FLAT_INCLUDES */
+
+typedef __u32 ext2_ino_t;
+typedef __u32 blk_t;
+typedef __u32 dgrp_t;
+typedef __u32 ext2_off_t;
+typedef __s64 e2_blkcnt_t;
+
+#if EXT2_FLAT_INCLUDES
+#include "com_err.h"
+#include "ext2_io.h"
+#include "ext2_err.h"
+#else
+#include <et/com_err.h>
+#include <ext2_io.h>
+#include <ext2_err.h>
+#endif
+
+/*
+ * Portability help for Microsoft Visual C++
+ */
+#ifdef _MSC_VER
+#define EXT2_QSORT_TYPE int __cdecl
+#else
+#define EXT2_QSORT_TYPE int
+#endif
+
+typedef struct struct_ext2_filsys *ext2_filsys;
+
+struct ext2fs_struct_generic_bitmap {
+ errcode_t magic;
+ ext2_filsys fs;
+ __u32 start, end;
+ __u32 real_end;
+ char * description;
+ char * bitmap;
+ errcode_t base_error_code;
+ __u32 reserved[7];
+};
+
+#define EXT2FS_MARK_ERROR 0
+#define EXT2FS_UNMARK_ERROR 1
+#define EXT2FS_TEST_ERROR 2
+
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
+
+#ifdef EXT2_DYNAMIC_REV
+#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s)
+#else
+#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO
+#define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
+#endif
+
+/*
+ * badblocks list definitions
+ */
+
+typedef struct ext2_struct_badblocks_list *ext2_badblocks_list;
+typedef struct ext2_struct_badblocks_iterate *ext2_badblocks_iterate;
+
+/* old */
+typedef struct ext2_struct_badblocks_list *badblocks_list;
+typedef struct ext2_struct_badblocks_iterate *badblocks_iterate;
+
+#define BADBLOCKS_FLAG_DIRTY 1
+
+/*
+ * ext2_dblist structure and abstractions (see dblist.c)
+ */
+struct ext2_db_entry {
+ ext2_ino_t ino;
+ blk_t blk;
+ int blockcnt;
+};
+
+typedef struct ext2_struct_dblist *ext2_dblist;
+
+#define DBLIST_ABORT 1
+
+/*
+ * ext2_fileio definitions
+ */
+
+#define EXT2_FILE_WRITE 0x0001
+#define EXT2_FILE_CREATE 0x0002
+
+#define EXT2_FILE_MASK 0x00FF
+
+#define EXT2_FILE_BUF_DIRTY 0x4000
+#define EXT2_FILE_BUF_VALID 0x2000
+
+typedef struct ext2_file *ext2_file_t;
+
+#define EXT2_SEEK_SET 0
+#define EXT2_SEEK_CUR 1
+#define EXT2_SEEK_END 2
+
+/*
+ * Flags for the ext2_filsys structure and for ext2fs_open()
+ */
+#define EXT2_FLAG_RW 0x01
+#define EXT2_FLAG_CHANGED 0x02
+#define EXT2_FLAG_DIRTY 0x04
+#define EXT2_FLAG_VALID 0x08
+#define EXT2_FLAG_IB_DIRTY 0x10
+#define EXT2_FLAG_BB_DIRTY 0x20
+#define EXT2_FLAG_SWAP_BYTES 0x40
+#define EXT2_FLAG_SWAP_BYTES_READ 0x80
+#define EXT2_FLAG_SWAP_BYTES_WRITE 0x100
+#define EXT2_FLAG_MASTER_SB_ONLY 0x200
+#define EXT2_FLAG_FORCE 0x400
+#define EXT2_FLAG_SUPER_ONLY 0x800
+#define EXT2_FLAG_JOURNAL_DEV_OK 0x1000
+#define EXT2_FLAG_IMAGE_FILE 0x2000
+
+/*
+ * Special flag in the ext2 inode i_flag field that means that this is
+ * a new inode. (So that ext2_write_inode() can clear extra fields.)
+ */
+#define EXT2_NEW_INODE_FL 0x80000000
+
+/*
+ * Flags for mkjournal
+ *
+ * EXT2_MKJOURNAL_V1_SUPER Make a (deprecated) V1 journal superblock
+ */
+#define EXT2_MKJOURNAL_V1_SUPER 0x0000001
+
+struct struct_ext2_filsys {
+ errcode_t magic;
+ io_channel io;
+ int flags;
+ char * device_name;
+ struct ext2_super_block * super;
+ int blocksize;
+ int fragsize;
+ dgrp_t group_desc_count;
+ unsigned long desc_blocks;
+ struct ext2_group_desc * group_desc;
+ int inode_blocks_per_group;
+ ext2fs_inode_bitmap inode_map;
+ ext2fs_block_bitmap block_map;
+ errcode_t (*get_blocks)(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
+ errcode_t (*check_directory)(ext2_filsys fs, ext2_ino_t ino);
+ errcode_t (*write_bitmaps)(ext2_filsys fs);
+ errcode_t (*read_inode)(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode);
+ errcode_t (*write_inode)(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode);
+ badblocks_list badblocks;
+ ext2_dblist dblist;
+ __u32 stride; /* for mke2fs */
+ struct ext2_super_block * orig_super;
+ struct ext2_image_hdr * image_header;
+ /*
+ * Reserved for future expansion
+ */
+ __u32 reserved[9];
+
+ /*
+ * Reserved for the use of the calling application.
+ */
+ void * priv_data;
+
+ /*
+ * Inode cache
+ */
+ struct ext2_inode_cache *icache;
+};
+
+#if EXT2_FLAT_INCLUDES
+#include "e2_bitops.h"
+#else
+#include <bitops.h>
+#endif
+
+/*
+ * Return flags for the block iterator functions
+ */
+#define BLOCK_CHANGED 1
+#define BLOCK_ABORT 2
+#define BLOCK_ERROR 4
+
+/*
+ * Block interate flags
+ *
+ * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
+ * function should be called on blocks where the block number is zero.
+ * This is used by ext2fs_expand_dir() to be able to add a new block
+ * to an inode. It can also be used for programs that want to be able
+ * to deal with files that contain "holes".
+ *
+ * BLOCK_FLAG_TRAVERSE indicates that the iterator function for the
+ * indirect, doubly indirect, etc. blocks should be called after all
+ * of the blocks containined in the indirect blocks are processed.
+ * This is useful if you are going to be deallocating blocks from an
+ * inode.
+ *
+ * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
+ * called for data blocks only.
+ *
+ * BLOCK_FLAG_NO_LARGE is for internal use only. It informs
+ * ext2fs_block_iterate2 that large files won't be accepted.
+ */
+#define BLOCK_FLAG_APPEND 1
+#define BLOCK_FLAG_HOLE 1
+#define BLOCK_FLAG_DEPTH_TRAVERSE 2
+#define BLOCK_FLAG_DATA_ONLY 4
+
+#define BLOCK_FLAG_NO_LARGE 0x1000
+
+/*
+ * Magic "block count" return values for the block iterator function.
+ */
+#define BLOCK_COUNT_IND (-1)
+#define BLOCK_COUNT_DIND (-2)
+#define BLOCK_COUNT_TIND (-3)
+#define BLOCK_COUNT_TRANSLATOR (-4)
+
+#if 0
+/*
+ * Flags for ext2fs_move_blocks
+ */
+#define EXT2_BMOVE_GET_DBLIST 0x0001
+#define EXT2_BMOVE_DEBUG 0x0002
+#endif
+
+/*
+ * 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_DOT_FILE 1
+#define DIRENT_DOT_DOT_FILE 2
+#define DIRENT_OTHER_FILE 3
+
+/*
+ * Inode scan definitions
+ */
+typedef struct ext2_struct_inode_scan *ext2_inode_scan;
+
+/*
+ * ext2fs_scan flags
+ */
+#define EXT2_SF_CHK_BADBLOCKS 0x0001
+#define EXT2_SF_BAD_INODE_BLK 0x0002
+#define EXT2_SF_BAD_EXTRA_BYTES 0x0004
+#define EXT2_SF_SKIP_MISSING_ITABLE 0x0008
+
+/*
+ * ext2fs_check_if_mounted flags
+ */
+#define EXT2_MF_MOUNTED 1
+#define EXT2_MF_ISROOT 2
+#define EXT2_MF_READONLY 4
+
+/*
+ * 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_icount_t abstraction
+ */
+#define EXT2_ICOUNT_OPT_INCREMENT 0x01
+
+typedef struct ext2_icount *ext2_icount_t;
+
+/*
+ * Flags for ext2fs_bmap
+ */
+#define BMAP_ALLOC 1
+
+/*
+ * Flags for imager.c functions
+ */
+#define IMAGER_FLAG_INODEMAP 1
+#define IMAGER_FLAG_SPARSEWRITE 2
+
+/*
+ * For checking structure magic numbers...
+ */
+
+#define EXT2_CHECK_MAGIC(struct, code) \
+ if ((struct)->magic != (code)) return (code)
+
+
+/*
+ * For ext2 compression support
+ */
+#define EXT2FS_COMPRESSED_BLKADDR ((blk_t) 0xffffffff)
+#define HOLE_BLKADDR(_b) ((_b) == 0 || (_b) == EXT2FS_COMPRESSED_BLKADDR)
+
+/*
+ * Features supported by this version of the library
+ */
+#define EXT2_LIB_FEATURE_COMPAT_SUPP (EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
+ EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
+ EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
+ EXT2_FEATURE_COMPAT_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|\
+ EXT3_FEATURE_INCOMPAT_RECOVER)
+#else
+#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
+ EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
+ EXT3_FEATURE_INCOMPAT_RECOVER)
+#endif
+#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
+/*
+ * function prototypes
+ */
+
+/* alloc.c */
+extern errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, int mode,
+ ext2fs_inode_bitmap map, ext2_ino_t *ret);
+extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
+ ext2fs_block_bitmap map, blk_t *ret);
+extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
+ blk_t finish, int num,
+ ext2fs_block_bitmap map,
+ blk_t *ret);
+extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
+ char *block_buf, blk_t *ret);
+
+/* alloc_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_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 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);
+
+/* bb_compat */
+extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
+extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
+extern int badblocks_list_test(badblocks_list bb, blk_t blk);
+extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
+ badblocks_iterate *ret);
+extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
+extern void badblocks_list_iterate_end(badblocks_iterate iter);
+extern void badblocks_list_free(badblocks_list bb);
+
+/* bb_inode.c */
+extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
+ ext2_badblocks_list bb_list);
+
+/* bitmaps.c */
+extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
+extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
+extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+ __u32 end,
+ __u32 real_end,
+ const char *descr,
+ ext2fs_generic_bitmap *ret);
+extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
+ const char *descr,
+ ext2fs_block_bitmap *ret);
+extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
+ const char *descr,
+ ext2fs_inode_bitmap *ret);
+extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
+ ext2_ino_t end, ext2_ino_t *oend);
+extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
+ blk_t end, blk_t *oend);
+extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
+extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
+extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
+extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
+
+/* block.c */
+extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
+ ext2_ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_filsys fs,
+ blk_t *blocknr,
+ int blockcnt,
+ void *priv_data),
+ void *priv_data);
+errcode_t ext2fs_block_iterate2(ext2_filsys fs,
+ ext2_ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_filsys fs,
+ blk_t *blocknr,
+ e2_blkcnt_t blockcnt,
+ blk_t ref_blk,
+ int ref_offset,
+ void *priv_data),
+ void *priv_data);
+
+/* bmap.c */
+extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode *inode,
+ char *block_buf, int bmap_flags,
+ blk_t block, blk_t *phys_blk);
+
+
+#if 0
+/* bmove.c */
+extern errcode_t ext2fs_move_blocks(ext2_filsys fs,
+ ext2fs_block_bitmap reserve,
+ ext2fs_block_bitmap alloc_map,
+ int flags);
+#endif
+
+/* check_desc.c */
+extern errcode_t ext2fs_check_desc(ext2_filsys fs);
+
+/* closefs.c */
+extern errcode_t ext2fs_close(ext2_filsys fs);
+extern errcode_t ext2fs_flush(ext2_filsys fs);
+extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block);
+extern void ext2fs_update_dynamic_rev(ext2_filsys fs);
+
+/* cmp_bitmaps.c */
+extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
+ ext2fs_block_bitmap bm2);
+extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
+ ext2fs_inode_bitmap bm2);
+
+/* dblist.c */
+
+extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
+extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
+extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino,
+ blk_t blk, int blockcnt);
+extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
+ int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info,
+ void *priv_data),
+ void *priv_data);
+extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino,
+ blk_t blk, int blockcnt);
+extern errcode_t ext2fs_copy_dblist(ext2_dblist src,
+ ext2_dblist *dest);
+extern int ext2fs_dblist_count(ext2_dblist dblist);
+
+/* dblist_dir.c */
+extern errcode_t
+ ext2fs_dblist_dir_iterate(ext2_dblist dblist,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_ino_t dir,
+ int entry,
+ struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data);
+
+/* dirblock.c */
+extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
+ void *buf);
+extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
+ void *buf);
+
+/* dir_iterate.c */
+extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
+ ext2_ino_t dir,
+ int flags,
+ char *block_buf,
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data);
+
+/* 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 */
+void ext2fs_swap_ext_attr(ext2_filsys fs, char *to, char *from);
+extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
+extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *buf);
+/* fileio.c */
+extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
+ int flags, ext2_file_t *ret);
+extern ext2_filsys ext2fs_file_get_fs(ext2_file_t file);
+extern errcode_t ext2fs_file_close(ext2_file_t file);
+extern errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
+ unsigned int wanted, unsigned int *got);
+extern errcode_t ext2fs_file_write(ext2_file_t file, void *buf,
+ unsigned int nbytes, unsigned int *written);
+extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
+ int whence, ext2_off_t *ret_pos);
+extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
+extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
+
+/* finddev.c */
+extern char *ext2fs_find_block_device(dev_t device);
+
+/* flushb.c */
+extern errcode_t ext2fs_sync_device(int fd, int flushb);
+
+/* freefs.c */
+extern void ext2fs_free(ext2_filsys fs);
+extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
+extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
+extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
+extern void ext2fs_free_dblist(ext2_dblist dblist);
+extern void ext2fs_badblocks_list_free(badblocks_list bb);
+
+/* getsize.c */
+extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
+ blk_t *retblocks);
+
+/* 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);
+
+/* initialize.c */
+extern errcode_t ext2fs_initialize(const char *name, int flags,
+ struct ext2_super_block *param,
+ io_manager manager, ext2_filsys *ret_fs);
+
+/* inode.c */
+extern errcode_t ext2fs_flush_icache(ext2_filsys fs);
+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 (ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode * inode);
+extern errcode_t ext2fs_write_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);
+
+/* icount.c */
+extern void ext2fs_free_icount(ext2_icount_t icount);
+extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, int size,
+ ext2_icount_t hint, ext2_icount_t *ret);
+extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, 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 *);
+
+/* ismounted.c */
+extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
+extern errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
+ char *mtpt, int mtlen);
+
+/* namei.c */
+extern errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
+ int namelen, char *buf, ext2_ino_t *inode);
+extern errcode_t ext2fs_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
+ const char *name, ext2_ino_t *inode);
+errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
+ const char *name, ext2_ino_t *inode);
+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
+ ext2_ino_t inode, ext2_ino_t *res_inode);
+
+/* native.c */
+int ext2fs_native_flag(void);
+
+/* newdir.c */
+extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
+ ext2_ino_t parent_ino, char **block);
+
+/* mkdir.c */
+extern errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
+ const char *name);
+
+/* mkjournal.c */
+extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
+ __u32 size, int flags,
+ char **ret_jsb);
+extern errcode_t ext2fs_add_journal_device(ext2_filsys fs,
+ ext2_filsys journal_dev);
+extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size,
+ int flags);
+
+/* openfs.c */
+extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
+ int block_size, io_manager manager,
+ ext2_filsys *ret_fs);
+
+/* get_pathname.c */
+extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
+ char **name);
+
+/* link.c */
+errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
+ ext2_ino_t ino, int flags);
+errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
+ ext2_ino_t ino, int flags);
+
+/* read_bb.c */
+extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
+ ext2_badblocks_list *bb_list);
+
+/* read_bb_file.c */
+extern errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f,
+ ext2_badblocks_list *bb_list,
+ void *private,
+ void (*invalid)(ext2_filsys fs,
+ blk_t blk,
+ char *badstr,
+ void *private));
+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));
+
+/* rs_bitmap.c */
+extern errcode_t ext2fs_resize_generic_bitmap(__u32 new_end,
+ __u32 new_real_end,
+ ext2fs_generic_bitmap bmap);
+extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
+ ext2fs_inode_bitmap bmap);
+extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
+ ext2fs_block_bitmap bmap);
+extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
+ ext2fs_generic_bitmap *dest);
+
+/* swapfs.c */
+extern void ext2fs_swap_super(struct ext2_super_block * super);
+extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
+extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
+ struct ext2_inode *f, int hostorder);
+
+/* valid_blk.c */
+extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
+
+/* version.c */
+extern int ext2fs_parse_version_string(const char *ver_string);
+extern int ext2fs_get_library_version(const char **ver_string,
+ const char **date_string);
+
+/* write_bb_file.c */
+extern errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
+ unsigned int flags,
+ FILE *f);
+
+
+/* inline functions */
+extern errcode_t ext2fs_get_mem(unsigned long size, void **ptr);
+extern errcode_t ext2fs_free_mem(void **ptr);
+extern errcode_t ext2fs_resize_mem(unsigned long old_size,
+ unsigned long size, void **ptr);
+extern void ext2fs_mark_super_dirty(ext2_filsys fs);
+extern void ext2fs_mark_changed(ext2_filsys fs);
+extern int ext2fs_test_changed(ext2_filsys fs);
+extern void ext2fs_mark_valid(ext2_filsys fs);
+extern void ext2fs_unmark_valid(ext2_filsys fs);
+extern int ext2fs_test_valid(ext2_filsys fs);
+extern void ext2fs_mark_ib_dirty(ext2_filsys fs);
+extern void ext2fs_mark_bb_dirty(ext2_filsys fs);
+extern int ext2fs_test_ib_dirty(ext2_filsys fs);
+extern int ext2fs_test_bb_dirty(ext2_filsys fs);
+extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
+extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino);
+
+/*
+ * The actual inlined functions definitions themselves...
+ *
+ * If NO_INLINE_FUNCS is defined, then we won't try to do inline
+ * functions at all!
+ */
+#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
+#ifdef INCLUDE_INLINE_FUNCS
+#define _INLINE_ extern
+#else
+#ifdef __GNUC__
+#define _INLINE_ extern __inline__
+#else /* For Watcom C */
+#define _INLINE_ extern inline
+#endif
+#endif
+
+#ifndef EXT2_CUSTOM_MEMORY_ROUTINES
+/*
+ * Allocate memory
+ */
+_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void **ptr)
+{
+ *ptr = malloc(size);
+ if (!*ptr)
+ return EXT2_ET_NO_MEMORY;
+ return 0;
+}
+
+/*
+ * Free memory
+ */
+_INLINE_ errcode_t ext2fs_free_mem(void **ptr)
+{
+ free(*ptr);
+ *ptr = 0;
+ return 0;
+}
+
+/*
+ * Resize memory
+ */
+_INLINE_ errcode_t ext2fs_resize_mem(unsigned long old_size,
+ unsigned long size, void **ptr)
+{
+ void *p;
+
+ p = realloc(*ptr, size);
+ if (!p)
+ return EXT2_ET_NO_MEMORY;
+ *ptr = p;
+ return 0;
+}
+#endif /* Custom memory routines */
+
+/*
+ * Mark a filesystem superblock as dirty
+ */
+_INLINE_ void ext2fs_mark_super_dirty(ext2_filsys fs)
+{
+ fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Mark a filesystem as changed
+ */
+_INLINE_ void ext2fs_mark_changed(ext2_filsys fs)
+{
+ fs->flags |= EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Check to see if a filesystem has changed
+ */
+_INLINE_ int ext2fs_test_changed(ext2_filsys fs)
+{
+ return (fs->flags & EXT2_FLAG_CHANGED);
+}
+
+/*
+ * Mark a filesystem as valid
+ */
+_INLINE_ void ext2fs_mark_valid(ext2_filsys fs)
+{
+ fs->flags |= EXT2_FLAG_VALID;
+}
+
+/*
+ * Mark a filesystem as NOT valid
+ */
+_INLINE_ void ext2fs_unmark_valid(ext2_filsys fs)
+{
+ fs->flags &= ~EXT2_FLAG_VALID;
+}
+
+/*
+ * Check to see if a filesystem is valid
+ */
+_INLINE_ int ext2fs_test_valid(ext2_filsys fs)
+{
+ return (fs->flags & EXT2_FLAG_VALID);
+}
+
+/*
+ * Mark the inode bitmap as dirty
+ */
+_INLINE_ void ext2fs_mark_ib_dirty(ext2_filsys fs)
+{
+ fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Mark the block bitmap as dirty
+ */
+_INLINE_ void ext2fs_mark_bb_dirty(ext2_filsys fs)
+{
+ fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Check to see if a filesystem's inode bitmap is dirty
+ */
+_INLINE_ int ext2fs_test_ib_dirty(ext2_filsys fs)
+{
+ return (fs->flags & EXT2_FLAG_IB_DIRTY);
+}
+
+/*
+ * Check to see if a filesystem's block bitmap is dirty
+ */
+_INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs)
+{
+ return (fs->flags & EXT2_FLAG_BB_DIRTY);
+}
+
+/*
+ * Return the group # of a block
+ */
+_INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
+{
+ return (blk - fs->super->s_first_data_block) /
+ fs->super->s_blocks_per_group;
+}
+
+/*
+ * Return the group # of an inode number
+ */
+_INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
+{
+ return (ino - 1) / fs->super->s_inodes_per_group;
+}
+#undef _INLINE_
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EXT2FS_EXT2FS_H */
diff --git a/e2fslib/ext2fsP.h b/e2fslib/ext2fsP.h
new file mode 100644
index 0000000..aedee15
--- /dev/null
+++ b/e2fslib/ext2fsP.h
@@ -0,0 +1,93 @@
+/*
+ * ext2fsP.h --- private header file for ext2 library
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "ext2fs.h"
+
+/*
+ * Badblocks list
+ */
+struct ext2_struct_badblocks_list {
+ int magic;
+ int num;
+ int size;
+ blk_t *list;
+ int badblocks_flags;
+};
+
+struct ext2_struct_badblocks_iterate {
+ int magic;
+ badblocks_list bb;
+ int ptr;
+};
+
+
+/*
+ * Directory block iterator definition
+ */
+struct ext2_struct_dblist {
+ int magic;
+ ext2_filsys fs;
+ ext2_ino_t size;
+ ext2_ino_t count;
+ int sorted;
+ struct ext2_db_entry * list;
+};
+
+/*
+ * For directory iterators
+ */
+struct dir_context {
+ ext2_ino_t dir;
+ int flags;
+ char *buf;
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data);
+ int (*func2)(ext2_ino_t dir,
+ int entry,
+ struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data);
+ void *priv_data;
+ errcode_t errcode;
+};
+
+/*
+ * Inode cache structure
+ */
+struct ext2_inode_cache {
+ void * buffer;
+ blk_t buffer_blk;
+ int cache_last;
+ int cache_size;
+ int refcount;
+ struct ext2_inode_cache_ent *cache;
+};
+
+struct ext2_inode_cache_ent {
+ ext2_ino_t ino;
+ struct ext2_inode inode;
+};
+
+/* Function prototypes */
+
+extern int ext2fs_process_dir_block(ext2_filsys fs,
+ blk_t *blocknr,
+ e2_blkcnt_t blockcnt,
+ blk_t ref_block,
+ int ref_offset,
+ void *priv_data);
+
+
diff --git a/e2fslib/ext_attr.c b/e2fslib/ext_attr.c
new file mode 100644
index 0000000..3a281e8
--- /dev/null
+++ b/e2fslib/ext_attr.c
@@ -0,0 +1,100 @@
+/*
+ * ext_attr.c --- extended attribute blocks
+ *
+ * Copyright (C) Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <time.h>
+
+#include "ext2_fs.h"
+#include "ext2_ext_attr.h"
+
+#include "ext2fs.h"
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+void ext2fs_swap_ext_attr(ext2_filsys fs, char *to, char *from)
+{
+ 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 + fs->blocksize;
+ int n;
+
+ if (to_header != from_header)
+ memcpy(to_header, from_header, fs->blocksize);
+
+ to_header->h_magic = ext2fs_swab32(from_header->h_magic);
+ to_header->h_blocks = ext2fs_swab32(from_header->h_blocks);
+ to_header->h_refcount = ext2fs_swab32(from_header->h_refcount);
+ for (n=0; n<4; n++)
+ to_header->h_reserved[n] =
+ ext2fs_swab32(from_header->h_reserved[n]);
+
+ from_entry = (struct ext2_ext_attr_entry *)(from_header+1);
+ to_entry = (struct ext2_ext_attr_entry *)(to_header+1);
+ while ((char *)from_entry < from_end && *(__u32 *)from_entry) {
+ to_entry->e_value_offs =
+ ext2fs_swab16(from_entry->e_value_offs);
+ to_entry->e_value_block =
+ ext2fs_swab32(from_entry->e_value_block);
+ to_entry->e_value_size =
+ ext2fs_swab32(from_entry->e_value_size);
+ from_entry = EXT2_EXT_ATTR_NEXT(from_entry);
+ to_entry = EXT2_EXT_ATTR_NEXT(to_entry);
+ }
+}
+#endif
+
+errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf)
+{
+ errcode_t retval;
+ struct ext2_ext_attr_entry *entry;
+
+ retval = io_channel_read_blk(fs->io, block, 1, buf);
+ if (retval)
+ return retval;
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if ((fs->flags & (EXT2_FLAG_SWAP_BYTES|
+ EXT2_FLAG_SWAP_BYTES_READ)) != 0)
+ ext2fs_swap_ext_attr(fs, buf, buf);
+#endif
+ return 0;
+}
+
+errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *inbuf)
+{
+ errcode_t retval;
+ char *p, *end, *write_buf;
+ char *buf = NULL;
+ struct ext2_dir_entry *dirent;
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+ (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) {
+ retval = ext2fs_get_mem(fs->blocksize, (void **) &buf);
+ if (retval)
+ return retval;
+ write_buf = buf;
+ ext2fs_swap_ext_attr(fs, buf, inbuf);
+ } else
+#endif
+ write_buf = (char *) inbuf;
+ retval = io_channel_write_blk(fs->io, block, 1, write_buf);
+ if (buf)
+ ext2fs_free_mem((void **) &buf);
+ if (!retval)
+ ext2fs_mark_changed(fs);
+ return retval;
+}
diff --git a/e2fslib/ext_attr.o b/e2fslib/ext_attr.o
new file mode 100644
index 0000000..f1fa6e9
--- /dev/null
+++ b/e2fslib/ext_attr.o
Binary files differ
diff --git a/e2fslib/fileio.c b/e2fslib/fileio.c
new file mode 100644
index 0000000..80e5032
--- /dev/null
+++ b/e2fslib/fileio.c
@@ -0,0 +1,336 @@
+/*
+ * fileio.c --- Simple file I/O routines
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+struct ext2_file {
+ errcode_t magic;
+ ext2_filsys fs;
+ ext2_ino_t ino;
+ struct ext2_inode inode;
+ int flags;
+ ext2_off_t pos;
+ blk_t blockno;
+ blk_t physblock;
+ char *buf;
+};
+
+#define BMAP_BUFFER (file->buf + fs->blocksize)
+
+errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
+ 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), (void **) &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;
+
+ retval = ext2fs_read_inode(fs, ino, &file->inode);
+ if (retval)
+ goto fail;
+
+ retval = ext2fs_get_mem(fs->blocksize * 3, (void **) &file->buf);
+ if (retval)
+ goto fail;
+
+ *ret = file;
+ return 0;
+
+fail:
+ if (file->buf)
+ ext2fs_free_mem((void **) &file->buf);
+ ext2fs_free_mem((void **) &file);
+ return retval;
+}
+
+/*
+ * This function returns the filesystem handle of a file from the structure
+ */
+ext2_filsys ext2fs_file_get_fs(ext2_file_t file)
+{
+ if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
+ return 0;
+ return file->fs;
+}
+
+/*
+ * This function flushes the dirty block buffer out to disk if
+ * necessary.
+ */
+static errcode_t ext2fs_file_flush(ext2_file_t file)
+{
+ errcode_t retval;
+ ext2_filsys fs;
+
+ EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
+ fs = file->fs;
+
+ if (!(file->flags & EXT2_FILE_BUF_VALID) ||
+ !(file->flags & EXT2_FILE_BUF_DIRTY))
+ return 0;
+
+ /*
+ * OK, the physical block hasn't been allocated yet.
+ * Allocate it.
+ */
+ if (!file->physblock) {
+ retval = ext2fs_bmap(fs, file->ino, &file->inode,
+ BMAP_BUFFER, BMAP_ALLOC,
+ file->blockno, &file->physblock);
+ if (retval)
+ return retval;
+ }
+
+ retval = io_channel_write_blk(fs->io, file->physblock,
+ 1, file->buf);
+ if (retval)
+ return retval;
+
+ file->flags &= ~EXT2_FILE_BUF_DIRTY;
+
+ return retval;
+}
+
+/*
+ * This function synchronizes the file's block buffer and the current
+ * file position, possibly invalidating block buffer if necessary
+ */
+static errcode_t sync_buffer_position(ext2_file_t file)
+{
+ blk_t b;
+ errcode_t retval;
+
+ b = file->pos / file->fs->blocksize;
+ if (b != file->blockno) {
+ retval = ext2fs_file_flush(file);
+ if (retval)
+ return retval;
+ file->flags &= ~EXT2_FILE_BUF_VALID;
+ }
+ file->blockno = b;
+ return 0;
+}
+
+/*
+ * This function loads the file's block buffer with valid data from
+ * the disk as necessary.
+ *
+ * If dontfill is true, then skip initializing the buffer since we're
+ * going to be replacing its entire contents anyway. If set, then the
+ * function basically only sets file->physblock and EXT2_FILE_BUF_VALID
+ */
+#define DONTFILL 1
+static errcode_t load_buffer(ext2_file_t file, int dontfill)
+{
+ ext2_filsys fs = file->fs;
+ errcode_t retval;
+
+ if (!(file->flags & EXT2_FILE_BUF_VALID)) {
+ retval = ext2fs_bmap(fs, file->ino, &file->inode,
+ BMAP_BUFFER, 0, file->blockno,
+ &file->physblock);
+ if (retval)
+ return retval;
+ if (!dontfill) {
+ if (file->physblock) {
+ retval = io_channel_read_blk(fs->io,
+ file->physblock,
+ 1, file->buf);
+ if (retval)
+ return retval;
+ } else
+ memset(file->buf, 0, fs->blocksize);
+ }
+ file->flags |= EXT2_FILE_BUF_VALID;
+ }
+ return 0;
+}
+
+
+errcode_t ext2fs_file_close(ext2_file_t file)
+{
+ errcode_t retval;
+
+ EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
+
+ retval = ext2fs_file_flush(file);
+
+ if (file->buf)
+ ext2fs_free_mem((void **) &file->buf);
+ ext2fs_free_mem((void **) &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, left, c, count = 0;
+ char *ptr = (char *) buf;
+
+ EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
+ fs = file->fs;
+
+ while ((file->pos < file->inode.i_size) && (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 = file->inode.i_size - 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, void *buf,
+ unsigned int nbytes, unsigned int *written)
+{
+ ext2_filsys fs;
+ blk_t pb;
+ errcode_t retval = 0;
+ unsigned int start, c, count = 0;
+ char *ptr = (char *) buf;
+ int dontfill;
+
+ EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
+ fs = file->fs;
+
+ if (!(file->flags & EXT2_FILE_WRITE))
+ return EXT2_ET_FILE_RO;
+
+ while (nbytes > 0) {
+ retval = sync_buffer_position(file);
+ if (retval)
+ goto fail;
+
+ start = file->pos % fs->blocksize;
+ c = fs->blocksize - start;
+ if (c > nbytes)
+ c = nbytes;
+
+ /*
+ * We only need to do a read-modify-update cycle if
+ * we're doing a partial write.
+ */
+ retval = load_buffer(file, (c == fs->blocksize));
+ if (retval)
+ goto fail;
+
+ file->flags |= EXT2_FILE_BUF_DIRTY;
+ memcpy(file->buf+start, ptr, c);
+ file->pos += c;
+ ptr += c;
+ count += c;
+ nbytes -= c;
+ }
+
+fail:
+ if (written)
+ *written = count;
+ return retval;
+}
+
+errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
+ int whence, ext2_off_t *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 = file->inode.i_size + offset;
+ else
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ if (ret_pos)
+ *ret_pos = file->pos;
+
+ 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)
+{
+ if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
+ return 0;
+ return file->inode.i_size;
+}
+
+/*
+ * This function sets the size of the file, truncating it if necessary
+ *
+ * XXX still need to call truncate
+ */
+errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size)
+{
+ errcode_t retval;
+ EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
+
+ file->inode.i_size = size;
+ retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
+ if (retval)
+ return retval;
+
+ /*
+ * XXX truncate inode if necessary
+ */
+
+ return 0;
+}
diff --git a/e2fslib/fileio.o b/e2fslib/fileio.o
new file mode 100644
index 0000000..c57d53f
--- /dev/null
+++ b/e2fslib/fileio.o
Binary files differ
diff --git a/e2fslib/finddev.c b/e2fslib/finddev.c
new file mode 100644
index 0000000..2e9d70a
--- /dev/null
+++ b/e2fslib/finddev.c
@@ -0,0 +1,208 @@
+/*
+ * finddev.c -- this routine attempts to find a particular device in
+ * /dev
+ *
+ * Copyright (C) 2000 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include <dirent.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if HAVE_SYS_MKDEV_H
+#include <sys/mkdev.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+struct dir_list {
+ char *name;
+ struct dir_list *next;
+};
+
+/*
+ * This function adds an entry to the directory list
+ */
+static void add_to_dirlist(const char *name, struct dir_list **list)
+{
+ struct dir_list *dp;
+
+ dp = malloc(sizeof(struct dir_list));
+ if (!dp)
+ return;
+ dp->name = malloc(strlen(name)+1);
+ if (!dp->name) {
+ free(dp);
+ return;
+ }
+ strcpy(dp->name, name);
+ dp->next = *list;
+ *list = dp;
+}
+
+/*
+ * This function frees a directory list
+ */
+static void free_dirlist(struct dir_list **list)
+{
+ struct dir_list *dp, *next;
+
+ for (dp = *list; dp; dp = next) {
+ next = dp->next;
+ free(dp->name);
+ free(dp);
+ }
+ *list = 0;
+}
+
+static int scan_dir(char *dirname, dev_t device, struct dir_list **list,
+ char **ret_path)
+{
+ DIR *dir;
+ struct dirent *dp;
+ char path[1024], *cp;
+ int dirlen;
+ struct stat st;
+
+ dirlen = strlen(dirname);
+ if ((dir = opendir(dirname)) == NULL)
+ return errno;
+ dp = readdir(dir);
+ while (dp) {
+ if (dirlen + strlen(dp->d_name) + 2 >= sizeof(path))
+ goto skip_to_next;
+ if (dp->d_name[0] == '.' &&
+ ((dp->d_name[1] == 0) ||
+ ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
+ goto skip_to_next;
+ sprintf(path, "%s/%s", dirname, dp->d_name);
+ if (stat(path, &st) < 0)
+ goto skip_to_next;
+ if (S_ISDIR(st.st_mode))
+ add_to_dirlist(path, list);
+ if (S_ISBLK(st.st_mode) && st.st_rdev == device) {
+ cp = malloc(strlen(path)+1);
+ if (!cp) {
+ closedir(dir);
+ return ENOMEM;
+ }
+ strcpy(cp, path);
+ *ret_path = cp;
+ goto success;
+ }
+ skip_to_next:
+ dp = readdir(dir);
+ }
+success:
+ closedir(dir);
+ return 0;
+}
+
+/*
+ * This function finds the pathname to a block device with a given
+ * device number. It returns a pointer to allocated memory to the
+ * pathname on success, and NULL on failure.
+ */
+char *ext2fs_find_block_device(dev_t device)
+{
+ struct dir_list *list = 0, *new_list = 0;
+ struct dir_list *current;
+ char *ret_path = 0;
+
+ /*
+ * Add the starting directories to search...
+ */
+ add_to_dirlist("/devices", &list);
+ add_to_dirlist("/devfs", &list);
+ add_to_dirlist("/dev", &list);
+
+ while (list) {
+ current = list;
+ list = list->next;
+#ifdef DEBUG
+ printf("Scanning directory %s\n", current->name);
+#endif
+ scan_dir(current->name, device, &new_list, &ret_path);
+ free(current->name);
+ free(current);
+ if (ret_path)
+ break;
+ /*
+ * If we're done checking at this level, descend to
+ * the next level of subdirectories. (breadth-first)
+ */
+ if (list == 0) {
+ list = new_list;
+ new_list = 0;
+ }
+ }
+ free_dirlist(&list);
+ free_dirlist(&new_list);
+ return ret_path;
+}
+
+
+#ifdef DEBUG
+int main(int argc, char** argv)
+{
+ char *devname, *tmp;
+ int major, minor;
+ dev_t device;
+ const char *errmsg = "Couldn't parse %s: %s\n";
+
+ if ((argc != 2) && (argc != 3)) {
+ fprintf(stderr, "Usage: %s device_number\n", argv[0]);
+ fprintf(stderr, "\t: %s major minor\n", argv[0]);
+ exit(1);
+ }
+ if (argc == 2) {
+ device = strtoul(argv[1], &tmp, 0);
+ if (*tmp) {
+ fprintf(stderr, errmsg, "device number", argv[1]);
+ exit(1);
+ }
+ } else {
+ major = strtoul(argv[1], &tmp, 0);
+ if (*tmp) {
+ fprintf(stderr, errmsg, "major number", argv[1]);
+ exit(1);
+ }
+ minor = strtoul(argv[2], &tmp, 0);
+ if (*tmp) {
+ fprintf(stderr, errmsg, "minor number", argv[2]);
+ exit(1);
+ }
+ device = makedev(major, minor);
+ printf("Looking for device 0x%04x (%d:%d)\n", device,
+ major, minor);
+ }
+ devname = ext2fs_find_block_device(device);
+ if (devname) {
+ printf("Found device! %s\n", devname);
+ free(devname);
+ } else {
+ printf("Couldn't find device.\n");
+ }
+ return 0;
+}
+
+#endif
diff --git a/e2fslib/finddev.o b/e2fslib/finddev.o
new file mode 100644
index 0000000..aec337f
--- /dev/null
+++ b/e2fslib/finddev.o
Binary files differ
diff --git a/e2fslib/flushb.c b/e2fslib/flushb.c
new file mode 100644
index 0000000..282dca3
--- /dev/null
+++ b/e2fslib/flushb.c
@@ -0,0 +1,76 @@
+/*
+ * flushb.c --- Hides system-dependent information for both syncing a
+ * device to disk and to flush any buffers from disk cache.
+ *
+ * Copyright (C) 2000 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#if HAVE_SYS_MOUNT_H
+#include <sys/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
+ ioctl (fd, BLKFLSBUF, 0); /* In case this is a HD */
+#else
+ #warning BLKFLSBUF not defined
+#endif
+#ifdef FDFLUSH
+ ioctl (fd, FDFLUSH, 0); /* In case this is floppy */
+#else
+ #warning FDFLUSH not defined
+#endif
+ }
+ return 0;
+}
diff --git a/e2fslib/flushb.o b/e2fslib/flushb.o
new file mode 100644
index 0000000..46dcc84
--- /dev/null
+++ b/e2fslib/flushb.o
Binary files differ
diff --git a/e2fslib/freefs.c b/e2fslib/freefs.c
new file mode 100644
index 0000000..5cb3cf8
--- /dev/null
+++ b/e2fslib/freefs.c
@@ -0,0 +1,137 @@
+/*
+ * freefs.c --- free an ext2 filesystem
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+
+static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache);
+
+void ext2fs_free(ext2_filsys fs)
+{
+ if (!fs || (fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS))
+ return;
+ if (fs->io) {
+ io_channel_close(fs->io);
+ }
+ if (fs->device_name)
+ ext2fs_free_mem((void **) &fs->device_name);
+ if (fs->super)
+ ext2fs_free_mem((void **) &fs->super);
+ if (fs->orig_super)
+ ext2fs_free_mem((void **) &fs->orig_super);
+ if (fs->group_desc)
+ ext2fs_free_mem((void **) &fs->group_desc);
+ if (fs->block_map)
+ ext2fs_free_block_bitmap(fs->block_map);
+ if (fs->inode_map)
+ ext2fs_free_inode_bitmap(fs->inode_map);
+
+ if (fs->badblocks)
+ ext2fs_badblocks_list_free(fs->badblocks);
+ fs->badblocks = 0;
+
+ if (fs->dblist)
+ ext2fs_free_dblist(fs->dblist);
+
+ if (fs->icache)
+ ext2fs_free_inode_cache(fs->icache);
+
+ fs->magic = 0;
+
+ ext2fs_free_mem((void **) &fs);
+}
+
+void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
+{
+ if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_GENERIC_BITMAP))
+ return;
+
+ bitmap->magic = 0;
+ if (bitmap->description) {
+ ext2fs_free_mem((void **) &bitmap->description);
+ bitmap->description = 0;
+ }
+ if (bitmap->bitmap) {
+ ext2fs_free_mem((void **) &bitmap->bitmap);
+ bitmap->bitmap = 0;
+ }
+ ext2fs_free_mem((void **) &bitmap);
+}
+
+void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
+{
+ if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
+ return;
+
+ bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ ext2fs_free_generic_bitmap(bitmap);
+}
+
+void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap)
+{
+ if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
+ return;
+
+ bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ ext2fs_free_generic_bitmap(bitmap);
+}
+
+/*
+ * Free the inode cache structure
+ */
+static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache)
+{
+ if (--icache->refcount)
+ return;
+ if (icache->buffer)
+ ext2fs_free_mem((void **) &icache->buffer);
+ if (icache->cache)
+ ext2fs_free_mem((void **) &icache->cache);
+ icache->buffer_blk = 0;
+ ext2fs_free_mem((void **) &icache);
+}
+
+/*
+ * This procedure frees a badblocks list.
+ */
+void ext2fs_badblocks_list_free(ext2_badblocks_list bb)
+{
+ if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
+ return;
+
+ if (bb->list)
+ ext2fs_free_mem((void **) &bb->list);
+ bb->list = 0;
+ ext2fs_free_mem((void **) &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((void **) &dblist->list);
+ dblist->list = 0;
+ if (dblist->fs && dblist->fs->dblist == dblist)
+ dblist->fs->dblist = 0;
+ dblist->magic = 0;
+ ext2fs_free_mem((void **) &dblist);
+}
+
diff --git a/e2fslib/freefs.o b/e2fslib/freefs.o
new file mode 100644
index 0000000..49787d6
--- /dev/null
+++ b/e2fslib/freefs.o
Binary files differ
diff --git a/e2fslib/gen_bitmap.c b/e2fslib/gen_bitmap.c
new file mode 100644
index 0000000..700affa
--- /dev/null
+++ b/e2fslib/gen_bitmap.c
@@ -0,0 +1,48 @@
+/*
+ * gen_bitmap.c --- Generic bitmap routines that used to be inlined.
+ *
+ * Copyright (C) 2001 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ __u32 bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
+ return 0;
+ }
+ return ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
+ return 0;
+ }
+ return ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
+}
diff --git a/e2fslib/gen_bitmap.o b/e2fslib/gen_bitmap.o
new file mode 100644
index 0000000..c1a81d0
--- /dev/null
+++ b/e2fslib/gen_bitmap.o
Binary files differ
diff --git a/e2fslib/get_pathname.c b/e2fslib/get_pathname.c
new file mode 100644
index 0000000..e218f2e
--- /dev/null
+++ b/e2fslib/get_pathname.c
@@ -0,0 +1,158 @@
+/*
+ * get_pathname.c --- do directry/inode -> name translation
+ *
+ * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ *
+ * ext2fs_get_pathname(fs, dir, ino, name)
+ *
+ * This function translates takes two inode numbers into a
+ * string, placing the result in <name>. <dir> is the containing
+ * directory inode, and <ino> is the inode number itself. If
+ * <ino> is zero, then ext2fs_get_pathname will return pathname
+ * of the the directory <dir>.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+struct get_pathname_struct {
+ ext2_ino_t search_ino;
+ ext2_ino_t parent;
+ char *name;
+ errcode_t errcode;
+};
+
+#ifdef __TURBOC__
+ #pragma argsused
+#endif
+static int get_pathname_proc(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ 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,
+ (void **) &gp->name);
+ if (retval) {
+ gp->errcode = retval;
+ return DIRENT_ABORT;
+ }
+ strncpy(gp->name, dirent->name, (dirent->name_len & 0xFF));
+ gp->name[dirent->name_len & 0xFF] = '\0';
+ return DIRENT_ABORT;
+ }
+ return 0;
+}
+
+static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir,
+ ext2_ino_t ino, int maxdepth,
+ char *buf, char **name)
+{
+ struct get_pathname_struct gp;
+ char *parent_name, *ret;
+ errcode_t retval;
+
+ if (dir == ino) {
+ retval = ext2fs_get_mem(2, (void **)name);
+ if (retval)
+ return retval;
+ strcpy(*name, (dir == EXT2_ROOT_INO) ? "/" : ".");
+ return 0;
+ }
+
+ if (!dir || (maxdepth < 0)) {
+ retval = ext2fs_get_mem(4, (void **)name);
+ if (retval)
+ return retval;
+ strcpy(*name, "...");
+ return 0;
+ }
+
+ gp.search_ino = ino;
+ gp.parent = 0;
+ gp.name = 0;
+ gp.errcode = 0;
+
+ retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp);
+ if (retval)
+ goto cleanup;
+ if (gp.errcode) {
+ retval = gp.errcode;
+ goto cleanup;
+ }
+
+ retval = ext2fs_get_pathname_int(fs, gp.parent, dir, maxdepth-1,
+ buf, &parent_name);
+ if (retval)
+ goto cleanup;
+ if (!ino) {
+ *name = parent_name;
+ return 0;
+ }
+
+ if (gp.name)
+ retval = ext2fs_get_mem(strlen(parent_name)+strlen(gp.name)+2,
+ (void **) &ret);
+ else
+ retval = ext2fs_get_mem(strlen(parent_name)+5,
+ (void **) &ret);
+ if (retval)
+ goto cleanup;
+
+ ret[0] = 0;
+ if (parent_name[1])
+ strcat(ret, parent_name);
+ strcat(ret, "/");
+ if (gp.name)
+ strcat(ret, gp.name);
+ else
+ strcat(ret, "???");
+ *name = ret;
+ ext2fs_free_mem((void **) &parent_name);
+ retval = 0;
+
+cleanup:
+ if (gp.name)
+ ext2fs_free_mem((void **) &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, (void **) &buf);
+ if (retval)
+ return retval;
+ if (dir == ino)
+ ino = 0;
+ retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name);
+ ext2fs_free_mem((void **) &buf);
+ return retval;
+
+}
diff --git a/e2fslib/get_pathname.o b/e2fslib/get_pathname.o
new file mode 100644
index 0000000..7428dc2
--- /dev/null
+++ b/e2fslib/get_pathname.o
Binary files differ
diff --git a/e2fslib/getsize.c b/e2fslib/getsize.c
new file mode 100644
index 0000000..e8fadba
--- /dev/null
+++ b/e2fslib/getsize.c
@@ -0,0 +1,157 @@
+/*
+ * getsize.c --- get the size of a partition.
+ *
+ * Copyright (C) 1995, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+#include <stdio.h>
+#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
+#ifdef HAVE_SYS_DISKLABEL_H
+#include <sys/ioctl.h>
+#include <sys/disklabel.h>
+#endif /* HAVE_SYS_DISKLABEL_H */
+
+#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
+#define BLKGETSIZE _IO(0x12,96) /* return device size */
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+static int valid_offset (int fd, ext2_loff_t offset)
+{
+ char ch;
+
+ if (ext2fs_llseek (fd, offset, 0) < 0)
+ return 0;
+ if (read (fd, &ch, 1) < 1)
+ return 0;
+ return 1;
+}
+
+/*
+ * Returns the number of blocks in a partition
+ */
+errcode_t ext2fs_get_device_size(const char *file, int blocksize,
+ blk_t *retblocks)
+{
+ int fd;
+#ifdef BLKGETSIZE
+ unsigned long size;
+#endif
+ ext2_loff_t high, low;
+#ifdef FDGETPRM
+ struct floppy_struct this_floppy;
+#endif
+#ifdef HAVE_SYS_DISKLABEL_H
+ int part;
+ struct disklabel lab;
+ struct partition *pp;
+ char ch;
+#endif /* HAVE_SYS_DISKLABEL_H */
+
+#ifdef HAVE_OPEN64
+ fd = open64(file, O_RDONLY);
+#else
+ fd = open(file, O_RDONLY);
+#endif
+ if (fd < 0)
+ return errno;
+
+#ifdef BLKGETSIZE
+ if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
+ close(fd);
+ *retblocks = size / (blocksize / 512);
+ return 0;
+ }
+#endif
+#ifdef FDGETPRM
+ if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
+ close(fd);
+ *retblocks = this_floppy.size / (blocksize / 512);
+ return 0;
+ }
+#endif
+#ifdef HAVE_SYS_DISKLABEL_H
+ part = strlen(file) - 1;
+ if (part >= 0) {
+ ch = file[part];
+ if (isdigit(ch))
+ part = 0;
+ else if (ch >= 'a' && ch <= 'h')
+ part = ch - 'a';
+ else
+ part = -1;
+ }
+ if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
+ pp = &lab.d_partitions[part];
+ if (pp->p_size) {
+ close(fd);
+ *retblocks = pp->p_size / (blocksize / 512);
+ return 0;
+ }
+ }
+#endif /* HAVE_SYS_DISKLABEL_H */
+
+ /*
+ * OK, we couldn't figure it out by using a specialized ioctl,
+ * which is generally the best way. So do binary search to
+ * find the size of the partition.
+ */
+ low = 0;
+ for (high = 1024; valid_offset (fd, high); high *= 2)
+ low = high;
+ while (low < high - 1)
+ {
+ const ext2_loff_t mid = (low + high) / 2;
+
+ if (valid_offset (fd, mid))
+ low = mid;
+ else
+ high = mid;
+ }
+ valid_offset (fd, 0);
+ close(fd);
+ *retblocks = (low + 1) / blocksize;
+ return 0;
+}
+
+#ifdef DEBUG
+int main(int argc, char **argv)
+{
+ blk_t blocks;
+ int retval;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s device\n", argv[0]);
+ exit(1);
+ }
+
+ retval = ext2fs_get_device_size(argv[1], 1024, &blocks);
+ if (retval) {
+ com_err(argv[0], retval,
+ "while calling ext2fs_get_device_size");
+ exit(1);
+ }
+ printf("Device %s has %d 1k blocks.\n", argv[1], blocks);
+ exit(0);
+}
+#endif
diff --git a/e2fslib/getsize.o b/e2fslib/getsize.o
new file mode 100644
index 0000000..533f3d9
--- /dev/null
+++ b/e2fslib/getsize.o
Binary files differ
diff --git a/e2fslib/icount.c b/e2fslib/icount.c
new file mode 100644
index 0000000..1ad3940
--- /dev/null
+++ b/e2fslib/icount.c
@@ -0,0 +1,482 @@
+/*
+ * icount.c --- an efficient inode count abstraction
+ *
+ * Copyright (C) 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+/*
+ * The data storage strategy used by icount relies on the observation
+ * that most inode counts are either zero (for non-allocated inodes),
+ * one (for most files), and only a few that are two or more
+ * (directories and files that are linked to more than one directory).
+ *
+ * Also, e2fsck tends to load the icount data sequentially.
+ *
+ * So, we use an inode bitmap to indicate which inodes have a count of
+ * one, and then use a sorted list to store the counts for inodes
+ * which are greater than one.
+ *
+ * We also use an optional bitmap to indicate which inodes are already
+ * in the sorted list, to speed up the use of this abstraction by
+ * e2fsck's pass 2. Pass 2 increments inode counts as it finds them,
+ * so this extra bitmap avoids searching the sorted list to see if a
+ * particular inode is on the sorted list already.
+ */
+
+struct ext2_icount_el {
+ ext2_ino_t ino;
+ __u16 count;
+};
+
+struct ext2_icount {
+ errcode_t magic;
+ ext2fs_inode_bitmap single;
+ ext2fs_inode_bitmap multiple;
+ ext2_ino_t count;
+ ext2_ino_t size;
+ ext2_ino_t num_inodes;
+ int cursor;
+ struct ext2_icount_el *list;
+};
+
+void ext2fs_free_icount(ext2_icount_t icount)
+{
+ if (!icount)
+ return;
+
+ icount->magic = 0;
+ if (icount->list)
+ ext2fs_free_mem((void **) &icount->list);
+ if (icount->single)
+ ext2fs_free_inode_bitmap(icount->single);
+ if (icount->multiple)
+ ext2fs_free_inode_bitmap(icount->multiple);
+ ext2fs_free_mem((void **) &icount);
+}
+
+errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, int size,
+ ext2_icount_t hint, ext2_icount_t *ret)
+{
+ ext2_icount_t icount;
+ errcode_t retval;
+ size_t bytes;
+ int i;
+
+ if (hint) {
+ EXT2_CHECK_MAGIC(hint, EXT2_ET_MAGIC_ICOUNT);
+ if (hint->size > size)
+ size = (size_t) hint->size;
+ }
+
+ retval = ext2fs_get_mem(sizeof(struct ext2_icount), (void **) &icount);
+ if (retval)
+ return retval;
+ memset(icount, 0, sizeof(struct ext2_icount));
+
+ retval = ext2fs_allocate_inode_bitmap(fs, 0,
+ &icount->single);
+ if (retval)
+ goto errout;
+
+ if (flags & EXT2_ICOUNT_OPT_INCREMENT) {
+ retval = ext2fs_allocate_inode_bitmap(fs, 0,
+ &icount->multiple);
+ if (retval)
+ goto errout;
+ } else
+ icount->multiple = 0;
+
+ if (size) {
+ icount->size = size;
+ } else {
+ /*
+ * Figure out how many special case inode counts we will
+ * have. We know we will need one for each directory;
+ * we also need to reserve some extra room for file links
+ */
+ retval = ext2fs_get_num_dirs(fs, &icount->size);
+ if (retval)
+ goto errout;
+ icount->size += fs->super->s_inodes_count / 50;
+ }
+
+ bytes = (size_t) (icount->size * sizeof(struct ext2_icount_el));
+#if 0
+ printf("Icount allocated %d entries, %d bytes.\n",
+ icount->size, bytes);
+#endif
+ retval = ext2fs_get_mem(bytes, (void **) &icount->list);
+ if (retval)
+ goto errout;
+ memset(icount->list, 0, bytes);
+
+ icount->magic = EXT2_ET_MAGIC_ICOUNT;
+ icount->count = 0;
+ icount->cursor = 0;
+ icount->num_inodes = fs->super->s_inodes_count;
+
+ /*
+ * Populate the sorted list with those entries which were
+ * found in the hint icount (since those are ones which will
+ * likely need to be in the sorted list this time around).
+ */
+ if (hint) {
+ for (i=0; i < hint->count; i++)
+ icount->list[i].ino = hint->list[i].ino;
+ icount->count = hint->count;
+ }
+
+ *ret = icount;
+ return 0;
+
+errout:
+ ext2fs_free_icount(icount);
+ return(retval);
+}
+
+errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, int size,
+ ext2_icount_t *ret)
+{
+ return ext2fs_create_icount2(fs, flags, size, 0, ret);
+}
+
+/*
+ * insert_icount_el() --- Insert a new entry into the sorted list at a
+ * specified position.
+ */
+static struct ext2_icount_el *insert_icount_el(ext2_icount_t icount,
+ ext2_ino_t ino, int pos)
+{
+ struct ext2_icount_el *el;
+ errcode_t retval;
+ ext2_ino_t new_size = 0;
+ int num;
+
+ if (icount->count >= icount->size) {
+ if (icount->count) {
+ new_size = icount->list[(unsigned)icount->count-1].ino;
+ new_size = (ext2_ino_t) (icount->count *
+ ((float) icount->num_inodes / new_size));
+ }
+ if (new_size < (icount->size + 100))
+ new_size = icount->size + 100;
+#if 0
+ printf("Reallocating icount %d entries...\n", new_size);
+#endif
+ retval = ext2fs_resize_mem((size_t) icount->size *
+ sizeof(struct ext2_icount_el),
+ (size_t) new_size *
+ sizeof(struct ext2_icount_el),
+ (void **) &icount->list);
+ if (retval)
+ return 0;
+ icount->size = new_size;
+ }
+ num = (int) icount->count - pos;
+ if (num < 0)
+ return 0; /* should never happen */
+ if (num) {
+ memmove(&icount->list[pos+1], &icount->list[pos],
+ sizeof(struct ext2_icount_el) * num);
+ }
+ icount->count++;
+ el = &icount->list[pos];
+ el->count = 0;
+ el->ino = ino;
+ return el;
+}
+
+/*
+ * get_icount_el() --- given an inode number, try to find icount
+ * information in the sorted list. If the create flag is set,
+ * and we can't find an entry, create one in the sorted list.
+ */
+static struct ext2_icount_el *get_icount_el(ext2_icount_t icount,
+ ext2_ino_t ino, int create)
+{
+ float range;
+ int low, high, mid;
+ ext2_ino_t lowval, highval;
+
+ if (!icount || !icount->list)
+ return 0;
+
+ if (create && ((icount->count == 0) ||
+ (ino > icount->list[(unsigned)icount->count-1].ino))) {
+ return insert_icount_el(icount, ino, (unsigned) icount->count);
+ }
+ if (icount->count == 0)
+ return 0;
+
+ if (icount->cursor >= icount->count)
+ icount->cursor = 0;
+ if (ino == icount->list[icount->cursor].ino)
+ return &icount->list[icount->cursor++];
+#if 0
+ printf("Non-cursor get_icount_el: %u\n", ino);
+#endif
+ low = 0;
+ high = (int) icount->count-1;
+ while (low <= high) {
+#if 0
+ mid = (low+high)/2;
+#else
+ if (low == high)
+ mid = low;
+ else {
+ /* Interpolate for efficiency */
+ lowval = icount->list[low].ino;
+ highval = icount->list[high].ino;
+
+ if (ino < lowval)
+ range = 0;
+ else if (ino > highval)
+ range = 1;
+ else
+ range = ((float) (ino - lowval)) /
+ (highval - lowval);
+ mid = low + ((int) (range * (high-low)));
+ }
+#endif
+ if (ino == icount->list[mid].ino) {
+ icount->cursor = mid+1;
+ return &icount->list[mid];
+ }
+ if (ino < icount->list[mid].ino)
+ high = mid-1;
+ else
+ low = mid+1;
+ }
+ /*
+ * If we need to create a new entry, it should be right at
+ * low (where high will be left at low-1).
+ */
+ if (create)
+ return insert_icount_el(icount, ino, low);
+ return 0;
+}
+
+errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *out)
+{
+ errcode_t ret = 0;
+ int i;
+ const char *bad = "bad icount";
+
+ EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+ if (icount->count > icount->size) {
+ fprintf(out, "%s: count > size\n", bad);
+ return EXT2_ET_INVALID_ARGUMENT;
+ }
+ for (i=1; i < icount->count; i++) {
+ if (icount->list[i-1].ino >= icount->list[i].ino) {
+ fprintf(out, "%s: list[%d].ino=%u, list[%d].ino=%u\n",
+ bad, i-1, icount->list[i-1].ino,
+ i, icount->list[i].ino);
+ ret = EXT2_ET_INVALID_ARGUMENT;
+ }
+ }
+ return ret;
+}
+
+errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino, __u16 *ret)
+{
+ struct ext2_icount_el *el;
+
+ EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+ if (!ino || (ino > icount->num_inodes))
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ if (ext2fs_test_inode_bitmap(icount->single, ino)) {
+ *ret = 1;
+ return 0;
+ }
+ if (icount->multiple &&
+ !ext2fs_test_inode_bitmap(icount->multiple, ino)) {
+ *ret = 0;
+ return 0;
+ }
+ el = get_icount_el(icount, ino, 0);
+ if (!el) {
+ *ret = 0;
+ return 0;
+ }
+ *ret = el->count;
+ return 0;
+}
+
+errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
+ __u16 *ret)
+{
+ struct ext2_icount_el *el;
+
+ EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+ if (!ino || (ino > icount->num_inodes))
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ if (ext2fs_test_inode_bitmap(icount->single, ino)) {
+ /*
+ * If the existing count is 1, then we know there is
+ * no entry in the list.
+ */
+ el = get_icount_el(icount, ino, 1);
+ if (!el)
+ return EXT2_ET_NO_MEMORY;
+ ext2fs_unmark_inode_bitmap(icount->single, ino);
+ el->count = 2;
+ } else if (icount->multiple) {
+ /*
+ * The count is either zero or greater than 1; if the
+ * inode is set in icount->multiple, then there should
+ * be an entry in the list, so find it using
+ * get_icount_el().
+ */
+ if (ext2fs_test_inode_bitmap(icount->multiple, ino)) {
+ el = get_icount_el(icount, ino, 1);
+ if (!el)
+ return EXT2_ET_NO_MEMORY;
+ el->count++;
+ } else {
+ /*
+ * The count was zero; mark the single bitmap
+ * and return.
+ */
+ zero_count:
+ ext2fs_mark_inode_bitmap(icount->single, ino);
+ if (ret)
+ *ret = 1;
+ return 0;
+ }
+ } else {
+ /*
+ * The count is either zero or greater than 1; try to
+ * find an entry in the list to determine which.
+ */
+ el = get_icount_el(icount, ino, 0);
+ if (!el) {
+ /* No entry means the count was zero */
+ goto zero_count;
+ }
+ el = get_icount_el(icount, ino, 1);
+ if (!el)
+ return EXT2_ET_NO_MEMORY;
+ el->count++;
+ }
+ if (icount->multiple)
+ ext2fs_mark_inode_bitmap(icount->multiple, ino);
+ if (ret)
+ *ret = el->count;
+ return 0;
+}
+
+errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
+ __u16 *ret)
+{
+ struct ext2_icount_el *el;
+
+ if (!ino || (ino > icount->num_inodes))
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+ if (ext2fs_test_inode_bitmap(icount->single, ino)) {
+ ext2fs_unmark_inode_bitmap(icount->single, ino);
+ if (icount->multiple)
+ ext2fs_unmark_inode_bitmap(icount->multiple, ino);
+ else {
+ el = get_icount_el(icount, ino, 0);
+ if (el)
+ el->count = 0;
+ }
+ if (ret)
+ *ret = 0;
+ return 0;
+ }
+
+ if (icount->multiple &&
+ !ext2fs_test_inode_bitmap(icount->multiple, ino))
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ el = get_icount_el(icount, ino, 0);
+ if (!el || el->count == 0)
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ el->count--;
+ if (el->count == 1)
+ ext2fs_mark_inode_bitmap(icount->single, ino);
+ if ((el->count == 0) && icount->multiple)
+ ext2fs_unmark_inode_bitmap(icount->multiple, ino);
+
+ if (ret)
+ *ret = el->count;
+ return 0;
+}
+
+errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
+ __u16 count)
+{
+ struct ext2_icount_el *el;
+
+ if (!ino || (ino > icount->num_inodes))
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+
+ if (count == 1) {
+ ext2fs_mark_inode_bitmap(icount->single, ino);
+ if (icount->multiple)
+ ext2fs_unmark_inode_bitmap(icount->multiple, ino);
+ return 0;
+ }
+ if (count == 0) {
+ ext2fs_unmark_inode_bitmap(icount->single, ino);
+ if (icount->multiple) {
+ /*
+ * If the icount->multiple bitmap is enabled,
+ * we can just clear both bitmaps and we're done
+ */
+ ext2fs_unmark_inode_bitmap(icount->multiple, ino);
+ } else {
+ el = get_icount_el(icount, ino, 0);
+ if (el)
+ el->count = 0;
+ }
+ return 0;
+ }
+
+ /*
+ * Get the icount element
+ */
+ el = get_icount_el(icount, ino, 1);
+ if (!el)
+ return EXT2_ET_NO_MEMORY;
+ el->count = count;
+ ext2fs_unmark_inode_bitmap(icount->single, ino);
+ if (icount->multiple)
+ ext2fs_mark_inode_bitmap(icount->multiple, ino);
+ return 0;
+}
+
+ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount)
+{
+ if (!icount || icount->magic != EXT2_ET_MAGIC_ICOUNT)
+ return 0;
+
+ return icount->size;
+}
diff --git a/e2fslib/icount.o b/e2fslib/icount.o
new file mode 100644
index 0000000..360baa9
--- /dev/null
+++ b/e2fslib/icount.o
Binary files differ
diff --git a/e2fslib/imager.c b/e2fslib/imager.c
new file mode 100644
index 0000000..242e36a
--- /dev/null
+++ b/e2fslib/imager.c
@@ -0,0 +1,380 @@
+/*
+ * image.c --- writes out the critical parts of the filesystem as a
+ * flat file.
+ *
+ * Copyright (C) 2000 Theodore Ts'o.
+ *
+ * Note: this uses the POSIX IO interfaces, unlike most of the other
+ * functions in this library. So sue me.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+/*
+ * This function returns 1 if the specified block is all zeros
+ */
+static int check_zero_block(char *buf, int blocksize)
+{
+ char *cp = buf;
+ int left = blocksize;
+
+ while (left > 0) {
+ if (*cp++)
+ return 0;
+ left--;
+ }
+ return 1;
+}
+
+/*
+ * Write the inode table out as a single block.
+ */
+#define BUF_BLOCKS 32
+
+errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags)
+{
+ unsigned int group, left, c, d;
+ char *buf, *cp;
+ blk_t blk;
+ ssize_t actual;
+ errcode_t retval;
+
+ buf = malloc(fs->blocksize * BUF_BLOCKS);
+ if (!buf)
+ return ENOMEM;
+
+ for (group = 0; group < fs->group_desc_count; group++) {
+ blk = fs->group_desc[(unsigned)group].bg_inode_table;
+ if (!blk)
+ return EXT2_ET_MISSING_INODE_TABLE;
+ left = fs->inode_blocks_per_group;
+ while (left) {
+ c = BUF_BLOCKS;
+ if (c > left)
+ c = left;
+ retval = io_channel_read_blk(fs->io, blk, c, buf);
+ if (retval)
+ goto errout;
+ cp = buf;
+ while (c) {
+ if (!(flags & IMAGER_FLAG_SPARSEWRITE)) {
+ d = c;
+ goto skip_sparse;
+ }
+ /* Skip zero blocks */
+ if (check_zero_block(cp, fs->blocksize)) {
+ c--;
+ blk++;
+ left--;
+ cp += fs->blocksize;
+ lseek(fd, fs->blocksize, SEEK_CUR);
+ continue;
+ }
+ /* Find non-zero blocks */
+ for (d=1; d < c; d++) {
+ if (check_zero_block(cp + d*fs->blocksize, fs->blocksize))
+ break;
+ }
+ skip_sparse:
+ actual = write(fd, cp, fs->blocksize * d);
+ if (actual == -1) {
+ retval = errno;
+ goto errout;
+ }
+ if (actual != 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)
+{
+ unsigned int group, c, left;
+ char *buf;
+ blk_t blk;
+ ssize_t actual;
+ errcode_t retval;
+
+ buf = malloc(fs->blocksize * BUF_BLOCKS);
+ if (!buf)
+ return ENOMEM;
+
+ for (group = 0; group < fs->group_desc_count; group++) {
+ blk = fs->group_desc[(unsigned)group].bg_inode_table;
+ if (!blk) {
+ retval = EXT2_ET_MISSING_INODE_TABLE;
+ goto errout;
+ }
+ left = fs->inode_blocks_per_group;
+ while (left) {
+ c = BUF_BLOCKS;
+ if (c > left)
+ c = left;
+ actual = read(fd, buf, fs->blocksize * c);
+ if (actual == -1) {
+ retval = errno;
+ goto errout;
+ }
+ if (actual != fs->blocksize * c) {
+ retval = EXT2_ET_SHORT_READ;
+ goto errout;
+ }
+ retval = io_channel_write_blk(fs->io, blk, c, buf);
+ if (retval)
+ goto errout;
+
+ blk += c;
+ left -= c;
+ }
+ }
+ retval = ext2fs_flush_icache(fs);
+
+errout:
+ free(buf);
+ return retval;
+}
+
+/*
+ * Write out superblock and group descriptors
+ */
+errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, int flags)
+{
+ 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 != 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 != 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)
+{
+ char *buf;
+ ssize_t actual, size;
+ errcode_t retval;
+
+ size = fs->blocksize * (fs->group_desc_count + 1);
+ buf = malloc(size);
+ if (!buf)
+ return ENOMEM;
+
+ /*
+ * Read it all in.
+ */
+ actual = read(fd, buf, size);
+ if (actual == -1) {
+ retval = errno;
+ goto errout;
+ }
+ if (actual != size) {
+ retval = EXT2_ET_SHORT_READ;
+ goto errout;
+ }
+
+ /*
+ * Now copy in the superblock and group descriptors
+ */
+ memcpy(fs->super, buf, SUPERBLOCK_SIZE);
+
+ memcpy(fs->group_desc, buf + fs->blocksize,
+ fs->blocksize * fs->group_desc_count);
+
+ retval = 0;
+
+errout:
+ free(buf);
+ return retval;
+}
+
+/*
+ * Write the block/inode bitmaps.
+ */
+errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
+{
+ char *ptr;
+ int c, size;
+ char zero_buf[1024];
+ ssize_t actual;
+ errcode_t retval;
+
+ if (flags & IMAGER_FLAG_INODEMAP) {
+ if (!fs->inode_map) {
+ retval = ext2fs_read_inode_bitmap(fs);
+ if (retval)
+ return retval;
+ }
+ ptr = fs->inode_map->bitmap;
+ size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
+ } else {
+ if (!fs->block_map) {
+ retval = ext2fs_read_block_bitmap(fs);
+ if (retval)
+ return retval;
+ }
+ ptr = fs->block_map->bitmap;
+ size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
+ }
+ size = size * fs->group_desc_count;
+
+ actual = write(fd, ptr, size);
+ if (actual == -1) {
+ retval = errno;
+ goto errout;
+ }
+ if (actual != size) {
+ retval = EXT2_ET_SHORT_WRITE;
+ goto errout;
+ }
+ size = size % fs->blocksize;
+ memset(zero_buf, 0, sizeof(zero_buf));
+ if (size) {
+ size = fs->blocksize - size;
+ while (size) {
+ c = size;
+ if (c > sizeof(zero_buf))
+ c = sizeof(zero_buf);
+ actual = write(fd, zero_buf, c);
+ if (actual == -1) {
+ retval = errno;
+ goto errout;
+ }
+ if (actual != c) {
+ retval = EXT2_ET_SHORT_WRITE;
+ goto errout;
+ }
+ size -= c;
+ }
+ }
+ retval = 0;
+errout:
+ return (retval);
+}
+
+
+/*
+ * Read the block/inode bitmaps.
+ */
+errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
+{
+ char *ptr, *buf = 0;
+ int size;
+ ssize_t actual;
+ errcode_t retval;
+
+ if (flags & IMAGER_FLAG_INODEMAP) {
+ if (!fs->inode_map) {
+ retval = ext2fs_read_inode_bitmap(fs);
+ if (retval)
+ return retval;
+ }
+ ptr = fs->inode_map->bitmap;
+ size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
+ } else {
+ if (!fs->block_map) {
+ retval = ext2fs_read_block_bitmap(fs);
+ if (retval)
+ return retval;
+ }
+ ptr = fs->block_map->bitmap;
+ size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
+ }
+ size = size * fs->group_desc_count;
+
+ buf = malloc(size);
+ if (!buf)
+ return ENOMEM;
+
+ actual = read(fd, buf, size);
+ if (actual == -1) {
+ retval = errno;
+ goto errout;
+ }
+ if (actual != size) {
+ retval = EXT2_ET_SHORT_WRITE;
+ goto errout;
+ }
+ memcpy(ptr, buf, size);
+
+ retval = 0;
+errout:
+ if (buf)
+ free(buf);
+ return (retval);
+}
diff --git a/e2fslib/imager.o b/e2fslib/imager.o
new file mode 100644
index 0000000..bc62f6b
--- /dev/null
+++ b/e2fslib/imager.o
Binary files differ
diff --git a/e2fslib/initialize.c b/e2fslib/initialize.c
new file mode 100644
index 0000000..821036e
--- /dev/null
+++ b/e2fslib/initialize.c
@@ -0,0 +1,326 @@
+/*
+ * initialize.c --- initialize a filesystem handle given superblock
+ * parameters. Used by mke2fs when initializing a filesystem.
+ *
+ * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+#if defined(__linux__) && defined(EXT2_OS_LINUX)
+#define CREATOR_OS EXT2_OS_LINUX
+#elif defined(__GNU__) && defined(EXT2_OS_HURD)
+#define CREATOR_OS EXT2_OS_HURD
+#elif defined(__FreeBSD__) && defined(EXT2_OS_FREEBSD)
+#define CREATOR_OS EXT2_OS_FREEBSD
+#elif defined(LITES) && defined(EXT2_OS_LITES)
+#define CREATOR_OS EXT2_OS_LITES
+#else
+#define CREATOR_OS EXT2_OS_LINUX /* by default */
+#endif
+
+/*
+ * Note we override the kernel include file's idea of what the default
+ * check interval (never) should be. It's a good idea to check at
+ * least *occasionally*, specially since servers will never rarely get
+ * to reboot, since Linux is so robust these days. :-)
+ *
+ * 180 days (six months) seems like a good value.
+ */
+#ifdef EXT2_DFL_CHECKINTERVAL
+#undef EXT2_DFL_CHECKINTERVAL
+#endif
+#define EXT2_DFL_CHECKINTERVAL (86400L * 180L)
+
+errcode_t ext2fs_initialize(const char *name, int flags,
+ struct ext2_super_block *param,
+ io_manager manager, ext2_filsys *ret_fs)
+{
+ ext2_filsys fs;
+ errcode_t retval;
+ struct ext2_super_block *super;
+ int frags_per_block;
+ int rem;
+ int overhead = 0;
+ blk_t group_block;
+ int i, j;
+ blk_t numblocks;
+ char *buf;
+
+ if (!param || !param->s_blocks_count)
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys),
+ (void **) &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;
+#ifdef WORDS_BIGENDIAN
+ fs->flags |= EXT2_FLAG_SWAP_BYTES;
+#endif
+ retval = manager->open(name, IO_FLAG_RW, &fs->io);
+ if (retval)
+ goto cleanup;
+ fs->io->app_data = fs;
+ retval = ext2fs_get_mem(strlen(name)+1, (void **) &fs->device_name);
+ if (retval)
+ goto cleanup;
+
+ strcpy(fs->device_name, name);
+ retval = ext2fs_get_mem(SUPERBLOCK_SIZE, (void **) &super);
+ if (retval)
+ goto cleanup;
+ fs->super = super;
+
+ memset(super, 0, SUPERBLOCK_SIZE);
+
+#define set_field(field, default) (super->field = param->field ? \
+ param->field : (default))
+
+ super->s_magic = EXT2_SUPER_MAGIC;
+ super->s_state = EXT2_VALID_FS;
+
+ set_field(s_log_block_size, 0); /* default blocksize: 1024 bytes */
+ set_field(s_log_frag_size, 0); /* default fragsize: 1024 bytes */
+ set_field(s_first_data_block, super->s_log_block_size ? 0 : 1);
+ set_field(s_max_mnt_count, EXT2_DFL_MAX_MNT_COUNT);
+ set_field(s_errors, EXT2_ERRORS_DEFAULT);
+ set_field(s_feature_compat, 0);
+ set_field(s_feature_incompat, 0);
+ set_field(s_feature_ro_compat, 0);
+ if (super->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)
+ return EXT2_ET_UNSUPP_FEATURE;
+ if (super->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)
+ return EXT2_ET_RO_UNSUPP_FEATURE;
+
+ set_field(s_rev_level, EXT2_GOOD_OLD_REV);
+ if (super->s_rev_level >= EXT2_DYNAMIC_REV) {
+ set_field(s_first_ino, EXT2_GOOD_OLD_FIRST_INO);
+ set_field(s_inode_size, EXT2_GOOD_OLD_INODE_SIZE);
+ }
+
+ set_field(s_checkinterval, EXT2_DFL_CHECKINTERVAL);
+ super->s_lastcheck = time(NULL);
+
+ super->s_creator_os = CREATOR_OS;
+
+ fs->blocksize = EXT2_BLOCK_SIZE(super);
+ fs->fragsize = EXT2_FRAG_SIZE(super);
+ frags_per_block = fs->blocksize / fs->fragsize;
+
+ /* default: (fs->blocksize*8) blocks/group */
+ set_field(s_blocks_per_group, fs->blocksize*8);
+ super->s_frags_per_group = super->s_blocks_per_group * frags_per_block;
+
+ super->s_blocks_count = param->s_blocks_count;
+ super->s_r_blocks_count = param->s_r_blocks_count;
+ if (super->s_r_blocks_count >= param->s_blocks_count) {
+ retval = EXT2_ET_INVALID_ARGUMENT;
+ goto cleanup;
+ }
+
+ /*
+ * If we're creating an external journal device, we don't need
+ * to bother with the rest.
+ */
+ if (super->s_feature_incompat &
+ EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
+ fs->group_desc_count = 0;
+ ext2fs_mark_super_dirty(fs);
+ *ret_fs = fs;
+ return 0;
+ }
+
+retry:
+ fs->group_desc_count = (super->s_blocks_count -
+ super->s_first_data_block +
+ EXT2_BLOCKS_PER_GROUP(super) - 1)
+ / EXT2_BLOCKS_PER_GROUP(super);
+ if (fs->group_desc_count == 0)
+ return EXT2_ET_TOOSMALL;
+ fs->desc_blocks = (fs->group_desc_count +
+ EXT2_DESC_PER_BLOCK(super) - 1)
+ / EXT2_DESC_PER_BLOCK(super);
+
+ /* n.b., fs->blocksize is <= 4096 */
+ set_field(s_inodes_count, super->s_blocks_count/(4096/fs->blocksize));
+
+ /*
+ * 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
+ */
+ super->s_inodes_per_group = (super->s_inodes_count +
+ fs->group_desc_count - 1) /
+ fs->group_desc_count;
+ if (super->s_inodes_per_group > fs->blocksize*8)
+ super->s_inodes_per_group = fs->blocksize*8;
+
+ /*
+ * Make sure the number of inodes per group completely fills
+ * the inode table blocks in the descriptor. If not, add some
+ * additional inodes/group. Waste not, want not...
+ */
+ fs->inode_blocks_per_group = (((super->s_inodes_per_group *
+ EXT2_INODE_SIZE(super)) +
+ EXT2_BLOCK_SIZE(super) - 1) /
+ EXT2_BLOCK_SIZE(super));
+ super->s_inodes_per_group = ((fs->inode_blocks_per_group *
+ EXT2_BLOCK_SIZE(super)) /
+ EXT2_INODE_SIZE(super));
+ /*
+ * Finally, make sure the number of inodes per group is a
+ * multiple of 8. This is needed to simplify the bitmap
+ * splicing code.
+ */
+ super->s_inodes_per_group &= ~7;
+ fs->inode_blocks_per_group = (((super->s_inodes_per_group *
+ EXT2_INODE_SIZE(super)) +
+ EXT2_BLOCK_SIZE(super) - 1) /
+ EXT2_BLOCK_SIZE(super));
+
+ /*
+ * adjust inode count to reflect the adjusted inodes_per_group
+ */
+ super->s_inodes_count = super->s_inodes_per_group *
+ fs->group_desc_count;
+ super->s_free_inodes_count = super->s_inodes_count;
+
+ /*
+ * Overhead is the number of bookkeeping blocks per group. It
+ * includes the superblock backup, the group descriptor
+ * backups, the inode bitmap, the block bitmap, and the inode
+ * table.
+ *
+ * XXX Not all block groups need the descriptor blocks, but
+ * being clever is tricky...
+ */
+ overhead = (int) (3 + fs->desc_blocks + fs->inode_blocks_per_group);
+
+ /*
+ * See if the last group is big enough to support the
+ * necessary data structures. If not, we need to get rid of
+ * it.
+ */
+ rem = (int) ((super->s_blocks_count - super->s_first_data_block) %
+ super->s_blocks_per_group);
+ if ((fs->group_desc_count == 1) && rem && (rem < overhead))
+ return EXT2_ET_TOOSMALL;
+ if (rem && (rem < overhead+50)) {
+ super->s_blocks_count -= rem;
+ goto retry;
+ }
+
+ /*
+ * At this point we know how big the filesystem will be. So
+ * we can do any and all allocations that depend on the block
+ * count.
+ */
+
+ retval = ext2fs_get_mem(strlen(fs->device_name) + 80,
+ (void **) &buf);
+ if (retval)
+ goto cleanup;
+
+ sprintf(buf, "block bitmap for %s", fs->device_name);
+ retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map);
+ if (retval)
+ goto cleanup;
+
+ sprintf(buf, "inode bitmap for %s", fs->device_name);
+ retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
+ if (retval)
+ goto cleanup;
+
+ ext2fs_free_mem((void **) &buf);
+
+ retval = ext2fs_get_mem((size_t) fs->desc_blocks * fs->blocksize,
+ (void **) &fs->group_desc);
+ if (retval)
+ goto cleanup;
+
+ memset(fs->group_desc, 0, (size_t) fs->desc_blocks * fs->blocksize);
+
+ /*
+ * Reserve the superblock and group descriptors for each
+ * group, and fill in the correct group statistics for group.
+ * Note that although the block bitmap, inode bitmap, and
+ * inode table have not been allocated (and in fact won't be
+ * by this routine), they are accounted for nevertheless.
+ */
+ group_block = super->s_first_data_block;
+ super->s_free_blocks_count = 0;
+ for (i = 0; i < fs->group_desc_count; i++) {
+ if (i == fs->group_desc_count-1) {
+ numblocks = (fs->super->s_blocks_count -
+ fs->super->s_first_data_block) %
+ fs->super->s_blocks_per_group;
+ if (!numblocks)
+ numblocks = fs->super->s_blocks_per_group;
+ } else
+ numblocks = fs->super->s_blocks_per_group;
+
+ if (ext2fs_bg_has_super(fs, i)) {
+ for (j=0; j < fs->desc_blocks+1; j++)
+ ext2fs_mark_block_bitmap(fs->block_map,
+ group_block + j);
+ numblocks -= 1 + fs->desc_blocks;
+ }
+
+ numblocks -= 2 + fs->inode_blocks_per_group;
+
+ super->s_free_blocks_count += numblocks;
+ fs->group_desc[i].bg_free_blocks_count = numblocks;
+ fs->group_desc[i].bg_free_inodes_count =
+ fs->super->s_inodes_per_group;
+ fs->group_desc[i].bg_used_dirs_count = 0;
+
+ group_block += super->s_blocks_per_group;
+ }
+
+ ext2fs_mark_super_dirty(fs);
+ ext2fs_mark_bb_dirty(fs);
+ ext2fs_mark_ib_dirty(fs);
+
+ io_channel_set_blksize(fs->io, fs->blocksize);
+
+ *ret_fs = fs;
+ return 0;
+cleanup:
+ ext2fs_free(fs);
+ return retval;
+}
+
+
+
diff --git a/e2fslib/initialize.o b/e2fslib/initialize.o
new file mode 100644
index 0000000..833c89f
--- /dev/null
+++ b/e2fslib/initialize.o
Binary files differ
diff --git a/e2fslib/inline.c b/e2fslib/inline.c
new file mode 100644
index 0000000..5833b1d
--- /dev/null
+++ b/e2fslib/inline.c
@@ -0,0 +1,32 @@
+/*
+ * inline.c --- Includes the inlined functions defined in the header
+ * files as standalone functions, in case the application program
+ * is compiled with inlining turned off.
+ *
+ * Copyright (C) 1993, 1994 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#define INCLUDE_INLINE_FUNCS
+#include "ext2fs.h"
+
diff --git a/e2fslib/inline.o b/e2fslib/inline.o
new file mode 100644
index 0000000..c727bb1
--- /dev/null
+++ b/e2fslib/inline.o
Binary files differ
diff --git a/e2fslib/inode.c b/e2fslib/inode.c
new file mode 100644
index 0000000..2da328c
--- /dev/null
+++ b/e2fslib/inode.c
@@ -0,0 +1,724 @@
+/*
+ * inode.c --- utility routines to read and write inodes
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fsP.h"
+#include "e2image.h"
+
+struct ext2_struct_inode_scan {
+ errcode_t magic;
+ ext2_filsys fs;
+ ext2_ino_t current_inode;
+ blk_t current_block;
+ dgrp_t current_group;
+ ext2_ino_t inodes_left;
+ blk_t blocks_left;
+ dgrp_t groups_left;
+ blk_t inode_buffer_blocks;
+ char * inode_buffer;
+ int inode_size;
+ char * ptr;
+ int bytes_left;
+ char *temp_buffer;
+ errcode_t (*done_group)(ext2_filsys fs,
+ ext2_inode_scan scan,
+ dgrp_t group,
+ void * priv_data);
+ void * done_group_data;
+ int bad_block_ptr;
+ int scan_flags;
+ int reserved[6];
+};
+
+/*
+ * This routine flushes the icache, if it exists.
+ */
+errcode_t ext2fs_flush_icache(ext2_filsys fs)
+{
+ int i;
+
+ if (!fs->icache)
+ return 0;
+
+ for (i=0; i < fs->icache->cache_size; i++)
+ fs->icache->cache[i].ino = 0;
+
+ 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),
+ (void **) &fs->icache);
+ if (retval)
+ return retval;
+
+ memset(fs->icache, 0, sizeof(struct ext2_inode_cache));
+ retval = ext2fs_get_mem(fs->blocksize, (void **) &fs->icache->buffer);
+ if (retval) {
+ ext2fs_free_mem((void **) &fs->icache);
+ return retval;
+ }
+ fs->icache->buffer_blk = 0;
+ fs->icache->cache_last = -1;
+ fs->icache->cache_size = 4;
+ fs->icache->refcount = 1;
+ retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache_ent)
+ * fs->icache->cache_size,
+ (void **) &fs->icache->cache);
+ if (retval) {
+ ext2fs_free_mem((void **) &fs->icache->buffer);
+ ext2fs_free_mem((void **) &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),
+ (void **) &scan);
+ if (retval)
+ return retval;
+ memset(scan, 0, sizeof(struct ext2_struct_inode_scan));
+
+ scan->magic = EXT2_ET_MAGIC_INODE_SCAN;
+ scan->fs = fs;
+ scan->inode_size = EXT2_INODE_SIZE(fs->super);
+ scan->bytes_left = 0;
+ scan->current_group = 0;
+ scan->groups_left = fs->group_desc_count - 1;
+ scan->inode_buffer_blocks = buffer_blocks ? buffer_blocks : 8;
+ scan->current_block = scan->fs->
+ group_desc[scan->current_group].bg_inode_table;
+ scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
+ scan->blocks_left = scan->fs->inode_blocks_per_group;
+ retval = ext2fs_get_mem((size_t) (scan->inode_buffer_blocks *
+ fs->blocksize),
+ (void **) &scan->inode_buffer);
+ scan->done_group = 0;
+ scan->done_group_data = 0;
+ scan->bad_block_ptr = 0;
+ if (retval) {
+ ext2fs_free_mem((void **) &scan);
+ return retval;
+ }
+ retval = ext2fs_get_mem(scan->inode_size,
+ (void **) &scan->temp_buffer);
+ if (retval) {
+ ext2fs_free_mem((void **) &scan->inode_buffer);
+ ext2fs_free_mem((void **) &scan);
+ return retval;
+ }
+ if (scan->fs->badblocks && scan->fs->badblocks->num)
+ scan->scan_flags |= EXT2_SF_CHK_BADBLOCKS;
+ *ret_scan = scan;
+ return 0;
+}
+
+void ext2fs_close_inode_scan(ext2_inode_scan scan)
+{
+ if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
+ return;
+
+ ext2fs_free_mem((void **) &scan->inode_buffer);
+ scan->inode_buffer = NULL;
+ ext2fs_free_mem((void **) &scan->temp_buffer);
+ scan->temp_buffer = NULL;
+ ext2fs_free_mem((void **) &scan);
+ return;
+}
+
+void ext2fs_set_inode_callback(ext2_inode_scan scan,
+ errcode_t (*done_group)(ext2_filsys fs,
+ ext2_inode_scan scan,
+ dgrp_t group,
+ void * priv_data),
+ void *done_group_data)
+{
+ if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
+ return;
+
+ scan->done_group = done_group;
+ scan->done_group_data = done_group_data;
+}
+
+int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
+ int clear_flags)
+{
+ int old_flags;
+
+ if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
+ return 0;
+
+ old_flags = scan->scan_flags;
+ scan->scan_flags &= ~clear_flags;
+ scan->scan_flags |= set_flags;
+ return old_flags;
+}
+
+/*
+ * This function is called by ext2fs_get_next_inode when it needs to
+ * get ready to read in a new blockgroup.
+ */
+static errcode_t get_next_blockgroup(ext2_inode_scan scan)
+{
+ scan->current_group++;
+ scan->groups_left--;
+
+ scan->current_block = scan->fs->
+ group_desc[scan->current_group].bg_inode_table;
+
+ scan->current_inode = scan->current_group *
+ EXT2_INODES_PER_GROUP(scan->fs->super);
+
+ scan->bytes_left = 0;
+ scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
+ scan->blocks_left = scan->fs->inode_blocks_per_group;
+ return 0;
+}
+
+errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
+ int group)
+{
+ scan->current_group = group - 1;
+ scan->groups_left = scan->fs->group_desc_count - group;
+ return get_next_blockgroup(scan);
+}
+
+/*
+ * This function is called by get_next_blocks() to check for bad
+ * blocks in the inode table.
+ *
+ * This function assumes that badblocks_list->list is sorted in
+ * increasing order.
+ */
+static errcode_t check_for_inode_bad_blocks(ext2_inode_scan scan,
+ blk_t *num_blocks)
+{
+ blk_t blk = scan->current_block;
+ badblocks_list bb = scan->fs->badblocks;
+
+ /*
+ * If the inode table is missing, then obviously there are no
+ * bad blocks. :-)
+ */
+ if (blk == 0)
+ return 0;
+
+ /*
+ * If the current block is greater than the bad block listed
+ * in the bad block list, then advance the pointer until this
+ * is no longer the case. If we run out of bad blocks, then
+ * we don't need to do any more checking!
+ */
+ while (blk > bb->list[scan->bad_block_ptr]) {
+ if (++scan->bad_block_ptr >= bb->num) {
+ scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
+ return 0;
+ }
+ }
+
+ /*
+ * If the current block is equal to the bad block listed in
+ * the bad block list, then handle that one block specially.
+ * (We could try to handle runs of bad blocks, but that
+ * only increases CPU efficiency by a small amount, at the
+ * expense of a huge expense of code complexity, and for an
+ * uncommon case at that.)
+ */
+ if (blk == bb->list[scan->bad_block_ptr]) {
+ scan->scan_flags |= EXT2_SF_BAD_INODE_BLK;
+ *num_blocks = 1;
+ if (++scan->bad_block_ptr >= bb->num)
+ scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
+ return 0;
+ }
+
+ /*
+ * If there is a bad block in the range that we're about to
+ * read in, adjust the number of blocks to read so that we we
+ * don't read in the bad block. (Then the next block to read
+ * will be the bad block, which is handled in the above case.)
+ */
+ if ((blk + *num_blocks) > bb->list[scan->bad_block_ptr])
+ *num_blocks = (int) (bb->list[scan->bad_block_ptr] - blk);
+
+ return 0;
+}
+
+/*
+ * This function is called by ext2fs_get_next_inode when it needs to
+ * read in more blocks from the current blockgroup's inode table.
+ */
+static errcode_t get_next_blocks(ext2_inode_scan scan)
+{
+ blk_t num_blocks;
+ errcode_t retval;
+
+ /*
+ * Figure out how many blocks to read; we read at most
+ * inode_buffer_blocks, and perhaps less if there aren't that
+ * many blocks left to read.
+ */
+ num_blocks = scan->inode_buffer_blocks;
+ if (num_blocks > scan->blocks_left)
+ num_blocks = scan->blocks_left;
+
+ /*
+ * If the past block "read" was a bad block, then mark the
+ * left-over extra bytes as also being bad.
+ */
+ if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK) {
+ if (scan->bytes_left)
+ scan->scan_flags |= EXT2_SF_BAD_EXTRA_BYTES;
+ scan->scan_flags &= ~EXT2_SF_BAD_INODE_BLK;
+ }
+
+ /*
+ * Do inode bad block processing, if necessary.
+ */
+ if (scan->scan_flags & EXT2_SF_CHK_BADBLOCKS) {
+ retval = check_for_inode_bad_blocks(scan, &num_blocks);
+ if (retval)
+ return retval;
+ }
+
+ if ((scan->scan_flags & EXT2_SF_BAD_INODE_BLK) ||
+ (scan->current_block == 0)) {
+ memset(scan->inode_buffer, 0,
+ (size_t) num_blocks * scan->fs->blocksize);
+ } else {
+ retval = io_channel_read_blk(scan->fs->io,
+ scan->current_block,
+ (int) num_blocks,
+ scan->inode_buffer);
+ if (retval)
+ return EXT2_ET_NEXT_INODE_READ;
+ }
+ scan->ptr = scan->inode_buffer;
+ scan->bytes_left = num_blocks * scan->fs->blocksize;
+
+ scan->blocks_left -= num_blocks;
+ if (scan->current_block)
+ scan->current_block += num_blocks;
+ return 0;
+}
+
+#if 0
+/*
+ * Returns 1 if the entire inode_buffer has a non-zero size and
+ * contains all zeros. (Not just deleted inodes, since that means
+ * that part of the inode table was used at one point; we want all
+ * zeros, which means that the inode table is pristine.)
+ */
+static inline int is_empty_scan(ext2_inode_scan scan)
+{
+ int i;
+
+ if (scan->bytes_left == 0)
+ return 0;
+
+ for (i=0; i < scan->bytes_left; i++)
+ if (scan->ptr[i])
+ return 0;
+ return 1;
+}
+#endif
+
+errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
+ struct ext2_inode *inode)
+{
+ errcode_t retval;
+ int extra_bytes = 0;
+
+ EXT2_CHECK_MAGIC(scan, EXT2_ET_MAGIC_INODE_SCAN);
+
+ /*
+ * Do we need to start reading a new block group?
+ */
+ if (scan->inodes_left <= 0) {
+ force_new_group:
+ if (scan->done_group) {
+ retval = (scan->done_group)
+ (scan->fs, scan, scan->current_group,
+ scan->done_group_data);
+ if (retval)
+ return retval;
+ }
+ if (scan->groups_left <= 0) {
+ *ino = 0;
+ return 0;
+ }
+ retval = get_next_blockgroup(scan);
+ if (retval)
+ return retval;
+ }
+ /*
+ * This is done outside the above if statement so that the
+ * check can be done for block group #0.
+ */
+ if (scan->current_block == 0) {
+ if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) {
+ goto force_new_group;
+ } else
+ return EXT2_ET_MISSING_INODE_TABLE;
+ }
+
+
+ /*
+ * Have we run out of space in the inode buffer? If so, we
+ * need to read in more blocks.
+ */
+ if (scan->bytes_left < scan->inode_size) {
+ memcpy(scan->temp_buffer, scan->ptr, scan->bytes_left);
+ extra_bytes = scan->bytes_left;
+
+ retval = get_next_blocks(scan);
+ if (retval)
+ return retval;
+#if 0
+ /*
+ * XXX test Need check for used inode somehow.
+ * (Note: this is hard.)
+ */
+ if (is_empty_scan(scan))
+ goto force_new_group;
+#endif
+ }
+
+ retval = 0;
+ if (extra_bytes) {
+ memcpy(scan->temp_buffer+extra_bytes, scan->ptr,
+ scan->inode_size - extra_bytes);
+ scan->ptr += scan->inode_size - extra_bytes;
+ scan->bytes_left -= scan->inode_size - extra_bytes;
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+ (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
+ ext2fs_swap_inode(scan->fs, inode,
+ (struct ext2_inode *) scan->temp_buffer, 0);
+ else
+#endif
+ *inode = *((struct ext2_inode *) scan->temp_buffer);
+ if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES)
+ retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
+ scan->scan_flags &= ~EXT2_SF_BAD_EXTRA_BYTES;
+ } else {
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+ (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
+ ext2fs_swap_inode(scan->fs, inode,
+ (struct ext2_inode *) scan->ptr, 0);
+ else
+#endif
+ *inode = *((struct ext2_inode *) scan->ptr);
+ 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;
+}
+
+/*
+ * Functions to read and write a single inode.
+ */
+errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode * inode)
+{
+ unsigned long group, block, block_nr, offset;
+ char *ptr;
+ errcode_t retval;
+ int clen, length, i, inodes_per_block;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ /* Check to see if user has an override function */
+ if (fs->read_inode) {
+ retval = (fs->read_inode)(fs, ino, inode);
+ if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
+ return retval;
+ }
+ /* Create inode cache if not present */
+ if (!fs->icache) {
+ retval = create_icache(fs);
+ if (retval)
+ return retval;
+ }
+ /* Check to see if it's in the inode cache */
+ for (i=0; i < fs->icache->cache_size; i++) {
+ if (fs->icache->cache[i].ino == ino) {
+ *inode = fs->icache->cache[i].inode;
+ return 0;
+ }
+ }
+ if ((ino == 0) || (ino > fs->super->s_inodes_count))
+ return EXT2_ET_BAD_INODE_NUM;
+ if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
+ inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super);
+ block_nr = fs->image_header->offset_inode / fs->blocksize;
+ block_nr += (ino - 1) / inodes_per_block;
+ offset = ((ino - 1) % inodes_per_block) *
+ EXT2_INODE_SIZE(fs->super);
+ } else {
+ group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
+ offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
+ EXT2_INODE_SIZE(fs->super);
+ block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
+ if (!fs->group_desc[(unsigned)group].bg_inode_table)
+ return EXT2_ET_MISSING_INODE_TABLE;
+ block_nr = fs->group_desc[(unsigned)group].bg_inode_table +
+ block;
+ }
+ if (block_nr != fs->icache->buffer_blk) {
+ retval = io_channel_read_blk(fs->io, block_nr, 1,
+ fs->icache->buffer);
+ if (retval)
+ return retval;
+ fs->icache->buffer_blk = block_nr;
+ }
+ offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
+ ptr = ((char *) fs->icache->buffer) + (unsigned) offset;
+
+ memset(inode, 0, sizeof(struct ext2_inode));
+ length = EXT2_INODE_SIZE(fs->super);
+ if (length > sizeof(struct ext2_inode))
+ length = sizeof(struct ext2_inode);
+
+ if ((offset + length) > EXT2_BLOCK_SIZE(fs->super)) {
+ clen = (int) (EXT2_BLOCK_SIZE(fs->super) - offset);
+ memcpy((char *) inode, ptr, clen);
+ length -= clen;
+
+ retval = io_channel_read_blk(fs->io, block_nr+1, 1,
+ fs->icache->buffer);
+ if (retval) {
+ fs->icache->buffer_blk = 0;
+ return retval;
+ }
+ fs->icache->buffer_blk = block_nr+1;
+
+ memcpy(((char *) inode) + clen,
+ fs->icache->buffer, length);
+ } else
+ memcpy((char *) inode, ptr, length);
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+ (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
+ ext2fs_swap_inode(fs, inode, inode, 0);
+#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_write_inode(ext2_filsys fs, ext2_ino_t ino,
+ struct ext2_inode * inode)
+{
+ unsigned long group, block, block_nr, offset;
+ errcode_t retval;
+ struct ext2_inode temp_inode;
+ char *ptr;
+ int clen, length, i;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ /* Check to see if user provided an override function */
+ if (fs->write_inode) {
+ retval = (fs->write_inode)(fs, ino, inode);
+ if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
+ return retval;
+ }
+
+ /* Check to see if the inode cache needs to be updated */
+ 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;
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+ if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
+ (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
+ ext2fs_swap_inode(fs, &temp_inode, inode, 1);
+ else
+#endif
+ memcpy(&temp_inode, inode, sizeof(struct ext2_inode));
+
+ group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
+ offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
+ EXT2_INODE_SIZE(fs->super);
+ block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
+ if (!fs->group_desc[(unsigned) group].bg_inode_table)
+ return EXT2_ET_MISSING_INODE_TABLE;
+ block_nr = fs->group_desc[(unsigned) group].bg_inode_table + block;
+ offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
+ ptr = (char *) fs->icache->buffer + (unsigned) offset;
+
+ length = EXT2_INODE_SIZE(fs->super);
+ clen = length;
+ if (length > sizeof(struct ext2_inode))
+ length = sizeof(struct ext2_inode);
+
+ if (fs->icache->buffer_blk != block_nr) {
+ retval = io_channel_read_blk(fs->io, block_nr, 1,
+ fs->icache->buffer);
+ if (retval)
+ return retval;
+ fs->icache->buffer_blk = block_nr;
+ }
+
+ if ((offset + length) > EXT2_BLOCK_SIZE(fs->super)) {
+ clen = (int) (EXT2_BLOCK_SIZE(fs->super) - offset);
+ length -= clen;
+ } else {
+ length = 0;
+ }
+ memcpy(ptr, &temp_inode, clen);
+ retval = io_channel_write_blk(fs->io, block_nr, 1, fs->icache->buffer);
+ if (retval)
+ return retval;
+
+ if (length) {
+ retval = io_channel_read_blk(fs->io, ++block_nr, 1,
+ fs->icache->buffer);
+ if (retval) {
+ fs->icache->buffer_blk = 0;
+ return retval;
+ }
+ fs->icache->buffer_blk = block_nr;
+ memcpy(fs->icache->buffer, ((char *) &temp_inode) + clen,
+ length);
+
+ retval = io_channel_write_blk(fs->io, block_nr, 1,
+ fs->icache->buffer);
+ if (retval)
+ return retval;
+ }
+
+ fs->flags |= EXT2_FLAG_CHANGED;
+ return 0;
+}
+
+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/e2fslib/inode.o b/e2fslib/inode.o
new file mode 100644
index 0000000..1cd9784
--- /dev/null
+++ b/e2fslib/inode.o
Binary files differ
diff --git a/e2fslib/irel.h b/e2fslib/irel.h
new file mode 100644
index 0000000..9b943ce
--- /dev/null
+++ b/e2fslib/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 Public
+ * License.
+ * %End-Header%
+ */
+
+struct ext2_inode_reference {
+ blk_t block;
+ __u16 offset;
+};
+
+struct ext2_inode_relocate_entry {
+ ext2_ino_t new;
+ ext2_ino_t orig;
+ __u16 flags;
+ __u16 max_refs;
+};
+
+typedef struct ext2_inode_relocation_table *ext2_irel;
+
+struct ext2_inode_relocation_table {
+ __u32 magic;
+ char *name;
+ ext2_ino_t current;
+ void *priv_data;
+
+ /*
+ * Add an inode relocation entry.
+ */
+ errcode_t (*put)(ext2_irel irel, ext2_ino_t old,
+ struct ext2_inode_relocate_entry *ent);
+ /*
+ * Get an inode relocation entry.
+ */
+ errcode_t (*get)(ext2_irel irel, ext2_ino_t old,
+ struct ext2_inode_relocate_entry *ent);
+
+ /*
+ * Get an inode relocation entry by its original inode number
+ */
+ errcode_t (*get_by_orig)(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
+ struct ext2_inode_relocate_entry *ent);
+
+ /*
+ * Initialize for iterating over the inode relocation entries.
+ */
+ errcode_t (*start_iter)(ext2_irel irel);
+
+ /*
+ * The iterator function for the inode relocation entries.
+ * Returns an inode number of 0 when out of entries.
+ */
+ errcode_t (*next)(ext2_irel irel, ext2_ino_t *old,
+ struct ext2_inode_relocate_entry *ent);
+
+ /*
+ * Add an inode reference (i.e., note the fact that a
+ * particular block/offset contains a reference to an inode)
+ */
+ errcode_t (*add_ref)(ext2_irel irel, ext2_ino_t ino,
+ struct ext2_inode_reference *ref);
+
+ /*
+ * Initialize for iterating over the inode references for a
+ * particular inode.
+ */
+ errcode_t (*start_iter_ref)(ext2_irel irel, ext2_ino_t ino);
+
+ /*
+ * The iterator function for the inode references for an
+ * inode. The references for only one inode can be interator
+ * over at a time, as the iterator state is stored in ext2_irel.
+ */
+ errcode_t (*next_ref)(ext2_irel irel,
+ struct ext2_inode_reference *ref);
+
+ /*
+ * Move the inode relocation table from one inode number to
+ * another. Note that the inode references also must move.
+ */
+ errcode_t (*move)(ext2_irel irel, ext2_ino_t old, ext2_ino_t new);
+
+ /*
+ * Remove an inode relocation entry, along with all of the
+ * inode references.
+ */
+ errcode_t (*delete)(ext2_irel irel, ext2_ino_t old);
+
+ /*
+ * Free the inode relocation table.
+ */
+ errcode_t (*free)(ext2_irel irel);
+};
+
+errcode_t ext2fs_irel_memarray_create(char *name, ext2_ino_t max_inode,
+ ext2_irel *irel);
+
+#define ext2fs_irel_put(irel, old, ent) ((irel)->put((irel), old, ent))
+#define ext2fs_irel_get(irel, old, ent) ((irel)->get((irel), old, ent))
+#define ext2fs_irel_get_by_orig(irel, orig, old, ent) \
+ ((irel)->get_by_orig((irel), orig, old, ent))
+#define ext2fs_irel_start_iter(irel) ((irel)->start_iter((irel)))
+#define ext2fs_irel_next(irel, old, ent) ((irel)->next((irel), old, ent))
+#define ext2fs_irel_add_ref(irel, ino, ref) ((irel)->add_ref((irel), ino, ref))
+#define ext2fs_irel_start_iter_ref(irel, ino) ((irel)->start_iter_ref((irel), ino))
+#define ext2fs_irel_next_ref(irel, ref) ((irel)->next_ref((irel), ref))
+#define ext2fs_irel_move(irel, old, new) ((irel)->move((irel), old, new))
+#define ext2fs_irel_delete(irel, old) ((irel)->delete((irel), old))
+#define ext2fs_irel_free(irel) ((irel)->free((irel)))
diff --git a/e2fslib/irel_ma.c b/e2fslib/irel_ma.c
new file mode 100644
index 0000000..437c06f
--- /dev/null
+++ b/e2fslib/irel_ma.c
@@ -0,0 +1,373 @@
+/*
+ * irel_ma.c
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+#include "irel.h"
+
+static errcode_t ima_put(ext2_irel irel, ext2_ino_t old,
+ struct ext2_inode_relocate_entry *ent);
+static errcode_t ima_get(ext2_irel irel, ext2_ino_t old,
+ struct ext2_inode_relocate_entry *ent);
+static errcode_t ima_get_by_orig(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
+ struct ext2_inode_relocate_entry *ent);
+static errcode_t ima_start_iter(ext2_irel irel);
+static errcode_t ima_next(ext2_irel irel, ext2_ino_t *old,
+ struct ext2_inode_relocate_entry *ent);
+static errcode_t ima_add_ref(ext2_irel irel, ext2_ino_t ino,
+ struct ext2_inode_reference *ref);
+static errcode_t ima_start_iter_ref(ext2_irel irel, ext2_ino_t ino);
+static errcode_t ima_next_ref(ext2_irel irel, struct ext2_inode_reference *ref);
+static errcode_t ima_move(ext2_irel irel, ext2_ino_t old, ext2_ino_t new);
+static errcode_t ima_delete(ext2_irel irel, ext2_ino_t old);
+static errcode_t ima_free(ext2_irel irel);
+
+/*
+ * This data structure stores the array of inode references; there is
+ * a structure for each inode.
+ */
+struct inode_reference_entry {
+ __u16 num;
+ struct ext2_inode_reference *refs;
+};
+
+struct irel_ma {
+ __u32 magic;
+ ext2_ino_t max_inode;
+ ext2_ino_t ref_current;
+ int ref_iter;
+ ext2_ino_t *orig_map;
+ struct ext2_inode_relocate_entry *entries;
+ struct inode_reference_entry *ref_entries;
+};
+
+errcode_t ext2fs_irel_memarray_create(char *name, ext2_ino_t max_inode,
+ ext2_irel *new_irel)
+{
+ ext2_irel irel = 0;
+ errcode_t retval;
+ struct irel_ma *ma = 0;
+ size_t size;
+
+ *new_irel = 0;
+
+ /*
+ * Allocate memory structures
+ */
+ retval = ext2fs_get_mem(sizeof(struct ext2_inode_relocation_table),
+ (void **) &irel);
+ if (retval)
+ goto errout;
+ memset(irel, 0, sizeof(struct ext2_inode_relocation_table));
+
+ retval = ext2fs_get_mem(strlen(name)+1, (void **) &irel->name);
+ if (retval)
+ goto errout;
+ strcpy(irel->name, name);
+
+ retval = ext2fs_get_mem(sizeof(struct irel_ma), (void **) &ma);
+ if (retval)
+ goto errout;
+ memset(ma, 0, sizeof(struct irel_ma));
+ irel->priv_data = ma;
+
+ size = (size_t) (sizeof(ext2_ino_t) * (max_inode+1));
+ retval = ext2fs_get_mem(size, (void **) &ma->orig_map);
+ if (retval)
+ goto errout;
+ memset(ma->orig_map, 0, size);
+
+ size = (size_t) (sizeof(struct ext2_inode_relocate_entry) *
+ (max_inode+1));
+ retval = ext2fs_get_mem(size, (void **) &ma->entries);
+ if (retval)
+ goto errout;
+ memset(ma->entries, 0, size);
+
+ size = (size_t) (sizeof(struct inode_reference_entry) *
+ (max_inode+1));
+ retval = ext2fs_get_mem(size, (void **) &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,
+ (void **) &ref_ent->refs);
+ if (retval)
+ return retval;
+ }
+
+ ma->entries[(unsigned) old] = *ent;
+ ma->orig_map[(unsigned) ent->orig] = old;
+ return 0;
+}
+
+static errcode_t ima_get(ext2_irel irel, ext2_ino_t old,
+ struct ext2_inode_relocate_entry *ent)
+{
+ struct irel_ma *ma;
+
+ ma = irel->priv_data;
+ if (old > ma->max_inode)
+ return EXT2_ET_INVALID_ARGUMENT;
+ if (ma->entries[(unsigned) old].new == 0)
+ return ENOENT;
+ *ent = ma->entries[(unsigned) old];
+ return 0;
+}
+
+static errcode_t ima_get_by_orig(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
+ struct ext2_inode_relocate_entry *ent)
+{
+ struct irel_ma *ma;
+ ext2_ino_t ino;
+
+ ma = irel->priv_data;
+ if (orig > ma->max_inode)
+ return EXT2_ET_INVALID_ARGUMENT;
+ ino = ma->orig_map[(unsigned) orig];
+ if (ino == 0)
+ return ENOENT;
+ *old = ino;
+ *ent = ma->entries[(unsigned) ino];
+ return 0;
+}
+
+static errcode_t ima_start_iter(ext2_irel irel)
+{
+ irel->current = 0;
+ return 0;
+}
+
+static errcode_t ima_next(ext2_irel irel, ext2_ino_t *old,
+ struct ext2_inode_relocate_entry *ent)
+{
+ struct irel_ma *ma;
+
+ ma = irel->priv_data;
+ while (++irel->current < ma->max_inode) {
+ if (ma->entries[(unsigned) irel->current].new == 0)
+ continue;
+ *old = irel->current;
+ *ent = ma->entries[(unsigned) irel->current];
+ return 0;
+ }
+ *old = 0;
+ return 0;
+}
+
+static errcode_t ima_add_ref(ext2_irel irel, ext2_ino_t ino,
+ struct ext2_inode_reference *ref)
+{
+ struct irel_ma *ma;
+ size_t size;
+ struct inode_reference_entry *ref_ent;
+ struct ext2_inode_relocate_entry *ent;
+ errcode_t retval;
+
+ ma = irel->priv_data;
+ if (ino > ma->max_inode)
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ ref_ent = ma->ref_entries + (unsigned) ino;
+ ent = ma->entries + (unsigned) ino;
+
+ /*
+ * If the inode reference array doesn't exist, create it.
+ */
+ if (ref_ent->refs == 0) {
+ size = (size_t) ((sizeof(struct ext2_inode_reference) *
+ ent->max_refs));
+ retval = ext2fs_get_mem(size, (void **) &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((void **) &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((void **) &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((void **) &ma->orig_map);
+ if (ma->entries)
+ ext2fs_free_mem((void **) &ma->entries);
+ if (ma->ref_entries) {
+ for (ino = 0; ino <= ma->max_inode; ino++) {
+ if (ma->ref_entries[(unsigned) ino].refs)
+ ext2fs_free_mem((void **) &ma->ref_entries[(unsigned) ino].refs);
+ }
+ ext2fs_free_mem((void **) &ma->ref_entries);
+ }
+ ext2fs_free_mem((void **) &ma);
+ }
+ if (irel->name)
+ ext2fs_free_mem((void **) &irel->name);
+ ext2fs_free_mem((void **) &irel);
+ return 0;
+}
diff --git a/e2fslib/ismounted.c b/e2fslib/ismounted.c
new file mode 100644
index 0000000..1b145c6
--- /dev/null
+++ b/e2fslib/ismounted.c
@@ -0,0 +1,261 @@
+/*
+ * ismounted.c --- Check to see if the filesystem was mounted
+ *
+ * Copyright (C) 1995,1996,1997,1998,1999,2000 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <fcntl.h>
+#ifdef HAVE_LINUX_FD_H
+#include <linux/fd.h>
+#endif
+#ifdef HAVE_MNTENT_H
+#include <mntent.h>
+#endif
+#ifdef HAVE_GETMNTINFO
+#include <paths.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#endif /* HAVE_GETMNTINFO */
+#include <string.h>
+#include <sys/stat.h>
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+#ifdef HAVE_MNTENT_H
+/*
+ * Helper function which checks a file in /etc/mtab format to see if a
+ * filesystem is mounted. Returns an error if the file doesn't exist
+ * or can't be opened.
+ */
+static errcode_t check_mntent_file(const char *mtab_file, const char *file,
+ int *mount_flags, char *mtpt, int mtlen)
+{
+ struct mntent *mnt;
+ struct stat st_mntpnt, st_file;
+ errcode_t retval = 0;
+ FILE *f;
+ int fd;
+
+ *mount_flags = 0;
+ if ((f = setmntent (mtab_file, "r")) == NULL)
+ return errno;
+ while ((mnt = getmntent (f)) != NULL)
+ if (strcmp(file, mnt->mnt_fsname) == 0)
+ 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 (stat("/", &st_mntpnt) == 0 && stat(file, &st_file) == 0) {
+ if (st_mntpnt.st_dev == st_file.st_rdev) {
+ *mount_flags = EXT2_MF_MOUNTED;
+ if (mtpt)
+ strncpy(mtpt, "/", mtlen);
+ goto is_root;
+ }
+ }
+#endif
+ goto exit;
+ }
+#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_mntpnt) < 0) {
+ retval = errno;
+ if (retval == ENOENT) {
+#ifdef DEBUG
+ printf("Bogus entry in %s! (%s does not exist)\n",
+ mtab_file, mnt->mnt_dir);
+#endif
+ retval = 0;
+ }
+ goto exit;
+ }
+ if (stat(file, &st_file) == 0) {
+ if (st_mntpnt.st_dev != st_file.st_rdev) {
+#ifdef DEBUG
+ printf("Bogus entry in %s! (%s not mounted on %s)\n",
+ mtab_file, file, mnt->mnt_dir);
+#endif
+ goto exit;
+ }
+ }
+#endif
+ *mount_flags = EXT2_MF_MOUNTED;
+
+ /* Check to see if the ro option is set */
+ if (hasmntopt(mnt, MNTOPT_RO))
+ *mount_flags |= EXT2_MF_READONLY;
+
+ if (mtpt)
+ strncpy(mtpt, mnt->mnt_dir, mtlen);
+ /*
+ * Check to see if we're referring to the root filesystem.
+ * If so, do a manual check to see if we can open /etc/mtab
+ * read/write, since if the root is mounted read/only, the
+ * contents of /etc/mtab may not be accurate.
+ */
+ if (!strcmp(mnt->mnt_dir, "/")) {
+is_root:
+#define TEST_FILE "/.ismount-test-file"
+ *mount_flags |= EXT2_MF_ISROOT;
+ fd = open(TEST_FILE, O_RDWR|O_CREAT);
+ if (fd < 0) {
+ if (errno == EROFS)
+ *mount_flags |= EXT2_MF_READONLY;
+ } else
+ close(fd);
+ (void) unlink(TEST_FILE);
+ }
+ retval = 0;
+exit:
+ 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
+#ifdef __linux__
+ retval = check_mntent_file("/proc/mounts", file, mount_flags,
+ mtpt, mtlen);
+ if (retval == 0)
+ return 0;
+#endif
+ retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen);
+ return retval;
+}
+
+#elif 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 */
+
+/*
+ * ext2fs_check_mount_point() returns 1 if the device is mounted, 0
+ * otherwise. 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)
+{
+#ifdef HAVE_MNTENT_H
+ return check_mntent(device, mount_flags, mtpt, mtlen);
+#else
+#ifdef HAVE_GETMNTINFO
+ return check_getmntinfo(device, mount_flags, mtpt, mtlen);
+#else
+#warning "Can't use getmntent or getmntinfo to check for mounted filesystems!"
+ *mount_flags = 0;
+ return 0;
+#endif /* HAVE_GETMNTINFO */
+#endif /* HAVE_MNTENT_H */
+}
+
+/*
+ * 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;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s device\n", argv[0]);
+ exit(1);
+ }
+
+ retval = ext2fs_check_if_mounted(argv[1], &mount_flags);
+ 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_MOUNTED)
+ printf("\t%s is mounted.\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]);
+
+ exit(0);
+}
+#endif
diff --git a/e2fslib/ismounted.o b/e2fslib/ismounted.o
new file mode 100644
index 0000000..7e06115
--- /dev/null
+++ b/e2fslib/ismounted.o
Binary files differ
diff --git a/e2fslib/jfs_dat.h b/e2fslib/jfs_dat.h
new file mode 100644
index 0000000..d6ad9c4
--- /dev/null
+++ b/e2fslib/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/e2fslib/jfs_user.h b/e2fslib/jfs_user.h
new file mode 100644
index 0000000..17a82c7
--- /dev/null
+++ b/e2fslib/jfs_user.h
@@ -0,0 +1,9 @@
+#ifndef _JFS_USER_H
+#define _JFS_USER_H
+
+typedef unsigned short kdev_t;
+
+#include <linux/jfs.h>
+
+
+#endif /* _JFS_USER_H */
diff --git a/e2fslib/libcom_err.a b/e2fslib/libcom_err.a
new file mode 100644
index 0000000..4c848dc
--- /dev/null
+++ b/e2fslib/libcom_err.a
Binary files differ
diff --git a/e2fslib/libext2fs.a b/e2fslib/libext2fs.a
new file mode 100644
index 0000000..2c8887b
--- /dev/null
+++ b/e2fslib/libext2fs.a
Binary files differ
diff --git a/e2fslib/link.c b/e2fslib/link.c
new file mode 100644
index 0000000..04ac00c
--- /dev/null
+++ b/e2fslib/link.c
@@ -0,0 +1,121 @@
+/*
+ * link.c --- create links in a ext2fs directory
+ *
+ * Copyright (C) 1993, 1994 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+struct link_struct {
+ const char *name;
+ int namelen;
+ ext2_ino_t inode;
+ int flags;
+ int done;
+ struct ext2_super_block *sb;
+};
+
+static int link_proc(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data)
+{
+ struct link_struct *ls = (struct link_struct *) priv_data;
+ struct ext2_dir_entry *next;
+ int rec_len, min_rec_len;
+ int ret = 0;
+
+ rec_len = EXT2_DIR_REC_LEN(ls->namelen);
+
+ /*
+ * See if the following directory entry (if any) is unused;
+ * if so, absorb it into this one.
+ */
+ next = (struct ext2_dir_entry *) (buf + offset + dirent->rec_len);
+ if ((offset + dirent->rec_len < blocksize - 8) &&
+ (next->inode == 0) &&
+ (offset + dirent->rec_len + next->rec_len <= blocksize)) {
+ dirent->rec_len += next->rec_len;
+ ret = DIRENT_CHANGED;
+ }
+
+ /*
+ * If the directory entry is used, see if we can split the
+ * directory entry to make room for the new name. If so,
+ * truncate it and return.
+ */
+ if (dirent->inode) {
+ min_rec_len = EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
+ if (dirent->rec_len < (min_rec_len + rec_len))
+ return ret;
+ rec_len = dirent->rec_len - min_rec_len;
+ dirent->rec_len = min_rec_len;
+ next = (struct ext2_dir_entry *) (buf + offset +
+ dirent->rec_len);
+ next->inode = 0;
+ next->name_len = 0;
+ next->rec_len = rec_len;
+ return DIRENT_CHANGED;
+ }
+
+ /*
+ * If we get this far, then the directory entry is not used.
+ * See if we can fit the request entry in. If so, do it.
+ */
+ if (dirent->rec_len < rec_len)
+ return ret;
+ dirent->inode = ls->inode;
+ dirent->name_len = ls->namelen;
+ strncpy(dirent->name, ls->name, ls->namelen);
+ if (ls->sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
+ dirent->name_len |= (ls->flags & 0x7) << 8;
+
+ ls->done++;
+ return DIRENT_ABORT|DIRENT_CHANGED;
+}
+
+/*
+ * Note: the low 3 bits of the flags field are used as the directory
+ * entry filetype.
+ */
+#ifdef __TURBOC__
+ #pragma argsused
+#endif
+errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
+ ext2_ino_t ino, int flags)
+{
+ errcode_t retval;
+ struct link_struct ls;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ if (!(fs->flags & EXT2_FLAG_RW))
+ return EXT2_ET_RO_FILSYS;
+
+ ls.name = name;
+ ls.namelen = name ? strlen(name) : 0;
+ ls.inode = ino;
+ ls.flags = flags;
+ ls.done = 0;
+ ls.sb = fs->super;
+
+ retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
+ 0, link_proc, &ls);
+ if (retval)
+ return retval;
+
+ return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE;
+}
diff --git a/e2fslib/link.o b/e2fslib/link.o
new file mode 100644
index 0000000..42913fc
--- /dev/null
+++ b/e2fslib/link.o
Binary files differ
diff --git a/e2fslib/linux/jfs.h b/e2fslib/linux/jfs.h
new file mode 100644
index 0000000..c00f4ed
--- /dev/null
+++ b/e2fslib/linux/jfs.h
@@ -0,0 +1,682 @@
+/*
+ * linux/include/linux/jfs.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_JFS_H
+#define _LINUX_JFS_H
+
+/* Allow this file to be included directly into e2fsprogs */
+#ifndef __KERNEL__
+#include "jfs_compat.h"
+#endif
+
+/*
+ * Debug code enabled by default for kernel builds
+ */
+#ifdef __KERNEL__
+#define JFS_DEBUG
+#endif
+
+extern int journal_enable_debug;
+
+#ifdef JFS_DEBUG
+#define jfs_debug(n, f, a...) \
+ do { \
+ if ((n) <= journal_enable_debug) { \
+ printk (KERN_DEBUG "JFS DEBUG: (%s, %d): %s: ", \
+ __FILE__