Many files:
Checked in e2fsprogs 1.05
diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog
index 90de2b5..41c9c54 100644
--- a/lib/ext2fs/ChangeLog
+++ b/lib/ext2fs/ChangeLog
@@ -1,3 +1,87 @@
+Sat Sep 7 07:36:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c: Override the kernel's idea of default
+ checkinterval from 0 (never) to 180 days.
+
+Wed Aug 28 03:20:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * namei.c (ext2fs_namei_follow): New function which follows
+ symbolic link (if any) at the target.
+
+Tue Aug 27 01:48:43 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_read_inode, ext2fs_write_inode): Add support
+ for shortcut function fs->read_inode() and fs->write_inode().
+ Added inode_cache to reduce CPU time spent in doing
+ byte swapping.
+
+ * swapfs.c (ext2fs_swap_super): Swap the new fields in a V2
+ superblock.
+
+ * namei.c (ext2fs_follow_link): New function.
+ (ext2fs_namei): Extended to have support for chasing
+ symbolic links. ext2fs_namei() still returns an inode
+ which is a symbolic link. Symbolic links are only chased
+ while resolving the containing directory. To chase
+ symbolic links of the final result, use
+ ext2fs_follow_link().
+
+Mon Aug 26 23:46:07 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2_err.et.in: Added new error code EXT2_ET_SYMLINK_LOOP.
+
+ * bitops.h (ext2fs_set_bit, ext2fs_celar_bit): Use asm inlines
+ provided by Pete A. Zaitcev (zaitcev@lab.sun.mcst.ru).
+
+Thu Aug 22 00:40:18 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c (ext2fs_initialize): On systems where the byte
+ order is not i386 compatible, set the swap_byte flag.
+
+ * inode.c (inocpy_with_swap): Check to see if inode contains a
+ fast symlink before swapping the inode block fields. This
+ required adding a new argument to inocpy_with_swap to
+ determine whether the mode field is in host order or not.
+
+Wed Aug 21 00:45:42 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * bitops.h (ext2fs_set_bit, ext2fs_clear_bit, ext2fs_test_bit): On
+ the sparc, if EXT2_STD_BITOPS set, use the standard
+ i386-compatible bitmask operations, instead on the
+ non-standard native bitmask operators.
+
+Fri Aug 9 11:11:35 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * block.c (ext2fs_block_iterate): Cause block iterator to return
+ the HURD translator block (along with everything else).
+ If the flag BLOCK_FLAG_DATA_ONLY is passed to the block
+ iterator, then don't return any meta data blocks
+ (including the HURD translator).
+
+Wed Jul 17 17:13:34 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * gen_uuid.c: New file, which generates DCE-compatible UUIDs.
+
+ * uuid.c: New file, containing UUID utility functions.
+
+Tue Jul 16 10:19:16 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: Add a definition of the "real" ext2 superblock.
+
+Fri May 24 14:54:55 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: Fix erroneous ino_t type used in block_bitmap type.
+
+Sun May 19 15:39:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * openfs.c (ext2fs_open): If the blocksize in the superblock is
+ zero, return the error EXT2_ET_CORRUPT_SUPERBLOCK, since
+ that's a basic value that must be correct for the rest of
+ the library to work.
+
+ * ext2_err.et.in (EXT2_ET_CORRUPT_SUPERBLOCK): Added new error
+ code.
+
Thu May 16 11:12:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.04
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 2666977..5319ce5 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -2,6 +2,7 @@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = ../..
+my_dir = lib/ext2fs
INSTALL = @INSTALL@
@MCONFIG@
@@ -29,6 +30,7 @@
llseek.o \
mkdir.o \
namei.o \
+ native.o \
newdir.o \
openfs.o \
read_bb.o \
@@ -60,6 +62,7 @@
$(srcdir)/llseek.c \
$(srcdir)/mkdir.c \
$(srcdir)/namei.c \
+ $(srcdir)/native.c \
$(srcdir)/newdir.c \
$(srcdir)/openfs.c \
$(srcdir)/read_bb.c \
@@ -83,7 +86,7 @@
DLL_MYDIR = ext2fs
DLL_INSTALL_DIR = $(libdir)
-ELF_VERSION = 2.0
+ELF_VERSION = 2.1
ELF_SO_VERSION = 2
ELF_IMAGE = libext2fs
ELF_MYDIR = ext2fs
@@ -154,88 +157,90 @@
# 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
+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
+ $(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
+ $(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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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
+ $(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
+ $(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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/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
+ $(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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.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 \
$(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/io.h
-
diff --git a/lib/ext2fs/bitmaps.c b/lib/ext2fs/bitmaps.c
index d5ef0ec..7aaf549 100644
--- a/lib/ext2fs/bitmaps.c
+++ b/lib/ext2fs/bitmaps.c
@@ -22,27 +22,25 @@
#include "ext2fs.h"
-errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
- const char *descr,
- ext2fs_inode_bitmap *ret)
+errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+ __u32 end,
+ __u32 real_end,
+ const char *descr,
+ ext2fs_generic_bitmap *ret)
{
ext2fs_inode_bitmap bitmap;
int size;
- EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-
- fs->write_bitmaps = ext2fs_write_bitmaps;
-
- bitmap = malloc(sizeof(struct ext2fs_struct_inode_bitmap));
+ bitmap = malloc(sizeof(struct ext2fs_struct_generic_bitmap));
if (!bitmap)
return ENOMEM;
- bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
- bitmap->fs = fs;
- bitmap->start = 1;
- bitmap->end = fs->super->s_inodes_count;
- bitmap->real_end = (EXT2_INODES_PER_GROUP(fs->super)
- * fs->group_desc_count);
+ bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ bitmap->fs = NULL;
+ bitmap->start = start;
+ bitmap->end = end;
+ bitmap->real_end = real_end;
+ bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
if (descr) {
bitmap->description = malloc(strlen(descr)+1);
if (!bitmap->description) {
@@ -66,46 +64,61 @@
return 0;
}
-errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
+errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
const char *descr,
- ext2fs_block_bitmap *ret)
+ ext2fs_inode_bitmap *ret)
{
- ext2fs_block_bitmap bitmap;
- int size;
+ ext2fs_inode_bitmap bitmap;
+ errcode_t retval;
+ __u32 start, end, real_end;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
fs->write_bitmaps = ext2fs_write_bitmaps;
- bitmap = malloc(sizeof(struct ext2fs_struct_inode_bitmap));
- if (!bitmap)
- return ENOMEM;
+ start = 1;
+ end = fs->super->s_inodes_count;
+ real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count);
+
+ retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+ descr, &bitmap);
+ if (retval)
+ return retval;
+
+ bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
+ bitmap->fs = fs;
+ bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
+
+ *ret = bitmap;
+ return 0;
+}
+
+errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
+ const char *descr,
+ ext2fs_block_bitmap *ret)
+{
+ ext2fs_block_bitmap bitmap;
+ errcode_t retval;
+ __u32 start, end, real_end;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ fs->write_bitmaps = ext2fs_write_bitmaps;
+
+ start = fs->super->s_first_data_block;
+ end = fs->super->s_blocks_count-1;
+ real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)
+ * fs->group_desc_count)-1 + start;
+
+ retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+ descr, &bitmap);
+ if (retval)
+ return retval;
bitmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
bitmap->fs = fs;
- bitmap->start = fs->super->s_first_data_block;
- bitmap->end = fs->super->s_blocks_count-1;
- bitmap->real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)
- * fs->group_desc_count)-1 + bitmap->start;
- if (descr) {
- bitmap->description = malloc(strlen(descr)+1);
- if (!bitmap->description) {
- free(bitmap);
- return ENOMEM;
- }
- strcpy(bitmap->description, descr);
- } else
- bitmap->description = 0;
-
- size = ((bitmap->real_end - bitmap->start) / 8) + 1;
- bitmap->bitmap = malloc(size);
- if (!bitmap->bitmap) {
- free(bitmap->description);
- free(bitmap);
- return ENOMEM;
- }
-
- memset(bitmap->bitmap, 0, size);
+ bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
+
*ret = bitmap;
return 0;
}
diff --git a/lib/ext2fs/bitops.c b/lib/ext2fs/bitops.c
index da69e3b..6f256e5 100644
--- a/lib/ext2fs/bitops.c
+++ b/lib/ext2fs/bitops.c
@@ -72,3 +72,13 @@
com_err(0, errcode, "#%u", arg);
}
+void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+ int code, unsigned long arg)
+{
+ if (bitmap->description)
+ com_err(0, bitmap->base_error_code+code,
+ "#%u for %s", arg, bitmap->description);
+ else
+ com_err(0, bitmap->base_error_code + code, "#%u", arg);
+}
+
diff --git a/lib/ext2fs/bitops.h b/lib/ext2fs/bitops.h
index e98e2d2..e967c87 100644
--- a/lib/ext2fs/bitops.h
+++ b/lib/ext2fs/bitops.h
@@ -27,6 +27,8 @@
extern const char *ext2fs_test_string;
extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
const char *description);
+extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+ int code, unsigned long arg);
extern void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
extern void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
@@ -172,6 +174,84 @@
#define _EXT2_HAVE_ASM_BITOPS_
+#ifndef EXT2_OLD_BITOPS
+
+/*
+ * Do the bitops so that we are compatible with the standard i386
+ * convention.
+ */
+
+_INLINE_ int ext2fs_set_bit(int nr,void * addr)
+{
+#if 1
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("ldub [%0], %%g6\n\t"
+ "or %%g6, %2, %%g5\n\t"
+ "stb %%g5, [%0]\n\t"
+ "and %%g6, %2, %0\n"
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g5", "g6");
+ return (int) ADDR;
+#else
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ retval = (mask & *ADDR) != 0;
+ *ADDR |= mask;
+ return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+#if 1
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("ldub [%0], %%g6\n\t"
+ "andn %%g6, %2, %%g5\n\t"
+ "stb %%g5, [%0]\n\t"
+ "and %%g6, %2, %0\n"
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g5", "g6");
+ return (int) ADDR;
+
+#else
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ retval = (mask & *ADDR) != 0;
+ *ADDR &= ~mask;
+ return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+ int mask;
+ const unsigned char *ADDR = (const unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ return ((mask & *ADDR) != 0);
+}
+
+#else
+
+/* Do things the old, unplesant way. */
+
_INLINE_ int ext2fs_set_bit(int nr, void *addr)
{
int mask, retval;
@@ -205,6 +285,7 @@
mask = 1 << (nr & 31);
return ((mask & *ADDR) != 0);
}
+#endif
#endif /* __sparc__ */
@@ -223,70 +304,72 @@
#endif /* !_EXT2_HAVE_ASM_SWAB */
+_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);
+ return;
+ }
+ ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
+ return;
+ }
+ ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
+ return 0;
+ }
+ return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
_INLINE_ void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
- if ((block < bitmap->start) || (block > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
- bitmap->description);
- return;
- }
- ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
+ ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
}
_INLINE_ void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
- if ((block < bitmap->start) || (block > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
- block, bitmap->description);
- return;
- }
- ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
+ ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
}
_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
- if ((block < bitmap->start) || (block > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
- block, bitmap->description);
- return 0;
- }
- return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
+ return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ block);
}
_INLINE_ void ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ino_t inode)
{
- if ((inode < bitmap->start) || (inode > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
- inode, bitmap->description);
- return;
- }
- ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
+ ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
}
_INLINE_ void ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ino_t inode)
{
- if ((inode < bitmap->start) || (inode > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
- inode, bitmap->description);
- return;
- }
- ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
+ ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
}
_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
ino_t inode)
{
- if ((inode < bitmap->start) || (inode > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
- inode, bitmap->description);
- return 0;
- }
- return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
+ return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ inode);
}
_INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
diff --git a/lib/ext2fs/block.c b/lib/ext2fs/block.c
index fe112b3..5138534 100644
--- a/lib/ext2fs/block.c
+++ b/lib/ext2fs/block.c
@@ -39,8 +39,10 @@
int i, flags, limit;
blk_t *block_nr;
- if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE))
- ret = (*ctx->func)(ctx->fs, ind_block, -1, ctx->private);
+ 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);
if (!*ind_block || (ret & BLOCK_ABORT))
return ret;
if (*ind_block >= ctx->fs->super->s_blocks_count ||
@@ -56,7 +58,8 @@
return ret;
}
limit = ctx->fs->blocksize >> 2;
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_READ)) {
block_nr = (blk_t *) ctx->ind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
@@ -86,7 +89,8 @@
}
}
if (changed & BLOCK_CHANGED) {
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_WRITE)) {
block_nr = (blk_t *) ctx->ind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
@@ -97,8 +101,10 @@
ret |= BLOCK_ERROR | BLOCK_ABORT;
}
if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
!(ret & BLOCK_ABORT))
- ret |= (*ctx->func)(ctx->fs, ind_block, -1, ctx->private);
+ ret |= (*ctx->func)(ctx->fs, ind_block,
+ BLOCK_COUNT_IND, ctx->private);
return ret;
}
@@ -108,8 +114,10 @@
int i, flags, limit;
blk_t *block_nr;
- if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE))
- ret = (*ctx->func)(ctx->fs, dind_block, -2, ctx->private);
+ 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);
if (!*dind_block || (ret & BLOCK_ABORT))
return ret;
if (*dind_block >= ctx->fs->super->s_blocks_count ||
@@ -125,7 +133,8 @@
return ret;
}
limit = ctx->fs->blocksize >> 2;
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_READ)) {
block_nr = (blk_t *) ctx->dind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
@@ -153,7 +162,8 @@
}
}
if (changed & BLOCK_CHANGED) {
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_WRITE)) {
block_nr = (blk_t *) ctx->dind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
@@ -164,8 +174,10 @@
ret |= BLOCK_ERROR | BLOCK_ABORT;
}
if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
!(ret & BLOCK_ABORT))
- ret |= (*ctx->func)(ctx->fs, dind_block, -2, ctx->private);
+ ret |= (*ctx->func)(ctx->fs, dind_block,
+ BLOCK_COUNT_DIND, ctx->private);
return ret;
}
@@ -175,8 +187,10 @@
int i, flags, limit;
blk_t *block_nr;
- if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE))
- ret = (*ctx->func)(ctx->fs, tind_block, -3, ctx->private);
+ 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);
if (!*tind_block || (ret & BLOCK_ABORT))
return ret;
if (*tind_block >= ctx->fs->super->s_blocks_count ||
@@ -192,7 +206,8 @@
return ret;
}
limit = ctx->fs->blocksize >> 2;
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_READ)) {
block_nr = (blk_t *) ctx->tind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
@@ -220,7 +235,8 @@
}
}
if (changed & BLOCK_CHANGED) {
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_WRITE)) {
block_nr = (blk_t *) ctx->tind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
@@ -231,8 +247,10 @@
ret |= BLOCK_ERROR | BLOCK_ABORT;
}
if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
!(ret & BLOCK_ABORT))
- ret |= (*ctx->func)(ctx->fs, tind_block, -3, ctx->private);
+ ret |= (*ctx->func)(ctx->fs, tind_block,
+ BLOCK_COUNT_TIND, ctx->private);
return ret;
}
@@ -248,6 +266,7 @@
void *private)
{
int i;
+ int got_inode = 0;
int ret = 0;
struct block_context ctx;
blk_t blocks[EXT2_N_BLOCKS]; /* directory data blocks */
@@ -274,7 +293,26 @@
}
ctx.dind_buf = ctx.ind_buf + fs->blocksize;
ctx.tind_buf = ctx.dind_buf + fs->blocksize;
+
+ /*
+ * Iterate over the HURD translator block (if present)
+ */
+ if ((fs->super->s_creator_os == EXT2_OS_HURD) &&
+ !(flags & BLOCK_FLAG_DATA_ONLY) &&
+ inode.osd1.hurd1.h_i_translator) {
+ ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
+ if (ctx.errcode)
+ goto abort;
+ got_inode = 1;
+ ret |= (*func)(fs, &inode.osd1.hurd1.h_i_translator,
+ BLOCK_COUNT_TRANSLATOR, private);
+ if (ret & BLOCK_ABORT)
+ goto abort;
+ }
+ /*
+ * Iterate over normal data blocks
+ */
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);
@@ -292,14 +330,19 @@
if (ret & BLOCK_ABORT)
goto abort;
}
- if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND))
+ if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK, &ctx);
+ if (ret & BLOCK_ABORT)
+ goto abort;
+ }
abort:
if (ret & BLOCK_CHANGED) {
- retval = ext2fs_read_inode(fs, ino, &inode);
- if (retval)
- return retval;
+ if (!got_inode) {
+ retval = ext2fs_read_inode(fs, ino, &inode);
+ if (retval)
+ return retval;
+ }
for (i=0; i < EXT2_N_BLOCKS; i++)
inode.i_block[i] = blocks[i];
retval = ext2fs_write_inode(fs, ino, &inode);
diff --git a/lib/ext2fs/dirblock.c b/lib/ext2fs/dirblock.c
index bb2f717..3d5dbb2 100644
--- a/lib/ext2fs/dirblock.c
+++ b/lib/ext2fs/dirblock.c
@@ -27,7 +27,7 @@
retval = io_channel_read_blk(fs->io, block, 1, buf);
if (retval)
return retval;
- if ((fs->flags & EXT2_SWAP_BYTES) == 0)
+ if ((fs->flags & (EXT2_SWAP_BYTES|EXT2_SWAP_BYTES_READ)) == 0)
return 0;
p = buf;
end = (char *) buf + fs->blocksize;
@@ -49,7 +49,8 @@
char *buf = 0;
struct ext2_dir_entry *dirent;
- if (fs->flags & EXT2_SWAP_BYTES) {
+ if ((fs->flags & EXT2_SWAP_BYTES) ||
+ (fs->flags & EXT2_SWAP_BYTES_WRITE)) {
write_buf = buf = malloc(fs->blocksize);
if (!buf)
return ENOMEM;
diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
index 71153ce..81e0c1e 100644
--- a/lib/ext2fs/ext2_err.et.in
+++ b/lib/ext2fs/ext2_err.et.in
@@ -34,8 +34,8 @@
ec EXT2_ET_MAGIC_INODE_BITMAP,
"Wrong magic number for inode_bitmap structure"
-ec EXT2_ET_MAGIC_RESERVED_1,
- "Wrong magic number --- RESERVED_1"
+ec EXT2_ET_MAGIC_GENERIC_BITMAP,
+ "Wrong magic number for generic_bitmap structure"
ec EXT2_ET_MAGIC_RESERVED_2,
"Wrong magic number --- RESERVED_2"
@@ -191,7 +191,24 @@
"Illegal or malformed device name"
ec EXT2_ET_MISSING_INODE_TABLE,
- "A block group is missing an inode table."
+ "A block group is missing an inode table"
+
+ec EXT2_ET_CORRUPT_SUPERBLOCK,
+ "The ext2 superblock is corrupt"
+
+ec EXT2_ET_BAD_GENERIC_MARK,
+ "Illegal generic bit number passed to ext2fs_mark_generic_bitmap"
+
+ec EXT2_ET_BAD_GENERIC_UNMARK,
+ "Illegal generic bit number passed to ext2fs_unmark_generic_bitmap"
+
+ec EXT2_ET_BAD_GENERIC_TEST,
+ "Illegal generic bit number passed to ext2fs_test_generic_bitmap"
+
+ec EXT2_ET_SYMLINK_LOOP,
+ "Too many symbolic links encountered."
+
+ec EXT2_ET_CALLBACK_NOTHANDLED,
+ "The callback function will not handle this case"
end
-
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 73194c0..f385770 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -21,6 +21,7 @@
*/
#define EXT2_LIB_CURRENT_REV 0
+#include <sys/types.h>
#include <linux/types.h>
typedef __u32 blk_t;
@@ -32,29 +33,26 @@
typedef struct struct_ext2_filsys *ext2_filsys;
-struct ext2fs_struct_inode_bitmap {
- int magic;
- ext2_filsys fs;
- ino_t start, end;
- ino_t real_end;
- char *description;
- char *bitmap;
- int reserved[8];
+struct ext2fs_struct_generic_bitmap {
+ int magic;
+ ext2_filsys fs;
+ __u32 start, end;
+ __u32 real_end;
+ char * description;
+ char * bitmap;
+ errcode_t base_error_code;
+ __u32 reserved[7];
};
-typedef struct ext2fs_struct_inode_bitmap *ext2fs_inode_bitmap;
+#define EXT2FS_MARK_ERROR 0
+#define EXT2FS_UNMARK_ERROR 1
+#define EXT2FS_TEST_ERROR 2
-struct ext2fs_struct_block_bitmap {
- int magic;
- ext2_filsys fs;
- blk_t start, end;
- ino_t real_end;
- char *description;
- char *bitmap;
- int reserved[8];
-};
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
-typedef struct ext2fs_struct_block_bitmap *ext2fs_block_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
+
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
#ifdef EXT2_DYNAMIC_REV
#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s)
@@ -74,6 +72,8 @@
#define EXT2_FLAG_IB_DIRTY 0x10
#define EXT2_FLAG_BB_DIRTY 0x20
#define EXT2_SWAP_BYTES 0x40
+#define EXT2_SWAP_BYTES_READ 0x80
+#define EXT2_SWAP_BYTES_WRITE 0x100
/*
* Special flag in the ext2 inode i_flag field that means that this is
@@ -98,7 +98,11 @@
errcode_t (*get_blocks)(ext2_filsys fs, ino_t ino, blk_t *blocks);
errcode_t (*check_directory)(ext2_filsys fs, ino_t ino);
errcode_t (*write_bitmaps)(ext2_filsys fs);
- int reserved[16];
+ errcode_t (*read_inode)(ext2_filsys fs, ino_t ino,
+ struct ext2_inode *inode);
+ errcode_t (*write_inode)(ext2_filsys fs, ino_t ino,
+ struct ext2_inode *inode);
+ __u32 reserved[14];
/*
* Not used by ext2fs library; reserved for the use of the
@@ -156,10 +160,22 @@
* of the blocks containined in the indirect blocks are processed.
* This is useful if you are going to be deallocating blocks from an
* inode.
+ *
+ * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
+ * called for data blocks only.
*/
#define BLOCK_FLAG_APPEND 1
#define BLOCK_FLAG_HOLE 1
#define BLOCK_FLAG_DEPTH_TRAVERSE 2
+#define BLOCK_FLAG_DATA_ONLY 4
+
+/*
+ * Magic "block count" return values for the block iterator function.
+ */
+#define BLOCK_COUNT_IND (-1)
+#define BLOCK_COUNT_DIND (-2)
+#define BLOCK_COUNT_TIND (-3)
+#define BLOCK_COUNT_TRANSLATOR (-4)
/*
* Return flags for the directory iterator functions
@@ -224,6 +240,21 @@
#define LINUX_S_ISGID 0002000
#define LINUX_S_ISVTX 0001000
+#define LINUX_S_IRWXU 00700
+#define LINUX_S_IRUSR 00400
+#define LINUX_S_IWUSR 00200
+#define LINUX_S_IXUSR 00100
+
+#define LINUX_S_IRWXG 00070
+#define LINUX_S_IRGRP 00040
+#define LINUX_S_IWGRP 00020
+#define LINUX_S_IXGRP 00010
+
+#define LINUX_S_IRWXO 00007
+#define LINUX_S_IROTH 00004
+#define LINUX_S_IWOTH 00002
+#define LINUX_S_IXOTH 00001
+
#define LINUX_S_ISLNK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
#define LINUX_S_ISREG(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
#define LINUX_S_ISDIR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
@@ -238,6 +269,63 @@
#define EXT2_CHECK_MAGIC(struct, code) \
if ((struct)->magic != (code)) return (code)
+
+
+/*
+ * The ext2fs library private definition of the ext2 superblock, so we
+ * don't have to depend on the kernel's definition of the superblock,
+ * which might not have the latest features.
+ */
+struct ext2fs_sb {
+ __u32 s_inodes_count; /* Inodes count */
+ __u32 s_blocks_count; /* Blocks count */
+ __u32 s_r_blocks_count; /* Reserved blocks count */
+ __u32 s_free_blocks_count; /* Free blocks count */
+ __u32 s_free_inodes_count; /* Free inodes count */
+ __u32 s_first_data_block; /* First Data Block */
+ __u32 s_log_block_size; /* Block size */
+ __s32 s_log_frag_size; /* Fragment size */
+ __u32 s_blocks_per_group; /* # Blocks per group */
+ __u32 s_frags_per_group; /* # Fragments per group */
+ __u32 s_inodes_per_group; /* # Inodes per group */
+ __u32 s_mtime; /* Mount time */
+ __u32 s_wtime; /* Write time */
+ __u16 s_mnt_count; /* Mount count */
+ __s16 s_max_mnt_count; /* Maximal mount count */
+ __u16 s_magic; /* Magic signature */
+ __u16 s_state; /* File system state */
+ __u16 s_errors; /* Behaviour when detecting errors */
+ __u16 s_minor_rev_level; /* minor revision level */
+ __u32 s_lastcheck; /* time of last check */
+ __u32 s_checkinterval; /* max. time between checks */
+ __u32 s_creator_os; /* OS */
+ __u32 s_rev_level; /* Revision level */
+ __u16 s_def_resuid; /* Default uid for reserved blocks */
+ __u16 s_def_resgid; /* Default gid for reserved blocks */
+ /*
+ * These fields are for EXT2_DYNAMIC_REV superblocks only.
+ *
+ * Note: the difference between the compatible feature set and
+ * the incompatible feature set is that if there is a bit set
+ * in the incompatible feature set that the kernel doesn't
+ * know about, it should refuse to mount the filesystem.
+ *
+ * e2fsck's requirements are more strict; if it doesn't know
+ * about a feature in either the compatible or incompatible
+ * feature set, it must abort and not try to meddle with
+ * things it doesn't understand...
+ */
+ __u32 s_first_ino; /* First non-reserved inode */
+ __u16 s_inode_size; /* size of inode structure */
+ __u16 s_block_group_nr; /* block group # of this superblock */
+ __u32 s_feature_compat; /* compatible feature set */
+ __u32 s_feature_incompat; /* incompatible feature set */
+ __u32 s_feature_ro_compat; /* readonly-compatible feature set */
+ __u8 s_uuid[16]; /* 128-bit uuid for volume */
+ char s_volume_name[16]; /* volume name */
+ char s_last_mounted[64]; /* directory where last mounted */
+ __u32 s_reserved[206]; /* Padding to the end of the block */
+};
/*
* function prototypes
@@ -272,6 +360,11 @@
extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+ __u32 end,
+ __u32 real_end,
+ const char *descr,
+ ext2fs_generic_bitmap *ret);
extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
const char *descr,
ext2fs_block_bitmap *ret);
@@ -323,6 +416,7 @@
/* freefs.c */
extern void ext2fs_free(ext2_filsys fs);
+extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
@@ -378,6 +472,13 @@
int namelen, char *buf, ino_t *inode);
extern errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd,
const char *name, ino_t *inode);
+errcode_t ext2fs_namei_follow(ext2_filsys fs, ino_t root, ino_t cwd,
+ const char *name, ino_t *inode);
+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ino_t root, ino_t cwd,
+ ino_t inode, ino_t *res_inode);
+
+/* native.c */
+int ext2fs_native_flag(void);
/* newdir.c */
extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ino_t dir_ino,
@@ -414,6 +515,9 @@
/* swapfs.c */
extern void ext2fs_swap_super(struct ext2_super_block * super);
extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
+extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
+ struct ext2_inode *f, int hostorder);
+
/* inline functions */
extern void ext2fs_mark_super_dirty(ext2_filsys fs);
diff --git a/lib/ext2fs/freefs.c b/lib/ext2fs/freefs.c
index 63b5235..5c70983 100644
--- a/lib/ext2fs/freefs.c
+++ b/lib/ext2fs/freefs.c
@@ -33,9 +33,9 @@
free(fs);
}
-void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
+void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
{
- if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
+ if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_GENERIC_BITMAP))
return;
bitmap->magic = 0;
@@ -50,20 +50,21 @@
free(bitmap);
}
+void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
+{
+ if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
+ return;
+
+ bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ ext2fs_free_generic_bitmap(bitmap);
+}
+
void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap)
{
if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
return;
- bitmap->magic = 0;
- if (bitmap->description) {
- free(bitmap->description);
- bitmap->description = 0;
- }
- if (bitmap->bitmap) {
- free(bitmap->bitmap);
- bitmap->bitmap = 0;
- }
- free(bitmap);
+ bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ ext2fs_free_generic_bitmap(bitmap);
}
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index cc7abd0..4108093 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -1,6 +1,11 @@
/*
* initialize.c --- initialize a filesystem handle given superblock
* parameters. Used by mke2fs when initializing a filesystem.
+ *
+ * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
*/
#include <stdio.h>
@@ -31,6 +36,19 @@
#define CREATOR_OS EXT2_OS_LINUX /* by default */
#endif
+/*
+ * Note we override the kernel include file's idea of what the default
+ * check interval (never) should be. It's a good idea to check at
+ * least *occasionally*, specially since servers will never rarely get
+ * to reboot, since Linux is so robust these days. :-)
+ *
+ * 180 days (six months) seems like a good value.
+ */
+#ifdef EXT2_DFL_CHECKINTERVAL
+#undef EXT2_DFL_CHECKINTERVAL
+#endif
+#define EXT2_DFL_CHECKINTERVAL (86400 * 180)
+
errcode_t ext2fs_initialize(const char *name, int flags,
struct ext2_super_block *param,
io_manager manager, ext2_filsys *ret_fs)
@@ -55,7 +73,7 @@
memset(fs, 0, sizeof(struct struct_ext2_filsys));
fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
- fs->flags = flags | EXT2_FLAG_RW;
+ fs->flags = flags | EXT2_FLAG_RW | ext2fs_native_flag();
retval = manager->open(name, IO_FLAG_RW, &fs->io);
if (retval)
goto cleanup;
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index 04c5e4d..7d25ae1 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -19,8 +19,6 @@
#include "ext2fs.h"
-static void inocpy_with_swap(struct ext2_inode *t, struct ext2_inode *f);
-
errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
ext2_inode_scan *ret_scan)
{
@@ -151,15 +149,17 @@
scan->ptr += scan->inode_size - extra_bytes;
scan->bytes_left -= scan->inode_size - extra_bytes;
- if (scan->fs->flags & EXT2_SWAP_BYTES)
- inocpy_with_swap(inode, (struct ext2_inode *)
- scan->temp_buffer);
+ if ((scan->fs->flags & EXT2_SWAP_BYTES) ||
+ (scan->fs->flags & EXT2_SWAP_BYTES_READ))
+ ext2fs_swap_inode(scan->fs, inode,
+ (struct ext2_inode *) scan->temp_buffer, 0);
else
*inode = *((struct ext2_inode *) scan->temp_buffer);
} else {
- if (scan->fs->flags & EXT2_SWAP_BYTES)
- inocpy_with_swap(inode, (struct ext2_inode *)
- scan->ptr);
+ if ((scan->fs->flags & EXT2_SWAP_BYTES) ||
+ (scan->fs->flags & EXT2_SWAP_BYTES_READ))
+ ext2fs_swap_inode(scan->fs, inode,
+ (struct ext2_inode *) scan->ptr, 0);
else
*inode = *((struct ext2_inode *) scan->ptr);
scan->ptr += scan->inode_size;
@@ -178,6 +178,15 @@
static char *inode_buffer = 0;
static blk_t inode_buffer_block = 0;
static int inode_buffer_size = 0;
+#define INODE_CACHE_SIZE 4
+#ifdef INODE_CACHE_SIZE
+static int cache_last = -1;
+static struct {
+ ino_t inode;
+ struct ext2_inode value;
+} inode_cache[INODE_CACHE_SIZE];
+#endif
+
errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
struct ext2_inode * inode)
@@ -185,10 +194,29 @@
unsigned long group, block, block_nr, offset;
char *ptr;
errcode_t retval;
- int clen, length;
+ int clen, length, i;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+ /* Check to see if user has an override function */
+ if (fs->read_inode) {
+ retval = (fs->read_inode)(fs, ino, inode);
+ if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
+ return retval;
+ }
+ /* Check to see if it's in the inode cache */
+#ifdef INODE_CACHE_SIZE
+ if (cache_last == -1) {
+ for (i=0; i < INODE_CACHE_SIZE; i++)
+ inode_cache[i].inode = 0;
+ cache_last = INODE_CACHE_SIZE-1;
+ } else for (i=0; i < INODE_CACHE_SIZE; i++) {
+ if (inode_cache[i].inode == ino) {
+ *inode = inode_cache[i].value;
+ return 0;
+ }
+ }
+#endif
if (ino > fs->super->s_inodes_count)
return EXT2_ET_BAD_INODE_NUM;
if (inode_buffer_size != fs->blocksize) {
@@ -238,8 +266,16 @@
} else
memcpy((char *) inode, ptr, length);
- if (fs->flags & EXT2_SWAP_BYTES)
- inocpy_with_swap(inode, inode);
+ if ((fs->flags & EXT2_SWAP_BYTES) ||
+ (fs->flags & EXT2_SWAP_BYTES_READ))
+ ext2fs_swap_inode(fs, inode, inode, 0);
+
+ /* Update the inode cache */
+#ifdef INODE_CACHE_SIZE
+ cache_last = (cache_last + 1) % INODE_CACHE_SIZE;
+ inode_cache[cache_last].inode = ino;
+ inode_cache[cache_last].value = *inode;
+#endif
return 0;
}
@@ -251,10 +287,25 @@
errcode_t retval;
struct ext2_inode temp_inode;
char *ptr;
- int i, clen, length;
+ int clen, length, i;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+ /* Check to see if user provided an override function */
+ if (fs->write_inode) {
+ retval = (fs->write_inode)(fs, ino, inode);
+ if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
+ return retval;
+ }
+ /* Check to see if the inode cache needs to be updated */
+#ifdef INODE_CACHE_SIZE
+ for (i=0; i < INODE_CACHE_SIZE; i++) {
+ if (inode_cache[i].inode == ino) {
+ inode_cache[i].value = *inode;
+ break;
+ }
+ }
+#endif
if (!(fs->flags & EXT2_FLAG_RW))
return EXT2_ET_RO_FILSYS;
@@ -271,8 +322,9 @@
inode_buffer_size = fs->blocksize;
inode_buffer_block = 0;
}
- if (fs->flags & EXT2_SWAP_BYTES)
- inocpy_with_swap(&temp_inode, inode);
+ if ((fs->flags & EXT2_SWAP_BYTES) ||
+ (fs->flags & EXT2_SWAP_BYTES_WRITE))
+ ext2fs_swap_inode(fs, &temp_inode, inode, 1);
else
memcpy(&temp_inode, inode, sizeof(struct ext2_inode));
@@ -367,32 +419,7 @@
if (retval)
return retval;
if (!LINUX_S_ISDIR(inode.i_mode))
- return ENOTDIR;
+ return ENOTDIR;
return 0;
}
-static void inocpy_with_swap(struct ext2_inode *t, struct ext2_inode *f)
-{
- unsigned i;
-
- t->i_mode = ext2fs_swab16(f->i_mode);
- t->i_uid = ext2fs_swab16(f->i_uid);
- t->i_size = ext2fs_swab32(f->i_size);
- t->i_atime = ext2fs_swab32(f->i_atime);
- t->i_ctime = ext2fs_swab32(f->i_ctime);
- t->i_mtime = ext2fs_swab32(f->i_mtime);
- t->i_dtime = ext2fs_swab32(f->i_dtime);
- t->i_gid = ext2fs_swab16(f->i_gid);
- t->i_links_count = ext2fs_swab16(f->i_links_count);
- t->i_blocks = ext2fs_swab32(f->i_blocks);
- t->i_flags = ext2fs_swab32(f->i_flags);
- for (i = 0; i < EXT2_N_BLOCKS; i++)
- t->i_block[i] = ext2fs_swab32(f->i_block[i]);
- t->i_version = ext2fs_swab32(f->i_version);
- t->i_file_acl = ext2fs_swab32(f->i_file_acl);
- t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
- t->i_faddr = ext2fs_swab32(f->i_faddr);
- t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
- t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
- t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
-}
diff --git a/lib/ext2fs/namei.c b/lib/ext2fs/namei.c
index 496c726..8fc71b0 100644
--- a/lib/ext2fs/namei.c
+++ b/lib/ext2fs/namei.c
@@ -13,6 +13,8 @@
#include <errno.h>
#endif
+/* #define NAMEI_DEBUG */
+
#include <linux/ext2_fs.h>
#include "ext2fs.h"
@@ -173,43 +175,186 @@
return (ls.found) ? 0 : ENOENT;
}
-errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd, const char *name,
- ino_t *inode)
-{
- ino_t dir = cwd;
- char *buf;
- const char *p = name, *q;
- int len;
- errcode_t retval;
+static errcode_t open_namei(ext2_filsys fs, ino_t root, ino_t base,
+ const char *pathname, int pathlen, int follow,
+ int link_count, char *buf, ino_t *res_inode);
+
+static errcode_t follow_link(ext2_filsys fs, ino_t root, ino_t dir,
+ ino_t inode, int link_count,
+ char *buf, ino_t *res_inode)
+{
+ char *pathname;
+ char *buffer = 0;
+ errcode_t retval;
+ struct ext2_inode ei;
+
+#ifdef NAMEI_DEBUG
+ printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
+ root, dir, inode, link_count);
+
+#endif
+ retval = ext2fs_read_inode (fs, inode, &ei);
+ if (retval) return retval;
+ if (!LINUX_S_ISLNK (ei.i_mode)) {
+ *res_inode = inode;
+ return 0;
+ }
+ if (link_count++ > 5) {
+ return EXT2_ET_SYMLINK_LOOP;
+ }
+ if (ei.i_blocks) {
+ buffer = malloc (fs->blocksize);
+ if (!buffer)
+ return ENOMEM;
+ retval = io_channel_read_blk(fs->io, ei.i_block[0], 1, buffer);
+ if (retval) {
+ free(buffer);
+ return retval;
+ }
+ pathname = buffer;
+ } else
+ pathname = (char *)&(ei.i_block[0]);
+ retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
+ link_count, buf, res_inode);
+ if (buffer)
+ free (buffer);
+ return retval;
+}
+
+/*
+ * This routine interprets a pathname in the context of the current
+ * directory and the root directory, and returns the inode of the
+ * containing directory, and a pointer to the filename of the file
+ * (pointing into the pathname) and the length of the filename.
+ */
+static errcode_t dir_namei(ext2_filsys fs, ino_t root, ino_t dir,
+ const char *pathname, int pathlen,
+ int link_count, char *buf,
+ const char **name, int *namelen, ino_t *res_inode)
+{
+ char c;
+ const char *thisname;
+ int len;
+ ino_t inode;
+ errcode_t retval;
+
+ if ((c = *pathname) == '/') {
+ dir = root;
+ pathname++;
+ pathlen--;
+ }
+ while (1) {
+ thisname = pathname;
+ for (len=0; --pathlen >= 0;len++) {
+ c = *(pathname++);
+ if (c == '/')
+ break;
+ }
+ if (pathlen < 0)
+ break;
+ retval = ext2fs_lookup (fs, dir, thisname, len, buf, &inode);
+ if (retval) return retval;
+ retval = follow_link (fs, root, dir, inode,
+ link_count, buf, &dir);
+ if (retval) return retval;
+ }
+ *name = thisname;
+ *namelen = len;
+ *res_inode = dir;
+ return 0;
+}
+
+static errcode_t open_namei(ext2_filsys fs, ino_t root, ino_t base,
+ const char *pathname, int pathlen, int follow,
+ int link_count, char *buf, ino_t *res_inode)
+{
+ const char *basename;
+ int namelen;
+ ino_t dir, inode;
+ errcode_t retval;
+
+#ifdef NAMEI_DEBUG
+ printf("open_namei: root=%lu, dir=%lu, path=%*s, lc=%d\n",
+ root, base, pathlen, pathname, link_count);
+#endif
+ retval = dir_namei(fs, root, base, pathname, pathlen,
+ link_count, buf, &basename, &namelen, &dir);
+ if (retval) return retval;
+ if (!namelen) { /* special case: '/usr/' etc */
+ *res_inode=dir;
+ return 0;
+ }
+ retval = ext2fs_lookup (fs, dir, basename, namelen, buf, &inode);
+ if (retval)
+ return retval;
+ if (follow) {
+ retval = follow_link(fs, root, dir, inode, link_count,
+ buf, &inode);
+ if (retval)
+ return retval;
+ }
+#ifdef NAMEI_DEBUG
+ printf("open_namei: (link_count=%d) returns %lu\n",
+ link_count, inode);
+#endif
+ *res_inode = inode;
+ return 0;
+}
+
+errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd,
+ const char *name, ino_t *inode)
+{
+ char *buf;
+ errcode_t retval;
+
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
buf = malloc(fs->blocksize);
if (!buf)
return ENOMEM;
- if (*p == '/') {
- p++;
- dir = root;
- }
- while (*p) {
- q = strchr(p, '/');
- if (q)
- len = q - p;
- else
- len = strlen(p);
- if (len) {
- retval = ext2fs_lookup(fs, dir, p, len, buf, &dir);
- if (retval) {
- free(buf);
- return retval;
- }
- }
- if (q)
- p = q+1;
- else
- break;
- }
- *inode = dir;
+
+ retval = open_namei(fs, root, cwd, name, strlen(name), 0, 0,
+ buf, inode);
+
free(buf);
- return 0;
+ return retval;
}
+
+errcode_t ext2fs_namei_follow(ext2_filsys fs, ino_t root, ino_t cwd,
+ const char *name, ino_t *inode)
+{
+ char *buf;
+ errcode_t retval;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ buf = malloc(fs->blocksize);
+ if (!buf)
+ return ENOMEM;
+
+ retval = open_namei(fs, root, cwd, name, strlen(name), 1, 0,
+ buf, inode);
+
+ free(buf);
+ return retval;
+}
+
+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ino_t root, ino_t cwd,
+ ino_t inode, ino_t *res_inode)
+{
+ char *buf;
+ errcode_t retval;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ buf = malloc(fs->blocksize);
+ if (!buf)
+ return ENOMEM;
+
+ retval = follow_link(fs, root, cwd, inode, 0, buf, res_inode);
+
+ free(buf);
+ return retval;
+}
+
diff --git a/lib/ext2fs/native.c b/lib/ext2fs/native.c
new file mode 100644
index 0000000..aa371ce
--- /dev/null
+++ b/lib/ext2fs/native.c
@@ -0,0 +1,31 @@
+/*
+ * native.c --- returns the ext2_flag for a native byte order
+ *
+ * Copyright (C) 1996 Theodore Ts'o.
+ *
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ */
+
+#include <stdio.h>
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+
+static int i386_byteorder(void)
+{
+ int one = 1;
+ char *cp = (char *) &one;
+
+ return (*cp == 1);
+}
+
+int ext2fs_native_flag(void)
+{
+ if (i386_byteorder())
+ return 0;
+ return EXT2_SWAP_BYTES;
+}
+
+
+
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index e8b01e2..74bf279 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -113,6 +113,10 @@
#endif
#endif
fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
+ if (fs->blocksize == 0) {
+ retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+ goto cleanup;
+ }
fs->fragsize = EXT2_FRAG_SIZE(fs->super);
fs->inode_blocks_per_group = ((fs->super->s_inodes_per_group *
EXT2_INODE_SIZE(fs->super) +
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index 371b8f9..968f41c 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -16,6 +16,8 @@
void ext2fs_swap_super(struct ext2_super_block * super)
{
+ struct ext2fs_sb *s = (struct ext2fs_sb *) super;
+
super->s_inodes_count = ext2fs_swab32(super->s_inodes_count);
super->s_blocks_count = ext2fs_swab32(super->s_blocks_count);
super->s_r_blocks_count = ext2fs_swab32(super->s_r_blocks_count);
@@ -34,6 +36,7 @@
super->s_magic = ext2fs_swab16(super->s_magic);
super->s_state = ext2fs_swab16(super->s_state);
super->s_errors = ext2fs_swab16(super->s_errors);
+ s->s_minor_rev_level = ext2fs_swab16(s->s_minor_rev_level);
super->s_lastcheck = ext2fs_swab32(super->s_lastcheck);
super->s_checkinterval = ext2fs_swab32(super->s_checkinterval);
super->s_creator_os = ext2fs_swab32(super->s_creator_os);
@@ -42,6 +45,12 @@
super->s_def_resuid = ext2fs_swab16(super->s_def_resuid);
super->s_def_resgid = ext2fs_swab16(super->s_def_resgid);
#endif
+ s->s_first_ino = ext2fs_swab32(s->s_first_ino);
+ s->s_inode_size = ext2fs_swab16(s->s_inode_size);
+ s->s_block_group_nr = ext2fs_swab16(s->s_block_group_nr);
+ s->s_feature_compat = ext2fs_swab32(s->s_feature_compat);
+ s->s_feature_incompat = ext2fs_swab32(s->s_feature_incompat);
+ s->s_feature_ro_compat = ext2fs_swab32(s->s_feature_ro_compat);
}
void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
@@ -54,5 +63,64 @@
gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
}
+void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
+ struct ext2_inode *f, int hostorder)
+{
+ unsigned i;
+ int islnk = 0;
+ if (hostorder && LINUX_S_ISLNK(f->i_mode))
+ islnk = 1;
+ t->i_mode = ext2fs_swab16(f->i_mode);
+ if (!hostorder && LINUX_S_ISLNK(t->i_mode))
+ islnk = 1;
+ t->i_uid = ext2fs_swab16(f->i_uid);
+ t->i_size = ext2fs_swab32(f->i_size);
+ t->i_atime = ext2fs_swab32(f->i_atime);
+ t->i_ctime = ext2fs_swab32(f->i_ctime);
+ t->i_mtime = ext2fs_swab32(f->i_mtime);
+ t->i_dtime = ext2fs_swab32(f->i_dtime);
+ t->i_gid = ext2fs_swab16(f->i_gid);
+ t->i_links_count = ext2fs_swab16(f->i_links_count);
+ t->i_blocks = ext2fs_swab32(f->i_blocks);
+ t->i_flags = ext2fs_swab32(f->i_flags);
+ if (!islnk || f->i_blocks) {
+ for (i = 0; i < EXT2_N_BLOCKS; i++)
+ t->i_block[i] = ext2fs_swab32(f->i_block[i]);
+ } else if (t != f) {
+ for (i = 0; i < EXT2_N_BLOCKS; i++)
+ t->i_block[i] = f->i_block[i];
+ }
+ t->i_version = ext2fs_swab32(f->i_version);
+ t->i_file_acl = ext2fs_swab32(f->i_file_acl);
+ t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
+ t->i_faddr = ext2fs_swab32(f->i_faddr);
+ switch (fs->super->s_creator_os) {
+ case EXT2_OS_LINUX:
+ t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
+ t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
+ t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
+ break;
+ case EXT2_OS_HURD:
+ t->osd1.hurd1.h_i_translator =
+ ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
+ t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
+ t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
+ t->osd2.hurd2.h_i_mode_high =
+ ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
+ t->osd2.hurd2.h_i_uid_high =
+ ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
+ t->osd2.hurd2.h_i_gid_high =
+ ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
+ t->osd2.hurd2.h_i_author =
+ ext2fs_swab32 (f->osd2.hurd2.h_i_author);
+ break;
+ case EXT2_OS_MASIX:
+ t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
+ t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
+ t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
+ break;
+ }
+}
+