diff options
Diffstat (limited to 'lib/ext2fs')
-rw-r--r-- | lib/ext2fs/ChangeLog | 151 | ||||
-rw-r--r-- | lib/ext2fs/Makefile.in | 333 | ||||
-rw-r--r-- | lib/ext2fs/alloc.c | 31 | ||||
-rw-r--r-- | lib/ext2fs/alloc_tables.c | 80 | ||||
-rw-r--r-- | lib/ext2fs/badblocks.c | 101 | ||||
-rw-r--r-- | lib/ext2fs/bb_compat.c | 62 | ||||
-rw-r--r-- | lib/ext2fs/bb_inode.c | 48 | ||||
-rw-r--r-- | lib/ext2fs/bitmaps.c | 9 | ||||
-rw-r--r-- | lib/ext2fs/bitops.c | 10 | ||||
-rw-r--r-- | lib/ext2fs/bitops.h | 141 | ||||
-rw-r--r-- | lib/ext2fs/block.c | 151 | ||||
-rw-r--r-- | lib/ext2fs/brel.h | 84 | ||||
-rw-r--r-- | lib/ext2fs/brel_ma.c | 191 | ||||
-rw-r--r-- | lib/ext2fs/check_desc.c | 8 | ||||
-rw-r--r-- | lib/ext2fs/closefs.c | 47 | ||||
-rw-r--r-- | lib/ext2fs/cmp_bitmaps.c | 8 | ||||
-rw-r--r-- | lib/ext2fs/dblist.c | 175 | ||||
-rw-r--r-- | lib/ext2fs/dblist_dir.c | 79 | ||||
-rw-r--r-- | lib/ext2fs/dir_iterate.c | 134 | ||||
-rw-r--r-- | lib/ext2fs/dirblock.c | 9 |
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> |