Whamcloud - gitweb
Many files:
authorTheodore Ts'o <tytso@mit.edu>
Tue, 29 Apr 1997 14:53:37 +0000 (14:53 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 29 Apr 1997 14:53:37 +0000 (14:53 +0000)
  Checked in e2fsprogs 1.05

136 files changed:
debugfs/ncheck.c
debugfs/util.c
e2fsck/ChangeLog
e2fsck/Makefile.in
e2fsck/e2fsck.8.in
e2fsck/e2fsck.c
e2fsck/e2fsck.h
e2fsck/pass1.c
e2fsck/pass1b.c
e2fsck/pass2.c
e2fsck/pass4.c
e2fsck/swapfs.c [new file with mode: 0644]
include/linux/types.h.in
lib/ChangeLog
lib/Makefile.elf-lib
lib/do_substitute
lib/e2p/ChangeLog
lib/e2p/MAKELOG [deleted file]
lib/e2p/Makefile.in
lib/e2p/e2p.h
lib/e2p/fgetflags.c
lib/e2p/fgetversion.c
lib/e2p/fsetflags.c
lib/e2p/fsetversion.c
lib/e2p/getflags.c
lib/e2p/getversion.c
lib/e2p/ls.c
lib/e2p/pe.c
lib/e2p/pf.c
lib/e2p/ps.c
lib/e2p/setflags.c
lib/e2p/setversion.c
lib/e2p/uuid.c [new file with mode: 0644]
lib/et/Makefile.in
lib/ext2fs/ChangeLog
lib/ext2fs/Makefile.in
lib/ext2fs/bitmaps.c
lib/ext2fs/bitops.c
lib/ext2fs/bitops.h
lib/ext2fs/block.c
lib/ext2fs/dirblock.c
lib/ext2fs/ext2_err.et.in
lib/ext2fs/ext2fs.h
lib/ext2fs/freefs.c
lib/ext2fs/initialize.c
lib/ext2fs/inode.c
lib/ext2fs/namei.c
lib/ext2fs/native.c [new file with mode: 0644]
lib/ext2fs/openfs.c
lib/ext2fs/swapfs.c
lib/ss/ChangeLog
lib/ss/Makefile.in
lib/ss/error.c
lib/ss/execute_cmd.c
lib/ss/invocation.c
lib/ss/listen.c
lib/ss/requests.c
lib/ss/ss.h
lib/ss/ss_internal.h
lib/ss/test_ss.c
lib/substitute_sh.in
lib/uuid/ChangeLog [new file with mode: 0644]
lib/uuid/Makefile.in [new file with mode: 0644]
lib/uuid/clear.c [new file with mode: 0644]
lib/uuid/compare.c [new file with mode: 0644]
lib/uuid/copy.c [new file with mode: 0644]
lib/uuid/gen_uuid.c [new file with mode: 0644]
lib/uuid/isnull.c [new file with mode: 0644]
lib/uuid/pack.c [new file with mode: 0644]
lib/uuid/parse.c [new file with mode: 0644]
lib/uuid/tst_uuid.c [new file with mode: 0644]
lib/uuid/unpack.c [new file with mode: 0644]
lib/uuid/unparse.c [new file with mode: 0644]
lib/uuid/uuid.h [new file with mode: 0644]
lib/uuid/uuidP.h [new file with mode: 0644]
misc/ChangeLog
misc/Makefile.in
misc/chattr.c
misc/dumpe2fs.c
misc/mke2fs.8.in
misc/mke2fs.c
misc/tune2fs.8.in
misc/tune2fs.c
relocate/Makefile.in [new file with mode: 0644]
relocate/README [new file with mode: 0644]
relocate/relocate.c [new file with mode: 0644]
relocate/relocate.h [new file with mode: 0644]
relocate/resize2fs.c [new file with mode: 0644]
tests/ChangeLog
tests/Makefile.in
tests/f_badbblocks/expect.1
tests/f_baddir/expect.1
tests/f_baddotdir/expect.1
tests/f_badinode/expect.1
tests/f_badlkcnt/expect.1 [deleted file]
tests/f_badlkcnt/expect.2 [deleted file]
tests/f_badlkcnt/image.gz [deleted file]
tests/f_badlkcnt/name [deleted file]
tests/f_badprimary/expect.1
tests/f_badroot/expect.1
tests/f_badtable/expect.1
tests/f_bbfile/expect.1
tests/f_bitmaps/expect.1
tests/f_crashdisk/expect.1 [new file with mode: 0644]
tests/f_crashdisk/image.gz [new file with mode: 0644]
tests/f_crashdisk/name [new file with mode: 0644]
tests/f_crashdisk/script [new file with mode: 0644]
tests/f_dirlink/expect.1
tests/f_dup/expect.1
tests/f_dup2/expect.1
tests/f_dupfsblks/expect.1
tests/f_dupsuper/expect.1
tests/f_end-bitmap/expect.1
tests/f_expand/expect.1
tests/f_holedir/expect.1
tests/f_illbbitmap/expect.1
tests/f_illibitmap/expect.1
tests/f_lotsbad/expect.1
tests/f_lpf/expect.1
tests/f_lpf/expect.2
tests/f_lpf/image.gz
tests/f_messy_inode/expect.1
tests/f_mke2fs2b/expect.1
tests/f_mke2fs2b/expect.2
tests/f_noroot/expect.1
tests/f_noroot/expect.2
tests/f_okgroup/expect.1
tests/f_overfsblks/expect.1
tests/f_swapfs/debugfs.cmd [new file with mode: 0644]
tests/f_swapfs/expect [new file with mode: 0644]
tests/f_swapfs/image.gz [new file with mode: 0644]
tests/f_swapfs/name [new file with mode: 0644]
tests/f_swapfs/script [new file with mode: 0644]
tests/run_e2fsck
tests/test_config
tests/test_script.in [moved from tests/test_script with 83% similarity]

index b5298c2..7dec343 100644 (file)
@@ -92,7 +92,7 @@ void do_ncheck(int argc, char **argv)
 
        iw.num_inodes = iw.inodes_left = argc-1;
 
-       retval = ext2fs_open_inode_scan(fs, 0, &scan);
+       retval = ext2fs_open_inode_scan(current_fs, 0, &scan);
        if (retval) {
                com_err("ncheck", retval, "while opening inode scan");
                goto error_out;
@@ -120,7 +120,7 @@ void do_ncheck(int argc, char **argv)
                iw.position = 0;
                iw.parent = ino;
                
-               retval = ext2fs_dir_iterate(fs, ino, 0, 0,
+               retval = ext2fs_dir_iterate(current_fs, ino, 0, 0,
                                            ncheck_proc, &iw);
                if (retval) {
                        com_err("ncheck", retval,
@@ -143,7 +143,7 @@ void do_ncheck(int argc, char **argv)
        for (i=0, iinfo = iw.iarray; i < iw.num_inodes; i++, iinfo++) {
                if (iinfo->parent == 0)
                        continue;
-               retval = ext2fs_get_pathname(fs, iinfo->parent,
+               retval = ext2fs_get_pathname(current_fs, iinfo->parent,
                                             iinfo->ino, &iinfo->pathname);
                if (retval)
                        com_err("ncheck", retval,
index 24957fb..c8eeae1 100644 (file)
@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
+#include <time.h>
 
 #include "debugfs.h"
 
@@ -56,7 +57,7 @@ ino_t string_to_inode(char *str)
                        return(atoi(str+1));
        }
 
-       retval = ext2fs_namei(fs, root, cwd, str, &ino);
+       retval = ext2fs_namei(current_fs, root, cwd, str, &ino);
        if (retval) {
                com_err(str, retval, "");
                return 0;
@@ -70,7 +71,7 @@ ino_t string_to_inode(char *str)
  */
 int check_fs_open(char *name)
 {
-       if (!fs) {
+       if (!current_fs) {
                com_err(name, 0, "Filesystem not open");
                return 1;
        }
@@ -83,12 +84,39 @@ int check_fs_open(char *name)
  */
 int check_fs_not_open(char *name)
 {
-       if (fs) {
+       if (current_fs) {
                com_err(name, 0,
                        "Filesystem %s is still open.  Close it first.\n",
-                       fs->device_name);
+                       current_fs->device_name);
                return 1;
        }
        return 0;
 }
 
+/*
+ * This routine returns 1 if a filesystem is not opened read/write,
+ * and prints an error message to that effect.
+ */
+int check_fs_read_write(char *name)
+{
+       if (!(current_fs->flags & EXT2_FLAG_RW)) {
+               com_err(name, 0, "Filesystem opened read/only");
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * This function takes a __u32 time value and converts it to a string,
+ * using ctime
+ */
+char *time_to_string(__u32 cl)
+{
+       time_t  t = (time_t) cl;
+
+       return ctime(&t);
+}
+
+
+       
+
index 1ea0a58..fcab1e6 100644 (file)
@@ -1,3 +1,60 @@
+Fri Aug 30 20:24:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * pass4.c (pass4): If the user refuses to connect an unattached
+               inode to lost+found, don't try to set i_links_count.  This
+               is bad, since if the user says yes, the inode will be
+               marked as unused, which is not necessarily the right
+               thing, especially since the rest of the cleanup doesn't
+               happen here.
+
+       * pass2.c (deallocate_inode): Set inode_link_info[ino] when
+               dellocating an inode.  (Not strictly necessary, but...)
+
+       * pass4.c (pass4): Add "bonehead" explanation to the "programming
+               error" message.
+
+Tue Aug 27 11:26:32 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * e2fsck.c (PRS,main): Added new options -s and -S.  -s will
+               byte-swap the filesystem so that it is normalized.  -S
+               will byte-swap the filesystem regardless of its current
+               byte-order.
+
+       * swapfs.c: New file, which will byte-swap a filesystem.
+
+Tue Aug 20 09:41:37 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * pass1.c (pass1): Change handling on files with non-zero dtime
+               and non-zero i_link_count; before we treated them as
+               deleted file per botched ext2 0.3c kernel behavior.  We
+               now clear dtime instead.
+
+Mon Aug 19 23:33:57 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * e2fsck.c (main): If e2fsck sets the clean bit, even if
+               nothing else is changed, make sure FSCK_NONDESTRUCT is
+               set (since after all having the filesystem set to
+               invalid is an error.  :-)
+
+Fri Aug  9 10:25:13 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * pass1.c (process_block): Make sure that meta data doesn't get
+               accidentally set in the dir_blocks array (which could
+               happen in some error condtions).
+       
+       * pass1.c (pass1): 
+       * pass2.c (process_bad_inode): Check for fragments in a
+               OS-independent fashion.
+
+Thu Aug  8 15:20:54 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * e2fsck.c (check_if_skip): Close the filesystem when skipping the
+               cleanup for the filesystem.
+
+Mon Jul 22 22:03:28 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * e2fsck.c: Improve corrupt_msg, so that it's less confusing.
+
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * Release of E2fsprogs version 1.04
index 8e2e51c..f4330c3 100644 (file)
@@ -6,6 +6,7 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ..
+my_dir = e2fsck
 INSTALL = @INSTALL@
 LDFLAG_STATIC = @LDFLAG_STATIC@
 
@@ -14,14 +15,14 @@ LDFLAG_STATIC = @LDFLAG_STATIC@
 PROGS=         e2fsck extend @EXTRA_PROGS@
 MANPAGES=      e2fsck.8
 
-LIBS= $(LIBEXT2FS) $(LIBCOM_ERR) 
-DEPLIBS= $(LIBEXT2FS) $(LIBCOM_ERR) 
+LIBS= $(LIBEXT2FS) $(LIBCOM_ERR) $(LIBUUID)
+DEPLIBS= $(LIBEXT2FS) $(LIBCOM_ERR) $(LIBUUID)
 
-STATIC_LIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) 
-STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) 
+STATIC_LIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(STATIC_LIBUUID)
+STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(STATIC_LIBUUID)
 
-PROFILED_LIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR) 
-PROFILED_DEPLIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR) 
+PROFILED_LIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR) $(PROFILED_LIBUUID)
+PROFILED_DEPLIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR) $(PROFILED_LIBUUID)
 
 .c.o:
        $(CC) -c $(ALL_CFLAGS) $< -o $@
@@ -52,12 +53,12 @@ PROFILED_DEPLIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR)
 #MCHECK= -DMCHECK
 
 OBJS= e2fsck.o pass1.o pass1b.o pass2.o pass3.o pass4.o pass5.o \
-       badblocks.o util.o dirinfo.o ehandler.o $(MTRACE_OBJ)
+       swapfs.o badblocks.o util.o dirinfo.o ehandler.o $(MTRACE_OBJ)
 
 PROFILED_OBJS= profiled/e2fsck.o profiled/pass1.o profiled/pass1b.o \
        profiled/pass2.o profiled/pass3.o profiled/pass4.o profiled/pass5.o \
        profiled/badblocks.o profiled/util.o profiled/dirinfo.o \
-       profiled/ehandler.o
+       profiled/ehandler.o profiled/swapfs.o
 
 SRCS= $(srcdir)/e2fsck.c \
        $(srcdir)/pass1.c \
@@ -72,7 +73,7 @@ SRCS= $(srcdir)/e2fsck.c \
        $(srcdir)/ehandler.c \
        $(MTRACE_SRC)
 
-all:: profiled $(PROGS) e2fsck.static e2fsck.shared
+all:: profiled $(PROGS) e2fsck.static e2fsck.shared $(MANPAGES)
 
 @PROFILE_CMT@all:: e2fsck.profiled
 
@@ -142,39 +143,35 @@ distclean: clean
 # Makefile dependencies follow.  This must be the last section in
 # the Makefile.in file
 #
-e2fsck.o: $(srcdir)/e2fsck.c \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
- $(srcdir)/../version.h
+e2fsck.o: $(srcdir)/e2fsck.c $(top_srcdir)/lib/et/com_err.h \
+ $(top_srcdir)/lib/uuid/uuid.h $(srcdir)/e2fsck.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/../version.h
 pass1.o: $(srcdir)/pass1.c $(top_srcdir)/lib/et/com_err.h \
  $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h
-pass1b.o: $(srcdir)/pass1b.c \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h \
+pass1b.o: $(srcdir)/pass1b.c $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h
-pass2.o: $(srcdir)/pass2.c $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
-pass3.o: $(srcdir)/pass3.c \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
+pass2.o: $(srcdir)/pass2.c $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
  $(top_srcdir)/lib/ext2fs/ext2fs.h \
  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h
+pass3.o: $(srcdir)/pass3.c $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h  $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
 pass4.o: $(srcdir)/pass4.c $(srcdir)/e2fsck.h \
  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h
 pass5.o: $(srcdir)/pass5.c $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
-badblocks.o: $(srcdir)/badblocks.c \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+badblocks.o: $(srcdir)/badblocks.c $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h
 util.o: $(srcdir)/util.c $(srcdir)/e2fsck.h \
@@ -182,13 +179,10 @@ util.o: $(srcdir)/util.c $(srcdir)/e2fsck.h \
  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h
 dirinfo.o: $(srcdir)/dirinfo.c $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
-ehandler.o: $(srcdir)/ehandler.c \
- $(srcdir)/e2fsck.h \
+ $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h
+ehandler.o: $(srcdir)/ehandler.c $(srcdir)/e2fsck.h \
  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h
-
index bfd20f3..cb71505 100644 (file)
@@ -8,7 +8,7 @@ e2fsck \- check a Linux second extended file system
 .SH SYNOPSIS
 .B e2fsck
 [
-.B \-pacnyrdfvtFV
+.B \-pacnyrdfvstFSV
 ]
 [
 .B \-b
@@ -104,6 +104,15 @@ Automatically repair ("preen") the file system without any questions.
 .I -r
 This option does nothing at all; it is provided only for backwards
 compatibility.
+.IP 
+.I -s
+This option will byte-swap the filesystem so that it is using the normalized, 
+standard byte-order (which is i386 or little endian).  If the filesystem is
+already in the standard byte-order, e2fsck will take no action.
+.TP
+.I -S
+This option will byte-swap the filesystem, regardless of its current 
+byte-order.
 .TP
 .I -t
 Print timing statistics for
index 6dbfa6f..9048298 100644 (file)
  * enforced (but it's not much fun on a character device :-). 
  */
 
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
 #include <string.h>
 #include <fcntl.h>
 #include <ctype.h>
@@ -36,6 +40,7 @@
 #include <malloc.h>
 
 #include "et/com_err.h"
+#include "uuid/uuid.h"
 #include "e2fsck.h"
 #include "../version.h"
 
@@ -52,6 +57,8 @@ int tflag = 0;                        /* Do timing */
 int cflag = 0;                 /* check disk */
 int preen = 0;
 int rwflag = 1;
+int swapfs = 0;
+int normalize_swapfs = 0;
 int inode_buffer_blocks = 0;
 blk_t superblock;
 int blocksize = 0;
@@ -80,7 +87,7 @@ int restart_e2fsck = 0;
 static void usage(NOARGS)
 {
        fprintf(stderr,
-               "Usage: %s [-panyrcdfvtFV] [-b superblock] [-B blocksize]\n"
+               "Usage: %s [-panyrcdfvstFSV] [-b superblock] [-B blocksize]\n"
                "\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n"
                "\t\t[-l|-L bad_blocks_file] device\n", program_name);
        exit(FSCK_USAGE);
@@ -206,11 +213,12 @@ static void sync_disks(NOARGS)
 #define MIN_CHECK 1
 #define MAX_CHECK 2
 
-static const char *corrupt_msg = "\nThe filesystem superblock is corrupt.  "
-       "Try running e2fsck with an alternate\n"
-       "superblock using the -b option.  "
-       "(8193 is commonly an alternate superblock;\n"
-       "Hence, 'e2fsck -b 8193 <device>' may recover the filesystem.)\n\n";
+static const char *corrupt_msg =
+"\nThe superblock could not be read or does not describe a correct ext2\n"
+"filesystem.  If the device is valid and it really contains an ext2\n"
+"filesystem (and not swap or ufs or something else), then the superblock\n"
+"is corrupt, and you might try running e2fsck with an alternate superblock:\n"
+"    e2fsck -b 8193 <device>\n\n";
 
 static void check_super_value(const char *descr, unsigned long value,
                              int flags, unsigned long min, unsigned long max)
@@ -224,7 +232,7 @@ static void check_super_value(const char *descr, unsigned long value,
        }
 }
 
-static void relocate_hint()
+static void relocate_hint(void)
 {
        static hint_issued = 0;
 
@@ -245,7 +253,7 @@ static void relocate_hint()
 static void check_super_block(ext2_filsys fs)
 {
        blk_t   first_block, last_block;
-       struct ext2_super_block *s = fs->super;
+       struct ext2fs_sb *s = (struct ext2fs_sb *) fs->super;
        blk_t   blocks_per_group = fs->super->s_blocks_per_group;
        int     i;
        blk_t   should_be;
@@ -375,6 +383,20 @@ static void check_super_block(ext2_filsys fs)
                first_block += fs->super->s_blocks_per_group;
                last_block += fs->super->s_blocks_per_group;
        }
+
+       /*
+        * If the UUID field isn't assigned, assign it.
+        */
+       if (rwflag && uuid_is_null(s->s_uuid)) {
+               if (preen)
+                       printf("%s: Adding UUID to filesystem.\n",
+                              device_name);
+               else
+                       printf("Filesystem did not have a UUID; "
+                              "generating one.\n\n");
+               uuid_generate(s->s_uuid);
+               ext2fs_mark_super_dirty(fs);
+       }
        return;
 }
 
@@ -387,7 +409,7 @@ static void check_if_skip(ext2_filsys fs)
 {
        const char *reason = NULL;
        
-       if (force || bad_blocks_file || cflag)
+       if (force || bad_blocks_file || cflag || swapfs)
                return;
        
        if (fs->super->s_state & EXT2_ERROR_FS)
@@ -409,6 +431,7 @@ static void check_if_skip(ext2_filsys fs)
                       fs->super->s_inodes_count,
                       fs->super->s_blocks_count - fs->super->s_free_blocks_count,
                       fs->super->s_blocks_count);
+               ext2fs_close(fs);
                exit(FSCK_OK);
        }
 }      
@@ -444,7 +467,7 @@ static void PRS(int argc, char *argv[])
        
        if (argc && *argv)
                program_name = *argv;
-       while ((c = getopt (argc, argv, "panyrcB:dfvtFVM:b:I:P:l:L:N:")) != EOF)
+       while ((c = getopt (argc, argv, "panyrcB:dfvtFVM:b:I:P:l:L:N:Ss")) != EOF)
                switch (c) {
                case 'p':
                case 'a':
@@ -515,6 +538,11 @@ static void PRS(int argc, char *argv[])
                case 'N':
                        device_name = optarg;
                        break;
+               case 's':
+                       normalize_swapfs = 1;
+               case 'S':
+                       swapfs = 1;
+                       break;
                default:
                        usage ();
                }
@@ -522,7 +550,7 @@ static void PRS(int argc, char *argv[])
                return;
        if (optind != argc - 1)
                usage ();
-       if (nflag && !bad_blocks_file && !cflag)
+       if (nflag && !bad_blocks_file && !cflag && !swapfs)
                rwflag = 0;
        filesystem_name = argv[optind];
        if (device_name == 0)
@@ -546,6 +574,13 @@ static void PRS(int argc, char *argv[])
                fatal_error ("BLKFLSBUF not supported");
 #endif /* BLKFLSBUF */
        }
+       if (swapfs) {
+               if (cflag || bad_blocks_file) {
+                       fprintf(stderr, "Incompatible options not "
+                               "allowed when byte-swapping.\n");
+                       fatal_error(0);
+               }
+       }
 }
                                        
 int main (int argc, char *argv[])
@@ -604,25 +639,18 @@ restart:
        if (retval) {
                com_err(program_name, retval, "while trying to open %s",
                        filesystem_name);
-               switch (retval) {
-               case EXT2_ET_REV_TOO_HIGH:
+               if (retval == EXT2_ET_REV_TOO_HIGH)
                        printf ("Get a newer version of e2fsck!\n");
-                       break;
-               case EXT2_ET_SHORT_READ:
+               else if (retval == EXT2_ET_SHORT_READ)
                        printf ("Could this be a zero-length partition?\n");
-                       break;
-               case EPERM:
-               case EACCES:
+               else if ((retval == EPERM) || (retval == EACCES))
                        printf("You must have %s access to the "
                               "filesystem or be root\n",
                               rwflag ? "r/w" : "r/o");
-                       break;
-               case ENXIO:
+               else if (retval == ENXIO)
                        printf("Possibly non-existent or swap device?\n");
-                       break;
-               default:
+               else
                        printf(corrupt_msg);
-               }
                fatal_error(0);
        }
 
@@ -662,11 +690,21 @@ restart:
        else if (cflag)
                test_disk(fs);
 
+       if (normalize_swapfs) {
+               if ((fs->flags & EXT2_SWAP_BYTES) == ext2fs_native_flag()) {
+                       fprintf(stderr, "%s: Filesystem byte order "
+                               "already normalized.\n", device_name);
+                       fatal_error(0);
+               }
+       }
+       if (swapfs)
+               swap_filesys(fs);
+
        /*
         * Mark the system as valid, 'til proven otherwise
         */
        ext2fs_mark_valid(fs);
-       
+
        pass1(fs);
        free(invalid_inode_bitmap);
        free(invalid_block_bitmap);
@@ -698,9 +736,11 @@ restart:
        if (!ext2fs_test_valid(fs))
                exit_value = FSCK_UNCORRECTED;
        if (rwflag) {
-               if (ext2fs_test_valid(fs))
+               if (ext2fs_test_valid(fs)) {
+                       if (!(fs->super->s_state & EXT2_VALID_FS))
+                               exit_value = FSCK_NONDESTRUCT;
                        fs->super->s_state = EXT2_VALID_FS;
-               else
+               else
                        fs->super->s_state &= ~EXT2_VALID_FS;
                fs->super->s_mnt_count = 0;
                fs->super->s_lastcheck = time(NULL);
index dea265d..2e0fa77 100644 (file)
@@ -42,7 +42,7 @@
  * The last ext2fs revision level that this version of e2fsck is able to
  * support
  */
-#define E2FSCK_CURRENT_REV     0
+#define E2FSCK_CURRENT_REV     1
 
 /*
  * Inode count arrays
@@ -145,6 +145,12 @@ extern struct resource_track       global_rtrack;
 extern int invalid_bitmaps;
 
 /*
+ * For pass1_check_directory and pass1_get_blocks
+ */
+extern ino_t stashed_ino;
+extern struct ext2_inode *stashed_inode;
+
+/*
  * Procedure declarations
  */
 
@@ -155,6 +161,14 @@ extern void pass3(ext2_filsys fs);
 extern void pass4(ext2_filsys fs);
 extern void pass5(ext2_filsys fs);
 
+/* pass1.c */
+extern errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino);
+extern errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks);
+extern errcode_t pass1_read_inode(ext2_filsys fs, ino_t ino,
+                                 struct ext2_inode *inode);
+extern errcode_t pass1_write_inode(ext2_filsys fs, ino_t ino,
+                                  struct ext2_inode *inode);
+
 /* badblock.c */
 extern void read_bad_blocks_file(ext2_filsys fs, const char *bad_blocks_file,
                                 int replace_bad_blocks);
@@ -171,6 +185,9 @@ extern int get_num_dirs(ext2_filsys fs);
 extern const char *ehandler_operation(const char *op);
 extern void ehandler_init(io_channel channel);
 
+/* swapfs.c */
+void swap_filesys(ext2_filsys fs);
+
 /* util.c */
 extern void *allocate_memory(int size, const char *description);
 extern int ask(const char * string, int def);
index 58f3c69..27ceecd 100644 (file)
@@ -69,8 +69,6 @@ ext2fs_block_bitmap block_found_map = 0;
 ext2fs_block_bitmap block_dup_map = 0;
 ext2fs_block_bitmap block_illegal_map = 0;
 
-static int fix_link_count = -1;
-
 unsigned short * inode_link_info = NULL;
 
 static int process_block(ext2_filsys fs, blk_t *blocknr,
@@ -80,8 +78,6 @@ static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
 static void check_blocks(ext2_filsys fs, ino_t ino, struct ext2_inode *inode,
                         char *block_buf);
 static void mark_table_blocks(ext2_filsys fs);
-static errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino);
-static errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks);
 static void alloc_bad_map(ext2_filsys fs);
 static void handle_fs_bad_blocks(ext2_filsys fs);
 static void process_inodes(ext2_filsys fs, char *block_buf);
@@ -170,6 +166,7 @@ void pass1(ext2_filsys fs)
        char            *block_buf;
        errcode_t       retval;
        struct resource_track   rtrack;
+       unsigned char   frag, fsize;
        
        init_resource_track(&rtrack);
        
@@ -229,6 +226,8 @@ void pass1(ext2_filsys fs)
        block_buf = allocate_memory(fs->blocksize * 3, "block interate buffer");
        fs->get_blocks = pass1_get_blocks;
        fs->check_directory = pass1_check_directory;
+       fs->read_inode = pass1_read_inode;
+       fs->write_inode = pass1_write_inode;
        ehandler_operation("doing inode scan");
        retval = ext2fs_open_inode_scan(fs, inode_buffer_blocks, &scan);
        if (retval) {
@@ -297,12 +296,6 @@ void pass1(ext2_filsys fs)
                                        inode.i_dtime = 0;
                                        e2fsck_write_inode(fs, ino, &inode,
                                                           "pass1");
-                                       printf("Note: /lost+found will "
-                                              "probably be deleted as well, "
-                                              "due to the mke2fs bug.\n"
-                                              "Be sure to run mklost+found "
-                                              "to recreate it after e2fsck "
-                                              "finishes.\n\n");
                                } else
                                        ext2fs_unmark_valid(fs);
                        }
@@ -340,37 +333,44 @@ void pass1(ext2_filsys fs)
                        goto next;
                }
                /*
-                * 0.3c ext2fs code didn't clear i_links_count for
+                * n.b.  0.3c ext2fs code didn't clear i_links_count for
                 * deleted files.  Oops.
+                *
+                * Since all new ext2 implementations get this right,
+                * we now assume that the case of non-zero
+                * i_links_count and non-zero dtime means that we
+                * should keep the file, not delete it.
                 * 
-                * In the future, when the new ext2fs behavior is the
-                * norm, we may want to handle the case of a non-zero
-                * i_links_count and non-zero dtime by clearing dtime
-                * and assuming the inode is in use, instead of
-                * assuming the inode is not in use.
                 */
                if (inode.i_dtime) {
-                       if (fix_link_count == -1) {
-                               printf("\nDeleted inode detected with non-zero link count.\n");
-                               printf("This is probably due to old ext2fs kernel code.  \n");
-                               fix_link_count = ask("Fix inode(s)", 1);
-                       }
-                       printf("Inode %lu is deleted w/ non-zero link_count.  %s\n",
-                              ino, clear_msg[fix_link_count]);
-                       if (fix_link_count) {
-                               inode.i_links_count = 0;
-                               inode_link_info[ino] = 0;
+                       printf("Inode %lu is in use, but has dtime set\n",
+                              ino);
+                       if (ask("Clear dtime", 1)) {
+                               inode.i_dtime = 0;
                                e2fsck_write_inode(fs, ino, &inode, "pass1");
                        } else
                                ext2fs_unmark_valid(fs);
-                       goto next;
                }
                
                ext2fs_mark_inode_bitmap(inode_used_map, ino);
-               if (inode.i_faddr
-#if HAVE_EXT2_FRAGS
-                   || inode.i_frag || inode.i_fsize
-#endif
+               switch (fs->super->s_creator_os) {
+                   case EXT2_OS_LINUX:
+                       frag = inode.osd2.linux2.l_i_frag;
+                       fsize = inode.osd2.linux2.l_i_fsize;
+                       break;
+                   case EXT2_OS_HURD:
+                       frag = inode.osd2.hurd2.h_i_frag;
+                       fsize = inode.osd2.hurd2.h_i_fsize;
+                       break;
+                   case EXT2_OS_MASIX:
+                       frag = inode.osd2.masix2.m_i_frag;
+                       fsize = inode.osd2.masix2.m_i_fsize;
+                       break;
+                   default:
+                       frag = fsize = 0;
+               }
+               
+               if (inode.i_faddr || frag || fsize
                    || inode.i_file_acl || inode.i_dir_acl) {
                        if (!inode_bad_map)
                                alloc_bad_map(fs);
@@ -448,10 +448,13 @@ void pass1(ext2_filsys fs)
                }
                pass1_dupblocks(fs, block_buf);
        }
-       fs->get_blocks = 0;
-       fs->check_directory = 0;
        free(inodes_to_process);
 endit:
+       fs->get_blocks = 0;
+       fs->check_directory = 0;
+       fs->read_inode = 0;
+       fs->write_inode = 0;
+       
        free(block_buf);
        ext2fs_free_block_bitmap(block_illegal_map);
        block_illegal_map = 0;
@@ -747,6 +750,10 @@ int process_block(ext2_filsys fs,
 
        if (blk == 0) {
                if (p->is_dir == 0) {
+                       /*
+                        * Should never happen, since only directories
+                        * get called with BLOCK_FLAG_HOLE
+                        */
                        printf("process_block() called with blk == 0, "
                               "inode %lu???", p->ino);
                        return 0;
@@ -818,12 +825,10 @@ int process_block(ext2_filsys fs,
 
        mark_block_used(fs, blk);
        p->num_blocks++;
-       if (blockcnt < 0)
-               return 0;
-       
-       p->last_block = blockcnt;
+       if (blockcnt >= 0)
+               p->last_block = blockcnt;
 mark_dir:
-       if (p->is_dir) {
+       if (p->is_dir && (blockcnt >= 0)) {
                if (dir_block_count >= dir_block_size) {
                        dir_block_size += 100;
                        dir_blocks = realloc(dir_blocks,
@@ -1208,7 +1213,7 @@ static void mark_table_blocks(ext2_filsys fs)
  * structure, so there's no point in letting the ext2fs library read
  * the inode again.
  */
-static errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
+errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
 {
        int     i;
        
@@ -1223,7 +1228,23 @@ static errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
        exit(FSCK_ERROR);
 }
 
-static errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino)
+errcode_t pass1_read_inode(ext2_filsys fs, ino_t ino, struct ext2_inode *inode)
+{
+       if (ino != stashed_ino)
+               return EXT2_ET_CALLBACK_NOTHANDLED;
+       *inode = *stashed_inode;
+       return 0;
+}
+
+errcode_t pass1_write_inode(ext2_filsys fs, ino_t ino,
+                           struct ext2_inode *inode)
+{
+       if (ino == stashed_ino)
+               *stashed_inode = *inode;
+       return EXT2_ET_CALLBACK_NOTHANDLED;
+}
+
+errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino)
 {
        if (ino == stashed_ino) {
                if (!LINUX_S_ISDIR(stashed_inode->i_mode))
index 287c24f..b3bc833 100644 (file)
@@ -98,12 +98,6 @@ static struct dup_block *dup_blk = 0;
 static struct dup_inode *dup_ino = 0;
 static int dup_inode_count = 0;
 
-/*
- * For pass1_check_directory and pass1_get_blocks
- */
-extern ino_t stashed_ino;
-extern struct ext2_inode *stashed_inode;
-
 static ext2fs_inode_bitmap inode_dup_map;
 
 /*
index f4a4d32..91bcc08 100644 (file)
@@ -530,6 +530,7 @@ static void deallocate_inode(ext2_filsys fs, ino_t ino,
        errcode_t               retval;
        struct ext2_inode       inode;
 
+       inode_link_info[ino] = 0;
        e2fsck_read_inode(fs, ino, &inode, "deallocate_inode");
        inode.i_links_count = 0;
        inode.i_dtime = time(0);
@@ -609,6 +610,7 @@ static int process_bad_inode(ext2_filsys fs, ino_t dir, ino_t ino)
        errcode_t               retval;
        int                     inode_modified = 0;
        char                    *pathname;
+       unsigned char           *frag, *fsize;
 
        e2fsck_read_inode(fs, ino, &inode, "process_bad_inode");
        retval = ext2fs_get_pathname(fs, dir, ino, &pathname);
@@ -634,23 +636,30 @@ static int process_bad_inode(ext2_filsys fs, ino_t dir, ino_t ino)
        }
        check_for_zero_u32(fs, ino, pathname, "i_faddr", &inode.i_faddr,
                            &inode_modified);
-#if HAVE_EXT2_FRAGS
-       check_for_zero_u8(fs, ino, pathname, "i_frag", &inode.i_frag,
-                           &inode_modified);
-       check_for_zero_u8(fs, ino, pathname, "i_fsize", &inode.i_fsize,
-                           &inode_modified);
-#else
-       /*
-        * Even if the OS specific fields don't support i_frag and
-        * i_fsize, make sure they are set to zero anyway.  This may
-        * cause problems if on some other OS these fields are reused
-        * for something else, but that's probably a bad idea....
-        */
-       check_for_zero_u8(fs, ino, pathname, "i_frag",
-                         &inode.osd2.linux2.l_i_frag, &inode_modified);
-       check_for_zero_u8(fs, ino, pathname, "i_fsize",
-                         &inode.osd2.linux2.l_i_fsize, &inode_modified);
-#endif
+
+       switch (fs->super->s_creator_os) {
+           case EXT2_OS_LINUX:
+               frag = &inode.osd2.linux2.l_i_frag;
+               fsize = &inode.osd2.linux2.l_i_fsize;
+               break;
+           case EXT2_OS_HURD:
+               frag = &inode.osd2.hurd2.h_i_frag;
+               fsize = &inode.osd2.hurd2.h_i_fsize;
+               break;
+           case EXT2_OS_MASIX:
+               frag = &inode.osd2.masix2.m_i_frag;
+               fsize = &inode.osd2.masix2.m_i_fsize;
+               break;
+           default:
+               frag = fsize = 0;
+       }
+       if (frag)
+               check_for_zero_u8(fs, ino, pathname, "i_frag", frag,
+                                 &inode_modified);
+       if (fsize)
+               check_for_zero_u8(fs, ino, pathname, "i_fsize", fsize,
+                                 &inode_modified);
+
        check_for_zero_u32(fs, ino, pathname, "i_file_acl", &inode.i_file_acl,
                            &inode_modified);
        check_for_zero_u32(fs, ino, pathname, "i_dir_acl", &inode.i_dir_acl,
index dde578b..f167d15 100644 (file)
@@ -38,13 +38,23 @@ void pass4(ext2_filsys fs)
                        if (ask("Connect to /lost+found", 1)) {
                                if (reconnect_file(fs, i))
                                        ext2fs_unmark_valid(fs);
-                       } else
+                       } else {
+                               /*
+                                * If we don't attach the inode, then
+                                * skip the i_links_test since there's
+                                * no point in trying to force
+                                * i_links_count to zero.
+                                */
                                ext2fs_unmark_valid(fs);
+                               continue;
+                       }
                }
                if (inode_count[i] != inode_link_info[i]) {
                        e2fsck_read_inode(fs, i, &inode, "pass4");
                        if (inode_link_info[i] != inode.i_links_count) {
                                printf("WARNING: PROGRAMMING BUG IN E2FSCK!\n");
+                               printf("\tOR SOME BONEHEAD (YOU) IS CHECKING "
+                                      "A MOUNTED (LIVE) FILESYSTEM.\n"); 
                                printf("inode_link_info[%ld] is %u, "
                                       "inode.i_links_count is %d.  "
                                       "They should be the same!\n",
diff --git a/e2fsck/swapfs.c b/e2fsck/swapfs.c
new file mode 100644 (file)
index 0000000..291fcb3
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * swapfs.c --- byte-swap an ext2 filesystem
+ */
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <et/com_err.h>
+#include "e2fsck.h"
+
+struct swap_block_struct {
+       ino_t           ino;
+       int             isdir;
+       errcode_t       errcode;
+       char            *dir_buf;
+       struct ext2_inode *inode;
+};
+
+/*
+ * This is a helper function for block_iterate.  We mark all of the
+ * indirect and direct blocks as changed, so that block_iterate will
+ * write them out.
+ */
+static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
+                     void *private)
+{
+       errcode_t       retval;
+       
+       struct swap_block_struct *sb = (struct swap_block_struct *) private;
+
+       if (sb->isdir && (blockcnt >= 0) && *block_nr) {
+               retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
+               if (retval) {
+                       sb->errcode = retval;
+                       return BLOCK_ABORT;
+               }
+               retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
+               if (retval) {
+                       sb->errcode = retval;
+                       return BLOCK_ABORT;
+               }
+       }
+       if (blockcnt >= 0) {
+               if (blockcnt < EXT2_NDIR_BLOCKS)
+                       return 0;
+               return BLOCK_CHANGED;
+       }
+       if (blockcnt == BLOCK_COUNT_IND) {
+               if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
+                       return 0;
+               return BLOCK_CHANGED;
+       }
+       if (blockcnt == BLOCK_COUNT_DIND) {
+               if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
+                       return 0;
+               return BLOCK_CHANGED;
+       }
+       if (blockcnt == BLOCK_COUNT_TIND) {
+               if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
+                       return 0;
+               return BLOCK_CHANGED;
+       }
+       return BLOCK_CHANGED;
+}
+
+/*
+ * This function is responsible for byte-swapping all of the indirect,
+ * block pointers.  It is also responsible for byte-swapping directories.
+ */
+static void swap_inode_blocks(ext2_filsys fs, ino_t ino, char *block_buf,
+                             struct ext2_inode *inode)
+{
+       errcode_t                       retval;
+       struct swap_block_struct        sb;
+
+       sb.ino = ino;
+       sb.inode = inode;
+       sb.dir_buf = block_buf + fs->blocksize*3;
+       sb.errcode = 0;
+       sb.isdir = 0;
+       if (LINUX_S_ISDIR(inode->i_mode))
+               sb.isdir = 1;
+
+       retval = ext2fs_block_iterate(fs, ino, 0, block_buf, swap_block, &sb);
+       if (retval) {
+               com_err("swap_inode_blocks", retval,
+                       "while calling ext2fs_block_iterate");
+               fatal_error(0);
+       }
+       if (sb.errcode) {
+               com_err("swap_inode_blocks", sb.errcode,
+                       "while calling iterator function");
+               fatal_error(0);
+       }
+}
+
+static void swap_inodes(ext2_filsys fs)
+{
+       int                     i, group;
+       ino_t                   ino = 1;
+       char                    *buf, *block_buf;
+       errcode_t               retval;
+       struct ext2_inode *     inode;
+
+       fs->read_inode = pass1_read_inode;
+       fs->get_blocks = pass1_get_blocks;
+       
+
+       buf = malloc(fs->blocksize * fs->inode_blocks_per_group);
+       if (!buf) {
+               com_err("swap_inodes", ENOMEM,
+                       "while allocating inode buffer");
+               fatal_error(0);
+       }
+       block_buf = allocate_memory(fs->blocksize * 4,
+                                   "block interate buffer");
+       for (group = 0; group < fs->group_desc_count; group++) {
+               retval = io_channel_read_blk(fs->io,
+                     fs->group_desc[group].bg_inode_table,
+                     fs->inode_blocks_per_group, buf);
+               if (retval) {
+                       com_err("swap_inodes", retval,
+                               "while reading inode table (group %d)",
+                               group);
+                       fatal_error(0);
+               }
+               inode = (struct ext2_inode *) buf;
+               for (i=0; i < fs->super->s_inodes_per_group; i++, ino++) {
+                       if (fs->flags & EXT2_SWAP_BYTES_READ)
+                               ext2fs_swap_inode(fs, inode, inode, 0);
+                       stashed_ino = ino;
+                       stashed_inode = inode;
+                       
+                       if (inode->i_block[EXT2_IND_BLOCK] ||
+                           inode->i_block[EXT2_DIND_BLOCK] ||
+                           inode->i_block[EXT2_TIND_BLOCK] ||
+                           LINUX_S_ISDIR(inode->i_mode))
+                               swap_inode_blocks(fs, ino, block_buf, inode);
+                       
+                       if (fs->flags & EXT2_SWAP_BYTES_WRITE)
+                               ext2fs_swap_inode(fs, inode, inode, 1);
+                       inode++;
+               }
+               retval = io_channel_write_blk(fs->io,
+                     fs->group_desc[group].bg_inode_table,
+                     fs->inode_blocks_per_group, buf);
+               if (retval) {
+                       com_err("swap_inodes", retval,
+                               "while writing inode table (group %d)",
+                               group);
+                       fatal_error(0);
+               }
+       }
+       free(buf);
+       free(block_buf);
+       fs->read_inode = 0;
+       fs->get_blocks = 0;
+}
+
+void swap_filesys(ext2_filsys fs)
+{
+       struct resource_track   rtrack;
+
+       init_resource_track(&rtrack);
+
+       if (!preen)
+               printf("Pass 0: Doing byte-swap of filesystem\n");
+       
+#ifdef MTRACE
+       mtrace_print("Byte swap");
+#endif
+
+       if (fs->super->s_mnt_count) {
+               fprintf(stderr, "%s: the filesystem must be freshly "
+                       "checked using fsck\n"
+                       "and not mounted before trying to "
+                       "byte-swap it.\n", device_name);
+               fatal_error(0);
+       }
+       if (fs->flags & EXT2_SWAP_BYTES) {
+               fs->flags &= ~(EXT2_SWAP_BYTES|EXT2_SWAP_BYTES_WRITE);
+               fs->flags |= EXT2_SWAP_BYTES_READ;
+       } else {
+               fs->flags &= ~EXT2_SWAP_BYTES_READ;
+               fs->flags |= EXT2_SWAP_BYTES_WRITE;
+       }
+       swap_inodes(fs);
+       if (fs->flags & EXT2_SWAP_BYTES_WRITE)
+               fs->flags |= EXT2_SWAP_BYTES;
+       fs->flags &= ~(EXT2_SWAP_BYTES_READ|EXT2_SWAP_BYTES_WRITE);
+       ext2fs_flush(fs);
+       
+       if (tflag > 1) {
+               printf("Byte swap: ");
+               print_resource_track(&rtrack);
+       }
+}
+
+
index 4353b5e..cd0feab 100644 (file)
@@ -4,6 +4,17 @@
 typedef unsigned char __u8;
 typedef signed char __s8;
 
+#if (@SIZEOF_INT@ == 8)
+typedef int            __s64;
+typedef unsigned int   __u64;
+#elif (@SIZEOF_LONG@ == 8)
+typedef long           __s64;
+typedef unsigned long  __u64;
+#elif (@SIZEOF_LONG_LONG@ == 8)
+typedef long           __s64;
+typedef unsigned long  __u64;
+#endif
+
 #if (@SIZEOF_INT@ == 2)
 typedef        int             __s16;
 typedef        unsigned int    __u16;
@@ -27,4 +38,8 @@ typedef       unsigned short  __u32;
  ?== error: undefined 32 bit type
 #endif
 
+#ifndef HAVE_INO_T
+typedef __u32 ino_t;
+#endif
+
 #endif /* LINUX_TYPES_H */
index 682e10c..fe60daf 100644 (file)
@@ -1,3 +1,16 @@
+Wed Aug 28 15:20:26 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+       * Makefile.elf-lib (installdirs-elf-lib): Renamed from installdirs
+       to avoid making random directories only neeeded when installing
+       normal libraries.
+       (install-shlibs): Use installdirs-elf-lib instead of installdirs.
+
+Thu May 23 12:40:12 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * Makefile.elf-lib: Install the .so files in /usr/lib, since the
+               .a files are stored there.  (We were installing the .so
+               files in the wrong place before.)
+
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * Release of E2fsprogs version 1.04
index 83b59fc..ff19bc9 100644 (file)
@@ -31,15 +31,19 @@ $(ELF_LIB): $(OBJS)
        $(LN) ../$(ELF_LIB) ../$(ELF_IMAGE).so
        $(LN) ../$(ELF_LIB) ../$(ELF_SONAME)
 
-installdirs::
-       $(top_srcdir)/mkinstalldirs $(DESTDIR)$(ELF_INSTALL_DIR)
+installdirs-elf-lib::
+       $(top_srcdir)/mkinstalldirs $(DESTDIR)$(ELF_INSTALL_DIR) \
+               $(DESTDIR)$(ulibdir)
 
-install-shlibs install:: $(ELF_LIB) installdirs
+installdirs:: installdirs-elf-lib
+
+install-shlibs install:: $(ELF_LIB) installdirs-elf-lib
        $(INSTALL_PROGRAM) $(ELF_LIB) $(DESTDIR)$(ELF_INSTALL_DIR)/$(ELF_LIB)
        $(STRIP) --strip-debug \
                $(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_LIB)
-       $(LN) -sf $(ELF_LIB) $(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_SONAME)
-       $(LN) -sf $(ELF_SONAME) $(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_IMAGE).so
+       $(LN_S) -f $(ELF_LIB) $(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_SONAME)
+       $(LN_S) -f $(DLL_INSTALL_DIR)/$(ELF_SONAME) \
+               $(DESTDIR)$(ulibdir)/$(ELF_IMAGE).so
        -ldconfig
 
 clean::
index 262609d..e18c3f4 100644 (file)
@@ -10,6 +10,7 @@ $SED  -e "s%@AWK@%$AWK%g" \
        -e "s%@E2FSPROGS_MONTH@%$E2FSPROGS_MONTH%g" \
        -e "s%@E2FSPROGS_YEAR@%$E2FSPROGS_YEAR%g" \
        -e "s%@E2FSPROGS_VERSION@%$E2FSPROGS_VERSION%g" \
+       -e "s%@SIZEOF_LONG_LONG@%$SIZEOF_LONG_LONG%g" \
        -e "s%@SIZEOF_LONG@%$SIZEOF_LONG%g" \
        -e "s%@SIZEOF_INT@%$SIZEOF_INT%g" \
        -e "s%@SIZEOF_SHORT@%$SIZEOF_SHORT%g" \
index 2422e73..fe4fa5e 100644 (file)
@@ -1,3 +1,20 @@
+Sat Sep  7 14:48:35 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * ls.c (interval_string): Pretty print the check interval.
+
+Tue Aug  6 14:12:36 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * ls.c (list_super): Display the OS, volume label, last mounted,
+               and UUID field if present.
+
+Mon Jun 24 09:55:58 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * ps.c, pf.c, pe.c, ls.c, setversion.c, setflags.c, getversion.c, 
+               fsetversion.c, fsetflags.c, fgetversion.c, fgetflags.c,
+               getflags.c: Remove include of ext2_fs.h, since it's
+               included by e2p.h; this also solves a sys/types.h vs
+               linux/types.h inclusion ordering problem with the GNU libc.
+
 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/e2p/MAKELOG b/lib/e2p/MAKELOG
deleted file mode 100644 (file)
index 27e4420..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-gcc -O2 -fomit-frame-pointer  -I.. -c pe.c
-In file included from pe.c:19:
-/usr/include/linux/ext2_fs.h:127: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:127: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:128: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:129: parse error before `aclh_acle_count'
-/usr/include/linux/ext2_fs.h:129: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:130: parse error before `aclh_first_acle'
-/usr/include/linux/ext2_fs.h:130: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:135: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:135: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:136: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:137: parse error before `acle_type'
-/usr/include/linux/ext2_fs.h:137: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:138: parse error before `acle_tag'
-/usr/include/linux/ext2_fs.h:138: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:139: parse error before `acle_pad1'
-/usr/include/linux/ext2_fs.h:139: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:140: parse error before `acle_next'
-/usr/include/linux/ext2_fs.h:140: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:149: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:149: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:150: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:151: parse error before `bg_inode_table'
-/usr/include/linux/ext2_fs.h:151: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:152: parse error before `bg_free_blocks_count'
-/usr/include/linux/ext2_fs.h:152: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:153: parse error before `bg_free_inodes_count'
-/usr/include/linux/ext2_fs.h:153: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:158: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:158: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:159: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:160: parse error before `bg_inode_table'
-/usr/include/linux/ext2_fs.h:160: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:161: parse error before `bg_free_blocks_count'
-/usr/include/linux/ext2_fs.h:161: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:162: parse error before `bg_free_inodes_count'
-/usr/include/linux/ext2_fs.h:162: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:163: parse error before `bg_used_dirs_count'
-/usr/include/linux/ext2_fs.h:163: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:164: parse error before `bg_pad'
-/usr/include/linux/ext2_fs.h:164: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:165: parse error before `bg_reserved'
-/usr/include/linux/ext2_fs.h:165: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:166: parse error before `}'
-/usr/include/linux/ext2_fs.h:213: parse error before `__u16'
-/usr/include/linux/ext2_fs.h:213: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:214: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:215: parse error before `i_size'
-/usr/include/linux/ext2_fs.h:215: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:216: parse error before `i_atime'
-/usr/include/linux/ext2_fs.h:216: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:217: parse error before `i_ctime'
-/usr/include/linux/ext2_fs.h:217: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:218: parse error before `i_mtime'
-/usr/include/linux/ext2_fs.h:218: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:219: parse error before `i_dtime'
-/usr/include/linux/ext2_fs.h:219: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:220: parse error before `i_gid'
-/usr/include/linux/ext2_fs.h:220: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:221: parse error before `i_links_count'
-/usr/include/linux/ext2_fs.h:221: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:222: parse error before `i_blocks'
-/usr/include/linux/ext2_fs.h:222: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:223: parse error before `i_flags'
-/usr/include/linux/ext2_fs.h:223: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:226: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:226: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:226: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:227: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:229: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:229: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:230: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:232: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:232: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:233: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:234: parse error before `}'
-/usr/include/linux/ext2_fs.h:234: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:235: parse error before `i_block'
-/usr/include/linux/ext2_fs.h:235: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:236: parse error before `i_version'
-/usr/include/linux/ext2_fs.h:236: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:237: parse error before `i_file_acl'
-/usr/include/linux/ext2_fs.h:237: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:238: parse error before `i_dir_acl'
-/usr/include/linux/ext2_fs.h:238: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:239: parse error before `i_faddr'
-/usr/include/linux/ext2_fs.h:239: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:242: parse error before `__u8'
-/usr/include/linux/ext2_fs.h:242: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:242: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:243: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:244: parse error before `i_pad1'
-/usr/include/linux/ext2_fs.h:244: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:245: parse error before `l_i_reserved2'
-/usr/include/linux/ext2_fs.h:245: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:246: parse error before `}'
-/usr/include/linux/ext2_fs.h:246: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:248: parse error before `__u8'
-/usr/include/linux/ext2_fs.h:248: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:249: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:250: parse error before `h_i_mode_high'
-/usr/include/linux/ext2_fs.h:250: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:251: parse error before `h_i_uid_high'
-/usr/include/linux/ext2_fs.h:251: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:252: parse error before `h_i_gid_high'
-/usr/include/linux/ext2_fs.h:252: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:253: parse error before `h_i_author'
-/usr/include/linux/ext2_fs.h:253: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:254: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:256: parse error before `__u8'
-/usr/include/linux/ext2_fs.h:256: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:257: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:258: parse error before `m_pad1'
-/usr/include/linux/ext2_fs.h:258: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:259: parse error before `m_i_reserved2'
-/usr/include/linux/ext2_fs.h:259: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:260: parse error before `}'
-/usr/include/linux/ext2_fs.h:260: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:261: parse error before `}'
-/usr/include/linux/ext2_fs.h:261: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:262: parse error before `}'
-/usr/include/linux/ext2_fs.h:329: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:329: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:330: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:331: parse error before `s_r_blocks_count'
-/usr/include/linux/ext2_fs.h:331: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:332: parse error before `s_free_blocks_count'
-/usr/include/linux/ext2_fs.h:332: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:333: parse error before `s_free_inodes_count'
-/usr/include/linux/ext2_fs.h:333: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:334: parse error before `s_first_data_block'
-/usr/include/linux/ext2_fs.h:334: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:335: parse error before `s_log_block_size'
-/usr/include/linux/ext2_fs.h:335: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:336: parse error before `s_log_frag_size'
-/usr/include/linux/ext2_fs.h:336: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:337: parse error before `s_blocks_per_group'
-/usr/include/linux/ext2_fs.h:337: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:338: parse error before `s_frags_per_group'
-/usr/include/linux/ext2_fs.h:338: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:339: parse error before `s_inodes_per_group'
-/usr/include/linux/ext2_fs.h:339: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:340: parse error before `s_mtime'
-/usr/include/linux/ext2_fs.h:340: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:341: parse error before `s_wtime'
-/usr/include/linux/ext2_fs.h:341: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:342: parse error before `s_mnt_count'
-/usr/include/linux/ext2_fs.h:342: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:343: parse error before `s_max_mnt_count'
-/usr/include/linux/ext2_fs.h:343: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:344: parse error before `s_magic'
-/usr/include/linux/ext2_fs.h:344: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:345: parse error before `s_state'
-/usr/include/linux/ext2_fs.h:345: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:346: parse error before `s_errors'
-/usr/include/linux/ext2_fs.h:346: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:347: parse error before `s_pad'
-/usr/include/linux/ext2_fs.h:347: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:348: parse error before `s_lastcheck'
-/usr/include/linux/ext2_fs.h:348: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:349: parse error before `s_checkinterval'
-/usr/include/linux/ext2_fs.h:349: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:350: parse error before `s_creator_os'
-/usr/include/linux/ext2_fs.h:350: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:351: parse error before `s_rev_level'
-/usr/include/linux/ext2_fs.h:351: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:352: parse error before `s_def_resuid'
-/usr/include/linux/ext2_fs.h:352: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:353: parse error before `s_def_resgid'
-/usr/include/linux/ext2_fs.h:353: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:354: parse error before `s_reserved'
-/usr/include/linux/ext2_fs.h:354: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:355: parse error before `}'
-/usr/include/linux/ext2_fs.h:372: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:372: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:373: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:374: parse error before `name_len'
-/usr/include/linux/ext2_fs.h:374: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:376: parse error before `}'
-make: *** [pe.o] Error 1
index 97f3fbc..4c433dc 100644 (file)
@@ -9,6 +9,7 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ../..
+my_dir = lib/e2p
 INSTALL = @INSTALL@
 
 @MCONFIG@
@@ -17,14 +18,15 @@ all::
 
 OBJS=          fgetflags.o fsetflags.o fgetversion.o fsetversion.o \
                getflags.o getversion.o iod.o ls.o pe.o pf.o ps.o \
-               setflags.o setversion.o
+               setflags.o setversion.o uuid.o
 
 SRCS=          $(srcdir)/fgetflags.c $(srcdir)/fsetflags.c \
                $(srcdir)/fgetversion.c $(srcdir)/fsetversion.c \
                $(srcdir)/getflags.c $(srcdir)/getversion.c \
                $(srcdir)/iod.c $(srcdir)/ls.c $(srcdir)/pe.c \
                $(srcdir)/pf.c $(srcdir)/ps.c \
-               $(srcdir)/setflags.c $(srcdir)/setversion.c
+               $(srcdir)/setflags.c $(srcdir)/setversion.c \
+               $(srcdir)/uuid.c
 
 LIBRARY= libe2p
 LIBDIR= e2p
@@ -38,7 +40,7 @@ DLL_STUB = libe2p
 DLL_MYDIR = e2p
 DLL_INSTALL_DIR = $(libdir)
 
-ELF_VERSION = 2.1
+ELF_VERSION = 2.2
 ELF_SO_VERSION = 2
 ELF_IMAGE = libe2p
 ELF_MYDIR = e2p
@@ -90,15 +92,16 @@ distclean:: clean
 # the Makefile.in file
 #
 fgetflags.o: $(srcdir)/fgetflags.c $(srcdir)/e2p.h
-fsetflags.o: $(srcdir)/fsetflags.c $(srcdir)/e2p.h
+fsetflags.o: $(srcdir)/fsetflags.c $(srcdir)/e2p.h 
 fgetversion.o: $(srcdir)/fgetversion.c $(srcdir)/e2p.h
 fsetversion.o: $(srcdir)/fsetversion.c $(srcdir)/e2p.h
 getflags.o: $(srcdir)/getflags.c $(srcdir)/e2p.h
 getversion.o: $(srcdir)/getversion.c $(srcdir)/e2p.h
 iod.o: $(srcdir)/iod.c $(srcdir)/e2p.h
-ls.o: $(srcdir)/ls.c  $(srcdir)/e2p.h
+ls.o: $(srcdir)/ls.c $(srcdir)/e2p.h
 pe.o: $(srcdir)/pe.c $(srcdir)/e2p.h
 pf.o: $(srcdir)/pf.c $(srcdir)/e2p.h
 ps.o: $(srcdir)/ps.c $(srcdir)/e2p.h
 setflags.o: $(srcdir)/setflags.c $(srcdir)/e2p.h
 setversion.o: $(srcdir)/setversion.c $(srcdir)/e2p.h
+uuid.o: $(srcdir)/uuid.c
index dc2dbe5..fa4a03b 100644 (file)
@@ -19,3 +19,6 @@ void print_flags (FILE * f, unsigned long flags, int long_format);
 void print_fs_state (FILE * f, unsigned short state);
 int setflags (int fd, unsigned long flags);
 int setversion (int fd, unsigned long version);
+
+int e2p_is_null_uuid(void *uu);
+void e2p_uuid_to_str(void *uu, char *out);
index 099446d..f01de26 100644 (file)
@@ -27,8 +27,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int fgetflags (const char * name, unsigned long * flags)
index ba4eec4..fea376b 100644 (file)
@@ -23,8 +23,6 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int fgetversion (const char * name, unsigned long * version)
index 06aabba..92e558b 100644 (file)
@@ -27,8 +27,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int fsetflags (const char * name, unsigned long flags)
index 1443fb5..49c7c36 100644 (file)
@@ -23,8 +23,6 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int fsetversion (const char * name, unsigned long version)
index ac014a7..8c476a3 100644 (file)
@@ -23,8 +23,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int getflags (int fd, unsigned long * flags)
index 309dfb6..be76b60 100644 (file)
@@ -19,8 +19,6 @@
 #endif
 #include <sys/ioctl.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int getversion (int fd, unsigned long * version)
index 0bd217b..55e0bbe 100644 (file)
@@ -9,16 +9,71 @@
  * Public License
  */
 
+#include <stdio.h>
 #include <sys/types.h>
+#include <string.h>
 #include <grp.h>
 #include <pwd.h>
-#include <stdio.h>
 #include <time.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
+/*
+ * 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 */
+};
+
 static void print_user (unsigned short uid)
 {
        struct passwd *pw;
@@ -43,6 +98,51 @@ static void print_group (unsigned short gid)
                printf ("(group %s)\n", gr->gr_name);
 }
 
+#define MONTH_INT (86400 * 30)
+#define WEEK_INT (86400 * 7)
+#define DAY_INT        (86400)
+#define HOUR_INT (60 * 60)
+#define MINUTE_INT (60)
+
+static char *interval_string(unsigned int secs)
+{
+       static char buf[256], tmp[80];
+       int             hr, min, num;
+
+       buf[0] = 0;
+
+       if (secs >= MONTH_INT) {
+               num = secs / MONTH_INT;
+               secs -= num*MONTH_INT;
+               sprintf(buf, "%d month%s", num, (num>1) ? "s" : "");
+       }
+       if (secs >= WEEK_INT) {
+               num = secs / WEEK_INT;
+               secs -= num*WEEK_INT;
+               sprintf(tmp, "%s%d week%s", buf[0] ? ", " : "",
+                       num, (num>1) ? "s" : "");
+               strcat(buf, tmp);
+       }
+       if (secs >= DAY_INT) {
+               num = secs / DAY_INT;
+               secs -= num*DAY_INT;
+               sprintf(tmp, "%s%d day%s", buf[0] ? ", " : "",
+                       num, (num>1) ? "s" : "");
+               strcat(buf, tmp);
+       }
+       if (secs > 0) {
+               hr = secs / HOUR_INT;
+               secs -= hr*HOUR_INT;
+               min = secs / MINUTE_INT;
+               secs -= min*MINUTE_INT;
+               sprintf(tmp, "%s%d:%02d:%02d", buf[0] ? ", " : "",
+                       hr, min, secs);
+               strcat(buf, tmp);
+       }
+       return buf;
+}
+
+
 #ifndef EXT2_INODE_SIZE
 #define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
 #endif
@@ -50,20 +150,43 @@ static void print_group (unsigned short gid)
 void list_super (struct ext2_super_block * s)
 {
        int inode_blocks_per_group;
+       struct ext2fs_sb *sb = (struct ext2fs_sb *) s;
+       char buf[80];
+       const char *os;
 
        inode_blocks_per_group = (((s->s_inodes_per_group *
                                    EXT2_INODE_SIZE(s)) +
                                   EXT2_BLOCK_SIZE(s) - 1) /
                                  EXT2_BLOCK_SIZE(s));
-       
        printf ("Filesystem magic number:  0x%04X\n", s->s_magic);
        printf ("Filesystem revision #:    %d\n", s->s_rev_level);
+       if (sb->s_volume_name[0]) {
+               memset(buf, 0, sizeof(buf));
+               strncpy(buf, sb->s_volume_name, sizeof(sb->s_volume_name));
+               printf("Filesystem volume name:   %s\n", buf);
+       }
+       if (sb->s_last_mounted[0]) {
+               memset(buf, 0, sizeof(buf));
+               strncpy(buf, sb->s_last_mounted, sizeof(sb->s_last_mounted));
+               printf("Last mounted on:          %s\n", buf);
+       }
+       if (!e2p_is_null_uuid(sb->s_uuid)) {
+               e2p_uuid_to_str(sb->s_uuid, buf);
+               printf("Filesystem UUID:          %s\n", buf);
+       }
        printf ("Filesystem state:        ");
        print_fs_state (stdout, s->s_state);
        printf ("\n");
        printf ("Errors behavior:          ");
        print_fs_errors (stdout, s->s_errors);
        printf ("\n");
+       switch (s->s_creator_os) {
+           case EXT2_OS_LINUX: os = "Linux"; break;
+           case EXT2_OS_HURD:  os = "GNU"; break;
+           case EXT2_OS_MASIX: os = "Masix"; break;
+           default:            os = "unknown"; break;
+       }
+       printf ("Filesystem OS type:       %s\n", os);
        printf ("Inode count:              %u\n", s->s_inodes_count);
        printf ("Block count:              %u\n", s->s_blocks_count);
        printf ("Reserved block count:     %u\n", s->s_r_blocks_count);
@@ -81,7 +204,8 @@ void list_super (struct ext2_super_block * s)
        printf ("Mount count:              %u\n", s->s_mnt_count);
        printf ("Maximum mount count:      %d\n", s->s_max_mnt_count);
        printf ("Last checked:             %s", ctime ((time_t *) &s->s_lastcheck));
-       printf ("Check interval:           %u\n", s->s_checkinterval);
+       printf ("Check interval:           %u (%s)\n", s->s_checkinterval,
+               interval_string(s->s_checkinterval));
        if (s->s_checkinterval)
        {
                time_t next;
@@ -102,3 +226,7 @@ void list_super (struct ext2_super_block * s)
        }
 #endif
 }
+
+
+
+
index efc74b3..4cce691 100644 (file)
@@ -16,8 +16,6 @@
 
 #include <stdio.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 void print_fs_errors (FILE * f, unsigned short errors)
index e4f072f..ec18dcb 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <stdio.h>
-#include <linux/ext2_fs.h>
 
 #include "e2p.h"
 
index 441d6dc..bec8b41 100644 (file)
@@ -16,8 +16,6 @@
 
 #include <stdio.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 void print_fs_state (FILE * f, unsigned short state)
index 06f127f..654ec9d 100644 (file)
@@ -24,8 +24,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int setflags (int fd, unsigned long flags)
index f2c48cd..3210f51 100644 (file)
@@ -19,8 +19,6 @@
 #endif
 #include <sys/ioctl.h>
 
-#include <linux/ext2_fs.h>
-
 #include "e2p.h"
 
 int setversion (int fd, unsigned long version)
diff --git a/lib/e2p/uuid.c b/lib/e2p/uuid.c
new file mode 100644 (file)
index 0000000..82462e8
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * uuid.c -- utility routines for manipulating UUID's.
+ */
+
+#include <stdio.h>
+#include <linux/types.h>
+
+struct uuid {
+       __u32   time_low;
+       __u16   time_mid;
+       __u16   time_hi_and_version;
+       __u16   clock_seq;
+       __u8    node[6];
+};
+
+/* Returns 1 if the uuid is the NULL uuid */
+int e2p_is_null_uuid(void *uu)
+{
+       __u8    *cp;
+       int     i;
+
+       for (i=0, cp = uu; i < 16; i++)
+               if (*cp)
+                       return 0;
+       return 1;
+}
+
+static void e2p_unpack_uuid(void *in, struct uuid *uu)
+{
+       __u8    *ptr = in;
+       __u32   tmp;
+
+       tmp = *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       uu->time_low = tmp;
+
+       tmp = *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       uu->time_mid = tmp;
+       
+       tmp = *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       uu->time_hi_and_version = tmp;
+
+       tmp = *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       uu->clock_seq = tmp;
+
+       memcpy(uu->node, ptr, 6);
+}
+
+void e2p_uuid_to_str(void *uu, char *out)
+{
+       struct uuid uuid;
+
+       e2p_unpack_uuid(uu, &uuid);
+       sprintf(out,
+               "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+               uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
+               uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
+               uuid.node[0], uuid.node[1], uuid.node[2],
+               uuid.node[3], uuid.node[4], uuid.node[5]);
+}
index 49c4fca..627ef4d 100644 (file)
@@ -6,6 +6,7 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ../..
+my_dir = lib/ss
 INSTALL = @INSTALL@
 
 @MCONFIG@
index 90de2b5..41c9c54 100644 (file)
@@ -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
index 2666977..5319ce5 100644 (file)
@@ -2,6 +2,7 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ../..
+my_dir = lib/ext2fs
 INSTALL = @INSTALL@
 
 @MCONFIG@
@@ -29,6 +30,7 @@ OBJS= ext2_err.o \
        llseek.o \
        mkdir.o \
        namei.o \
+       native.o \
        newdir.o \
        openfs.o \
        read_bb.o \
@@ -60,6 +62,7 @@ SRCS= ext2_err.c \
        $(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_LIBS = -L../.. -lcom_err
 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 @@ 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
+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
-
index d5ef0ec..7aaf549 100644 (file)
 
 #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 @@ errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
        return 0;
 }
 
+errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
+                                      const char *descr,
+                                      ext2fs_inode_bitmap *ret)
+{
+       ext2fs_inode_bitmap bitmap;
+       errcode_t       retval;
+       __u32           start, end, real_end;
+
+       EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+       fs->write_bitmaps = ext2fs_write_bitmaps;
+
+       start = 1;
+       end = fs->super->s_inodes_count;
+       real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count);
+
+       retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+                                               descr, &bitmap);
+       if (retval)
+               return retval;
+       
+       bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
+       bitmap->fs = fs;
+       bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
+       
+       *ret = bitmap;
+       return 0;
+}
+
 errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
                                       const char *descr,
                                       ext2fs_block_bitmap *ret)
 {
        ext2fs_block_bitmap bitmap;
-       int     size;
+       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 = 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;
 }
index da69e3b..6f256e5 100644 (file)
@@ -72,3 +72,13 @@ void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
                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);
+}
+
index e98e2d2..e967c87 100644 (file)
@@ -27,6 +27,8 @@ extern const char *ext2fs_unmark_string;
 extern const char *ext2fs_test_string;
 extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
                               const char *description);
+extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+                               int code, unsigned long arg);
 
 extern 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 @@ _INLINE_ int ext2fs_test_bit(int nr, const void * addr)
 
 #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 @@ _INLINE_ int ext2fs_test_bit(int nr, const void *addr)
        mask = 1 << (nr & 31);
        return ((mask & *ADDR) != 0);
 }
+#endif
 
 #endif /* __sparc__ */
 
@@ -223,70 +304,72 @@ _INLINE_ __u32 ext2fs_swab32(__u32 val)
 
 #endif /* !_EXT2_HAVE_ASM_SWAB */
 
-_INLINE_ void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
-                                      blk_t block)
+_INLINE_ void ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+                                      __u32 bitno)
 {
-       if ((block < bitmap->start) || (block > bitmap->end)) {
-               ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
-                                  bitmap->description);
+       if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+               ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
                return;
        }
-       ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
+       ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
 }
 
-_INLINE_ void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
-                                        blk_t block)
+_INLINE_ void ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+                                        blk_t bitno)
 {
-       if ((block < bitmap->start) || (block > bitmap->end)) {
-               ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
-                                  block, bitmap->description);
+       if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+               ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
                return;
        }
-       ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
+       ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
 }
 
-_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
-                                      blk_t block)
+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+                                      blk_t bitno)
 {
-       if ((block < bitmap->start) || (block > bitmap->end)) {
-               ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
-                                  block, bitmap->description);
+       if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+               ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
                return 0;
        }
-       return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
+       return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+                                      blk_t block)
+{
+       ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+                                        blk_t block)
+{
+       ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
+                                      blk_t block)
+{
+       return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
+                                         block);
 }
 
 _INLINE_ 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,
index fe112b3..5138534 100644 (file)
@@ -39,8 +39,10 @@ static int block_iterate_ind(blk_t *ind_block, struct block_context *ctx)
        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 @@ static int block_iterate_ind(blk_t *ind_block, struct block_context *ctx)
                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 @@ static int block_iterate_ind(blk_t *ind_block, struct block_context *ctx)
                }
        }
        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 @@ static int block_iterate_ind(blk_t *ind_block, struct block_context *ctx)
                        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 @@ static int block_iterate_dind(blk_t *dind_block, struct block_context *ctx)
        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 @@ static int block_iterate_dind(blk_t *dind_block, struct block_context *ctx)
                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 @@ static int block_iterate_dind(blk_t *dind_block, struct block_context *ctx)
                }
        }
        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 @@ static int block_iterate_dind(blk_t *dind_block, struct block_context *ctx)
                        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 @@ static int block_iterate_tind(blk_t *tind_block, struct block_context *ctx)
        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 @@ static int block_iterate_tind(blk_t *tind_block, struct block_context *ctx)
                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 @@ static int block_iterate_tind(blk_t *tind_block, struct block_context *ctx)
                }
        }
        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 @@ static int block_iterate_tind(blk_t *tind_block, struct block_context *ctx)
                        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 @@ errcode_t ext2fs_block_iterate(ext2_filsys fs,
                               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 @@ errcode_t ext2fs_block_iterate(ext2_filsys fs,
        }
        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 @@ errcode_t ext2fs_block_iterate(ext2_filsys fs,
                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);
index bb2f717..3d5dbb2 100644 (file)
@@ -27,7 +27,7 @@ errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
        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 @@ errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
        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;
index 71153ce..81e0c1e 100644 (file)
@@ -34,8 +34,8 @@ ec    EXT2_ET_MAGIC_BLOCK_BITMAP,
 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 @@ ec EXT2_ET_BAD_DEVICE_NAME,
        "Illegal or malformed device name"
 
 ec     EXT2_ET_MISSING_INODE_TABLE,
-       "A block group is missing an inode table."
+       "A block group is missing an inode table"
 
-       end
+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
index 73194c0..f385770 100644 (file)
@@ -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 unsigned int        dgrp_t;
 
 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 @@ typedef struct ext2fs_struct_block_bitmap *ext2fs_block_bitmap;
 #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 @@ struct struct_ext2_filsys {
        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 @@ struct struct_badblocks_iterate {
  * 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 @@ struct ext2_struct_inode_scan {
 #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 @@ struct ext2_struct_inode_scan {
 
 #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_inode_bitmap(ext2_filsys fs);
 extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
 extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
 extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+                                               __u32 end,
+                                               __u32 real_end,
+                                               const char *descr,
+                                               ext2fs_generic_bitmap *ret);
 extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
                                              const char *descr,
                                              ext2fs_block_bitmap *ret);
@@ -323,6 +416,7 @@ extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ino_t dir);
 
 /* 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 @@ extern errcode_t ext2fs_lookup(ext2_filsys fs, ino_t dir, const char *name,
                         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 @@ extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
 /* 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);
index 63b5235..5c70983 100644 (file)
@@ -33,9 +33,9 @@ void ext2fs_free(ext2_filsys fs)
        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 @@ void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
        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);
 }
 
index cc7abd0..4108093 100644 (file)
@@ -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>
 #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 @@ errcode_t ext2fs_initialize(const char *name, int flags,
        
        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;
index 04c5e4d..7d25ae1 100644 (file)
@@ -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 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
                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 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
 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 @@ errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
        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 @@ errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
        } 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 ext2fs_write_inode(ext2_filsys fs, unsigned long ino,
        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 @@ errcode_t ext2fs_write_inode(ext2_filsys fs, unsigned long ino,
                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 @@ errcode_t ext2fs_check_directory(ext2_filsys fs, ino_t ino)
        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);
-}
index 496c726..8fc71b0 100644 (file)
@@ -13,6 +13,8 @@
 #include <errno.h>
 #endif
 
+/* #define NAMEI_DEBUG */
+
 #include <linux/ext2_fs.h>
 
 #include "ext2fs.h"
@@ -173,43 +175,186 @@ errcode_t ext2fs_lookup(ext2_filsys fs, ino_t dir, const char *name,
        return (ls.found) ? 0 : ENOENT;
 }
 
-errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd, const char *name,
-                      ino_t *inode)
+
+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)
 {
-       ino_t           dir = cwd;
-       char            *buf;
-       const char      *p = name, *q;
-       int             len;
-       errcode_t       retval;
+       char *pathname;
+       char *buffer = 0;
+       errcode_t retval;
+       struct ext2_inode ei;
 
-       EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+#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;
+}
 
-       buf = malloc(fs->blocksize);
-       if (!buf)
-               return ENOMEM;
-       if (*p == '/') {
-               p++;
-               dir = root;
+/*
+ * 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 (*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;
-                       }
+       while (1) {
+               thisname = pathname;
+               for (len=0; --pathlen >= 0;len++) {
+                       c = *(pathname++);
+                       if (c == '/')
+                               break;
                }
-               if (q)
-                       p = q+1;
-               else
+               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;
        }
-       *inode = dir;
-       free(buf);
+       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;
+       
+       retval = open_namei(fs, root, cwd, name, strlen(name), 0, 0,
+                           buf, inode);
+
+       free(buf);
+       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 (file)
index 0000000..aa371ce
--- /dev/null
@@ -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;
+}
+
+       
+       
index e8b01e2..74bf279 100644 (file)
@@ -113,6 +113,10 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
 #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) +
index 371b8f9..968f41c 100644 (file)
@@ -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 @@ void ext2fs_swap_super(struct ext2_super_block * super)
        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 @@ void ext2fs_swap_super(struct ext2_super_block * super)
        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 @@ void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
        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;
+       }
+}
+       
index 7943820..96b3612 100644 (file)
@@ -1,3 +1,15 @@
+Fri Aug 30 22:36:48 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * invocation.c (ss_create_invocation): Change function prototype
+               of invocation so that the first two arguments are const
+               char *, and that the info_ptr is a void *, not a char *.
+
+       * ss.h: Added declaration of ss_execute_line()
+
+Sat Aug 10 00:17:14 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * listen.c (ss_listen): Fix -Wall flames.
+
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * Release of E2fsprogs version 1.04
index 9af2c2f..777c34b 100644 (file)
@@ -6,6 +6,7 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ../..
+my_dir = lib/ss
 INSTALL = @INSTALL@
 
 @MCONFIG@
index 80ebc82..7f2e96f 100644 (file)
@@ -75,7 +75,7 @@ void ss_error (va_alist)
     va_dcl
 #endif
 {
-    register char const *whoami;
+    register char *whoami;
     va_list pvar;
 #ifndef HAVE_STDARG_H
     int sci_idx;
index be13dd8..74b5969 100644 (file)
@@ -151,7 +151,7 @@ static int really_execute_command (sci_idx, argc, argv)
  * Notes:
  */
 
-ss_execute_command(sci_idx, argv)
+int ss_execute_command(sci_idx, argv)
        int sci_idx;
        register char *argv[];
 {
index c4c15ca..c4aecf1 100644 (file)
@@ -13,8 +13,8 @@
 
 int ss_create_invocation(subsystem_name, version_string, info_ptr,
                         request_table_ptr, code_ptr)
-       char *subsystem_name, *version_string;
-       char *info_ptr;
+       const char *subsystem_name, *version_string;
+       void *info_ptr;
        ss_request_table *request_table_ptr;
        int *code_ptr;
 {
index 765b757..aab8733 100644 (file)
@@ -29,7 +29,7 @@ typedef void sigret_t;
 static ss_data *current_info;
 static jmp_buf listen_jmpb;
 
-static sigret_t print_prompt()
+static sigret_t print_prompt(int sig)
 {
 #ifdef BSD
     /* put input into a reasonable mode */
@@ -45,19 +45,18 @@ static sigret_t print_prompt()
     (void) fflush(stdout);
 }
 
-static sigret_t listen_int_handler()
+static sigret_t listen_int_handler(int sig)
 {
     putc('\n', stdout);
     signal(SIGINT, listen_int_handler);
     longjmp(listen_jmpb, 1);
 }
 
-int ss_listen (sci_idx)
-    int sci_idx;
+int ss_listen (int sci_idx)
 {
     char *cp;
     ss_data *info;
-    sigret_t (*sig_int)(), (*sig_cont)(), (*old_sig_cont)();
+    sigret_t (*sig_int)(int), (*sig_cont)(int), (*old_sig_cont)(int);
     char input[BUFSIZ];
     char buffer[BUFSIZ];
     char *end = buffer;
@@ -71,7 +70,7 @@ int ss_listen (sci_idx)
     ss_data *old_info = current_info;
     
     current_info = info = ss_info(sci_idx);
-    sig_cont = (sigret_t (*)()) 0;
+    sig_cont = (sigret_t (*)(int)) 0;
     info->abort = 0;
 #ifdef POSIX_SIGNALS
     sigemptyset(&igmask);
@@ -89,7 +88,7 @@ int ss_listen (sci_idx)
     (void) sigsetmask(mask);
 #endif
     while(!info->abort) {
-       print_prompt();
+       print_prompt(0);
        *end = '\0';
        old_sig_cont = sig_cont;
        sig_cont = signal(SIGCONT, print_prompt);
@@ -133,20 +132,14 @@ egress:
     return code;
 }
 
-void ss_abort_subsystem(sci_idx, code)
-    int sci_idx;
-    int code;
+void ss_abort_subsystem(int sci_idx, int code)
 {
     ss_info(sci_idx)->abort = 1;
     ss_info(sci_idx)->exit_status = code;
     
 }
 
-int ss_quit(argc, argv, sci_idx, infop)
-    int argc;
-    char **argv;
-    int sci_idx;
-    pointer infop;
+void ss_quit(int argc, const char * const *argv, int sci_idx, pointer infop)
 {
     ss_abort_subsystem(sci_idx, 0);
 }
index 9da9607..c214213 100644 (file)
 #include "ss_internal.h"
 
 #ifdef __STDC__
-#define        DECLARE(name) void name(int argc,char **argv, int sci_idx)
+#define        DECLARE(name) void name(int argc,const char * const *argv, \
+                               int sci_idx, void *infop)
 #else
-#define        DECLARE(name) void name(argc,argv,sci_idx)int argc,sci_idx;char **argv;
+#define        DECLARE(name) void name(argc,argv,sci_idx,info)int argc,sci_idx;char **argv;void *infop;
+
 #endif
        
 /*
index f992bd9..3b86f87 100644 (file)
@@ -54,12 +54,22 @@ char *ss_current_request(); /* This is actually a macro */
 char *ss_name(int sci_idx);
 void ss_error (int, long, char const *, ...);
 void ss_perror (int, long, char const *);
-int ss_create_invocation(char *, char *, char *, ss_request_table *, int *);
+int ss_create_invocation(const char *, const char *, void *,
+                        ss_request_table *, int *);
 void ss_delete_invocation(int);
 int ss_listen(int);
+int ss_execute_line(int, char *);
 void ss_add_request_table(int, ss_request_table *, int, int *);
 void ss_delete_request_table(int, ss_request_table *, int *);
 void ss_abort_subsystem(int sci_idx, int code);
+void ss_quit(int argc, const char * const *argv, int sci_idx, void *infop);
+void ss_self_identify(int argc, const char * const *argv, int sci_idx, void *infop);
+void ss_subsystem_name(int argc, const char * const *argv,
+                      int sci_idx, void *infop);
+void ss_subsystem_version(int argc, const char * const *argv,
+                         int sci_idx, void *infop);
+void ss_unimplemented(int argc, const char * const *argv,
+                     int sci_idx, void *infop);
 #else
 char *ss_name();
 void ss_error ();
@@ -67,9 +77,15 @@ void ss_perror ();
 int ss_create_invocation();
 void ss_delete_invocation();
 int ss_listen();
+int ss_execute_line();
 void ss_add_request_table();
 void ss_delete_request_table();
 void ss_abort_subsystem();
+void ss_quit();
+void ss_self_identify();
+void ss_subsystem_name();
+void ss_subsystem_version();
+void ss_unimplemented();
 #endif
 extern ss_request_table ss_std_requests;
 #endif /* _ss_h */
index 388a376..3bd5987 100644 (file)
@@ -70,8 +70,8 @@ typedef struct {
 
 typedef struct _ss_data {      /* init values */
     /* this subsystem */
-    char *subsystem_name;
-    char *subsystem_version;
+    const char *subsystem_name;
+    const char *subsystem_version;
     /* current request info */
     int argc;
     char **argv;               /* arg list */
index aa4c7f3..3eddbab 100644 (file)
@@ -9,8 +9,8 @@
  * $Locker$
  *
  * $Log$
- * Revision 1.7  1997/04/29 14:34:41  tytso
- * Checked in e2fsprogs 1.04.
+ * Revision 1.8  1997/04/29 14:52:31  tytso
+ * Checked in e2fsprogs 1.05
  *
  * Revision 1.1  1993/06/03  12:31:25  tytso
  * Initial revision
index f3b1680..f80d4d9 100644 (file)
@@ -9,6 +9,7 @@ SS_DIR=@SS_DIR@
 E2FSPROGS_MONTH=@E2FSPROGS_MONTH@
 E2FSPROGS_YEAR=@E2FSPROGS_YEAR@
 E2FSPROGS_VERSION=@E2FSPROGS_VERSION@
+SIZEOF_LONG_LONG=@SIZEOF_LONG_LONG@
 SIZEOF_LONG=@SIZEOF_LONG@
 SIZEOF_INT=@SIZEOF_INT@
 SIZEOF_SHORT=@SIZEOF_SHORT@
diff --git a/lib/uuid/ChangeLog b/lib/uuid/ChangeLog
new file mode 100644 (file)
index 0000000..8803ded
--- /dev/null
@@ -0,0 +1,10 @@
+Tue Aug 27 16:50:43 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+       * uuid/gen_uuid.c [HAVE_NET_IF_H] <net/if.h>: Include guarded.
+       [HAVE_NETINET_IN_H] <netinet/in.h>: Include guarded.
+       (get_node_id): Surround bulk of function with #ifdef HAVE_NET_IF_H.
+
+Tue Aug 27 16:50:16 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * gen_uuid.c (get_node_id): Add a specific ifdef for the HURD,
+               since it is broken w.r.t getting hardware addresses.
diff --git a/lib/uuid/Makefile.in b/lib/uuid/Makefile.in
new file mode 100644 (file)
index 0000000..c226197
--- /dev/null
@@ -0,0 +1,118 @@
+# Makefile for the second extended file system utility functions
+#
+# Copyright (C) 1993 Remy Card (card@masi.ibp.fr)
+#
+# This file can be redistributed under the terms of the GNU General
+# Public License
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+top_builddir = ../..
+my_dir = lib/uuid
+INSTALL = @INSTALL@
+
+@MCONFIG@
+
+all:: 
+
+OBJS=          clear.o \
+               compare.o \
+               copy.o \
+               gen_uuid.o \
+               isnull.o \
+               pack.o \
+               parse.o \
+               unpack.o \
+               unparse.o
+
+SRCS=          $(srcdir)/clear.c \
+               $(srcdir)/compare.c \
+               $(srcdir)/copy.c \
+               $(srcdir)/gen_uuid.c \
+               $(srcdir)/isnull.c \
+               $(srcdir)/pack.c \
+               $(srcdir)/parse.c \
+               $(srcdir)/unpack.c \
+               $(srcdir)/unparse.c
+
+LIBRARY= libuuid
+LIBDIR= uuid
+
+DLL_ADDRESS = 0x66980000
+DLL_JUMPSIZE = 0x1000
+DLL_GOTSIZE  = 0x1000
+DLL_VERSION = 1.0
+DLL_IMAGE = libuuid
+DLL_STUB = libuuid
+DLL_MYDIR = uuid
+DLL_INSTALL_DIR = $(libdir)
+
+ELF_VERSION = 1.0
+ELF_SO_VERSION = 1
+ELF_IMAGE = libuuid
+ELF_MYDIR = uuid
+ELF_INSTALL_DIR = $(libdir)
+
+BSDLIB_VERSION = 1.0
+BSDLIB_IMAGE = libuuid
+BSDLIB_MYDIR = uuid
+BSDLIB_INSTALL_DIR = $(libdir)
+
+@MAKEFILE_LIBRARY@
+@MAKEFILE_DLL@
+@MAKEFILE_ELF@
+@MAKEFILE_BSDLIB@
+@MAKEFILE_PROFILE@
+@MAKEFILE_CHECKER@
+
+.c.o:
+       $(CC) $(ALL_CFLAGS) -c $< -o $@
+@PROFILE_CMT@  $(CC) $(ALL_CFLAGS) -pg -o profiled/$*.o -c $<
+@CHECKER_CMT@  $(CC) $(ALL_CFLAGS) -checker -g -o checker/$*.o -c $<
+@DLL_CMT@      (export JUMP_DIR=`pwd`/jump; $(CC) -B$(JUMP_PREFIX) $(ALL_CFLAGS) \
+@DLL_CMT@              -o jump/$*.o -c $<)
+@ELF_CMT@      $(CC) $(ALL_CFLAGS) -fPIC -o elfshared/$*.o -c $<
+@BSDLIB_CMT@   $(CC) $(ALL_CFLAGS) -fpic -o pic/$*.o -c $<
+
+all:: tst_uuid
+
+tst_uuid: tst_uuid.o $(LIBUUID)
+       $(CC) $(ALL_LDFLAGS) -o tst_uuid tst_uuid.o $(LIBUUID)
+
+installdirs::
+       $(top_srcdir)/mkinstalldirs $(DESTDIR)$(ulibdir)  \
+               $(DESTDIR)$(includedir)/uuid
+
+install:: all installdirs 
+       $(INSTALL_DATA) libuuid.a $(DESTDIR)$(ulibdir)/libuuid.a
+       $(CHMOD) 644 $(DESTDIR)$(ulibdir)/libuuid.a
+       -$(RANLIB) $(DESTDIR)$(ulibdir)/libuuid.a
+       $(CHMOD) $(LIBMODE) $(DESTDIR)$(ulibdir)/libuuid.a
+       $(INSTALL_DATA) $(srcdir)/uuid.h $(DESTDIR)$(includedir)/uuid/uuid.h
+
+uninstall::
+       $(RM) -f $(ulibdir)/libuuid.a
+
+clean::
+       $(RM) -f \#* *.s *.o *.a *~ *.bak core profiled/* checker/*
+       $(RM) -f ../libuuid.a ../libuuid_p.a tst_uuid
+
+mostlyclean:: clean
+distclean:: clean
+       $(RM) -f .depend Makefile
+
+# +++ Dependency line eater +++
+# 
+# Makefile dependencies follow.  This must be the last section in
+# the Makefile.in file
+#
+clear.o: $(srcdir)/clear.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+compare.o: $(srcdir)/compare.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+copy.o: $(srcdir)/copy.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+gen_uuid.o: $(srcdir)/gen_uuid.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+isnull.o: $(srcdir)/isnull.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+pack.o: $(srcdir)/pack.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+parse.o: $(srcdir)/parse.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+unpack.o: $(srcdir)/unpack.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+unparse.o: $(srcdir)/unparse.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
diff --git a/lib/uuid/clear.c b/lib/uuid/clear.c
new file mode 100644 (file)
index 0000000..5127e01
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * clear.c -- Clear a UUID
+ */
+
+#include "uuidP.h"
+
+void uuid_clear(uuid_t uu)
+{
+       memset(uu, 0, 16);
+}
+
diff --git a/lib/uuid/compare.c b/lib/uuid/compare.c
new file mode 100644 (file)
index 0000000..44052c3
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * compare.c --- compare whether or not two UUID's are the same
+ *
+ * Returns 0 if the two UUID's are different, and 1 if they are the same.
+ */
+
+#include "uuidP.h"
+
+int uuid_compare(uuid_t uu1, uuid_t uu2)
+{
+       unsigned char   *cp1, *cp2;
+       int             i;
+
+       for (i=0, cp1 = uu1, cp2 = uu2; i < 16; i++)
+               if (*cp1++ != *cp2++)
+                       return 0;
+       return 1;
+}
+
diff --git a/lib/uuid/copy.c b/lib/uuid/copy.c
new file mode 100644 (file)
index 0000000..739e2dd
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * copy.c --- copy UUIDs
+ */
+
+#include "uuidP.h"
+
+void uuid_copy(uuid_t uu1, uuid_t uu2)
+{
+       unsigned char   *cp1, *cp2;
+       int             i;
+
+       for (i=0, cp1 = uu1, cp2 = uu2; i < 16; i++)
+               *cp1++ = *cp2++;
+}
diff --git a/lib/uuid/gen_uuid.c b/lib/uuid/gen_uuid.c
new file mode 100644 (file)
index 0000000..8eaab4a
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * gen_uuid.c --- generate a DCE-compatible uuid
+ */
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "uuidP.h"
+
+#ifdef HAVE_SRANDOM
+#define srand(x)       srandom(x)
+#define rand()                 random()
+#endif
+
+/*
+ * Generate a series of random bytes.  Use /dev/urandom if possible,
+ * and if not, use srandom/random.
+ */
+static void get_random_bytes(void *buf, int nbytes)
+{
+       static int fd = -2;
+       int i;
+       char *cp = (char *) buf;
+
+       if (fd == -2) {
+               fd = open("/dev/urandom", O_RDONLY);
+               srand((getpid() << 16) ^ getuid() ^ time(0));
+       }
+       if (fd > 0) {
+               i = read(fd, cp, nbytes);
+               if (i == nbytes)
+                       return;
+               if (i > 0) {
+                       nbytes -= i;
+                       cp += i;
+               }
+       }
+       for (i=0; i < nbytes; i++)
+               *cp++ = rand() & 0xFF;
+}
+
+/*
+ * Get the ethernet hardware address, if we can find it...
+ */
+static int get_node_id(unsigned char *node_id)
+{
+#ifdef HAVE_NET_IF_H
+       int             sd;
+       struct ifreq    ifr, *ifrp;
+       struct ifconf   ifc;
+       char buf[1024];
+       int             n, i;
+       unsigned char   *a;
+       
+/*
+ * BSD 4.4 defines the size of an ifreq to be
+ * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
+ * However, under earlier systems, sa_len isn't present, so the size is 
+ * just sizeof(struct ifreq)
+ */
+#ifdef HAVE_SA_LEN
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#define ifreq_size(i) max(sizeof(struct ifreq),\
+     sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
+#else
+#define ifreq_size(i) sizeof(struct ifreq)
+#endif /* HAVE_SA_LEN*/
+
+       sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+       if (sd < 0) {
+               return -1;
+       }
+       memset(buf, 0, sizeof(buf));
+       ifc.ifc_len = sizeof(buf);
+       ifc.ifc_buf = buf;
+       if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
+               close(sd);
+               return -1;
+       }
+       n = ifc.ifc_len;
+       for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
+               ifrp = (struct ifreq *)((caddr_t) ifc.ifc_buf+i);
+               strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
+#ifdef SIOCGIFHWADDR
+               if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
+                       continue;
+               a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
+#else
+#ifdef SIOCGENADDR
+               if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
+                       continue;
+               a = (unsigned char *) ifr.ifr_enaddr;
+#else
+               /*
+                * XXX we don't have a way of getting the hardware
+                * address
+                */
+               close(sd);
+               return 0;
+#endif /* SIOCGENADDR */
+#endif /* SIOCGIFHWADDR */
+               if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
+                       continue;
+               if (node_id) {
+                       memcpy(node_id, a, 6);
+                       close(sd);
+                       return 1;
+               }
+       }
+       close(sd);
+#endif
+       return 0;
+}
+
+/* Assume that the gettimeofday() has microsecond granularity */
+#define MAX_ADJUSTMENT 10
+
+static int get_clock(__u32 *clock_high, __u32 *clock_low, __u16 *ret_clock_seq)
+{
+       static int                      adjustment = 0;
+       static struct timeval           last = {0, 0};
+       static __u16                    clock_seq;
+       struct timeval                  tv;
+       unsigned long long              clock;
+       
+try_again:
+       gettimeofday(&tv, 0);
+       if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
+               get_random_bytes(&clock_seq, sizeof(clock_seq));
+               clock_seq &= 0x1FFF;
+               last = tv;
+               last.tv_sec--;
+       }
+       if ((tv.tv_sec < last.tv_sec) ||
+           ((tv.tv_sec == last.tv_sec) &&
+            (tv.tv_usec < last.tv_usec))) {
+               clock_seq = (clock_seq+1) & 0x1FFF;
+               adjustment = 0;
+       } else if ((tv.tv_sec == last.tv_sec) &&
+           (tv.tv_usec == last.tv_usec)) {
+               if (adjustment >= MAX_ADJUSTMENT)
+                       goto try_again;
+               adjustment++;
+       } else
+               adjustment = 0;
+       
+       clock = tv.tv_usec*10 + adjustment;
+       clock += ((unsigned long long) tv.tv_sec)*10000000;
+       clock += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
+
+       *clock_high = clock >> 32;
+       *clock_low = clock;
+       *ret_clock_seq = clock_seq;
+       return 0;
+}
+
+void uuid_generate(uuid_t out)
+{
+       static unsigned char node_id[6];
+       static int has_init = 0;
+       struct uuid uu;
+       __u32   clock_mid;
+
+       if (!has_init) {
+               if (get_node_id(node_id) <= 0)
+                       get_random_bytes(node_id, 6);
+               has_init = 1;
+       }
+       get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
+       uu.clock_seq |= 0x8000;
+       uu.time_mid = (__u16) clock_mid;
+       uu.time_hi_and_version = (clock_mid >> 16) | 0x1000;
+       memcpy(uu.node, node_id, 6);
+       uuid_pack(&uu, out);
+}
diff --git a/lib/uuid/isnull.c b/lib/uuid/isnull.c
new file mode 100644 (file)
index 0000000..f72e8fb
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * isnull.c --- Check whether or not the UUID is null
+ */
+
+#include "uuidP.h"
+
+/* Returns 1 if the uuid is the NULL uuid */
+int uuid_is_null(uuid_t uu)
+{
+       unsigned char   *cp;
+       int             i;
+
+       for (i=0, cp = uu; i < 16; i++)
+               if (*cp++)
+                       return 0;
+       return 1;
+}
+
diff --git a/lib/uuid/pack.c b/lib/uuid/pack.c
new file mode 100644 (file)
index 0000000..476b7a1
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Internal routine for packing UUID's
+ */
+
+#include "uuidP.h"
+
+void uuid_pack(struct uuid *uu, uuid_t ptr)
+{
+       __u32   tmp;
+       unsigned char   *out = ptr;
+
+       tmp = uu->time_low;
+       out[3] = (unsigned char) tmp;
+       tmp >>= 8;
+       out[2] = (unsigned char) tmp;
+       tmp >>= 8;
+       out[1] = (unsigned char) tmp;
+       tmp >>= 8;
+       out[0] = (unsigned char) tmp;
+       
+       tmp = uu->time_mid;
+       out[5] = (unsigned char) tmp;
+       tmp >>= 8;
+       out[4] = (unsigned char) tmp;
+
+       tmp = uu->time_hi_and_version;
+       out[7] = (unsigned char) tmp;
+       tmp >>= 8;
+       out[6] = (unsigned char) tmp;
+
+       tmp = uu->clock_seq;
+       out[9] = (unsigned char) tmp;
+       tmp >>= 8;
+       out[8] = (unsigned char) tmp;
+
+       memcpy(out+10, uu->node, 6);
+}
+
diff --git a/lib/uuid/parse.c b/lib/uuid/parse.c
new file mode 100644 (file)
index 0000000..ce3f88d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * parse.c --- UUID parsing
+ */
+
+#include <stdio.h>
+
+#include "uuidP.h"
+
+int uuid_parse(char *in, uuid_t uu)
+{
+       struct uuid uuid;
+       int i;
+       char *cp, buf[3];
+
+       if (strlen(in) != 36)
+               return -1;
+       for (i=0, cp = in; i <= 36; i++,cp++) {
+               if ((i == 8) || (i == 13) || (i == 18) ||
+                   (i == 23))
+                       if (*cp == '-')
+                               continue;
+               if (i== 36)
+                       if (*cp == 0)
+                               continue;
+               if (!isxdigit(*cp))
+                       return -1;
+       }
+       uuid.time_low = strtoul(in, NULL, 16);
+       uuid.time_mid = strtoul(in+9, NULL, 16);
+       uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
+       uuid.clock_seq = strtoul(in+19, NULL, 16);
+       cp = in+24;
+       buf[2] = 0;
+       for (i=0; i < 6; i++) {
+               buf[0] = *cp++;
+               buf[1] = *cp++;
+               uuid.node[i] = strtoul(buf, NULL, 16);
+       }
+       
+       uuid_pack(&uuid, uu);
+       return 0;
+}
diff --git a/lib/uuid/tst_uuid.c b/lib/uuid/tst_uuid.c
new file mode 100644 (file)
index 0000000..068eea8
--- /dev/null
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <linux/ext2_fs.h>
+
+#include "uuid.h"
+
+int
+main(int argc, char *argv)
+{
+       uuid_t          buf, tst;
+       char            str[100];
+       unsigned char   *cp;
+       int i;
+       int failed = 0;
+
+       uuid_generate(buf);
+       uuid_unparse(buf, str);
+       printf("UUID string = %s\n", str);
+       printf("UUID: ");
+       for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
+               printf("%02x", *cp++);
+       }
+       printf("\n");
+       uuid_parse(str, tst);
+       if (uuid_compare(buf, tst))
+               printf("UUID parse and compare succeeded.\n");
+       else {
+               printf("UUID parse and compare failed!\n");
+               failed++;
+       }
+       uuid_clear(tst);
+       if (uuid_is_null(tst))
+               printf("UUID clear and is null succeeded.\n");
+       else {
+               printf("UUID clear and is null failed!\n");
+               failed++;
+       }
+       uuid_copy(buf, tst);
+       if (uuid_compare(buf, tst))
+               printf("UUID copy and compare succeeded.\n");
+       else {
+               printf("UUID copy and compare failed!\n");
+               failed++;
+       }
+       if (failed) {
+               printf("%d failures.\n", failed);
+               exit(1);
+       }
+       return 0;
+}
+
+       
+
diff --git a/lib/uuid/unpack.c b/lib/uuid/unpack.c
new file mode 100644 (file)
index 0000000..406587d
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Internal routine for unpacking UUID
+ */
+
+#include "uuidP.h"
+
+void uuid_unpack(uuid_t in, struct uuid *uu)
+{
+       __u8    *ptr = in;
+       __u32   tmp;
+
+       tmp = *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       uu->time_low = tmp;
+
+       tmp = *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       uu->time_mid = tmp;
+       
+       tmp = *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       uu->time_hi_and_version = tmp;
+
+       tmp = *ptr++;
+       tmp = (tmp << 8) | *ptr++;
+       uu->clock_seq = tmp;
+
+       memcpy(uu->node, ptr, 6);
+}
+
diff --git a/lib/uuid/unparse.c b/lib/uuid/unparse.c
new file mode 100644 (file)
index 0000000..32f7995
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * uuid_to_str.c -- convert a UUID to string
+ */
+
+#include <stdio.h>
+
+#include "uuidP.h"
+
+void uuid_unparse(uuid_t uu, char *out)
+{
+       struct uuid uuid;
+
+       uuid_unpack(uu, &uuid);
+       sprintf(out,
+               "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+               uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
+               uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
+               uuid.node[0], uuid.node[1], uuid.node[2],
+               uuid.node[3], uuid.node[4], uuid.node[5]);
+}
+
diff --git a/lib/uuid/uuid.h b/lib/uuid/uuid.h
new file mode 100644 (file)
index 0000000..9568c03
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Public include file for the UUID library
+ */
+
+typedef unsigned char uuid_t[16];
+
+/* clear.c */
+void uuid_clear(uuid_t uu);
+
+/* compare.c */
+int uuid_compare(uuid_t uu1, uuid_t uu2);
+
+/* copy.c */
+void uuid_copy(uuid_t uu1, uuid_t uu2);
+
+/* gen_uuid.c */
+void uuid_generate(uuid_t out);
+
+/* isnull.c */
+int uuid_is_null(uuid_t uu);
+
+/* parse.c */
+int uuid_parse(char *in, uuid_t uu);
+
+/* unparse.c */
+void uuid_unparse(uuid_t uu, char *out);
+
+
+
diff --git a/lib/uuid/uuidP.h b/lib/uuid/uuidP.h
new file mode 100644 (file)
index 0000000..0ef9261
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * uuid.h -- private header file for uuids
+ */
+
+#include <sys/types.h>
+#include <linux/types.h>
+
+#include "uuid.h"
+
+/*
+ * Offset between 15-Oct-1582 and 1-Jan-70
+ */
+#define TIME_OFFSET_HIGH 0x01B21DD2
+#define TIME_OFFSET_LOW  0x13814000
+
+struct uuid {
+       __u32   time_low;
+       __u16   time_mid;
+       __u16   time_hi_and_version;
+       __u16   clock_seq;
+       __u8    node[6];
+};
+
+
+/*
+ * prototypes
+ */
+void uuid_pack(struct uuid *uu, uuid_t ptr);
+void uuid_unpack(uuid_t in, struct uuid *uu);
+
+
+
+
index 1fa8a92..d521773 100644 (file)
@@ -1,3 +1,45 @@
+Sat Sep  7 07:34:11 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * tune2fs.c (main): Add support for new option -C, which sets the 
+               current number of mounts.
+               (main): Allow the interval to be specified in seconds,
+               mostly for debugging.
+
+Tue Aug 27 17:27:43 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+       * Makefile.in (SMANPAGES): Use @FSCK_MAN@ instead of fsck.8.
+       (SPROGS): Use @FSCK_PROG@ instead of fsck.
+
+Thu Aug 22 00:51:44 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * mke2fs.c (zap_bootblock): Don't do zap_bootblock on a
+               sparc.
+
+Tue Aug 20 00:15:46 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * chattr.c (main): Fixed bug so that chattr -v works.  (Bug report
+               and fix sent by Charles Howes, chowes@eznet.ca)
+
+Fri Aug  9 11:52:42 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * tune2fs.8.in:
+       * tune2fs.c: Added support for the -L option which sets the volume
+               label, the -M option which sets the last mounted
+               directory, and the -U option which sets the filesystem UUID.
+
+       * mke2fs.8.in:
+       * mke2fs.c: Added support for the -o option, which overrides the
+               creator OS.  Generate a UUID for the filesystem, if
+               applicable.  Added support for the -L option which sets
+               the volume label, and the -M option which sets the last
+               mounted directory.
+
+Sat Jun 22 17:43:17 1996  Remy Card  <card@bbj.linux.eu.org>
+
+       * chattr.c (decode_arg): Integrated Michael Nonweiler's fix to
+               avoid a segmentation fault when the "-v" option is used
+               and no version number is specified.
+       
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * Release of E2fsprogs version 1.04
index 69f164c..b0d06a2 100644 (file)
@@ -6,13 +6,15 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ..
+my_dir = misc
 INSTALL = @INSTALL@
 
 @MCONFIG@
 
-SPROGS=                mke2fs badblocks tune2fs dumpe2fs fsck
+SPROGS=                mke2fs badblocks tune2fs dumpe2fs @FSCK_PROG@
 USPROGS=       mklost+found
-SMANPAGES=     tune2fs.8 mklost+found.8 mke2fs.8 dumpe2fs.8 badblocks.8 fsck.8
+SMANPAGES=     tune2fs.8 mklost+found.8 mke2fs.8 dumpe2fs.8 badblocks.8 \
+                       @FSCK_MAN@
 
 UPROGS=                chattr lsattr
 UMANPAGES=     chattr.1 lsattr.1
@@ -44,18 +46,21 @@ DEPLIBS_E2P= $(LIBEXT2FS) $(LIBE2P) $(LIBCOM_ERR)
 
 all:: $(SPROGS) $(UPROGS) $(USPROGS) fix_substitute $(SMANPAGES) $(UMANPAGES)
 
-tune2fs: $(TUNE2FS_OBJS) $(DEPLIBS_E2P)
-       $(CC) $(ALL_LDFLAGS) -o tune2fs $(TUNE2FS_OBJS) $(LIBS_E2P)
+tune2fs: $(TUNE2FS_OBJS) $(DEPLIBS_E2P) $(LIBUUID)
+       $(CC) $(ALL_LDFLAGS) -o tune2fs $(TUNE2FS_OBJS) $(LIBS_E2P) $(LIBUUID)
 
 mklost+found: $(MKLPF_OBJS)
        $(CC) $(ALL_LDFLAGS) -o mklost+found $(MKLPF_OBJS)
 
-mke2fs: $(MKE2FS_OBJS) $(DEPLIBS)
-       $(CC) $(ALL_LDFLAGS) -o mke2fs $(MKE2FS_OBJS) $(LIBS)
+mke2fs: $(MKE2FS_OBJS) $(DEPLIBS) $(LIBUUID)
+       $(CC) $(ALL_LDFLAGS) -o mke2fs $(MKE2FS_OBJS) $(LIBS) $(LIBUUID)
 
-mke2fs.static: $(MKE2FS_OBJS) $(STATIC_DEPLIBS)
+mke2fs.static: $(MKE2FS_OBJS) $(STATIC_DEPLIBS) $(STATIC_LIBUUID)
        $(CC) $(ALL_LDFLAGS) -static -o mke2fs.static $(MKE2FS_OBJS) \
-               $(STATIC_LIBS)
+               $(STATIC_LIBS) $(STATIC_LIBUUID)
+
+resize2fs: resize2fs.o $(DEPLIBS)
+       $(CC) $(ALL_LDFLAGS) -o resize2fs resize2fs.o $(LIBS)
 
 chattr: $(CHATTR_OBJS) $(DEPLIBS_E2P)
        $(CC) $(ALL_LDFLAGS) -o chattr $(CHATTR_OBJS) $(LIBS_E2P)
@@ -156,26 +161,24 @@ distclean: clean
 # Makefile dependencies follow.  This must be the last section in
 # the Makefile.in file
 #
-tune2fs.o: $(srcdir)/tune2fs.c \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/e2p/e2p.h \
+tune2fs.o: $(srcdir)/tune2fs.c $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(top_srcdir)/lib/uuid/uuid.h $(top_srcdir)/lib/e2p/e2p.h \
  $(srcdir)/../version.h
 mklost+found.o: $(srcdir)/mklost+found.c $(srcdir)/../version.h
 mke2fs.o: $(srcdir)/mke2fs.c $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
- $(srcdir)/../version.h
+ $(top_srcdir)/lib/uuid/uuid.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/../version.h
 chattr.o: $(srcdir)/chattr.c $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/e2p/e2p.h $(srcdir)/../version.h
 lsattr.o: $(srcdir)/lsattr.c $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/e2p/e2p.h $(srcdir)/../version.h
-dumpe2fs.o: $(srcdir)/dumpe2fs.c \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/e2p/e2p.h \
- $(srcdir)/../version.h
+dumpe2fs.o: $(srcdir)/dumpe2fs.c $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(top_srcdir)/lib/e2p/e2p.h $(srcdir)/../version.h
 badblocks.o: $(srcdir)/badblocks.c $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/io.h
 fsck.o: $(srcdir)/fsck.c $(srcdir)/../version.h $(srcdir)/fsck.h
-
index a90bdf4..b359248 100644 (file)
@@ -114,9 +114,9 @@ static int decode_arg (int * i, int argc, char ** argv)
                                rem = 1;
                                break;
                        case 'v':
+                               (*i)++;
                                if (*i >= argc)
                                        usage ();
-                               (*i)++;
                                version = strtol (argv[*i], &tmp, 0);
                                if (*tmp)
                                {
@@ -310,9 +310,9 @@ void main (int argc, char ** argv)
                fprintf (stderr, "= is incompatible with - and +\n");
                exit (1);
        }
-       if (!(add || rem || set))
+       if (!(add || rem || set || set_version))
        {
-               fprintf (stderr, "Must use =, - or +\n");
+               fprintf (stderr, "Must use '-v', =, - or +\n");
                exit (1);
        }
        for (j = i; j < argc; j++)
index 1161e3b..740f01b 100644 (file)
@@ -150,12 +150,20 @@ static void dump_bad_blocks(ext2_filsys fs)
        badblocks_list_iterate_end(bb_iter);
 }
 
+static int i386_byteorder(void)
+{
+       int one = 1;
+       char *cp = (char *) &one;
+
+       return (*cp == 1);
+}
 
 void main (int argc, char ** argv)
 {
        errcode_t       retval;
        ext2_filsys     fs;
        int             print_badblocks = 0;
+       int             big_endian;
        char            c;
 
        fprintf (stderr, "dumpe2fs %s, %s for EXT2 FS %s, %s\n",
@@ -195,6 +203,11 @@ void main (int argc, char ** argv)
                        ext2fs_close (fs);
                        exit (1);
                }
+               big_endian = ((fs->flags & EXT2_SWAP_BYTES) != 0);
+               if (!i386_byteorder())
+                       big_endian = !big_endian;
+               if (big_endian)
+                       printf("Note: This is a byte-swapped filesystem\n");
                list_super (fs->super);
                list_bad_blocks (fs);
                list_desc (fs);
index 10d6aa8..5526551 100644 (file)
@@ -14,23 +14,27 @@ mke2fs \- create a Linux second extended file system
 .\" test
 .\" |
 .B \-l
-filename
+.I filename
 ]
 [
 .B \-b
-block-size
+.I block-size
 ]
 [
 .B \-f
-fragment-size
+.I fragment-size
 ]
 [
 .B \-i
-bytes-per-inode
+.I bytes-per-inode
 ]
 [
 .B \-m
-reserved-blocks-percentage
+.I reserved-blocks-percentage
+]
+[
+.B \-o
+.I creator-os
 ]
 [
 .B \-q
@@ -42,11 +46,19 @@ reserved-blocks-percentage
 .B \-F
 ]
 [
+.B \-L
+.I volume-label
+]
+[
+.B \-M
+.I last-mounted-directory
+]
+[
 .B \-S
 ]
-device
+.I device
 [
-blocks-count
+.I blocks-count
 ]
 .SH DESCRIPTION
 .B mke2fs
@@ -94,6 +106,11 @@ defaults to 5%.
 .\" Check the device for bad blocks before creating the file system
 .\" using the specified test.
 .TP
+.I -o
+Manually override the default value of the "creator os" field of the 
+filesystem.  Normally the creator field is set by default to the native OS
+of the mke2fs executable.
+.TP
 .I -q
 Quiet execution.  Useful if mke2fs is run in a script.
 .TP
@@ -104,6 +121,14 @@ Verbose execution.
 Force mke2fs to run, even if the specified device is not a 
 block special device.
 .TP
+.I -L
+Set the volume label for the filesystem.
+.TP
+.I -M
+Set the last mounted directory for the filesystem.  This might be useful 
+for the sake of utilities that key off of the last mounted directory to 
+determine where the filesytem should be mounted.
+.TP
 .I -S
 Write superblock and group descriptors only.  This is useful if all of
 the superblock and backup superblocks are corrupted, and a last-ditch
index 69f5c39..0cdcc05 100644 (file)
 #endif
 
 #include "et/com_err.h"
+#include "uuid/uuid.h"
 #include "ext2fs/ext2fs.h"
 #include "../version.h"
 
 #define STRIDE_LENGTH 8
 
+#ifndef sparc
+#define ZAP_BOOTBLOCK
+#endif
+
 extern int isatty(int);
 extern FILE *fpopen(const char *cmd, const char *mode);
 
@@ -67,14 +72,17 @@ int force = 0;
 char   *bad_blocks_filename = 0;
 
 struct ext2_super_block param;
+char *creator_os = NULL;
+char *volume_label = NULL;
+char *mount_dir = NULL;
 
 static void usage(NOARGS)
 {
-       fprintf(stderr,
-               "Usage: %s [-c|-t|-l filename] [-b block-size] "
-               "[-f fragment-size]\n\t[-i bytes-per-inode] "
-               "[-m reserved-blocks-percentage] [-qvS]\n"
-               "\t[-g blocks-per-group] device [blocks-count]\n",
+       fprintf(stderr, "Usage: %s [-c|-t|-l filename] [-b block-size] "
+       "[-f fragment-size]\n\t[-i bytes-per-inode] "
+       "[-m reserved-blocks-percentage] [-qvS]\n\t"
+       "[-o creator-os] [-g blocks-per-group] [-L volume-label]\n\t"
+       "[-M last-mounted-directory] device [blocks-count]\n",
                program_name);
        exit(1);
 }
@@ -437,6 +445,7 @@ static void reserve_inodes(ext2_filsys fs)
        ext2fs_mark_ib_dirty(fs);
 }
 
+#ifdef ZAP_BOOTBLOCK
 static void zap_bootblock(ext2_filsys fs)
 {
        char buf[512];
@@ -449,11 +458,13 @@ static void zap_bootblock(ext2_filsys fs)
                printf("Warning: could not erase block 0: %s\n", 
                       error_message(retval));
 }
+#endif
        
 
 static void show_stats(ext2_filsys fs)
 {
-       struct ext2_super_block *s = fs->super;
+       struct ext2fs_sb        *s = (struct ext2fs_sb *) fs->super;
+       char                    buf[80];
        blk_t                   group_block;
        int                     i, col_left;
        
@@ -461,6 +472,16 @@ static void show_stats(ext2_filsys fs)
                printf("warning: %d blocks unused.\n\n",
                       param.s_blocks_count - s->s_blocks_count);
        
+       switch (fs->super->s_creator_os) {
+           case EXT2_OS_LINUX: printf ("Linux"); break;
+           case EXT2_OS_HURD:  printf ("GNU/hurd");   break;
+           case EXT2_OS_MASIX: printf ("Masix"); break;
+           default:            printf ("(unknown os)");
+        }
+       printf (" ext2 filesystem format\n");
+       memset(buf, 0, sizeof(buf));
+       strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
+       printf("Filesystem label=%s\n", buf);
        printf("%u inodes, %u blocks\n", s->s_inodes_count,
               s->s_blocks_count);
        printf("%u blocks (%2.2f%%) reserved for the super user\n",
@@ -498,6 +519,41 @@ static void show_stats(ext2_filsys fs)
        printf("\n\n");
 }
 
+#ifndef HAVE_STRCASECMP
+static int strcasecmp (char *s1, char *s2)
+{
+       while (*s1 && *s2) {
+               int ch1 = *s1++, ch2 = *s2++;
+               if (isupper (ch1))
+                       ch1 = tolower (ch1);
+               if (isupper (ch2))
+                       ch2 = tolower (ch2);
+               if (ch1 != ch2)
+                       return ch1 - ch2;
+       }
+       return *s1 ? 1 : *s2 ? -1 : 0;
+}
+#endif
+
+/*
+ * Set the S_CREATOR_OS field.  Return true if OS is known,
+ * otherwise, 0.
+ */
+static int set_os(struct ext2_super_block *sb, char *os)
+{
+       if (isdigit (*os))
+               sb->s_creator_os = atoi (os);
+       else if (strcasecmp(os, "linux") == 0)
+               sb->s_creator_os = EXT2_OS_LINUX;
+       else if (strcasecmp(os, "GNU") == 0 || strcasecmp(os, "hurd") == 0)
+               sb->s_creator_os = EXT2_OS_HURD;
+       else if (strcasecmp(os, "masix") == 0)
+               sb->s_creator_os = EXT2_OS_MASIX;
+       else
+               return 0;
+       return 1;
+}
+
 #define PATH_SET "PATH=/sbin"
 
 static void PRS(int argc, char *argv[])
@@ -532,7 +588,8 @@ static void PRS(int argc, char *argv[])
                 EXT2FS_VERSION, EXT2FS_DATE);
        if (argc && *argv)
                program_name = *argv;
-       while ((c = getopt (argc, argv, "b:cf:g:i:l:m:qr:tvI:SF")) != EOF)
+       while ((c = getopt (argc, argv,
+                           "b:cf:g:i:l:m:o:qr:tvI:SFL:M:")) != EOF)
                switch (c) {
                case 'b':
                        size = strtoul(optarg, &tmp, 0);
@@ -606,6 +663,9 @@ static void PRS(int argc, char *argv[])
                                exit(1);
                        }
                        break;
+               case 'o':
+                       creator_os = optarg;
+                       break;
                case 'r':
                        param.s_rev_level = atoi(optarg);
                        break;
@@ -623,6 +683,12 @@ static void PRS(int argc, char *argv[])
                case 'F':
                        force = 1;
                        break;
+               case 'L':
+                       volume_label = optarg;
+                       break;
+               case 'M':
+                       mount_dir = optarg;
+                       break;
                case 'S':
                        super_only = 1;
                        break;
@@ -655,7 +721,7 @@ static void PRS(int argc, char *argv[])
                                                EXT2_BLOCK_SIZE(&param),
                                                &param.s_blocks_count);
                if (retval) {
-                       com_err(program_name, 0,
+                       com_err(program_name, retval,
                                "while trying to determine filesystem size");
                        exit(1);
                }
@@ -679,6 +745,7 @@ int main (int argc, char *argv[])
        errcode_t       retval = 0;
        ext2_filsys     fs;
        badblocks_list  bb_list = 0;
+       struct ext2fs_sb *s;
        
        PRS(argc, argv);
 
@@ -692,6 +759,38 @@ int main (int argc, char *argv[])
                exit(1);
        }
 
+       /*
+        * Generate a UUID for it...
+        */
+       s = (struct ext2fs_sb *) fs->super;
+       uuid_generate(s->s_uuid);
+
+       /*
+        * Override the creator OS, if applicable
+        */
+       if (creator_os && !set_os(fs->super, creator_os)) {
+               com_err (program_name, 0, "unknown os - %s", creator_os);
+               exit(1);
+       }
+
+       /*
+        * Set the volume label...
+        */
+       if (volume_label) {
+               memset(s->s_volume_name, 0, sizeof(s->s_volume_name));
+               strncpy(s->s_volume_name, volume_label,
+                       sizeof(s->s_volume_name));
+       }
+
+       /*
+        * Set the last mount directory
+        */
+       if (mount_dir) {
+               memset(s->s_last_mounted, 0, sizeof(s->s_last_mounted));
+               strncpy(s->s_last_mounted, mount_dir,
+                       sizeof(s->s_last_mounted));
+       }
+       
        if (!quiet)
                show_stats(fs);
 
@@ -710,7 +809,9 @@ int main (int argc, char *argv[])
                create_lost_and_found(fs);
                reserve_inodes(fs);
                create_bad_block_inode(fs, bb_list);
+#ifdef ZAP_BOOTBLOCK
                zap_bootblock(fs);
+#endif
        }
        
        if (!quiet)
index ee123d2..9b92711 100644 (file)
@@ -38,6 +38,22 @@ tune2fs \- adjust tunable filesystem parameters on second extended filesystems
 .B -g
 .I group
 ]
+[
+.B -C
+.I mount-count
+]
+[
+.B -L
+.I volume-name
+]
+[
+.B -M
+.I last-mounted-directory
+]
+[
+.B -U
+.I UUID
+]
 device
 .SH DESCRIPTION
 .BI tune2fs
@@ -85,6 +101,21 @@ adjust the reserved blocks count on the given device.
 set the user who can benefit from the reserved blocks.
 .I user
 can be a numerical uid or a user name.
+.IP
+.I -C mount-count
+set the number of times the filesystem has been mounted.
+.TP
+.I -L volume-label
+set the volume label of the filesystem.
+.TP
+.I -M last-mounted-directory
+set the last-mounted direcctory for the filesystem.
+.TP
+.I -U UUID
+set the UUID of the filesystem.  A sample UUID looks like this: 
+"c1b9d5a2-f162-11cf-9ece-0020afc76f16".  The uuid may also be "null", 
+which will set the filesystem UUID to the null UUID.  The uuid may also 
+be "random", which will generate a new random UUID for the filesystem.
 .PP
 .SH BUGS
 We didn't find any bugs yet. Perhaps there are bugs but it's unlikely.
index 1576ce4..a6e2486 100644 (file)
 
 #include "ext2fs/ext2fs.h"
 #include "et/com_err.h"
+#include "uuid/uuid.h"
 #include "e2p/e2p.h"
 
 #include "../version.h"
 
 const char * program_name = "tune2fs";
 char * device_name = NULL;
+char * new_label = NULL;
+char * new_last_mounted = NULL;
+char * new_UUID = NULL;
 int c_flag = 0;
+int C_flag = 0;
 int e_flag = 0;
 int g_flag = 0;
 int i_flag = 0;
 int l_flag = 0;
+int L_flag = 0;
 int m_flag = 0;
+int M_flag = 0;
 int r_flag = 0;
 int u_flag = 0;
-int max_mount_count;
+int U_flag = 0;
+int max_mount_count, mount_count;
 unsigned long interval;
 unsigned long reserved_ratio = 0;
 unsigned long reserved_blocks = 0;
@@ -61,12 +69,30 @@ unsigned short errors;
 unsigned long resgid = 0;
 unsigned long resuid = 0;
 
+#ifndef HAVE_STRCASECMP
+static int strcasecmp (char *s1, char *s2)
+{
+       while (*s1 && *s2) {
+               int ch1 = *s1++, ch2 = *s2++;
+               if (isupper (ch1))
+                       ch1 = tolower (ch1);
+               if (isupper (ch2))
+                       ch2 = tolower (ch2);
+               if (ch1 != ch2)
+                       return ch1 - ch2;
+       }
+       return *s1 ? 1 : *s2 ? -1 : 0;
+}
+#endif
+
 static volatile void usage (void)
 {
        fprintf (stderr, "Usage: %s [-c max-mounts-count] [-e errors-behavior] "
                 "[-g group]\n"
                 "\t[-i interval[d|m|w]] [-l] [-m reserved-blocks-percent]\n"
-                "\t[-r reserved-blocks-count] [-u user] device\n", program_name);
+                "\t[-r reserved-blocks-count] [-u user] [-C mount-count]\n"
+                "\t[-L volume-label] [-M last-mounted-dir] [-U UUID] "
+                "device\n", program_name);
        exit (1);
 }
 
@@ -76,8 +102,10 @@ void main (int argc, char ** argv)
        char * tmp;
        errcode_t retval;
        ext2_filsys fs;
+       struct ext2fs_sb *sb;
        struct group * gr;
        struct passwd * pw;
+       int open_flag = 0;
 
        fprintf (stderr, "tune2fs %s, %s for EXT2 FS %s, %s\n",
                 E2FSPROGS_VERSION, E2FSPROGS_DATE,
@@ -85,7 +113,7 @@ void main (int argc, char ** argv)
        if (argc && *argv)
                program_name = *argv;
        initialize_ext2_error_table();
-       while ((c = getopt (argc, argv, "c:e:g:i:lm:r:u:")) != EOF)
+       while ((c = getopt (argc, argv, "c:e:g:i:lm:r:u:C:L:M:U:")) != EOF)
                switch (c)
                {
                        case 'c':
@@ -98,6 +126,19 @@ void main (int argc, char ** argv)
                                        usage ();
                                }
                                c_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
+                               break;
+                       case 'C':
+                               mount_count = strtoul (optarg, &tmp, 0);
+                               if (*tmp || mount_count > 16000)
+                               {
+                                       com_err (program_name, 0,
+                                                "bad mounts count - %s",
+                                                optarg);
+                                       usage ();
+                               }
+                               C_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
                                break;
                        case 'e':
                                if (strcmp (optarg, "continue") == 0)
@@ -114,6 +155,7 @@ void main (int argc, char ** argv)
                                        usage ();
                                }
                                e_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
                                break;
                        case 'g':
                                resgid = strtoul (optarg, &tmp, 0);
@@ -135,28 +177,31 @@ void main (int argc, char ** argv)
                                        usage ();
                                }
                                g_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
                                break;
                        case 'i':
                                interval = strtoul (optarg, &tmp, 0);
-                               switch (*tmp)
-                               {
-                                       case '\0':
-                                       case 'd':
-                                       case 'D': /* days */
-                                               interval *= 86400;
-                                               if (*tmp != '\0')
-                                                       tmp++;
-                                               break;
-                                       case 'm':
-                                       case 'M': /* months! */
-                                               interval *= 86400 * 30;
-                                               tmp++;
-                                               break;
-                                       case 'w':
-                                       case 'W': /* weeks */
-                                               interval *= 86400 * 7;
+                               switch (*tmp) {
+                               case 's':
+                                       tmp++;
+                                       break;
+                               case '\0':
+                               case 'd':
+                               case 'D': /* days */
+                                       interval *= 86400;
+                                       if (*tmp != '\0')
                                                tmp++;
-                                               break;
+                                       break;
+                               case 'm':
+                               case 'M': /* months! */
+                                       interval *= 86400 * 30;
+                                       tmp++;
+                                       break;
+                               case 'w':
+                               case 'W': /* weeks */
+                                       interval *= 86400 * 7;
+                                       tmp++;
+                                       break;
                                }
                                if (*tmp || interval > (365 * 86400))
                                {
@@ -165,10 +210,16 @@ void main (int argc, char ** argv)
                                        usage ();
                                }
                                i_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
                                break;
                        case 'l':
                                l_flag = 1;
                                break;
+                       case 'L':
+                               new_label = optarg;
+                               L_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
+                               break;
                        case 'm':
                                reserved_ratio = strtoul (optarg, &tmp, 0);
                                if (*tmp || reserved_ratio > 50)
@@ -179,6 +230,12 @@ void main (int argc, char ** argv)
                                        usage ();
                                }
                                m_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
+                               break;
+                       case 'M':
+                               new_last_mounted = optarg;
+                               M_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
                                break;
                        case 'r':
                                reserved_blocks = strtoul (optarg, &tmp, 0);
@@ -190,6 +247,7 @@ void main (int argc, char ** argv)
                                        usage ();
                                }
                                r_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
                                break;
                        case 'u':
                                resuid = strtoul (optarg, &tmp, 0);
@@ -211,20 +269,23 @@ void main (int argc, char ** argv)
                                        usage ();
                                }
                                u_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
+                               break;
+                       case 'U':
+                               new_UUID = optarg;
+                               U_flag = 1;
+                               open_flag = EXT2_FLAG_RW;
                                break;
                        default:
                                usage ();
                }
        if (optind < argc - 1 || optind == argc)
                usage ();
-       if (!c_flag && !e_flag && !g_flag && !i_flag && !l_flag && !m_flag
-           && !r_flag && !u_flag)
-               usage ();
+       if (!open_flag && !l_flag)
+               usage();
        device_name = argv[optind];
-       retval = ext2fs_open (device_name,
-                             (c_flag || e_flag || g_flag || i_flag || m_flag
-                              || r_flag || u_flag) ? EXT2_FLAG_RW : 0,
-                             0, 0, unix_io_manager, &fs);
+       retval = ext2fs_open (device_name, open_flag, 0, 0,
+                             unix_io_manager, &fs);
         if (retval)
        {
                com_err (program_name, retval, "while trying to open %s",
@@ -232,15 +293,20 @@ void main (int argc, char ** argv)
                printf("Couldn't find valid filesystem superblock.\n");
                exit(1);
        }
+       sb = (struct ext2fs_sb *) fs->super;
 
-       if (c_flag)
-       {
+       if (c_flag) {
                fs->super->s_max_mnt_count = max_mount_count;
                ext2fs_mark_super_dirty(fs);
-               printf ("Setting maximal mount count to %d\n", max_mount_count);
+               printf ("Setting maximal mount count to %d\n",
+                       max_mount_count);
        }
-       if (e_flag)
-       {
+       if (C_flag) {
+               fs->super->s_mnt_count = mount_count;
+               ext2fs_mark_super_dirty(fs);
+               printf ("Setting current mount count to %d\n", mount_count);
+       }
+       if (e_flag) {
                fs->super->s_errors = errors;
                ext2fs_mark_super_dirty(fs);
                printf ("Setting error behavior to %d\n", errors);
@@ -268,7 +334,7 @@ void main (int argc, char ** argv)
                fs->super->s_r_blocks_count = (fs->super->s_blocks_count / 100)
                        * reserved_ratio;
                ext2fs_mark_super_dirty(fs);
-               printf ("Setting reserved blocks percentage to %lu (%lu blocks)\n",
+               printf ("Setting reserved blocks percentage to %lu (%u blocks)\n",
                        reserved_ratio, fs->super->s_r_blocks_count);
        }
        if (r_flag)
@@ -297,6 +363,30 @@ void main (int argc, char ** argv)
                         "The -u option is not supported by this version -- "
                         "Recompile with a newer kernel");
 #endif
+       if (L_flag) {
+               memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
+               strncpy(sb->s_volume_name, new_label,
+                       sizeof(sb->s_volume_name));
+               ext2fs_mark_super_dirty(fs);
+       }
+       if (M_flag) {
+               memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
+               strncpy(sb->s_last_mounted, new_last_mounted,
+                       sizeof(sb->s_last_mounted));
+               ext2fs_mark_super_dirty(fs);
+       }
+       if (U_flag) {
+               if (strcasecmp(new_UUID, "null") == 0) {
+                       uuid_clear(sb->s_uuid);
+               } else if (strcasecmp(new_UUID, "random") == 0) {
+                       uuid_generate(sb->s_uuid);
+               } else if (uuid_parse(new_UUID, sb->s_uuid)) {
+                       com_err(program_name, 0, "Invalid UUID format\n");
+                       exit(1);
+               }
+               ext2fs_mark_super_dirty(fs);
+       }
+
        if (l_flag)
                list_super (fs->super);
        ext2fs_close (fs);
diff --git a/relocate/Makefile.in b/relocate/Makefile.in
new file mode 100644 (file)
index 0000000..01cfcf2
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# Relocation e2fsprogs prologue....
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+top_builddir = ..
+my_dir = relocate
+INSTALL = @INSTALL@
+
+@MCONFIG@
+
+SRCS=  $(srcdir)/resize2fs.c 
+
+LIBS= $(LIBEXT2FS) $(LIBCOM_ERR) 
+DEPLIBS= $(LIBEXT2FS) $(LIBCOM_ERR) 
+
+STATIC_LIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) 
+STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) 
+
+LIBS_E2P= $(LIBEXT2FS) $(LIBE2P) $(LIBCOM_ERR) 
+DEPLIBS_E2P= $(LIBEXT2FS) $(LIBE2P) $(LIBCOM_ERR) 
+
+.c.o:
+       $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+all:: resize2fs
+
+resize2fs: resize2fs.o $(DEPLIBS)
+       $(CC) $(ALL_LDFLAGS) -o resize2fs resize2fs.o $(LIBS)
+
+clean::
+       $(RM) -f resize2fs \#* *.s *.o *.a *~ core
diff --git a/relocate/README b/relocate/README
new file mode 100644 (file)
index 0000000..9c32d80
--- /dev/null
@@ -0,0 +1 @@
+This directory is under construction still....
diff --git a/relocate/relocate.c b/relocate/relocate.c
new file mode 100644 (file)
index 0000000..3ea47c0
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * relocate.c --- maintains the relocation table
+ *
+ * Copyright (C) 1996 Theodore Ts'o.  This file may be redistributed
+ * under the terms of the GNU Public License.
+ */
+
+#include <et/com_err.h>
+
+/*
+ * This routine creates a relocation table
+ */
+errcode_t ext2fs_create_relocation_table(__u32 max, int size,
+                                        ext2_relocate_table *ret);
+{
+       ext2_relocate_table table;
+
+       table = malloc(sizeof(struct ext2_relocate_struct));
+       if (!table)
+               return -ENOMEM;
+       table->magic = 0;
+       table->count = 0;
+       table->size = size ? size : 30;
+       table->max = max;
+       table->entries = malloc(table->size * sizeof(ext2_relocate_entry));
+       if (table->entries == 0) {
+               free(table);
+               return ENOMEM;
+       }
+       memset(table->entries, 0, table->size * sizeof(ext2_relocate_entry));
+       *ret = table;
+       return 0;
+}
+
+/*
+ * Free a relocation table
+ */
+void ext2fs_free_relocation_table(ext2_relocate_table table)
+{
+       free(table->entries);
+       table->count = 0;
+       table->size = 0;
+       table->magic = 0;
+       free(table);
+}
+
+/*
+ * Add a relocation table entry
+ */
+errcode_t ext2fs_add_relocation(ext2_relocate_table table, __u32 old,
+                               __u32 new, __u32 owner)
+{
+       struct ext2_relocate_entry *new;
+       
+       if (table->count >= table->size) {
+               table->size += 30;
+               new = realloc(table->entries,
+                             table->size * sizeof(ext2_relocate_entry));
+               if (!new)
+                       return ENOMEM;
+               table->entries = new;
+       }
+       if (table->count && table->entries[table->count-1].old > old) {
+               for (i = table->count-1; i > 0; i--)
+                       if (table->entries[i-1].old < old)
+                               break;
+               new = &table->entries[i];
+               if (new->old != old) 
+                       for (j = table->count++; j > i; j--)
+                               table->entries[j] = table_entries[j-1];
+       } else
+               new = &table->entries[table->coun++];
+       
+       new->old = old;
+       new->new = new;
+       new->owner = owner;
+}
+
+/*
+ * ext2fs_get_reloc_by_old() --- given the source of the relcation
+ * entry, find the entry for it.
+ */
+struct relocate_entry *ext2fs_get_reloc_by_old(ext2_relocate_table tbl,
+                                              __u32 old)
+{
+       int     low, high, mid;
+       int     i, j;
+
+       low = 0;
+       high = tbl->count-1;
+       if (old == table->entries[low].old)
+               return &table->entries[low];
+       if  (old == table->entries[high].old)
+               return &table->entries[high];
+
+       while (low < high) {
+               mid = (low+high)/2;
+               if (mid == low || mid == high)
+                       break;
+               if (old == table->entries[mid].old)
+                       return &table->entries[mid];
+               if (old < table->entries[mid].old)
+                       high = mid;
+               else
+                       low = mid;
+       }
+       return 0;
+}
+
+/*
+ * ext2fs_get_reloc_by_new() --- given the destination of the relcation
+ * entry, find the entry for it.
+ *
+ * Note: this is currently very slow...
+ */
+struct relocate_entry *ext2fs_get_reloc_by_new(ext2_relocate_table tbl,
+                                              __u32 new)
+{
+       int     i;
+
+       for (i = 0; i < table->count; i++) {
+               if (tbl->entries[i].new == new)
+                       return &table->entries[i];
+       }
+       return 0;
+}
+
+/*
+ * Find "loops" in the relocation tables
+ */
+{
+       int     i;
+       struct ext2_relocate_entry *ent, *next;
+       
+
+       for (i=0, ent=table->entries; i < table->size; i++, ent++) {
+               /*
+                * If we know this inode is OK, then keep going.
+                */
+               if (ext2fs_test_generic_bitmap(done_map, dir->old))
+                       continue;
+               ext2fs_clear_generic_bitmap(loop_detect);
+               while (1) {
+                       ext2fs_mark_generic_bitmap(loop_detect, dir->old);
+                       next = ext2fs_get_reloc_by_old(table, dir->new);
+                       if (next == NULL)
+                               break;
+                       if (ext2fs_test_generic_bitmap(loop_detect,
+                                                      dir->new))
+                               break_loop(table, dir);
+                       ext2fs_mark_generic_bitmap(done_map, dir->old);
+                       dir = next;
+               }
+       }
+}
+
+       
+       
+               
diff --git a/relocate/relocate.h b/relocate/relocate.h
new file mode 100644 (file)
index 0000000..f1eec6d
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * relocate.h
+ * 
+ * Copyright (C) 1996 Theodore Ts'o.  This file may be redistributed
+ * under the terms of the GNU Public License.
+ */
+
+struct ext2_relocate_entry {
+       __u32   new, old;
+       __u32   owner;
+}
+
+struct ext2_relocate_struct {
+       int     magic;
+       int     count;
+       int     size;
+       int     max;
+       struct ext2_relocate_entry *entries;
+};
+
+typedef struct ext2_relocate_struct  *ext2_relocate_table;
diff --git a/relocate/resize2fs.c b/relocate/resize2fs.c
new file mode 100644 (file)
index 0000000..f5b5f24
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * resize2fs.c  - Resize the ext2 filesystem.
+ *
+ * Copyright (C) 1996 Theodore Ts'o
+ *
+ * This file can be redistributed under the terms of the GNU General
+ * Public License
+ */
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fs/ext2fs.h"
+
+#include "../version.h"
+
+const char * program_name = "resize2fs";
+char * device_name = NULL;
+
+static volatile void usage (void)
+{
+       fprintf (stderr, "usage: %s device\n", program_name);
+       exit (1);
+}
+
+errcode_t ext2fs_resize_inode_bitmap(ext2_filsys fs,
+                                    ext2fs_inode_bitmap ibmap)
+{
+       ino_t   new_end, new_real_end;
+       size_t  size, new_size;
+       char    *new_bitmap, *old_bitmap;
+       
+       EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+       EXT2_CHECK_MAGIC(ibmap, EXT2_ET_MAGIC_INODE_BITMAP);
+
+       new_end = fs->super->s_inodes_count;
+       new_real_end = (EXT2_INODES_PER_GROUP(fs->super)
+                       * fs->group_desc_count);
+
+       if (new_real_end == ibmap->real_end) {
+               ibmap->end = new_end;
+               return 0;
+       }
+       
+       size = ((ibmap->real_end - ibmap->start) / 8) + 1;
+       new_size = ((new_real_end - ibmap->start) / 8) + 1;
+
+       new_bitmap = malloc(size);
+       if (!new_bitmap)
+               return ENOMEM;
+       if (size > new_size)
+               size = new_size;
+       memcpy(new_bitmap, ibmap->bitmap, size);
+       if (new_size > size)
+               memset(new_bitmap + size, 0, new_size - size);
+
+       old_bitmap = ibmap->bitmap;
+       ibmap->bitmap = new_bitmap;
+       free(old_bitmap);
+       ibmap->end = new_end;
+       ibmap->real_end = new_real_end;
+}
+
+errcode_t ext2fs_resize_block_bitmap(ext2_filsys fs,
+                                    ext2fs_inode_bitmap bbmap)
+{
+       ino_t   new_end, new_real_end;
+       size_t  size, new_size;
+       char    *new_bitmap, *old_bitmap;
+       
+       EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+       EXT2_CHECK_MAGIC(bbmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
+
+       new_end = fs->super->s_inodes_count;
+       new_real_end = (EXT2_INODES_PER_GROUP(fs->super)
+                       * fs->group_desc_count);
+
+       if (new_real_end == bbmap->real_end) {
+               bbmap->end = new_end;
+               return 0;
+       }
+       
+       size = ((bbmap->real_end - bbmap->start) / 8) + 1;
+       new_size = ((new_real_end - bbmap->start) / 8) + 1;
+
+       new_bitmap = malloc(size);
+       if (!new_bitmap)
+               return ENOMEM;
+       if (size > new_size)
+               size = new_size;
+       memcpy(new_bitmap, bbmap->bitmap, size);
+       if (new_size > size)
+               memset(new_bitmap + size, 0, new_size - size);
+
+       old_bitmap = bbmap->bitmap;
+       bbmap->bitmap = new_bitmap;
+       free(old_bitmap);
+       bbmap->end = new_end;
+       bbmap->real_end = new_real_end;
+}
+
+
+       
+errcode_t ext2fs_resize(ext2_filsys fs, blk_t new_size)
+{
+       __u32 new_block_groups, new_desc_blocks;
+       
+       if (new_size = fs->super->s_blocks_count)
+               return 0;
+
+       new_block_groups = (fs->super->s_blocks_count -
+                           fs->super->s_first_data_block +
+                           EXT2_BLOCKS_PER_GROUP(fs->super) - 1)
+               / EXT2_BLOCKS_PER_GROUP(fs->super);
+       if (new_block_groups == 0)
+               return EXT2_ET_TOOSMALL;
+       new_desc_blocks = (new_block_groups +
+                          EXT2_DESC_PER_BLOCK(fs->super) - 1)
+               / EXT2_DESC_PER_BLOCK(fs->super);
+
+}
+
+
+
+void main (int argc, char ** argv)
+{
+       errcode_t       retval;
+       ext2_filsys     fs;
+       int             c;
+
+       fprintf (stderr, "resize2fs %s, %s for EXT2 FS %s, %s\n",
+                E2FSPROGS_VERSION, E2FSPROGS_DATE,
+                EXT2FS_VERSION, EXT2FS_DATE);
+       if (argc && *argv)
+               program_name = *argv;
+       
+       while ((c = getopt (argc, argv, "h")) != EOF) {
+               switch (c) {
+               case 'h':
+                       usage();
+                       break;
+               default:
+                       usage ();
+               }
+       }
+       if (optind > argc - 1)
+               usage ();
+       device_name = argv[optind++];
+       initialize_ext2_error_table();
+       retval = ext2fs_open (device_name, EXT2_FLAG_RW, 0, 0,
+                             unix_io_manager, &fs);
+       if (retval) {
+               com_err (program_name, retval, "while trying to open %s",
+                        device_name);
+               printf ("Couldn't find valid filesystem superblock.\n");
+               exit (1);
+       }
+       retval = ext2fs_read_bitmaps (fs);
+       if (retval) {
+               com_err (program_name, retval,
+                        "while trying to read the bitmaps", device_name);
+               ext2fs_close (fs);
+               exit (1);
+       }
+       ext2fs_close (fs);
+       exit (0);
+}
index 4dcec34..11367d8 100644 (file)
@@ -1,3 +1,22 @@
+Mon Sep  9 23:09:47 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * Makefile.in (check): Add explicit ./ to test_script invokation,
+               since not all people will have "." in their path.
+
+Tue Sep  3 15:13:05 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * test_config (PAGER): Unset pager to prevent debugfs forking a
+               pager, since the escape sequences confuse the expect
+               script.
+
+Sun May 19 23:37:35 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * test_script: New feature; second optional argument allows
+               developers to only run one test case.
+
+       * f_crashdisk: New test case which contains a patently illegal
+               superblock with a valid magic number.
+
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * Release of E2fsprogs version 1.04
index 4c77666..5e04dc8 100644 (file)
@@ -6,17 +6,27 @@ srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ..
+my_dir = tests
 INSTALL = @INSTALL@
 
+@MCONFIG@
+
 all:: @DO_TEST_SUITE@
 
-check::
+test_script: test_script.in Makefile
+       @echo "Creating test_script..."
+       @echo "#!/bin/sh" > test_script
+       @echo "SRCDIR=@srcdir@" >> test_script
+       @cat $(srcdir)/test_script.in >> test_script
+       @chmod +x test_script
+
+check:: test_script
        @echo "Running e2fsprogs test suite..."
        @echo " "
-       @$(srcdir)/test_script $(srcdir)
+       @./test_script
 
 clean::
-       $(RM) -f *.log *.new *.failed *.ok test.img
+       $(RM) -f *.log *.new *.failed *.ok test.img test_script
 
 distclean:: clean
        $(RM) -f Makefile
index 3fcfb3b..fd60f67 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Remove illegal block(s) in bad block inode? yes
 
index 646ba24..766a0a5 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Directory 12, incorrect size, 182 (counted = 1024). Set size to counted? yes
 
index e9499cb..d24b281 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Missing '.' in directory inode 12.
index 4552569..c6842d2 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Inode 12 (/motd) has a bad mode (0110444).
diff --git a/tests/f_badlkcnt/expect.1 b/tests/f_badlkcnt/expect.1
deleted file mode 100644 (file)
index 63b9d9f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Pass 1: Checking inodes, blocks, and sizes
-
-Deleted inode detected with non-zero link count.
-This is probably due to old ext2fs kernel code.  
-Fix inode(s)? yes
-
-Inode 13 is deleted w/ non-zero link_count.  CLEARED
-Inode 15 is deleted w/ non-zero link_count.  CLEARED
-Inode 16 is deleted w/ non-zero link_count.  CLEARED
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 29/32 files (0.0% non-contiguous), 32/100 blocks
-Exit status is 1
diff --git a/tests/f_badlkcnt/expect.2 b/tests/f_badlkcnt/expect.2
deleted file mode 100644 (file)
index a28c8bd..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-test_filesys: 29/32 files (0.0% non-contiguous), 32/100 blocks
-Exit status is 0
diff --git a/tests/f_badlkcnt/image.gz b/tests/f_badlkcnt/image.gz
deleted file mode 100644 (file)
index 3ba07cc..0000000
Binary files a/tests/f_badlkcnt/image.gz and /dev/null differ
diff --git a/tests/f_badlkcnt/name b/tests/f_badlkcnt/name
deleted file mode 100644 (file)
index d57851d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-deleted files with non-zero link count
index f41e319..bca07d2 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 The primary superblock (1) is on the bad block list.
 
index ebe7e3a..fd760a1 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Root inode is not a directory.  Clear? yes
 
index 0f22af9..b8d2cd0 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Group 0's block bitmap (3) is bad.  Relocate? yes
 
index 957ff48..ea2f810 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Group 0's inode bitmap (4) is bad.  Relocate? yes
 
index 6d23cec..9b15ea2 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
diff --git a/tests/f_crashdisk/expect.1 b/tests/f_crashdisk/expect.1
new file mode 100644 (file)
index 0000000..d12c3da
--- /dev/null
@@ -0,0 +1,9 @@
+../e2fsck/e2fsck: The ext2 superblock is corrupt while trying to open ./test.img
+
+The superblock could not be read or does not describe a correct ext2
+filesystem.  If the device is valid and it really contains an ext2
+filesystem (and not swap or ufs or something else), then the superblock
+is corrupt, and you might try running e2fsck with an alternate superblock:
+    e2fsck -b 8193 <device>
+
+Exit status is 8
diff --git a/tests/f_crashdisk/image.gz b/tests/f_crashdisk/image.gz
new file mode 100644 (file)
index 0000000..060e7a0
Binary files /dev/null and b/tests/f_crashdisk/image.gz differ
diff --git a/tests/f_crashdisk/name b/tests/f_crashdisk/name
new file mode 100644 (file)
index 0000000..5ba8a60
--- /dev/null
@@ -0,0 +1 @@
+Superblock with illegal values
diff --git a/tests/f_crashdisk/script b/tests/f_crashdisk/script
new file mode 100644 (file)
index 0000000..8ab2b9c
--- /dev/null
@@ -0,0 +1,2 @@
+ONE_PASS_ONLY="true"
+. $cmd_dir/run_e2fsck
index 73c008a..f53c0e1 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Entry 'quux' in /foo (12) is a link to directory /bar (13).
index df5c077..4359732 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Duplicate blocks found... invoking duplicate block passes.
 Pass 1B: Rescan for duplicate/bad blocks
index 5872546..6ba93bd 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Duplicate blocks found... invoking duplicate block passes.
 Pass 1B: Rescan for duplicate/bad blocks
@@ -38,5 +40,5 @@ Padding at end of block bitmap is not set. Fix? yes
 
 
 test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 16/16 files (6.2% non-contiguous), 78/100 blocks
+test_filesys: 16/16 files (6.3% non-contiguous), 78/100 blocks
 Exit status is 1
index 772295d..9d1ed34 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Remove illegal block(s) in inode 12? yes
 
index 37b21d9..e3aa122 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Remove illegal block(s) in inode 12? yes
 
index a54605a..f2beea6 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
index 1b88680..aca5ee4 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Deleted inode 2 has zero dtime.
 Set dtime? yes
index 898ef6f..ebf4539 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Hole found in directory inode 11!  (blkcnt=0)
 Hole found in directory inode 11!  (blkcnt=3)
index 5734c25..29fa496 100644 (file)
@@ -8,6 +8,8 @@ group descriptor may be OK.
 Block bitmap for group 0 is not in group.  (block 4096)
 Relocate? yes
 
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Relocating group 0's block bitmap to 4...
 Pass 2: Checking directory structure
index d06aa30..ed9d579 100644 (file)
@@ -8,6 +8,8 @@ group descriptor may be OK.
 Inode bitmap group 0 not in group.  (block 4000)
 Relocate? yes
 
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Relocating group 0's inode bitmap to 4...
 Pass 2: Checking directory structure
index 8861f9f..1340520 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Remove illegal block(s) in inode 12? yes
 
index a5b67e0..0b8dca1 100644 (file)
@@ -1,19 +1,23 @@
-Pass 1: Checking inodes, blocks, and sizes
+Filesystem did not have a UUID; generating one.
 
-Deleted inode detected with non-zero link count.
-This is probably due to old ext2fs kernel code.  
-Fix inode(s)? yes
+Pass 1: Checking inodes, blocks, and sizes
+Inode 13 is in use, but has dtime set
+Clear dtime? yes
 
-Inode 11 is deleted w/ non-zero link_count.  CLEARED
-Inode 13 is deleted w/ non-zero link_count.  CLEARED
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
-Unattached inode 14
+Unattached inode 13
 Connect to /lost+found? yes
 
 /lost+found not found.  Create? yes
 
+Inode 13 has ref count 2, expecting 1.
+Set i_nlinks to count? yes
+
+Unattached inode 14
+Connect to /lost+found? yes
+
 Inode 14 has ref count 2, expecting 1.
 Set i_nlinks to count? yes
 
@@ -26,14 +30,16 @@ Set i_nlinks to count? yes
 Pass 5: Checking group summary information
 Fix summary information? yes
 
-Free blocks count wrong for group 0 (25, counted=38).  FIXED
-Free blocks count wrong (39, counted=38).  FIXED
-Free inodes count wrong for group #0 (2, counted=1).  FIXED
+Block bitmap differences: +22 +23 +49 +57 +58.  FIXED
+Free blocks count wrong for group 0 (25, counted=33).  FIXED
+Free blocks count wrong (39, counted=33).  FIXED
+Inode bitmap differences: +13.  FIXED
+Free inodes count wrong for group #0 (2, counted=0).  FIXED
 Directories count wrong for group #0 (1, counted=2).  FIXED
-Free inodes count wrong (2, counted=1).  FIXED
+Free inodes count wrong (2, counted=0).  FIXED
 Padding at end of block bitmap is not set. Fix? yes
 
 
 test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 15/16 files (6.7% non-contiguous), 62/100 blocks
+test_filesys: 16/16 files (12.5% non-contiguous), 67/100 blocks
 Exit status is 1
index 1a3af49..36110ee 100644 (file)
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
-test_filesys: 15/16 files (6.7% non-contiguous), 62/100 blocks
+test_filesys: 16/16 files (12.5% non-contiguous), 67/100 blocks
 Exit status is 0
index 659b278..2a71bcf 100644 (file)
Binary files a/tests/f_lpf/image.gz and b/tests/f_lpf/image.gz differ
index 8400b51..3ea8de3 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Remove illegal block(s) in inode 14? yes
 
index e55d520..325b12e 100644 (file)
@@ -1,36 +1,30 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Root inode has dtime set (probably due to old mke2fs).  Fix? yes
 
-Note: /lost+found will probably be deleted as well, due to the mke2fs bug.
-Be sure to run mklost+found to recreate it after e2fsck finishes.
-
+Inode 11 is in use, but has dtime set
+Clear dtime? yes
 
-Deleted inode detected with non-zero link count.
-This is probably due to old ext2fs kernel code.  
-Fix inode(s)? yes
+Inode 15 is in use, but has dtime set
+Clear dtime? yes
 
-Inode 11 is deleted w/ non-zero link_count.  CLEARED
-Inode 15 is deleted w/ non-zero link_count.  CLEARED
 Pass 2: Checking directory structure
-Entry 'lost+found' in / (2) has deleted/unused inode 11.
-Clear? yes
-
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
-Inode 2 has ref count 4, expecting 3.
+Unattached inode 15
+Connect to /lost+found? yes
+
+Inode 15 has ref count 2, expecting 1.
 Set i_nlinks to count? yes
 
 Pass 5: Checking group summary information
 Fix summary information? yes
 
-Block bitmap differences: -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20.  FIXED
-Free blocks count wrong for group 0 (75, counted=87).  FIXED
-Free blocks count wrong (75, counted=87).  FIXED
-Inode bitmap differences: -11.  FIXED
-Free inodes count wrong for group #0 (17, counted=18).  FIXED
-Directories count wrong for group #0 (4, counted=3).  FIXED
-Free inodes count wrong (17, counted=18).  FIXED
+Inode bitmap differences: +15.  FIXED
+Free inodes count wrong for group #0 (17, counted=16).  FIXED
+Free inodes count wrong (17, counted=16).  FIXED
 
 test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 14/32 files (0.0% non-contiguous), 13/100 blocks
+test_filesys: 16/32 files (0.0% non-contiguous), 25/100 blocks
 Exit status is 1
index e87d8b9..763dc47 100644 (file)
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
-test_filesys: 14/32 files (0.0% non-contiguous), 13/100 blocks
+test_filesys: 16/32 files (0.0% non-contiguous), 25/100 blocks
 Exit status is 0
index d6d4d80..4c14638 100644 (file)
@@ -1,10 +1,9 @@
-Pass 1: Checking inodes, blocks, and sizes
+Filesystem did not have a UUID; generating one.
 
-Deleted inode detected with non-zero link count.
-This is probably due to old ext2fs kernel code.  
-Fix inode(s)? yes
+Pass 1: Checking inodes, blocks, and sizes
+Inode 15 is in use, but has dtime set
+Clear dtime? yes
 
-Inode 15 is deleted w/ non-zero link_count.  CLEARED
 Pass 2: Checking directory structure
 Entry '..' in /lost+found (11) has deleted/unused inode 2.
 Clear? yes
@@ -30,15 +29,22 @@ Set i_nlinks to count? yes
 Inode 12 has ref count 4, expecting 3.
 Set i_nlinks to count? yes
 
+Unattached inode 15
+Connect to /lost+found? yes
+
+Inode 15 has ref count 2, expecting 1.
+Set i_nlinks to count? yes
+
 Pass 5: Checking group summary information
 Fix summary information? yes
 
 Free blocks count wrong for group 0 (75, counted=74).  FIXED
 Free blocks count wrong (75, counted=74).  FIXED
-Free inodes count wrong for group #0 (17, counted=16).  FIXED
+Inode bitmap differences: +15.  FIXED
+Free inodes count wrong for group #0 (17, counted=15).  FIXED
 Directories count wrong for group #0 (4, counted=5).  FIXED
-Free inodes count wrong (17, counted=16).  FIXED
+Free inodes count wrong (17, counted=15).  FIXED
 
 test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 16/32 files (0.0% non-contiguous), 26/100 blocks
+test_filesys: 17/32 files (0.0% non-contiguous), 26/100 blocks
 Exit status is 1
index 5ea5bc7..b9c4e8a 100644 (file)
@@ -3,5 +3,5 @@ Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
-test_filesys: 16/32 files (0.0% non-contiguous), 26/100 blocks
+test_filesys: 17/32 files (0.0% non-contiguous), 26/100 blocks
 Exit status is 0
index 44856c0..6f44d89 100644 (file)
@@ -1,7 +1,11 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
 test_filesys: 11/2048 files (0.0% non-contiguous), 274/8193 blocks
-Exit status is 0
+Exit status is 1
index 6d44426..d0f47eb 100644 (file)
@@ -1,3 +1,5 @@
+Filesystem did not have a UUID; generating one.
+
 Pass 1: Checking inodes, blocks, and sizes
 Group 0's inode bitmap at 3 conflicts with some other fs block.
 Relocate? yes
diff --git a/tests/f_swapfs/debugfs.cmd b/tests/f_swapfs/debugfs.cmd
new file mode 100644 (file)
index 0000000..df583b2
--- /dev/null
@@ -0,0 +1,5 @@
+ls
+stat sym
+stat double-indirect-test
+cat fluff
+quit
diff --git a/tests/f_swapfs/expect b/tests/f_swapfs/expect
new file mode 100644 (file)
index 0000000..640c314
--- /dev/null
@@ -0,0 +1,133 @@
+Swapfs test
+e2fsck -yf -N test_filesys
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 25/256 files (0.0% non-contiguous), 418/1024 blocks
+Exit status is 0
+e2fsck -Sy -N test_filesys
+Pass 0: Doing byte-swap of filesystem
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 25/256 files (0.0% non-contiguous), 418/1024 blocks
+Exit status is 0
+Running debugfs....
+debugfs: ls
+2 (12) .   2 (12) ..   11 (20) lost+found   12 (16) fluff   
+13 (28) indirect-fluff-test   14 (28) double-indirect-test   15 (20) sym   
+16 (24) long-sym-test   17 (864) dir-test   
+debugfs: stat sym
+Inode: 15   Type: symlink    Mode:  0777   Flags: 0x0   Version: 1
+User:     0   Group:     0   Size: 5
+File ACL: 0    Directory ACL: 0
+Links: 1   Blockcount: 0
+Fragment:  Address: 0    Number: 0    Size: 0
+ctime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+atime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+mtime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+Fast_link_dest: fluff
+debugfs: stat double-indirect-test
+Inode: 14   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
+User:     0   Group:     0   Size: 348960
+File ACL: 0    Directory ACL: 0
+Links: 1   Blockcount: 688
+Fragment:  Address: 0    Number: 0    Size: 0
+ctime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+atime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+mtime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+BLOCKS:
+70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 
+TOTAL: 344
+
+debugfs: cat fluff
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+
+debugfs: quit
+Exit status is 0
+e2fsck -yf -N test_filesys
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 25/256 files (0.0% non-contiguous), 418/1024 blocks
+Exit status is 0
+e2fsck -sy -N test_filesys
+Pass 0: Doing byte-swap of filesystem
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 25/256 files (0.0% non-contiguous), 418/1024 blocks
+Exit status is 0
+Running debugfs....
+debugfs: ls
+2 (12) .   2 (12) ..   11 (20) lost+found   12 (16) fluff   
+13 (28) indirect-fluff-test   14 (28) double-indirect-test   15 (20) sym   
+16 (24) long-sym-test   17 (864) dir-test   
+debugfs: stat sym
+Inode: 15   Type: symlink    Mode:  0777   Flags: 0x0   Version: 1
+User:     0   Group:     0   Size: 5
+File ACL: 0    Directory ACL: 0
+Links: 1   Blockcount: 0
+Fragment:  Address: 0    Number: 0    Size: 0
+ctime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+atime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+mtime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+Fast_link_dest: fluff
+debugfs: stat double-indirect-test
+Inode: 14   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
+User:     0   Group:     0   Size: 348960
+File ACL: 0    Directory ACL: 0
+Links: 1   Blockcount: 688
+Fragment:  Address: 0    Number: 0    Size: 0
+ctime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+atime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+mtime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+BLOCKS:
+70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 
+TOTAL: 344
+
+debugfs: cat fluff
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+yabba dabba doo.  cocka doodle doo.  yabba dabba doo.  cocka doodle doo. yipyip
+
+debugfs: quit
+Exit status is 0
+e2fsck -yf -N test_filesys
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 25/256 files (0.0% non-contiguous), 418/1024 blocks
+Exit status is 0
diff --git a/tests/f_swapfs/image.gz b/tests/f_swapfs/image.gz
new file mode 100644 (file)
index 0000000..ab6f498
Binary files /dev/null and b/tests/f_swapfs/image.gz differ
diff --git a/tests/f_swapfs/name b/tests/f_swapfs/name
new file mode 100644 (file)
index 0000000..b4520ba
--- /dev/null
@@ -0,0 +1 @@
+checking the e2fsck swapfs functionality
diff --git a/tests/f_swapfs/script b/tests/f_swapfs/script
new file mode 100644 (file)
index 0000000..69e51e6
--- /dev/null
@@ -0,0 +1,71 @@
+IMAGE=$test_dir/image.gz
+VERIFY_FSCK_OPT=-yf
+SWAP_FSCK_OPT=-Sy
+NATIVE_FSCK_OPT=-sy
+OUT=$test_name.log
+EXP=$test_dir/expect
+
+gunzip < $IMAGE > $TMPFILE
+
+echo "Swapfs test" > $OUT
+
+echo e2fsck $VERIFY_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $VERIFY_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -e '2d' $OUT.new >> $OUT
+
+echo e2fsck $SWAP_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $SWAP_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -e '2d' $OUT.new >> $OUT
+
+echo Running debugfs.... >> $OUT
+$DEBUGFS -f $test_dir/debugfs.cmd $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+echo e2fsck $VERIFY_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $VERIFY_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -e '2d' $OUT.new >> $OUT
+
+echo e2fsck $NATIVE_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $NATIVE_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -e '2d' $OUT.new >> $OUT
+
+echo Running debugfs.... >> $OUT
+$DEBUGFS -f $test_dir/debugfs.cmd $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+echo e2fsck $VERIFY_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $VERIFY_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -e '2d' $OUT.new >> $OUT
+rm -f $OUT.new
+
+rm $TMPFILE
+
+#
+# Do the verification
+#
+
+rm -f $test_name.ok $test_name.failed
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+       echo "ok"
+       touch $test_name.ok
+else
+       echo "failed"
+       diff -c $EXP $OUT > $test_name.failed
+fi
+
+unset IMAGE VERIFY_FSCK_OPT SWAP_FSCK_OPT NATIVE_FSCK_OPT OUT EXP 
index 4923c66..91277e1 100644 (file)
@@ -68,5 +68,6 @@ if [ "$SKIP_VERIFY" != "true" ] ; then
 fi
 
 if [ "$SKIP_CLEANUP" != "true" ] ; then
-       unset IMAGE FSCK_OPT SECOND_FSCK_OPT OUT1 OUT2 EXP1 EXP2
+       unset IMAGE FSCK_OPT SECOND_FSCK_OPT OUT1 OUT2 EXP1 EXP2 ONE_PASS_ONLY
 fi
+
index 86a5bde..5eb3627 100644 (file)
@@ -3,7 +3,9 @@
 #
 
 FSCK=../e2fsck/e2fsck
+DEBUGFS=../debugfs/debugfs
 LD_LIBRARY_PATH=../lib:../lib/ext2fs:../lib/e2p:../lib/et:../lib/ss
 export LD_LIBRARY_PATH
 TZ=GMT
 export TZ
+unset PAGER
similarity index 83%
rename from tests/test_script
rename to tests/test_script.in
index dc104f4..38a0f45 100644 (file)
@@ -4,9 +4,13 @@
 #
 
 if test "$1"x = x ; then
-SRCDIR=.
+  TESTS=$SRCDIR/[a-zA-Z]_*
 else
-SRCDIR=$1
+  TESTS=
+  for i 
+  do
+    TESTS="$TESTS $SRCDIR/$i"
+  done
 fi
 
 cmd_dir=$SRCDIR
@@ -14,7 +18,7 @@ TMPFILE=./test.img
 
 . $SRCDIR/test_config
 
-for test_dir in $SRCDIR/[a-zA-Z]_*
+for test_dir in $TESTS
 do
        test_name=`echo $test_dir | sed -e 's;.*/;;'`
        if [ -f $test_dir/name ]; then
@@ -36,7 +40,7 @@ do
        fi
 done
 
-num_ok=`ls *.ok | wc -l`
+num_ok=`ls *.ok 2>/dev/null | wc -l`
 num_failed=`ls *.failed 2>/dev/null | wc -l`
 
 echo "$num_ok tests succeeded  $num_failed tests failed"