summaryrefslogtreecommitdiff
path: root/lib/ext2fs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ext2fs')
-rw-r--r--lib/ext2fs/ChangeLog151
-rw-r--r--lib/ext2fs/Makefile.in333
-rw-r--r--lib/ext2fs/alloc.c31
-rw-r--r--lib/ext2fs/alloc_tables.c80
-rw-r--r--lib/ext2fs/badblocks.c101
-rw-r--r--lib/ext2fs/bb_compat.c62
-rw-r--r--lib/ext2fs/bb_inode.c48
-rw-r--r--lib/ext2fs/bitmaps.c9
-rw-r--r--lib/ext2fs/bitops.c10
-rw-r--r--lib/ext2fs/bitops.h141
-rw-r--r--lib/ext2fs/block.c151
-rw-r--r--lib/ext2fs/brel.h84
-rw-r--r--lib/ext2fs/brel_ma.c191
-rw-r--r--lib/ext2fs/check_desc.c8
-rw-r--r--lib/ext2fs/closefs.c47
-rw-r--r--lib/ext2fs/cmp_bitmaps.c8
-rw-r--r--lib/ext2fs/dblist.c175
-rw-r--r--lib/ext2fs/dblist_dir.c79
-rw-r--r--lib/ext2fs/dir_iterate.c134
-rw-r--r--lib/ext2fs/dirblock.c9
20 files changed, 1618 insertions, 234 deletions
diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog
index d8dad462..dd6da6a3 100644
--- a/lib/ext2fs/ChangeLog
+++ b/lib/ext2fs/ChangeLog
@@ -1,3 +1,154 @@
+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,
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 5319ce51..2867dce8 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -9,25 +9,34 @@ INSTALL = @INSTALL@
OBJS= ext2_err.o \
alloc.o \
+ alloc_tables.o \
badblocks.o \
+ bb_compat.o \
bb_inode.o \
bitmaps.o \
bitops.o \
block.o \
+ brel_ma.o \
check_desc.o \
closefs.o \
cmp_bitmaps.o \
+ dblist.o \
+ dblist_dir.o \
dirblock.o \
+ dir_iterate.o \
expanddir.o \
freefs.o \
get_pathname.o \
getsize.o \
+ icount.o \
initialize.o \
inline.o \
inode.o \
+ irel_ma.o \
ismounted.o \
link.o \
llseek.o \
+ lookup.o \
mkdir.o \
namei.o \
native.o \
@@ -35,31 +44,44 @@ OBJS= ext2_err.o \
openfs.o \
read_bb.o \
read_bb_file.o \
+ rs_bitmap.o \
rw_bitmaps.o \
swapfs.o \
- unix_io.o
+ test_io.o \
+ unix_io.o \
+ unlink.o \
+ valid_blk.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)/brel_ma.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)/expanddir.c \
$(srcdir)/freefs.c \
$(srcdir)/get_pathname.c \
$(srcdir)/getsize.c \
+ $(srcdir)/icount.c \
$(srcdir)/initialize.c \
$(srcdir)/inline.c \
$(srcdir)/inode.c \
+ $(srcdir)/irel_ma.c \
$(srcdir)/ismounted.c \
$(srcdir)/link.c \
$(srcdir)/llseek.c \
+ $(srcdir)/lookup.c \
$(srcdir)/mkdir.c \
$(srcdir)/namei.c \
$(srcdir)/native.c \
@@ -67,9 +89,13 @@ SRCS= ext2_err.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)/unix_io.c
+ $(srcdir)/test_io.c \
+ $(srcdir)/unix_io.c \
+ $(srcdir)/unlink.c \
+ $(srcdir)/valid_blk.c
HFILES= bitops.h ext2fs.h io.h
@@ -86,11 +112,12 @@ DLL_LIBS = -L../.. -lcom_err
DLL_MYDIR = ext2fs
DLL_INSTALL_DIR = $(libdir)
-ELF_VERSION = 2.1
+ELF_VERSION = 2.2
ELF_SO_VERSION = 2
ELF_IMAGE = libext2fs
ELF_MYDIR = ext2fs
ELF_INSTALL_DIR = $(libdir)
+ELF_OTHER_LIBS = -lc -L../.. -lcom_err
BSDLIB_VERSION = 2.0
BSDLIB_IMAGE = libext2fs
@@ -106,7 +133,7 @@ BSDLIB_INSTALL_DIR = $(libdir)
.c.o:
$(CC) $(ALL_CFLAGS) -c $< -o $@
-@PROFILE_CMT@ $(CC) $(ALL_CFLAGS) -pg -o profiled/$*.o -c $<
+@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 $<)
@@ -124,6 +151,17 @@ ext2_err.et: $(SUBSTITUTE) $(srcdir)/ext2_err.et.in
ext2_err.c ext2_err.h: ext2_err.et
$(COMPILE_ET) ext2_err.et
+tst_badblocks: tst_badblocks.o badblocks.o
+ $(CC) -o tst_badblocks tst_badblocks.o badblocks.o $(LIBCOM_ERR)
+
+tst_iscan: tst_iscan.o inode.o $(STATIC_LIBEXT2FS)
+ $(CC) -o tst_iscan tst_iscan.o inode.o $(STATIC_LIBEXT2FS) \
+ $(LIBCOM_ERR)
+
+check:: tst_badblocks tst_iscan
+ ./tst_badblocks
+ ./tst_iscan
+
installdirs::
$(top_srcdir)/mkinstalldirs $(DESTDIR)$(ulibdir) \
$(DESTDIR)$(includedir)/ext2fs
@@ -157,90 +195,205 @@ distclean:: clean
# the Makefile.in file
#
ext2_err.o: ext2_err.c
-alloc.o: $(srcdir)/alloc.c $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
-badblocks.o: $(srcdir)/badblocks.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
-bb_inode.o: $(srcdir)/bb_inode.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-bitmaps.o: $(srcdir)/bitmaps.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-bitops.o: $(srcdir)/bitops.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
-block.o: $(srcdir)/block.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-check_desc.o: $(srcdir)/check_desc.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-closefs.o: $(srcdir)/closefs.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-cmp_bitmaps.o: $(srcdir)/cmp_bitmaps.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-dirblock.o: $(srcdir)/dirblock.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-expanddir.o: $(srcdir)/expanddir.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-freefs.o: $(srcdir)/freefs.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-get_pathname.o: $(srcdir)/get_pathname.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-getsize.o: $(srcdir)/getsize.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-initialize.o: $(srcdir)/initialize.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-inline.o: $(srcdir)/inline.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-inode.o: $(srcdir)/inode.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-ismounted.o: $(srcdir)/ismounted.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-link.o: $(srcdir)/link.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-llseek.o: $(srcdir)/llseek.c $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/io.h
-mkdir.o: $(srcdir)/mkdir.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-namei.o: $(srcdir)/namei.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-native.o: $(srcdir)/native.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-newdir.o: $(srcdir)/newdir.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-openfs.o: $(srcdir)/openfs.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-read_bb.o: $(srcdir)/read_bb.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-read_bb_file.o: $(srcdir)/read_bb_file.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-rw_bitmaps.o: $(srcdir)/rw_bitmaps.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-swapfs.o: $(srcdir)/swapfs.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
- $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
-unix_io.o: $(srcdir)/unix_io.c $(top_srcdir)/lib/et/com_err.h \
+alloc.o: $(srcdir)/alloc.c \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+alloc_tables.o: $(srcdir)/alloc_tables.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+badblocks.o: $(srcdir)/badblocks.c \
+ $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+bb_compat.o: $(srcdir)/bb_compat.c \
+ $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+bb_inode.o: $(srcdir)/bb_inode.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+bitmaps.o: $(srcdir)/bitmaps.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+bitops.o: $(srcdir)/bitops.c \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+block.o: $(srcdir)/block.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+brel_ma.o: $(srcdir)/brel_ma.c \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h $(srcdir)/brel.h
+check_desc.o: $(srcdir)/check_desc.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+closefs.o: $(srcdir)/closefs.c \
+ $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+cmp_bitmaps.o: $(srcdir)/cmp_bitmaps.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+dblist.o: $(srcdir)/dblist.c \
+ $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+dblist_dir.o: $(srcdir)/dblist_dir.c \
+ $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+dirblock.o: $(srcdir)/dirblock.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+dir_iterate.o: $(srcdir)/dir_iterate.c \
+ $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+expanddir.o: $(srcdir)/expanddir.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+freefs.o: $(srcdir)/freefs.c \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+get_pathname.o: $(srcdir)/get_pathname.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+getsize.o: $(srcdir)/getsize.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+icount.o: $(srcdir)/icount.c $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2fs.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+initialize.o: $(srcdir)/initialize.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+inline.o: $(srcdir)/inline.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+inode.o: $(srcdir)/inode.c \
+ $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+irel_ma.o: $(srcdir)/irel_ma.c \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h $(srcdir)/irel.h
+ismounted.o: $(srcdir)/ismounted.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+link.o: $(srcdir)/link.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+llseek.o: $(srcdir)/llseek.c \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h
+lookup.o: $(srcdir)/lookup.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+mkdir.o: $(srcdir)/mkdir.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+namei.o: $(srcdir)/namei.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+native.o: $(srcdir)/native.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+newdir.o: $(srcdir)/newdir.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+openfs.o: $(srcdir)/openfs.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+read_bb.o: $(srcdir)/read_bb.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+read_bb_file.o: $(srcdir)/read_bb_file.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+rs_bitmap.o: $(srcdir)/rs_bitmap.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+rw_bitmaps.o: $(srcdir)/rw_bitmaps.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+swapfs.o: $(srcdir)/swapfs.c \
+ $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+test_io.o: $(srcdir)/test_io.c \
+ $(top_srcdir)/lib/et/com_err.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/io.h
+unix_io.o: $(srcdir)/unix_io.c \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/io.h
+unlink.o: $(srcdir)/unlink.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
+valid_blk.o: $(srcdir)/valid_blk.c \
+ $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/bitops.h
diff --git a/lib/ext2fs/alloc.c b/lib/ext2fs/alloc.c
index c0488795..0bc637db 100644
--- a/lib/ext2fs/alloc.c
+++ b/lib/ext2fs/alloc.c
@@ -1,8 +1,13 @@
/*
* alloc.c --- allocate new inodes, blocks for ext2fs
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * 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>
@@ -84,26 +89,12 @@ errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
return 0;
}
i++;
- if (i > fs->super->s_blocks_count)
+ if (i >= fs->super->s_blocks_count)
i = fs->super->s_first_data_block;
} while (i != goal);
return ENOSPC;
}
-static int check_blocks_free(ext2_filsys fs, ext2fs_block_bitmap map,
- blk_t blk, int num)
-{
- int i;
-
- for (i=0; i < num; i++) {
- if ((blk+i) > fs->super->s_blocks_count)
- return 0;
- if (ext2fs_test_block_bitmap(map, blk+i))
- return 0;
- }
- return 1;
-}
-
errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
int num, ext2fs_block_bitmap map, blk_t *ret)
{
@@ -122,13 +113,13 @@ errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
if (!num)
num = 1;
do {
- if (check_blocks_free(fs, map, b, num)) {
+ 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++;
- if (b > fs->super->s_blocks_count)
- b = fs->super->s_first_data_block;
} while (b != finish);
return ENOSPC;
}
diff --git a/lib/ext2fs/alloc_tables.c b/lib/ext2fs/alloc_tables.c
new file mode 100644
index 00000000..97bceefe
--- /dev/null
+++ b/lib/ext2fs/alloc_tables.c
@@ -0,0 +1,80 @@
+/*
+ * 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>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+
+errcode_t ext2fs_allocate_tables(ext2_filsys fs)
+{
+ errcode_t retval;
+ blk_t group_blk, last_blk, new_blk, blk;
+ int i, j;
+
+ group_blk = fs->super->s_first_data_block;
+ for (i = 0; i < fs->group_desc_count; i++) {
+ last_blk = group_blk + fs->super->s_blocks_per_group;
+
+ /*
+ * Allocate the block bitmap
+ */
+ retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
+ 1, fs->block_map, &new_blk);
+ if (retval)
+ return retval;
+ ext2fs_mark_block_bitmap(fs->block_map, new_blk);
+ fs->group_desc[i].bg_block_bitmap = new_blk;
+
+ /*
+ * ... and the inode bitmap
+ */
+ retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
+ 1, fs->block_map, &new_blk);
+ if (retval)
+ return retval;
+ ext2fs_mark_block_bitmap(fs->block_map, new_blk);
+ fs->group_desc[i].bg_inode_bitmap = new_blk;
+
+ /*
+ * Finally, allocate the inode table
+ */
+ retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
+ fs->inode_blocks_per_group,
+ fs->block_map, &new_blk);
+ if (retval)
+ return retval;
+ for (j=0, blk = new_blk;
+ j < fs->inode_blocks_per_group;
+ j++, blk++)
+ ext2fs_mark_block_bitmap(fs->block_map, blk);
+ fs->group_desc[i].bg_inode_table = new_blk;
+
+ /*
+ * Increment the start of the block group
+ */
+ group_blk += fs->super->s_blocks_per_group;
+ }
+ return 0;
+}
+
diff --git a/lib/ext2fs/badblocks.c b/lib/ext2fs/badblocks.c
index f286747b..722af8d0 100644
--- a/lib/ext2fs/badblocks.c
+++ b/lib/ext2fs/badblocks.c
@@ -1,8 +1,12 @@
/*
* badblocks.c --- routines to manipulate the bad block structure
*
- * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * 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>
@@ -19,19 +23,19 @@
#include <linux/ext2_fs.h>
-#include "ext2fs.h"
+#include "ext2fsP.h"
/*
* This procedure create an empty badblocks list.
*/
-errcode_t badblocks_list_create(badblocks_list *ret, int size)
+errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
{
- badblocks_list bb;
+ ext2_badblocks_list bb;
- bb = malloc(sizeof(struct struct_badblocks_list));
+ bb = malloc(sizeof(struct ext2_struct_badblocks_list));
if (!bb)
return ENOMEM;
- memset(bb, 0, sizeof(struct struct_badblocks_list));
+ memset(bb, 0, sizeof(struct ext2_struct_badblocks_list));
bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
bb->size = size ? size : 10;
bb->list = malloc(bb->size * sizeof(blk_t));
@@ -45,42 +49,42 @@ errcode_t badblocks_list_create(badblocks_list *ret, int size)
/*
* This procedure frees a badblocks list.
+ *
+ * (note: moved to closefs.c)
*/
-void badblocks_list_free(badblocks_list bb)
-{
- if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
- return;
- if (bb->list)
- free(bb->list);
- bb->list = 0;
- free(bb);
-}
/*
* This procedure adds a block to a badblocks list.
*/
-errcode_t badblocks_list_add(badblocks_list bb, blk_t blk)
+errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
{
- int i;
+ int i, j;
+ blk_t *new_list;
EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
- for (i=0; i < bb->num; i++)
- if (bb->list[i] == blk)
- return 0;
-
if (bb->num >= bb->size) {
bb->size += 10;
- bb->list = realloc(bb->list, bb->size * sizeof(blk_t));
- if (!bb->list) {
- bb->size = 0;
- bb->num = 0;
+ new_list = realloc(bb->list, bb->size * sizeof(blk_t));
+ if (!new_list)
return ENOMEM;
- }
+ bb->list = new_list;
}
- bb->list[bb->num++] = blk;
+ 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;
}
@@ -88,27 +92,42 @@ errcode_t badblocks_list_add(badblocks_list bb, blk_t blk)
* This procedure tests to see if a particular block is on a badblocks
* list.
*/
-int badblocks_list_test(badblocks_list bb, blk_t blk)
+int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
{
- int i;
+ int low, high, mid;
- EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
+ if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
+ return 0;
- for (i=0; i < bb->num; i++)
- if (bb->list[i] == blk)
- return 1;
+ 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 badblocks_list_iterate_begin(badblocks_list bb,
- badblocks_iterate *ret)
+errcode_t ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
+ ext2_badblocks_iterate *ret)
{
- badblocks_iterate iter;
+ ext2_badblocks_iterate iter;
EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
- iter = malloc(sizeof(struct struct_badblocks_iterate));
+ iter = malloc(sizeof(struct ext2_struct_badblocks_iterate));
if (!iter)
return ENOMEM;
@@ -119,9 +138,9 @@ errcode_t badblocks_list_iterate_begin(badblocks_list bb,
return 0;
}
-int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk)
+int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk)
{
- badblocks_list bb;
+ ext2_badblocks_list bb;
if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE)
return 0;
@@ -139,7 +158,7 @@ int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk)
return 0;
}
-void badblocks_list_iterate_end(badblocks_iterate iter)
+void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter)
{
if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE))
return;
diff --git a/lib/ext2fs/bb_compat.c b/lib/ext2fs/bb_compat.c
new file mode 100644
index 00000000..38aeb8aa
--- /dev/null
+++ b/lib/ext2fs/bb_compat.c
@@ -0,0 +1,62 @@
+/*
+ * 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>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/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/lib/ext2fs/bb_inode.c b/lib/ext2fs/bb_inode.c
index c8dfeba1..a5dd3a96 100644
--- a/lib/ext2fs/bb_inode.c
+++ b/lib/ext2fs/bb_inode.c
@@ -5,8 +5,12 @@
* this routine returns an error, the bad block inode may be in an
* inconsistent state.
*
- * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * 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>
@@ -26,7 +30,7 @@
#include "ext2fs.h"
struct set_badblock_record {
- badblocks_iterate bb_iter;
+ ext2_badblocks_iterate bb_iter;
int bad_block_count;
blk_t *ind_blocks;
int max_ind_blocks;
@@ -37,15 +41,16 @@ struct set_badblock_record {
};
static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt,
- void *private);
+ blk_t ref_block, int ref_offset, void *private);
static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt,
- void *private);
+ blk_t ref_block, int ref_offset,
+ void *private);
/*
* Given a bad blocks bitmap, update the bad blocks inode to reflect
* the map.
*/
-errcode_t ext2fs_update_bb_inode(ext2_filsys fs, badblocks_list bb_list)
+errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
{
errcode_t retval;
struct set_badblock_record rec;
@@ -75,9 +80,9 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, badblocks_list bb_list)
/*
* First clear the old bad blocks (while saving the indirect blocks)
*/
- retval = ext2fs_block_iterate(fs, EXT2_BAD_INO,
- BLOCK_FLAG_DEPTH_TRAVERSE, 0,
- clear_bad_block_proc, &rec);
+ 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) {
@@ -93,22 +98,24 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, badblocks_list bb_list)
* block inode (!).
*/
if (bb_list) {
- retval = badblocks_list_iterate_begin(bb_list, &rec.bb_iter);
+ retval = ext2fs_badblocks_list_iterate_begin(bb_list,
+ &rec.bb_iter);
if (retval)
goto cleanup;
- while (badblocks_list_iterate(rec.bb_iter, &blk)) {
+ while (ext2fs_badblocks_list_iterate(rec.bb_iter, &blk)) {
ext2fs_mark_block_bitmap(fs->block_map, blk);
}
- badblocks_list_iterate_end(rec.bb_iter);
+ ext2fs_badblocks_list_iterate_end(rec.bb_iter);
ext2fs_mark_bb_dirty(fs);
- retval = badblocks_list_iterate_begin(bb_list, &rec.bb_iter);
+ retval = ext2fs_badblocks_list_iterate_begin(bb_list,
+ &rec.bb_iter);
if (retval)
goto cleanup;
- retval = ext2fs_block_iterate(fs, EXT2_BAD_INO,
- BLOCK_FLAG_APPEND, 0,
- set_bad_block_proc, &rec);
- badblocks_list_iterate_end(rec.bb_iter);
+ 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) {
@@ -148,7 +155,7 @@ cleanup:
* indirect blocks.
*/
static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt,
- void *private)
+ blk_t ref_block, int ref_offset, void *private)
{
struct set_badblock_record *rec = (struct set_badblock_record *)
private;
@@ -201,7 +208,8 @@ static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, int blockcnt,
* Set the block list in the bad block inode, using the supplied bitmap.
*/
static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
- int blockcnt, void *private)
+ int blockcnt, blk_t ref_block,
+ int ref_offset, void *private)
{
struct set_badblock_record *rec = (struct set_badblock_record *)
private;
@@ -213,7 +221,7 @@ static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
/*
* Get the next bad block.
*/
- if (!badblocks_list_iterate(rec->bb_iter, &blk))
+ if (!ext2fs_badblocks_list_iterate(rec->bb_iter, &blk))
return BLOCK_ABORT;
rec->bad_block_count++;
} else {
diff --git a/lib/ext2fs/bitmaps.c b/lib/ext2fs/bitmaps.c
index 7250c800..3ef5666c 100644
--- a/lib/ext2fs/bitmaps.c
+++ b/lib/ext2fs/bitmaps.c
@@ -2,8 +2,12 @@
* bitmaps.c --- routines to read, write, and manipulate the inode and
* block bitmaps.
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * 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>
@@ -166,4 +170,3 @@ void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap)
memset(bitmap->bitmap, 0,
((bitmap->real_end - bitmap->start) / 8) + 1);
}
-
diff --git a/lib/ext2fs/bitops.c b/lib/ext2fs/bitops.c
index 6f256e5c..8ae02427 100644
--- a/lib/ext2fs/bitops.c
+++ b/lib/ext2fs/bitops.c
@@ -2,10 +2,12 @@
* bitops.c --- Bitmap frobbing code. See bitops.h for the inlined
* routines.
*
- * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
- * redistributed under the terms of the GNU Public License.
- *
- * Taken from <asm/bitops.h>, Copyright 1992, Linus Torvalds.
+ * 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>
diff --git a/lib/ext2fs/bitops.h b/lib/ext2fs/bitops.h
index e967c876..24bd5a74 100644
--- a/lib/ext2fs/bitops.h
+++ b/lib/ext2fs/bitops.h
@@ -2,10 +2,15 @@
* bitops.h --- Bitmap frobbing code. The byte swapping routines are
* also included here.
*
- * Copyright (C) 1993, 1994, 1995 Theodore Ts'o. This file may be
- * redistributed under the terms of the GNU Public License.
+ * 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%
*
- * Taken from <asm/bitops.h>, Copyright 1992, Linus Torvalds.
+ * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
+ * Linus Torvalds.
*/
@@ -54,9 +59,22 @@ extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
ino_t inode);
extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
-extern blk_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
+extern ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
-extern blk_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
+extern 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);
/*
* The inline routines themselves...
@@ -305,7 +323,14 @@ _INLINE_ __u32 ext2fs_swab32(__u32 val)
#endif /* !_EXT2_HAVE_ASM_SWAB */
_INLINE_ void ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
- __u32 bitno)
+ __u32 bitno);
+_INLINE_ void 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_ void ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ __u32 bitno)
{
if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
@@ -315,7 +340,7 @@ _INLINE_ void ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
}
_INLINE_ void ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
- blk_t bitno)
+ blk_t bitno)
{
if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
@@ -325,7 +350,7 @@ _INLINE_ void ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
}
_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
- blk_t bitno)
+ blk_t bitno)
{
if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
@@ -455,7 +480,7 @@ _INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
return bitmap->start;
}
-_INLINE_ blk_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
+_INLINE_ ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
{
return bitmap->start;
}
@@ -465,11 +490,107 @@ _INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
return bitmap->end;
}
-_INLINE_ blk_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
+_INLINE_ 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/lib/ext2fs/block.c b/lib/ext2fs/block.c
index b7f0aa3b..3552dab1 100644
--- a/lib/ext2fs/block.c
+++ b/lib/ext2fs/block.c
@@ -1,8 +1,12 @@
/*
* block.c --- iterate over all blocks in an inode
*
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * 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>
@@ -22,6 +26,8 @@ struct block_context {
int (*func)(ext2_filsys fs,
blk_t *blocknr,
int bcount,
+ blk_t ref_blk,
+ int ref_offset,
void *private);
int bcount;
int bsize;
@@ -33,16 +39,18 @@ struct block_context {
void *private;
};
-static int block_iterate_ind(blk_t *ind_block, struct block_context *ctx)
+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;
+ int i, flags, limit, offset;
blk_t *block_nr;
if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
!(ctx->flags & BLOCK_FLAG_DATA_ONLY))
ret = (*ctx->func)(ctx->fs, ind_block,
- BLOCK_COUNT_IND, ctx->private);
+ BLOCK_COUNT_IND, ref_block,
+ ref_offset, ctx->private);
if (!*ind_block || (ret & BLOCK_ABORT))
return ret;
if (*ind_block >= ctx->fs->super->s_blocks_count ||
@@ -65,27 +73,32 @@ static int block_iterate_ind(blk_t *ind_block, struct block_context *ctx)
*block_nr = ext2fs_swab32(*block_nr);
}
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->private);
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->private);
changed |= flags;
if (flags & BLOCK_ABORT) {
ret |= BLOCK_ABORT;
break;
}
+ offset += sizeof(blk_t);
}
}
if (changed & BLOCK_CHANGED) {
@@ -104,20 +117,23 @@ static int block_iterate_ind(blk_t *ind_block, struct block_context *ctx)
!(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
!(ret & BLOCK_ABORT))
ret |= (*ctx->func)(ctx->fs, ind_block,
- BLOCK_COUNT_IND, ctx->private);
+ BLOCK_COUNT_IND, ref_block,
+ ref_offset, ctx->private);
return ret;
}
-static int block_iterate_dind(blk_t *dind_block, struct block_context *ctx)
+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;
+ int i, flags, limit, offset;
blk_t *block_nr;
if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
!(ctx->flags & BLOCK_FLAG_DATA_ONLY))
ret = (*ctx->func)(ctx->fs, dind_block,
- BLOCK_COUNT_DIND, ctx->private);
+ BLOCK_COUNT_DIND, ref_block,
+ ref_offset, ctx->private);
if (!*dind_block || (ret & BLOCK_ABORT))
return ret;
if (*dind_block >= ctx->fs->super->s_blocks_count ||
@@ -140,25 +156,32 @@ static int block_iterate_dind(blk_t *dind_block, struct block_context *ctx)
*block_nr = ext2fs_swab32(*block_nr);
}
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, ctx);
+ 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)
continue;
- flags = block_iterate_ind(block_nr, ctx);
+ flags = block_iterate_ind(block_nr,
+ *dind_block, offset,
+ ctx);
changed |= flags;
if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
break;
}
+ offset += sizeof(blk_t);
}
}
if (changed & BLOCK_CHANGED) {
@@ -177,20 +200,23 @@ static int block_iterate_dind(blk_t *dind_block, struct block_context *ctx)
!(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
!(ret & BLOCK_ABORT))
ret |= (*ctx->func)(ctx->fs, dind_block,
- BLOCK_COUNT_DIND, ctx->private);
+ BLOCK_COUNT_DIND, ref_block,
+ ref_offset, ctx->private);
return ret;
}
-static int block_iterate_tind(blk_t *tind_block, struct block_context *ctx)
+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;
+ int i, flags, limit, offset;
blk_t *block_nr;
if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
!(ctx->flags & BLOCK_FLAG_DATA_ONLY))
ret = (*ctx->func)(ctx->fs, tind_block,
- BLOCK_COUNT_TIND, ctx->private);
+ BLOCK_COUNT_TIND, ref_block,
+ ref_offset, ctx->private);
if (!*tind_block || (ret & BLOCK_ABORT))
return ret;
if (*tind_block >= ctx->fs->super->s_blocks_count ||
@@ -213,25 +239,32 @@ static int block_iterate_tind(blk_t *tind_block, struct block_context *ctx)
*block_nr = ext2fs_swab32(*block_nr);
}
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, ctx);
+ 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)
continue;
- flags = block_iterate_dind(block_nr, ctx);
+ flags = block_iterate_dind(block_nr,
+ *tind_block,
+ offset, ctx);
changed |= flags;
if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
break;
}
+ offset += sizeof(blk_t);
}
}
if (changed & BLOCK_CHANGED) {
@@ -250,29 +283,32 @@ static int block_iterate_tind(blk_t *tind_block, struct block_context *ctx)
!(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
!(ret & BLOCK_ABORT))
ret |= (*ctx->func)(ctx->fs, tind_block,
- BLOCK_COUNT_TIND, ctx->private);
+ BLOCK_COUNT_TIND, ref_block,
+ ref_offset, ctx->private);
return ret;
}
-errcode_t ext2fs_block_iterate(ext2_filsys fs,
- ino_t ino,
- int flags,
- char *block_buf,
- int (*func)(ext2_filsys fs,
- blk_t *blocknr,
- int blockcnt,
- void *private),
- void *private)
+errcode_t ext2fs_block_iterate2(ext2_filsys fs,
+ ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_filsys fs,
+ blk_t *blocknr,
+ int blockcnt,
+ blk_t ref_blk,
+ int ref_offset,
+ void *private),
+ void *private)
{
int i;
int got_inode = 0;
int ret = 0;
- struct block_context ctx;
blk_t blocks[EXT2_N_BLOCKS]; /* directory data blocks */
struct ext2_inode inode;
errcode_t retval;
-
+ struct block_context ctx;
+
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
ret = ext2fs_get_blocks(fs, ino, blocks);
@@ -282,8 +318,8 @@ errcode_t ext2fs_block_iterate(ext2_filsys fs,
ctx.fs = fs;
ctx.func = func;
ctx.private = private;
- ctx.bcount = 0;
ctx.flags = flags;
+ ctx.bcount = 0;
if (block_buf) {
ctx.ind_buf = block_buf;
} else {
@@ -304,8 +340,10 @@ errcode_t ext2fs_block_iterate(ext2_filsys fs,
goto abort;
got_inode = 1;
if (inode.osd1.hurd1.h_i_translator) {
- ret |= (*func)(fs, &inode.osd1.hurd1.h_i_translator,
- BLOCK_COUNT_TRANSLATOR, private);
+ ret |= (*ctx.func)(fs,
+ &inode.osd1.hurd1.h_i_translator,
+ BLOCK_COUNT_TRANSLATOR,
+ 0, 0, private);
if (ret & BLOCK_ABORT)
goto abort;
}
@@ -316,23 +354,27 @@ errcode_t ext2fs_block_iterate(ext2_filsys fs,
*/
for (i = 0; i < EXT2_NDIR_BLOCKS ; i++, ctx.bcount++) {
if (blocks[i] || (flags & BLOCK_FLAG_APPEND)) {
- ret |= (*func)(fs, &blocks[i], ctx.bcount, private);
+ ret |= (*ctx.func)(fs, &blocks[i],
+ ctx.bcount, 0, 0, private);
if (ret & BLOCK_ABORT)
goto abort;
}
}
if (*(blocks + EXT2_IND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
- ret |= block_iterate_ind(blocks + EXT2_IND_BLOCK, &ctx);
+ ret |= block_iterate_ind(blocks + EXT2_IND_BLOCK,
+ 0, 0, &ctx);
if (ret & BLOCK_ABORT)
goto abort;
}
if (*(blocks + EXT2_DIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
- ret |= block_iterate_dind(blocks + EXT2_DIND_BLOCK, &ctx);
+ ret |= block_iterate_dind(blocks + EXT2_DIND_BLOCK,
+ 0, 0, &ctx);
if (ret & BLOCK_ABORT)
goto abort;
}
if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
- ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK, &ctx);
+ ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK,
+ 0, 0, &ctx);
if (ret & BLOCK_ABORT)
goto abort;
}
@@ -356,3 +398,40 @@ abort:
return (ret & BLOCK_ERROR) ? ctx.errcode : 0;
}
+
+struct xlate {
+ int (*func)(ext2_filsys fs,
+ blk_t *blocknr,
+ int bcount,
+ void *private);
+ void *real_private;
+};
+
+static int xlate_func(ext2_filsys fs, blk_t *blocknr, int blockcnt,
+ blk_t ref_block, int ref_offset, void *private)
+{
+ struct xlate *xl = private;
+
+ return (*xl->func)(fs, blocknr, blockcnt, xl->real_private);
+}
+
+errcode_t ext2fs_block_iterate(ext2_filsys fs,
+ ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_filsys fs,
+ blk_t *blocknr,
+ int blockcnt,
+ void *private),
+ void *private)
+{
+ struct xlate xl;
+
+ xl.real_private = private;
+ xl.func = func;
+
+ return ext2fs_block_iterate2(fs, ino, flags, block_buf,
+ xlate_func, &xl);
+}
+
+
diff --git a/lib/ext2fs/brel.h b/lib/ext2fs/brel.h
new file mode 100644
index 00000000..f31b7ae2
--- /dev/null
+++ b/lib/ext2fs/brel.h
@@ -0,0 +1,84 @@
+/*
+ * 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;
+ ino_t inode_ref;
+ } owner;
+};
+
+#define RELOCATE_INODE_REF 0x0001
+
+typedef struct ext2_block_relocation_table *ext2_brel;
+
+struct ext2_block_relocation_table {
+ __u32 magic;
+ char *name;
+ blk_t current;
+ void *private;
+
+ /*
+ * 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/lib/ext2fs/brel_ma.c b/lib/ext2fs/brel_ma.c
new file mode 100644
index 00000000..a4258a70
--- /dev/null
+++ b/lib/ext2fs/brel_ma.c
@@ -0,0 +1,191 @@
+/*
+ * brel_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 <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <linux/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 = ENOMEM;
+ brel = malloc(sizeof(struct ext2_block_relocation_table));
+ if (!brel)
+ goto errout;
+ memset(brel, 0, sizeof(struct ext2_block_relocation_table));
+
+ brel->name = malloc(strlen(name)+1);
+ if (!brel->name)
+ goto errout;
+ strcpy(brel->name, name);
+
+ ma = malloc(sizeof(struct brel_ma));
+ if (!ma)
+ goto errout;
+ memset(ma, 0, sizeof(struct brel_ma));
+ brel->private = ma;
+
+ size = sizeof(struct ext2_block_relocate_entry) * (max_block+1);
+ ma->entries = malloc(size);
+ if (!ma->entries)
+ 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->private;
+ if (old > ma->max_block)
+ return EINVAL;
+ ma->entries[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->private;
+ if (old > ma->max_block)
+ return EINVAL;
+ if (ma->entries[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->private;
+ while (++brel->current < ma->max_block) {
+ if (ma->entries[brel->current].new == 0)
+ continue;
+ *old = brel->current;
+ *ent = ma->entries[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->private;
+ if ((old > ma->max_block) || (new > ma->max_block))
+ return EINVAL;
+ if (ma->entries[old].new == 0)
+ return ENOENT;
+ ma->entries[new] = ma->entries[old];
+ ma->entries[old].new = 0;
+ return 0;
+}
+
+static errcode_t bma_delete(ext2_brel brel, blk_t old)
+{
+ struct brel_ma *ma;
+
+ ma = brel->private;
+ if (old > ma->max_block)
+ return EINVAL;
+ if (ma->entries[old].new == 0)
+ return ENOENT;
+ ma->entries[old].new = 0;
+ return 0;
+}
+
+static errcode_t bma_free(ext2_brel brel)
+{
+ struct brel_ma *ma;
+
+ if (!brel)
+ return 0;
+
+ ma = brel->private;
+
+ if (ma) {
+ if (ma->entries)
+ free (ma->entries);
+ free(ma);
+ }
+ if (brel->name)
+ free(brel->name);
+ free (brel);
+ return 0;
+}
diff --git a/lib/ext2fs/check_desc.c b/lib/ext2fs/check_desc.c
index 7d3f3d41..74b3e2d4 100644
--- a/lib/ext2fs/check_desc.c
+++ b/lib/ext2fs/check_desc.c
@@ -1,8 +1,12 @@
/*
* check_desc.c --- Check the group descriptors of an ext2 filesystem
*
- * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * 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>
diff --git a/lib/ext2fs/closefs.c b/lib/ext2fs/closefs.c
index 18a93db5..e24b6b69 100644
--- a/lib/ext2fs/closefs.c
+++ b/lib/ext2fs/closefs.c
@@ -1,8 +1,12 @@
/*
* closefs.c --- close an ext2 filesystem
*
- * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * 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>
@@ -16,7 +20,7 @@
#include <linux/ext2_fs.h>
-#include "ext2fs.h"
+#include "ext2fsP.h"
errcode_t ext2fs_flush(ext2_filsys fs)
{
@@ -118,7 +122,6 @@ errcode_t ext2fs_flush(ext2_filsys fs)
if (retval)
goto errout;
}
-
retval = 0;
errout:
fs->super->s_state = fs_state;
@@ -142,6 +145,42 @@ errcode_t ext2fs_close(ext2_filsys fs)
if (retval)
return retval;
}
+ if (fs->write_bitmaps) {
+ retval = fs->write_bitmaps(fs);
+ if (retval)
+ return retval;
+ }
ext2fs_free(fs);
return 0;
}
+
+/*
+ * This procedure frees a badblocks list.
+ */
+void ext2fs_badblocks_list_free(ext2_badblocks_list bb)
+{
+ if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
+ return;
+
+ if (bb->list)
+ free(bb->list);
+ bb->list = 0;
+ free(bb);
+}
+
+/*
+ * Close a directory block list
+ */
+void ext2fs_free_dblist(ext2_dblist dblist)
+{
+ if (!dblist || (dblist->magic != EXT2_ET_MAGIC_DBLIST))
+ return;
+
+ if (dblist->list)
+ free(dblist->list);
+ dblist->list = 0;
+ if (dblist->fs && dblist->fs->dblist == dblist)
+ dblist->fs->dblist = 0;
+ dblist->magic = 0;
+ free(dblist);
+}
diff --git a/lib/ext2fs/cmp_bitmaps.c b/lib/ext2fs/cmp_bitmaps.c
index cc9eb6d7..3d04a97e 100644
--- a/lib/ext2fs/cmp_bitmaps.c
+++ b/lib/ext2fs/cmp_bitmaps.c
@@ -1,8 +1,12 @@
/*
* cmp_bitmaps.c --- routines to compare inode and block bitmaps.
*
- * Copyright (C) 1995 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * 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>
diff --git a/lib/ext2fs/dblist.c b/lib/ext2fs/dblist.c
new file mode 100644
index 00000000..72d58407
--- /dev/null
+++ b/lib/ext2fs/dblist.c
@@ -0,0 +1,175 @@
+/*
+ * 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>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fsP.h"
+
+static int 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, ino_t *ret_num_dirs)
+{
+ int i;
+ ino_t num_dirs;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ num_dirs = 0;
+ for (i = 0; i < fs->group_desc_count; i++)
+ num_dirs += fs->group_desc[i].bg_used_dirs_count;
+
+ *ret_num_dirs = num_dirs;
+
+ return 0;
+}
+
+/*
+ * Initialize a directory block list
+ */
+errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist)
+{
+ ext2_dblist dblist;
+ errcode_t retval;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ if ((ret_dblist == 0) && fs->dblist &&
+ (fs->dblist->magic == EXT2_ET_MAGIC_DBLIST))
+ return 0;
+
+ dblist = malloc(sizeof(struct ext2_struct_dblist));
+ if (!dblist)
+ return ENOMEM;
+ memset(dblist, 0, sizeof(struct ext2_struct_dblist));
+
+ dblist->magic = EXT2_ET_MAGIC_DBLIST;
+ dblist->fs = fs;
+ retval = ext2fs_get_num_dirs(fs, &dblist->size);
+ if (retval)
+ goto cleanup;
+
+ dblist->count = 0;
+ dblist->sorted = 1;
+ dblist->list = malloc(sizeof(struct ext2_db_entry) * dblist->size);
+ if (dblist->list == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ if (ret_dblist)
+ *ret_dblist = dblist;
+ else
+ fs->dblist = dblist;
+
+ return 0;
+cleanup:
+ if (dblist)
+ free(dblist);
+ return retval;
+}
+
+/*
+ * 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, ino_t ino, blk_t blk,
+ int blockcnt)
+{
+ struct ext2_db_entry *nlist, *new;
+
+ EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+
+ if (dblist->count >= dblist->size) {
+ dblist->size += 100;
+ nlist = realloc(dblist->list,
+ dblist->size * sizeof(struct ext2_db_entry));
+ if (nlist == 0) {
+ dblist->size -= 100;
+ return ENOMEM;
+ }
+ dblist->list = nlist;
+ }
+ new = dblist->list + dblist->count++;
+ new->blk = blk;
+ new->ino = ino;
+ new->blockcnt = blockcnt;
+
+ dblist->sorted = 0;
+
+ return 0;
+}
+
+/*
+ * 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 *private),
+ void *private)
+{
+ ino_t i;
+ int ret;
+
+ EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
+
+ if (!dblist->sorted) {
+ qsort(dblist->list, 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[i], private);
+ if (ret & DBLIST_ABORT)
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static int 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 (db_a->blk - db_b->blk);
+
+ if (db_a->ino != db_b->ino)
+ return (db_a->ino - db_b->ino);
+
+ return (db_a->blockcnt - db_b->blockcnt);
+}
+
+
diff --git a/lib/ext2fs/dblist_dir.c b/lib/ext2fs/dblist_dir.c
new file mode 100644
index 00000000..10c7b58a
--- /dev/null
+++ b/lib/ext2fs/dblist_dir.c
@@ -0,0 +1,79 @@
+/*
+ * 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>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fsP.h"
+
+static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info,
+ void *private);
+
+extern errcode_t
+ ext2fs_dblist_dir_iterate(ext2_dblist dblist,
+ int flags,
+ char *block_buf,
+ int (*func)(ino_t dir,
+ int entry,
+ struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *private),
+ void *private)
+{
+ 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 {
+ ctx.buf = malloc(dblist->fs->blocksize);
+ if (!ctx.buf)
+ return ENOMEM;
+ }
+ ctx.func = 0;
+ ctx.func2 = func;
+ ctx.private = private;
+ ctx.errcode = 0;
+
+ retval = ext2fs_dblist_iterate(dblist, db_dir_proc, &ctx);
+
+ if (!block_buf)
+ free(ctx.buf);
+ if (retval)
+ return retval;
+ return ctx.errcode;
+}
+
+static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info,
+ void *private)
+{
+ struct dir_context *ctx = private;
+
+ ctx->dir = db_info->ino;
+
+ return ext2fs_process_dir_block(fs, &db_info->blk,
+ db_info->blockcnt, private);
+}
diff --git a/lib/ext2fs/dir_iterate.c b/lib/ext2fs/dir_iterate.c
new file mode 100644
index 00000000..91f8ca67
--- /dev/null
+++ b/lib/ext2fs/dir_iterate.c
@@ -0,0 +1,134 @@
+/*
+ * 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>
+#include <unistd.h>
+#include <stdlib.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fsP.h"
+
+errcode_t ext2fs_dir_iterate(ext2_filsys fs,
+ ino_t dir,
+ int flags,
+ char *block_buf,
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *private),
+ void *private)
+{
+ 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 {
+ ctx.buf = malloc(fs->blocksize);
+ if (!ctx.buf)
+ return ENOMEM;
+ }
+ ctx.func = func;
+ ctx.func2 = 0;
+ ctx.private = private;
+ ctx.errcode = 0;
+ retval = ext2fs_block_iterate(fs, dir, 0, 0,
+ ext2fs_process_dir_block, &ctx);
+ if (!block_buf)
+ free(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()
+ */
+extern int ext2fs_process_dir_block(ext2_filsys fs,
+ blk_t *blocknr,
+ int blockcnt,
+ void *private)
+{
+ struct dir_context *ctx = (struct dir_context *) private;
+ 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;
+
+ ctx->errcode = ext2fs_read_dir_block(fs, *blocknr, ctx->buf);
+ if (ctx->errcode)
+ return BLOCK_ABORT;
+
+ entry = blockcnt ? DIRENT_OTHER_FILE : DIRENT_DOT_FILE;
+
+ while (offset < fs->blocksize) {
+ dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
+ if (!dirent->inode &&
+ !(ctx->flags & DIRENT_FLAG_INCLUDE_EMPTY))
+ goto next;
+
+ if (ctx->func)
+ ret = (ctx->func)(dirent, offset, fs->blocksize,
+ ctx->buf, ctx->private);
+ else if (ctx->func2) {
+ ret = (ctx->func2)(ctx->dir, entry, dirent, offset,
+ fs->blocksize, ctx->buf,
+ ctx->private);
+ if (entry < DIRENT_OTHER_FILE)
+ entry++;
+ }
+
+ if (ret & DIRENT_CHANGED)
+ changed++;
+ if (ret & DIRENT_ABORT) {
+ do_abort++;
+ break;
+ }
+next:
+ if (((offset + dirent->rec_len) > fs->blocksize) ||
+ (dirent->rec_len < 8) ||
+ ((dirent->name_len+8) > dirent->rec_len)) {
+ ctx->errcode = EXT2_ET_DIR_CORRUPTED;
+ return BLOCK_ABORT;
+ }
+ 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/lib/ext2fs/dirblock.c b/lib/ext2fs/dirblock.c
index 0f56617d..4db5b18c 100644
--- a/lib/ext2fs/dirblock.c
+++ b/lib/ext2fs/dirblock.c
@@ -1,13 +1,18 @@
/*
* dirblock.c --- directory block routines.
*
- * Copyright (C) 1995 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
+ * 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>
#include <unistd.h>
#include <stdlib.h>
+#include <string.h>
#include <time.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>