Whamcloud - gitweb
Many files:
authorTheodore Ts'o <tytso@mit.edu>
Mon, 3 Nov 1997 19:42:40 +0000 (19:42 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 3 Nov 1997 19:42:40 +0000 (19:42 +0000)
  Change ext2fs_read_inode, ext2fs_write_inode to take the e2fsck
  context as their first argument.
  Change dir_info.c routines to take an e2fsck_context, renamed them to
  start with e2fsck_ to avoid namespace issues, and changed them to
  store the directory information inside the e2fsck context.
  Added e2fsck_run() which calls all of the e2fsck passes in the correct
  order, and which handles the return of abort codes.
  Added abort processing, both via setjmp/longjmp and via flags in the
  e2fsck context.
  Use a flag in the e2fsck context instead of the restart_e2fsck global
  variable.
  Change uses of free and malloc to ext2fs_free_mem and ext2fs_get_mem.

17 files changed:
e2fsck/ChangeLog
e2fsck/Makefile.in
e2fsck/Makefile.pq
e2fsck/dirinfo.c
e2fsck/e2fsck.c
e2fsck/e2fsck.h
e2fsck/message.c
e2fsck/pass1.c
e2fsck/pass1b.c
e2fsck/pass2.c
e2fsck/pass3.c
e2fsck/pass4.c
e2fsck/pass5.c
e2fsck/super.c
e2fsck/swapfs.c
e2fsck/unix.c
e2fsck/util.c

index aaa3ec4..083d7ac 100644 (file)
@@ -1,3 +1,19 @@
+Mon Nov  3 14:35:29 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * [lots of files]:  Change ext2fs_read_inode, ext2fs_write_inode
+               to take the e2fsck context as their first argument.
+               Change dir_info.c routines to take an e2fsck_context,
+               renamed them to start with e2fsck_ to avoid namespace
+               issues, and changed them to store the directory
+               information inside the e2fsck context.
+               Added e2fsck_run() which calls all of the e2fsck passes in
+               the correct order, and which handles the return of abort
+               codes.  Added abort processing, both via setjmp/longjmp
+               and via flags in the e2fsck context.  Use a flag in the
+               e2fsck context instead of the restart_e2fsck global
+               variable.   Change uses of free and malloc to
+               ext2fs_free_mem and ext2fs_get_mem.
+       
 Fri Oct 31 01:12:43 1997  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * pass1.c, pass3.c: Rename new error codes to _ET_ in them for
index 40595e6..82acdb9 100644 (file)
@@ -151,35 +151,39 @@ distclean: clean
 # the Makefile.in file
 #
 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 \
+ $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
+super.o: $(srcdir)/super.c $(top_srcdir)/lib/uuid/uuid.h $(srcdir)/e2fsck.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.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 \
+pass1.o: $(srcdir)/pass1.c $(srcdir)/e2fsck.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.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/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.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/ext2_io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
- $(srcdir)/problem.h
-pass3.o: $(srcdir)/pass3.c $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+pass2.o: $(srcdir)/pass2.c $(srcdir)/e2fsck.h  \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
+pass3.o: $(srcdir)/pass3.c $(srcdir)/e2fsck.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.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/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
-pass5.o: $(srcdir)/pass5.c $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+pass5.o: $(srcdir)/pass5.c $(srcdir)/e2fsck.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(top_srcdir)/lib/ext2fs/bitops.h
+ $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.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/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
@@ -187,7 +191,12 @@ badblocks.o: $(srcdir)/badblocks.c $(top_srcdir)/lib/et/com_err.h \
 util.o: $(srcdir)/util.c $(srcdir)/e2fsck.h \
  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(top_srcdir)/lib/ext2fs/bitops.h 
+ $(top_srcdir)/lib/ext2fs/bitops.h  
+unix.o: $(srcdir)/unix.c $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h \
+ $(srcdir)/../version.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/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
@@ -195,9 +204,8 @@ dirinfo.o: $(srcdir)/dirinfo.c $(top_srcdir)/lib/et/com_err.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/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(top_srcdir)/lib/ext2fs/bitops.h 
+ $(top_srcdir)/lib/ext2fs/bitops.h  
 problem.o: $(srcdir)/problem.c $(srcdir)/e2fsck.h \
  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
-
index a5e5b49..6388e6c 100644 (file)
@@ -2,8 +2,8 @@ TOPSRC=..
 LIBNAME=E2FSCK.LIB
 OBJFILE=E2FSCK.LST
 
-OBJS= super.obj pass1.obj pass1b.obj pass2.obj pass3.obj pass4.obj \
-       pass5.obj
+OBJS= e2fsck.obj super.obj pass1.obj pass2.obj pass3.obj \
+       pass4.obj pass5.obj
 
 !include $(TOPSRC)\powerquest\MCONFIG
 
index 5218234..8d37544 100644 (file)
@@ -8,12 +8,9 @@
 #include <et/com_err.h>
 #include "e2fsck.h"
 
-static int             dir_info_count = 0;
-static int             dir_info_size = 0;
-static struct dir_info *dir_info = 0;
-
-int get_num_dirs(ext2_filsys fs)
+int e2fsck_get_num_dirs(e2fsck_t ctx)
 {
+       ext2_filsys fs = ctx->fs;
        int     i, num_dirs;
 
        num_dirs = 0;
@@ -28,27 +25,33 @@ int get_num_dirs(ext2_filsys fs)
  * entry.  During pass1, the passed-in parent is 0; it will get filled
  * in during pass2.  
  */
-void add_dir_info(ext2_filsys fs, ino_t ino, ino_t parent)
+void e2fsck_add_dir_info(e2fsck_t ctx, ino_t ino, ino_t parent)
 {
        struct dir_info *dir;
-       int     i, j;
+       int             i, j;
+       errcode_t       retval;
 
 #if 0
        printf("add_dir_info for inode %lu...\n", ino);
 #endif
-       if (!dir_info) {
-               dir_info_count = 0;
-               dir_info_size = get_num_dirs(fs) + 10;
+       if (!ctx->dir_info) {
+               ctx->dir_info_count = 0;
+               ctx->dir_info_size = e2fsck_get_num_dirs(ctx) + 10;
 
-               dir_info  = allocate_memory(dir_info_size *
-                                          sizeof (struct dir_info),
-                                          "directory map");
+               ctx->dir_info  = allocate_memory(ctx->dir_info_size *
+                                                sizeof (struct dir_info),
+                                                "directory map");
        }
        
-       if (dir_info_count >= dir_info_size) {
-               dir_info_size += 10;
-               dir_info = realloc(dir_info,
-                                 dir_info_size * sizeof(struct dir_info));
+       if (ctx->dir_info_count >= ctx->dir_info_size) {
+               ctx->dir_info_size += 10;
+               retval = ext2fs_resize_mem(ctx->dir_info_size *
+                                          sizeof(struct dir_info),
+                                          (void **) &ctx->dir_info);
+               if (retval) {
+                       ctx->dir_info_size -= 10;
+                       return;
+               }
        }
 
        /*
@@ -60,16 +63,17 @@ void add_dir_info(ext2_filsys fs, ino_t ino, ino_t parent)
         * the dir_info array needs to be sorted by inode number for
         * get_dir_info()'s sake.
         */
-       if (dir_info_count && dir_info[dir_info_count-1].ino >= ino) {
-               for (i = dir_info_count-1; i > 0; i--)
-                       if (dir_info[i-1].ino < ino)
+       if (ctx->dir_info_count &&
+           ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
+               for (i = ctx->dir_info_count-1; i > 0; i--)
+                       if (ctx->dir_info[i-1].ino < ino)
                                break;
-               dir = &dir_info[i];
+               dir = &ctx->dir_info[i];
                if (dir->ino != ino) 
-                       for (j = dir_info_count++; j > i; j--)
-                               dir_info[j] = dir_info[j-1];
+                       for (j = ctx->dir_info_count++; j > i; j--)
+                               ctx->dir_info[j] = ctx->dir_info[j-1];
        } else
-               dir = &dir_info[dir_info_count++];
+               dir = &ctx->dir_info[ctx->dir_info_count++];
        
        dir->ino = ino;
        dir->dotdot = parent;
@@ -80,26 +84,26 @@ void add_dir_info(ext2_filsys fs, ino_t ino, ino_t parent)
  * get_dir_info() --- given an inode number, try to find the directory
  * information entry for it.
  */
-struct dir_info *get_dir_info(ino_t ino)
+struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ino_t ino)
 {
        int     low, high, mid;
 
        low = 0;
-       high = dir_info_count-1;
-       if (!dir_info)
+       high = ctx->dir_info_count-1;
+       if (!ctx->dir_info)
                return 0;
-       if (ino == dir_info[low].ino)
-               return &dir_info[low];
-       if  (ino == dir_info[high].ino)
-               return &dir_info[high];
+       if (ino == ctx->dir_info[low].ino)
+               return &ctx->dir_info[low];
+       if  (ino == ctx->dir_info[high].ino)
+               return &ctx->dir_info[high];
 
        while (low < high) {
                mid = (low+high)/2;
                if (mid == low || mid == high)
                        break;
-               if (ino == dir_info[mid].ino)
-                       return &dir_info[mid];
-               if (ino < dir_info[mid].ino)
+               if (ino == ctx->dir_info[mid].ino)
+                       return &ctx->dir_info[mid];
+               if (ino < ctx->dir_info[mid].ino)
                        high = mid;
                else
                        low = mid;
@@ -110,23 +114,23 @@ struct dir_info *get_dir_info(ino_t ino)
 /*
  * Free the dir_info structure when it isn't needed any more.
  */
-void free_dir_info(ext2_filsys fs)
+void e2fsck_free_dir_info(e2fsck_t ctx)
 {
-       if (dir_info) {
-               free(dir_info);
-               dir_info = 0;
+       if (ctx->dir_info) {
+               ext2fs_free_mem((void **) &ctx->dir_info);
+               ctx->dir_info = 0;
        }
-       dir_info_size = 0;
-       dir_info_count = 0;
+       ctx->dir_info_size = 0;
+       ctx->dir_info_count = 0;
 }
 
 /*
  * A simple interator function
  */
-struct dir_info *dir_info_iter(int *control)
+struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
 {
-       if (*control >= dir_info_count)
+       if (*control >= ctx->dir_info_count)
                return 0;
 
-       return(dir_info + (*control)++);
+       return(ctx->dir_info + (*control)++);
 }
index 592541b..c80036e 100644 (file)
 errcode_t e2fsck_allocate_context(e2fsck_t *ret)
 {
        e2fsck_t        context;
+       errcode_t       retval;
 
-       context = malloc(sizeof(struct e2fsck_struct));
-       if (!context)
-               return ENOMEM;
-
+       retval = ext2fs_get_mem(sizeof(struct e2fsck_struct),
+                               (void **) &context);
+       if (retval)
+               return retval;
+       
        memset(context, 0, sizeof(struct e2fsck_struct));
 
        context->process_inode_size = 256;
@@ -41,6 +43,7 @@ errcode_t e2fsck_allocate_context(e2fsck_t *ret)
  */
 errcode_t e2fsck_reset_context(e2fsck_t ctx)
 {
+       ctx->flags = 0;
        if (ctx->inode_used_map) {
                ext2fs_free_inode_bitmap(ctx->inode_used_map);
                ctx->inode_used_map = 0;
@@ -61,7 +64,7 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx)
                ext2fs_free_dblist(ctx->fs->dblist);
                ctx->fs->dblist = 0;
        }
-       free_dir_info(ctx->fs);
+       e2fsck_free_dir_info(ctx);
        if (ctx->block_dup_map) {
                ext2fs_free_block_bitmap(ctx->block_dup_map);
                ctx->block_dup_map = 0;
@@ -79,15 +82,15 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx)
         * Clear the array of invalid meta-data flags
         */
        if (ctx->invalid_inode_bitmap_flag) {
-               free(ctx->invalid_inode_bitmap_flag);
+               ext2fs_free_mem((void **) &ctx->invalid_inode_bitmap_flag);
                ctx->invalid_inode_bitmap_flag = 0;
        }
        if (ctx->invalid_block_bitmap_flag) {
-               free(ctx->invalid_block_bitmap_flag);
+               ext2fs_free_mem((void **) &ctx->invalid_block_bitmap_flag);
                ctx->invalid_block_bitmap_flag = 0;
        }
        if (ctx->invalid_inode_table_flag) {
-               free(ctx->invalid_inode_table_flag);
+               ext2fs_free_mem((void **) &ctx->invalid_inode_table_flag);
                ctx->invalid_inode_table_flag = 0;
        }
 
@@ -121,5 +124,44 @@ void e2fsck_free_context(e2fsck_t ctx)
        
        e2fsck_reset_context(ctx);
        
-       free(ctx);
+       ext2fs_free_mem((void **) &ctx);
 }
+
+/*
+ * This function runs through the e2fsck passes and calls them all,
+ * returning restart, abort, or cancel as necessary...
+ */
+typedef void (*pass_t)(e2fsck_t ctx);
+
+pass_t e2fsck_passes[] = {
+       e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
+       e2fsck_pass5, 0 };
+
+int e2fsck_run(e2fsck_t ctx)
+{
+       int     i;
+       pass_t  e2fsck_pass;
+
+#ifdef HAVE_SETJMP_H
+       if (setjmp(ctx->abort_loc))
+               return (ctx->flags & E2F_FLAG_SIGNAL_MASK);
+       ctx->flags |= E2F_FLAG_SETJMP_OK;
+#endif
+               
+       for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
+               if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
+                       break;
+               e2fsck_pass(ctx);
+       }
+       ctx->flags &= ~E2F_FLAG_SETJMP_OK;
+       
+       if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
+               return (ctx->flags & E2F_FLAG_SIGNAL_MASK);
+       return 0;
+}
+
+
+       
+
+       
+
index 83c5d61..a497fb2 100644 (file)
@@ -16,6 +16,9 @@
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
 
 #ifdef HAVE_LINUX_FS_H
 #include <linux/fs.h>
 
 #include "ext2fs/ext2fs.h"
 
-#ifdef __STDC__
+/* Everything is STDC, these days */
 #define NOARGS void
-#else
-#define NOARGS
-#define const
-#endif
 
 /*
  * Exit codes used by fsck-type programs
@@ -85,17 +84,47 @@ struct resource_track {
 #define E2F_OPT_DEBUG          0x0080
 
 /*
+ * E2fsck flags
+ */
+#define E2F_FLAG_ABORT         0x0001 /* Abort signaled */
+#define E2F_FLAG_CANCEL                0x0002 /* Cancel signaled */
+#define E2F_FLAG_RESTART       0x0004 /* Restart signaled */
+#define E2F_FLAG_SIGNAL_MASK   0x000F
+
+#define E2F_FLAG_SETJMP_OK     0x0010 /* Setjmp valid for abort */
+
+/*
+ * Defines for indicating the e2fsck pass number
+ */
+#define E2F_PASS_1     1
+#define E2F_PASS_2     2
+#define E2F_PASS_3     3
+#define E2F_PASS_4     4
+#define E2F_PASS_5     5
+#define E2F_PASS_1B    6
+
+/*
  * This is the global e2fsck structure.
  */
+typedef struct e2fsck_struct *e2fsck_t;
+
 struct e2fsck_struct {
        ext2_filsys fs;
        const char *program_name;
        const char *filesystem_name;
        const char *device_name;
+       int     flags;          /* E2fsck internal flags */
        int     options;
        blk_t   use_superblock; /* sb requested by user */
        blk_t   superblock;     /* sb used to open fs */
 
+#ifdef HAVE_SETJMP_H
+       jmp_buf abort_loc;
+#endif
+
+       void (*progress)(e2fsck_t ctx, int pass, unsigned long cur,
+                        unsigned long max);
+
        ext2fs_inode_bitmap inode_used_map; /* Inodes which are in use */
        ext2fs_inode_bitmap inode_bad_map; /* Inodes which are bad somehow */
        ext2fs_inode_bitmap inode_dir_map; /* Inodes which are directories */
@@ -121,12 +150,24 @@ struct e2fsck_struct {
        int invalid_bitmaps;    /* There are invalid bitmaps/itable */
 
        /*
+        * Block buffer
+        */
+       char *block_buf;
+
+       /*
         * For pass1_check_directory and pass1_get_blocks
         */
        ino_t stashed_ino;
        struct ext2_inode *stashed_inode;
 
        /*
+        * Directory information
+        */
+       int             dir_info_count;
+       int             dir_info_size;
+       struct dir_info *dir_info;
+
+       /*
         * Tuning parameters
         */
        int process_inode_size;
@@ -157,28 +198,24 @@ struct e2fsck_struct {
        int fs_fragmented;
 };
 
-typedef struct e2fsck_struct *e2fsck_t;
-
-/*
- * Variables
- */
-extern int restart_e2fsck;
 
 /*
  * Procedure declarations
  */
 
-extern void pass1(e2fsck_t ctx);
-extern void pass1_dupblocks(e2fsck_t ctx, char *block_buf);
-extern void pass2(e2fsck_t ctx);
-extern void pass3(e2fsck_t ctx);
-extern void pass4(e2fsck_t ctx);
-extern void pass5(e2fsck_t ctx);
+extern void e2fsck_pass1(e2fsck_t ctx);
+extern void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
+extern void e2fsck_pass2(e2fsck_t ctx);
+extern void e2fsck_pass3(e2fsck_t ctx);
+extern void e2fsck_pass4(e2fsck_t ctx);
+extern void e2fsck_pass5(e2fsck_t ctx);
 
 /* e2fsck.c */
-errcode_t e2fsck_allocate_context(e2fsck_t *ret);
-errcode_t e2fsck_reset_context(e2fsck_t ctx);
-void e2fsck_free_context(e2fsck_t ctx);
+extern errcode_t e2fsck_allocate_context(e2fsck_t *ret);
+extern errcode_t e2fsck_reset_context(e2fsck_t ctx);
+extern void e2fsck_free_context(e2fsck_t ctx);
+extern int e2fsck_run(e2fsck_t ctx);
+
 
 /* pass1.c */
 extern errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino);
@@ -195,11 +232,11 @@ extern void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
 extern void test_disk(e2fsck_t ctx);
 
 /* dirinfo.c */
-extern void add_dir_info(ext2_filsys fs, ino_t ino, ino_t parent);
-extern struct dir_info *get_dir_info(ino_t ino);
-extern void free_dir_info(ext2_filsys fs);
-extern int get_num_dirs(ext2_filsys fs);
-extern struct dir_info *dir_info_iter(int *control);
+extern void e2fsck_add_dir_info(e2fsck_t ctx, ino_t ino, ino_t parent);
+extern struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ino_t ino);
+extern void e2fsck_free_dir_info(e2fsck_t ctx);
+extern int e2fsck_get_num_dirs(e2fsck_t ctx);
+extern struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control);
 
 /* ehandler.c */
 extern const char *ehandler_operation(const char *op);
@@ -225,18 +262,16 @@ extern void print_resource_track(const char *desc,
 extern void init_resource_track(struct resource_track *track);
 #endif
 extern int inode_has_valid_blocks(struct ext2_inode *inode);
-extern void e2fsck_read_inode(ext2_filsys fs, unsigned long ino,
+extern void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
                              struct ext2_inode * inode, const char * proc);
-extern void e2fsck_write_inode(ext2_filsys fs, unsigned long ino,
+extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
                               struct ext2_inode * inode, const char * proc);
 #ifdef MTRACE
 extern void mtrace_print(char *mesg);
 #endif
 extern blk_t get_backup_sb(ext2_filsys fs);
 
-#define die(str)       fatal_error(str)
-
 /*
  * pass3.c
  */
-extern int reconnect_file(e2fsck_t ctx, ino_t inode);
+extern int e2fsck_reconnect_file(e2fsck_t ctx, ino_t inode);
index 673c463..e7bdd51 100644 (file)
@@ -147,7 +147,7 @@ static void print_pathname(ext2_filsys fs, ino_t dir, ino_t ino)
                fputs("???", stdout);
        else {
                fputs(path, stdout);
-               free(path);
+               ext2fs_free_mem((void **) &path);
        }
 }
 
index 6a2681a..ea443b8 100644 (file)
@@ -96,7 +96,8 @@ static int process_inode_count;
  */
 static void unwind_pass1(ext2_filsys fs)
 {
-       free(inodes_to_process);inodes_to_process = 0;
+       ext2fs_free_mem((void **) &inodes_to_process);
+       inodes_to_process = 0;
 }
 
 /*
@@ -113,7 +114,7 @@ int e2fsck_pass1_check_device_inode(struct ext2_inode *inode)
        return 1;
 }
 
-void pass1(e2fsck_t ctx)
+void e2fsck_pass1(e2fsck_t ctx)
 {
        ext2_filsys fs = ctx->fs;
        ino_t   ino;
@@ -146,34 +147,39 @@ void pass1(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.num = 1;
                fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        pctx.errcode = ext2fs_allocate_inode_bitmap(fs, "directory inode map",
                                              &ctx->inode_dir_map);
        if (pctx.errcode) {
                pctx.num = 2;
                fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        pctx.errcode = ext2fs_allocate_block_bitmap(fs, "in-use block map",
                                              &ctx->block_found_map);
        if (pctx.errcode) {
                pctx.num = 1;
                fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        pctx.errcode = ext2fs_allocate_block_bitmap(fs, "illegal block map",
                                              &ctx->block_illegal_map);
        if (pctx.errcode) {
                pctx.num = 2;
                fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
                                             &ctx->inode_link_info);
        if (pctx.errcode) {
                fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        inodes_to_process = allocate_memory(ctx->process_inode_size *
                                            sizeof(struct process_inode_block),
@@ -183,7 +189,8 @@ void pass1(e2fsck_t ctx)
        pctx.errcode = ext2fs_init_dblist(fs, 0);
        if (pctx.errcode) {
                fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
 
        mark_table_blocks(ctx);
@@ -197,13 +204,15 @@ void pass1(e2fsck_t ctx)
                                              &scan);
        if (pctx.errcode) {
                fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
        pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
        if (pctx.errcode) {
                fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        ctx->stashed_inode = &inode;
        ext2fs_set_inode_callback(scan, scan_callback, block_buf);
@@ -217,7 +226,8 @@ void pass1(e2fsck_t ctx)
                        if (pctx.errcode) {
                                pctx.num = inode.i_links_count;
                                fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
-                               fatal_error(0);
+                               ctx->flags |= E2F_FLAG_ABORT;
+                               return;
                        }
                }
                if (ino == EXT2_BAD_INO) {
@@ -235,7 +245,8 @@ void pass1(e2fsck_t ctx)
                                     block_buf, process_bad_block, &pb);
                        if (pctx.errcode) {
                                fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
-                               fatal_error(0);
+                               ctx->flags |= E2F_FLAG_ABORT;
+                               return;
                        }
                        ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
                        clear_problem_context(&pctx);
@@ -253,7 +264,7 @@ void pass1(e2fsck_t ctx)
                                        inode.i_links_count = 0;
                                        ext2fs_icount_store(ctx->inode_link_info,
                                                            ino, 0);
-                                       e2fsck_write_inode(fs, ino, &inode,
+                                       e2fsck_write_inode(ctx, ino, &inode,
                                                           "pass1");
                                }
                        }
@@ -269,7 +280,7 @@ void pass1(e2fsck_t ctx)
                        if (inode.i_dtime && inode.i_links_count) {
                                if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
                                        inode.i_dtime = 0;
-                                       e2fsck_write_inode(fs, ino, &inode,
+                                       e2fsck_write_inode(ctx, ino, &inode,
                                                           "pass1");
                                }
                        }
@@ -286,7 +297,7 @@ void pass1(e2fsck_t ctx)
                                if (fix_problem(ctx,
                                            PR_1_RESERVED_BAD_MODE, &pctx)) {
                                        inode.i_mode = 0;
-                                       e2fsck_write_inode(fs, ino, &inode,
+                                       e2fsck_write_inode(ctx, ino, &inode,
                                                           "pass1");
                                }
                        }
@@ -302,7 +313,7 @@ void pass1(e2fsck_t ctx)
                                if (fix_problem(ctx,
                                            PR_1_ZERO_DTIME, &pctx)) {
                                        inode.i_dtime = time(0);
-                                       e2fsck_write_inode(fs, ino, &inode,
+                                       e2fsck_write_inode(ctx, ino, &inode,
                                                           "pass1");
                                }
                        }
@@ -321,7 +332,7 @@ void pass1(e2fsck_t ctx)
                if (inode.i_dtime) {
                        if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
                                inode.i_dtime = 0;
-                               e2fsck_write_inode(fs, ino, &inode, "pass1");
+                               e2fsck_write_inode(ctx, ino, &inode, "pass1");
                        }
                }
                
@@ -352,7 +363,7 @@ void pass1(e2fsck_t ctx)
                
                if (LINUX_S_ISDIR(inode.i_mode)) {
                        ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
-                       add_dir_info(fs, ino, 0);
+                       e2fsck_add_dir_info(ctx, ino, 0);
                        ctx->fs_directory_count++;
                } else if (LINUX_S_ISREG (inode.i_mode))
                        ctx->fs_regular_count++;
@@ -393,8 +404,15 @@ void pass1(e2fsck_t ctx)
                } else
                        check_blocks(ctx, &pctx, block_buf);
 
-               if (process_inode_count >= ctx->process_inode_size)
+               if (ctx->flags & E2F_FLAG_ABORT)
+                       return;
+
+               if (process_inode_count >= ctx->process_inode_size) {
                        process_inodes(ctx, block_buf);
+
+                       if (ctx->flags & E2F_FLAG_ABORT)
+                               return;
+               }
        next:
                pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
                if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
@@ -406,7 +424,8 @@ void pass1(e2fsck_t ctx)
                }
                if (pctx.errcode) {
                        fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
-                       fatal_error(0);
+                       ctx->flags |= E2F_FLAG_ABORT;
+                       return;
                }
        }
        process_inodes(ctx, block_buf);
@@ -416,7 +435,7 @@ void pass1(e2fsck_t ctx)
        if (ctx->invalid_bitmaps)
                handle_fs_bad_blocks(ctx);
 
-       if (restart_e2fsck) {
+       if (ctx->flags & E2F_FLAG_RESTART) {
                unwind_pass1(fs);
                goto endit;
        }
@@ -426,16 +445,16 @@ void pass1(e2fsck_t ctx)
                        clear_problem_context(&pctx);
                        fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
                }
-               pass1_dupblocks(ctx, block_buf);
+               e2fsck_pass1_dupblocks(ctx, block_buf);
        }
-       free(inodes_to_process);
+       ext2fs_free_mem((void **) &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_mem((void **) &block_buf);
        ext2fs_free_block_bitmap(ctx->block_illegal_map);
        ctx->block_illegal_map = 0;
 
@@ -487,6 +506,9 @@ static void process_inodes(e2fsck_t ctx, char *block_buf)
                sprintf(buf, "reading indirect blocks of inode %lu", pctx.ino);
                ehandler_operation(buf);
                check_blocks(ctx, &pctx, block_buf);
+
+               if (ctx->flags & E2F_FLAG_ABORT)
+                       return;
        }
        ctx->stashed_inode = old_stashed_inode;
        ctx->stashed_ino = old_stashed_ino;
@@ -522,7 +544,9 @@ static void alloc_bad_map(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.num = 3;
                fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
-               fatal_error(0);
+               /* Should never get here */
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
 }
 
@@ -540,7 +564,9 @@ static void alloc_bb_map(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.num = 4;
                fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
-               fatal_error(0);
+               /* Should never get here */
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
 }
 
@@ -566,7 +592,9 @@ static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
                                pctx.num = 3;
                                fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, 
                                            &pctx);
-                               fatal_error(0);
+                               /* Should never get here */
+                               ctx->flags |= E2F_FLAG_ABORT;
+                               return;
                        }
                }
                ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
@@ -604,6 +632,8 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
        pctx->errcode = ext2fs_block_iterate2(fs, ino,
                                       pb.is_dir ? BLOCK_FLAG_HOLE : 0,
                                       block_buf, process_block, &pb);
+       if (ctx->flags & E2F_FLAG_ABORT)
+               return;
        end_problem_latch(ctx, PR_LATCH_BLOCK);
        if (pctx->errcode)
                fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
@@ -612,11 +642,11 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                ctx->fs_fragmented++;
 
        if (pb.clear) {
-               e2fsck_read_inode(fs, ino, inode, "check_blocks");
+               e2fsck_read_inode(ctx, ino, inode, "check_blocks");
                inode->i_links_count = 0;
                ext2fs_icount_store(ctx->inode_link_info, ino, 0);
                inode->i_dtime = time(0);
-               e2fsck_write_inode(fs, ino, inode, "check_blocks");
+               e2fsck_write_inode(ctx, ino, inode, "check_blocks");
                ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
                ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
                /*
@@ -624,7 +654,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                 * before processing was aborted, so we need to
                 * restart the pass 1 scan.
                 */
-               restart_e2fsck++;
+               ctx->flags |= E2F_FLAG_RESTART;
                return;
        }
 
@@ -639,7 +669,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                        inode->i_links_count = 0;
                        ext2fs_icount_store(ctx->inode_link_info, ino, 0);
                        inode->i_dtime = time(0);
-                       e2fsck_write_inode(fs, ino, inode, "check_blocks");
+                       e2fsck_write_inode(ctx, ino, inode, "check_blocks");
                        ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
                        ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
                        ctx->fs_directory_count--;
@@ -652,7 +682,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                pctx->num = (pb.last_block+1) * fs->blocksize;
                if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
                        inode->i_size = pctx->num;
-                       e2fsck_write_inode(fs, ino, inode, "check_blocks");
+                       e2fsck_write_inode(ctx, ino, inode, "check_blocks");
                }
                pctx->num = 0;
        }
@@ -660,7 +690,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                pctx->num = pb.num_blocks;
                if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
                        inode->i_blocks = pb.num_blocks;
-                       e2fsck_write_inode(fs, ino, inode, "check_blocks");
+                       e2fsck_write_inode(ctx, ino, inode, "check_blocks");
                }
                pctx->num = 0;
        }
@@ -826,7 +856,9 @@ mark_dir:
                        pctx->blk = blk;
                        pctx->num = blockcnt;
                        fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
-                       fatal_error(0);
+                       /* Should never get here */
+                       ctx->flags |= E2F_FLAG_ABORT;
+                       return BLOCK_ABORT;
                }
        }
        return ret_code;
@@ -841,7 +873,7 @@ static void bad_block_indirect(e2fsck_t ctx, blk_t blk)
         * Prompt to see if we should continue or not.
         */
        if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, &pctx))
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
 }
 
 int process_bad_block(ext2_filsys fs,
@@ -878,9 +910,11 @@ int process_bad_block(ext2_filsys fs,
        }
 
        if (blockcnt < 0) {
-               if (ext2fs_test_block_bitmap(ctx->block_found_map, blk))
+               if (ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
                        bad_block_indirect(ctx, blk);
-               else
+                       if (ctx->flags & E2F_FLAG_ABORT)
+                               return BLOCK_ABORT;
+               } else
                        mark_block_used(ctx, blk);
                return 0;
        }
@@ -966,6 +1000,8 @@ int process_bad_block(ext2_filsys fs,
        if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
            p->inode->i_block[EXT2_DIND_BLOCK]) {
                bad_block_indirect(ctx, blk);
+               if (ctx->flags & E2F_FLAG_ABORT)
+                       return BLOCK_ABORT;
                return 0;
        }
 
@@ -1001,8 +1037,8 @@ static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
                ext2fs_unmark_valid(fs);
                return;
        }
-       buf = malloc(fs->blocksize);
-       if (!buf) {
+       pctx.errcode = ext2fs_get_mem(fs->blocksize, (void **) &buf);
+       if (pctx.errcode) {
                fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
                ext2fs_unmark_valid(fs);
                return;
@@ -1029,7 +1065,7 @@ static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
                if (pctx.errcode)
                        fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
        }
-       free(buf);
+       ext2fs_free_mem((void **) &buf);
 }
 
 /*
@@ -1058,7 +1094,7 @@ static void handle_fs_bad_blocks(e2fsck_t ctx)
                        new_table_block(ctx, first_block, i, "inode table",
                                        fs->inode_blocks_per_group, 
                                        &fs->group_desc[i].bg_inode_table);
-                       restart_e2fsck++;
+                       ctx->flags |= E2F_FLAG_RESTART;
                }
                first_block += fs->super->s_blocks_per_group;
        }
index e965217..1aa586b 100644 (file)
@@ -105,7 +105,7 @@ static ext2fs_inode_bitmap inode_dup_map;
 /*
  * Main procedure for handling duplicate blocks
  */
-void pass1_dupblocks(e2fsck_t ctx, char *block_buf)
+void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
 {
        ext2_filsys             fs = ctx->fs;
        struct dup_block        *p, *q, *next_p, *next_q;
@@ -135,12 +135,12 @@ void pass1_dupblocks(e2fsck_t ctx, char *block_buf)
                next_p = p->next_block;
                for (q = p; q; q = next_q) {
                        next_q = q->next_inode;
-                       free(q);
+                       ext2fs_free_mem((void **) &q);
                }
        }
        for (r = dup_ino; r; r = next_r) {
                next_r = r->next;
-               free(r);
+               ext2fs_free_mem((void **) &r);
        }
 }
 
@@ -154,7 +154,7 @@ struct process_block_struct {
        struct problem_context *pctx;
 };
 
-void pass1b(e2fsck_t ctx, char *block_buf)
+static void pass1b(e2fsck_t ctx, char *block_buf)
 {
        ext2_filsys fs = ctx->fs;
        ino_t   ino;
@@ -322,7 +322,7 @@ static int search_dirent_proc(ino_t dir, int entry,
 }
 
 
-void pass1c(e2fsck_t ctx, char *block_buf)
+static void pass1c(e2fsck_t ctx, char *block_buf)
 {
        ext2_filsys fs = ctx->fs;
        struct dup_inode        *p;
@@ -468,7 +468,7 @@ static void pass1d(e2fsck_t ctx, char *block_buf)
                else
                        ext2fs_unmark_valid(fs);
        }
-       free(shared);
+       ext2fs_free_mem((void **) &shared);
 }
 
 static int delete_file_block(ext2_filsys fs,
@@ -530,10 +530,10 @@ static void delete_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
        ext2fs_unmark_inode_bitmap(fs->inode_map, dp->ino);
        ext2fs_mark_ib_dirty(fs);
        ext2fs_mark_bb_dirty(fs);
-       e2fsck_read_inode(fs, dp->ino, &inode, "delete_file");
+       e2fsck_read_inode(ctx, dp->ino, &inode, "delete_file");
        inode.i_links_count = 0;
        inode.i_dtime = time(0);
-       e2fsck_write_inode(fs, dp->ino, &inode, "delete_file");
+       e2fsck_write_inode(ctx, dp->ino, &inode, "delete_file");
 }
 
 struct clone_struct {
@@ -616,9 +616,9 @@ static int clone_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
        cs.errcode = 0;
        cs.dir = 0;
        cs.ctx = ctx;
-       cs.buf = malloc(fs->blocksize);
-       if (!cs.buf)
-               return ENOMEM;
+       retval = ext2fs_get_mem(fs->blocksize, (void **) &cs.buf);
+       if (retval)
+               return retval;
 
        if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dp->ino))
                cs.dir = dp->ino;
@@ -626,7 +626,7 @@ static int clone_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
        retval = ext2fs_block_iterate(fs, dp->ino, 0, block_buf,
                                      clone_file_block, &cs);
        ext2fs_mark_bb_dirty(fs);
-       free(cs.buf);
+       ext2fs_free_mem((void **) &cs.buf);
        if (retval) {
                com_err("clone_file", retval,
                        "while calling ext2fs_block_iterate for inode %d",
index edb2482..4facc60 100644 (file)
@@ -66,7 +66,7 @@ struct check_dir_struct {
        e2fsck_t ctx;
 };     
 
-void pass2(e2fsck_t ctx)
+void e2fsck_pass2(e2fsck_t ctx)
 {
        ext2_filsys     fs = ctx->fs;
        char    *buf;
@@ -94,7 +94,8 @@ void pass2(e2fsck_t ctx)
                                                &ctx->inode_count);
        if (cd.pctx.errcode) {
                fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        buf = allocate_memory(fs->blocksize, "directory scan buffer");
 
@@ -103,7 +104,7 @@ void pass2(e2fsck_t ctx)
         * present.  (If the root directory is not present, we will
         * create it in pass 3.)
         */
-       dir = get_dir_info(EXT2_ROOT_INO);
+       dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
        if (dir)
                dir->parent = EXT2_ROOT_INO;
 
@@ -112,12 +113,15 @@ void pass2(e2fsck_t ctx)
        
        cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
                                                &cd);
+       if (ctx->flags & E2F_FLAG_ABORT)
+               return;
        if (cd.pctx.errcode) {
                fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        
-       free(buf);
+       ext2fs_free_mem((void **) &buf);
        ext2fs_free_dblist(fs->dblist);
 
        if (ctx->inode_bad_map) {
@@ -309,8 +313,10 @@ static int check_dir_block(ext2_filsys fs,
        
        cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
        if (cd->pctx.errcode) {
-               if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx))
-                       fatal_error(0);
+               if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
+                       ctx->flags |= E2F_FLAG_ABORT;
+                       return DIRENT_ABORT;
+               }
                memset(buf, 0, fs->blocksize);
        }
 
@@ -343,10 +349,11 @@ static int check_dir_block(ext2_filsys fs,
                        if (check_dot(ctx, dirent, ino, &cd->pctx))
                                dir_modified++;
                } else if (dot_state == 2) {
-                       dir = get_dir_info(ino);
+                       dir = e2fsck_get_dir_info(ctx, ino);
                        if (!dir) {
                                fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
-                               fatal_error(0);
+                               ctx->flags |= E2F_FLAG_ABORT;
+                               return DIRENT_ABORT;
                        }
                        if (check_dotdot(ctx, dirent, dir, &cd->pctx))
                                dir_modified++;
@@ -438,6 +445,8 @@ static int check_dir_block(ext2_filsys fs,
                                dir_modified++;
                                goto next;
                        }
+                       if (ctx->flags & E2F_FLAG_ABORT)
+                               return DIRENT_ABORT;
                }
 
                if (check_name(ctx, dirent, ino, &cd->pctx))
@@ -453,11 +462,12 @@ static int check_dir_block(ext2_filsys fs,
                if ((dot_state > 2) &&
                    (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
                                              dirent->inode))) {
-                       subdir = get_dir_info(dirent->inode);
+                       subdir = e2fsck_get_dir_info(ctx, dirent->inode);
                        if (!subdir) {
                                cd->pctx.ino = dirent->inode;
                                fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
-                               fatal_error(0);
+                               ctx->flags |= E2F_FLAG_ABORT;
+                               return DIRENT_ABORT;
                        }
                        if (subdir->parent) {
                                cd->pctx.ino2 = subdir->parent;
@@ -493,8 +503,11 @@ static int check_dir_block(ext2_filsys fs,
        if (dir_modified) {
                cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
                if (cd->pctx.errcode) {
-                       if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK, &cd->pctx))
-                               fatal_error(0);
+                       if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
+                                        &cd->pctx)) {
+                               ctx->flags |= E2F_FLAG_ABORT;
+                               return DIRENT_ABORT;
+                       }
                }
                ext2fs_mark_changed(fs);
        }
@@ -530,10 +543,10 @@ static void deallocate_inode(e2fsck_t ctx, ino_t ino,
        struct problem_context  pctx;
        
        ext2fs_icount_store(ctx->inode_link_info, ino, 0);
-       e2fsck_read_inode(fs, ino, &inode, "deallocate_inode");
+       e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
        inode.i_links_count = 0;
        inode.i_dtime = time(0);
-       e2fsck_write_inode(fs, ino, &inode, "deallocate_inode");
+       e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
        clear_problem_context(&pctx);
        pctx.ino = ino;
 
@@ -556,7 +569,8 @@ static void deallocate_inode(e2fsck_t ctx, ino_t ino,
                                            deallocate_inode_block, ctx);
        if (pctx.errcode) {
                fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
 }
 
@@ -567,8 +581,9 @@ static int process_bad_inode(e2fsck_t ctx, ino_t dir, ino_t ino)
        int                     inode_modified = 0;
        unsigned char           *frag, *fsize;
        struct problem_context  pctx;
+       int     problem = 0;
 
-       e2fsck_read_inode(fs, ino, &inode, "process_bad_inode");
+       e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
 
        clear_problem_context(&pctx);
        pctx.ino = ino;
@@ -578,29 +593,26 @@ static int process_bad_inode(e2fsck_t ctx, ino_t dir, ino_t ino)
        if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
            !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
            !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
-           !(LINUX_S_ISSOCK(inode.i_mode))) {
-               if (fix_problem(ctx, PR_2_BAD_MODE, &pctx)) {
-                       deallocate_inode(ctx, ino, 0);
-                       return 1;
-               }
-       }
+           !(LINUX_S_ISSOCK(inode.i_mode)))
+               problem = PR_2_BAD_MODE;
 
        if (LINUX_S_ISCHR(inode.i_mode)
-           && !e2fsck_pass1_check_device_inode(&inode)) {
-               if (fix_problem(ctx, PR_2_BAD_CHAR_DEV, &pctx)) {
-                       deallocate_inode(ctx, ino, 0);
-                       return 1;
-               }
-       }
+           && !e2fsck_pass1_check_device_inode(&inode))
+               problem = PR_2_BAD_CHAR_DEV;
                
        if (LINUX_S_ISBLK(inode.i_mode)
-           && !e2fsck_pass1_check_device_inode(&inode)) {
-               if (fix_problem(ctx, PR_2_BAD_BLOCK_DEV, &pctx)) {
+           && !e2fsck_pass1_check_device_inode(&inode))
+               problem = PR_2_BAD_BLOCK_DEV;
+
+       if (problem) {
+               if (fix_problem(ctx, problem, &pctx)) {
                        deallocate_inode(ctx, ino, 0);
+                       if (ctx->flags & E2F_FLAG_ABORT)
+                               return 0;
                        return 1;
                }
+               problem = 0;
        }
-
                
        if (inode.i_faddr &&
            fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
@@ -652,7 +664,7 @@ static int process_bad_inode(e2fsck_t ctx, ino_t dir, ino_t ino)
                inode_modified++;
        }
        if (inode_modified)
-               e2fsck_write_inode(fs, ino, &inode, "process_bad_inode");
+               e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
        return 0;
 }
 
@@ -710,7 +722,7 @@ static int allocate_dir_block(e2fsck_t ctx,
        }
 
        pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
-       free(block);
+       ext2fs_free_mem((void **) &block);
        if (pctx->errcode) {
                pctx->str = "ext2fs_write_dir_block";
                fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
@@ -720,11 +732,11 @@ static int allocate_dir_block(e2fsck_t ctx,
        /*
         * Update the inode block count
         */
-       e2fsck_read_inode(fs, db->ino, &inode, "allocate_dir_block");
+       e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
        inode.i_blocks += fs->blocksize / 512;
        if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
                inode.i_size = (db->blockcnt+1) * fs->blocksize;
-       e2fsck_write_inode(fs, db->ino, &inode, "allocate_dir_block");
+       e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
 
        /*
         * Finally, update the block pointers for the inode
index 48d3c7c..f85d9bd 100644 (file)
  * offer to reconnect the directory to /lost+found in to break the
  * filesystem loop.
  * 
- * Pass 3 also contains the subroutine, reconnect_file() to reconnect
- * inodes to /lost+found; this subroutine is also used by pass 4.
- * reconnect_file() calls get_lost_and_found(), which is responsible
- * for creating /lost+found if it does not exist.
+ * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
+ * reconnect inodes to /lost+found; this subroutine is also used by
+ * pass 4.  e2fsck_reconnect_file() calls get_lost_and_found(), which
+ * is responsible for creating /lost+found if it does not exist.
  *
  * Pass 3 frees the following data structures:
  *             - The dirinfo directory information cache.
@@ -55,7 +55,7 @@ static int bad_lost_and_found = 0;
 static ext2fs_inode_bitmap inode_loop_detect;
 static ext2fs_inode_bitmap inode_done_map;
        
-void pass3(e2fsck_t ctx)
+void e2fsck_pass3(e2fsck_t ctx)
 {
        ext2_filsys fs = ctx->fs;
        int             i;
@@ -86,14 +86,16 @@ void pass3(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.num = 1;
                fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        pctx.errcode = ext2fs_allocate_inode_bitmap(fs, "inode done bitmap",
                                                    &inode_done_map);
        if (pctx.errcode) {
                pctx.num = 2;
                fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
 #ifdef RESOURCE_TRACK
        if (ctx->options & E2F_OPT_TIME)
@@ -101,15 +103,18 @@ void pass3(e2fsck_t ctx)
 #endif
 
        check_root(ctx);
+       if (ctx->flags & E2F_FLAG_ABORT)
+               return;
+
        ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
 
-       for (i=0; (dir = dir_info_iter(&i)) != 0;) {
+       for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
                if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
                        check_directory(ctx, dir, &pctx);
        }
        
        
-       free_dir_info(fs);
+       e2fsck_free_dir_info(ctx);
        ext2fs_free_inode_bitmap(inode_loop_detect);
        ext2fs_free_inode_bitmap(inode_done_map);
 #ifdef RESOURCE_TRACK
@@ -134,7 +139,7 @@ static void check_root(e2fsck_t ctx)
        
        if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
                /*
-                * If the root inode is a directory, die here.  The
+                * If the root inode is not a directory, die here.  The
                 * user must have answered 'no' in pass1 when we
                 * offered to clear it.
                 */
@@ -156,7 +161,8 @@ static void check_root(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.str = "ext2fs_new_block";
                fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
        ext2fs_mark_block_bitmap(fs->block_map, blk);
@@ -170,16 +176,18 @@ static void check_root(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.str = "ext2fs_new_dir_block";
                fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
 
        pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
        if (pctx.errcode) {
                pctx.str = "ext2fs_write_dir_block";
                fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
-       free(block);
+       ext2fs_free_mem((void **) &block);
 
        /*
         * Set up the inode structure
@@ -199,13 +207,14 @@ static void check_root(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.str = "ext2fs_write_inode";
                fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        
        /*
         * Miscellaneous bookkeeping...
         */
-       add_dir_info(fs, EXT2_ROOT_INO, EXT2_ROOT_INO);
+       e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
        ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
        ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
 
@@ -259,7 +268,7 @@ static void check_directory(e2fsck_t ctx, struct dir_info *dir,
                        break;
                ext2fs_mark_inode_bitmap(inode_loop_detect,
                                         p->parent);
-               p = get_dir_info(p->parent);
+               p = e2fsck_get_dir_info(ctx, p->parent);
        }
        /*
         * If we've reached here, we've hit a detached directory
@@ -267,7 +276,7 @@ static void check_directory(e2fsck_t ctx, struct dir_info *dir,
         */
        pctx->ino = p->ino;
        if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
-               if (reconnect_file(ctx, p->ino))
+               if (e2fsck_reconnect_file(ctx, p->ino))
                        ext2fs_unmark_valid(fs);
                else {
                        p->parent = lost_and_found;
@@ -362,7 +371,7 @@ ino_t get_lost_and_found(e2fsck_t ctx)
        }
 
        retval = ext2fs_write_dir_block(fs, blk, block);
-       free(block);
+       ext2fs_free_mem((void **) &block);
        if (retval) {
                pctx.errcode = retval;
                fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
@@ -402,7 +411,7 @@ ino_t get_lost_and_found(e2fsck_t ctx)
        /*
         * Miscellaneous bookkeeping that needs to be kept straight.
         */
-       add_dir_info(fs, ino, EXT2_ROOT_INO);
+       e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
        adjust_inode_count(ctx, EXT2_ROOT_INO, +1);
        ext2fs_icount_store(ctx->inode_count, ino, 2);
        ext2fs_icount_store(ctx->inode_link_info, ino, 2);
@@ -415,7 +424,7 @@ ino_t get_lost_and_found(e2fsck_t ctx)
 /*
  * This routine will connect a file to lost+found
  */
-int reconnect_file(e2fsck_t ctx, ino_t inode)
+int e2fsck_reconnect_file(e2fsck_t ctx, ino_t inode)
 {
        ext2_filsys fs = ctx->fs;
        errcode_t       retval;
@@ -613,9 +622,9 @@ static int expand_dir_proc(ext2_filsys fs,
                }
                es->done = 1;
        } else {
-               block = malloc(fs->blocksize);
-               if (!block) {
-                       es->err = ENOMEM;
+               retval = ext2fs_get_mem(fs->blocksize, (void **) &block);
+               if (retval) {
+                       es->err = retval;
                        return BLOCK_ABORT;
                }
                memset(block, 0, fs->blocksize);
@@ -625,7 +634,7 @@ static int expand_dir_proc(ext2_filsys fs,
                es->err = retval;
                return BLOCK_ABORT;
        }
-       free(block);
+       ext2fs_free_mem((void **) &block);
        *blocknr = new_blk;
        ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
        ext2fs_mark_block_bitmap(fs->block_map, new_blk);
@@ -672,7 +681,7 @@ static errcode_t expand_directory(e2fsck_t ctx, ino_t dir)
        inode.i_size += fs->blocksize;
        inode.i_blocks += fs->blocksize / 512;
 
-       e2fsck_write_inode(fs, dir, &inode, "expand_directory");
+       e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
 
        return 0;
 }
index 9b814b4..6aca7d4 100644 (file)
@@ -28,7 +28,7 @@ static int disconnect_inode(e2fsck_t ctx, ino_t i)
        struct ext2_inode       inode;
        struct problem_context  pctx;
 
-       e2fsck_read_inode(fs, i, &inode, "pass4: disconnect_inode");
+       e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
        clear_problem_context(&pctx);
        pctx.ino = i;
        pctx.inode = &inode;
@@ -42,7 +42,7 @@ static int disconnect_inode(e2fsck_t ctx, ino_t i)
                        ext2fs_icount_store(ctx->inode_link_info, i, 0);
                        inode.i_links_count = 0;
                        inode.i_dtime = time(0);
-                       e2fsck_write_inode(fs, i, &inode,
+                       e2fsck_write_inode(ctx, i, &inode,
                                           "disconnect_inode");
                        /*
                         * Fix up the bitmaps...
@@ -60,7 +60,7 @@ static int disconnect_inode(e2fsck_t ctx, ino_t i)
         * Prompt to reconnect.
         */
        if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
-               if (reconnect_file(ctx, i))
+               if (e2fsck_reconnect_file(ctx, i))
                        ext2fs_unmark_valid(fs);
        } else {
                /*
@@ -75,7 +75,7 @@ static int disconnect_inode(e2fsck_t ctx, ino_t i)
 }
 
 
-void pass4(e2fsck_t ctx)
+void e2fsck_pass4(e2fsck_t ctx)
 {
        ext2_filsys fs = ctx->fs;
        ino_t   i;
@@ -118,7 +118,7 @@ void pass4(e2fsck_t ctx)
                                            &link_counted);
                }
                if (link_counted != link_count) {
-                       e2fsck_read_inode(fs, i, &inode, "pass4");
+                       e2fsck_read_inode(ctx, i, &inode, "pass4");
                        pctx.ino = i;
                        pctx.inode = &inode;
                        if (link_count != inode.i_links_count) {
@@ -129,7 +129,7 @@ void pass4(e2fsck_t ctx)
                        pctx.num = link_counted;
                        if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
                                inode.i_links_count = link_counted;
-                               e2fsck_write_inode(fs, i, &inode, "pass4");
+                               e2fsck_write_inode(ctx, i, &inode, "pass4");
                        }
                }
        }
index be2edd9..9dcb7fd 100644 (file)
@@ -18,7 +18,7 @@ static void check_inode_bitmaps(e2fsck_t ctx);
 static void check_inode_end(e2fsck_t ctx);
 static void check_block_end(e2fsck_t ctx);
 
-void pass5(e2fsck_t ctx)
+void e2fsck_pass5(e2fsck_t ctx)
 {
 #ifdef RESOURCE_TRACK
        struct resource_track   rtrack;
@@ -41,9 +41,17 @@ void pass5(e2fsck_t ctx)
        read_bitmaps(ctx);
 
        check_block_bitmaps(ctx);
+       if (ctx->flags & E2F_FLAG_ABORT)
+               return;
        check_inode_bitmaps(ctx);
+       if (ctx->flags & E2F_FLAG_ABORT)
+               return;
        check_inode_end(ctx);
+       if (ctx->flags & E2F_FLAG_ABORT)
+               return;
        check_block_end(ctx);
+       if (ctx->flags & E2F_FLAG_ABORT)
+               return;
 
        ext2fs_free_inode_bitmap(ctx->inode_used_map);
        ctx->inode_used_map = 0;
@@ -86,8 +94,9 @@ static void check_block_bitmaps(e2fsck_t ctx)
                pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
                pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
                fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
-               /* fatal */
-               fatal_error(0);
+
+               ctx->flags |= E2F_FLAG_ABORT; /* fatal */
+               return;
        }
                       
        if ((fs->super->s_first_data_block <
@@ -100,8 +109,9 @@ static void check_block_bitmaps(e2fsck_t ctx)
                pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
                pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
                fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
-               /* fatal */
-               fatal_error(0);
+
+               ctx->flags |= E2F_FLAG_ABORT; /* fatal */
+               return;
        }
                       
 redo_counts:                  
@@ -184,7 +194,7 @@ redo_counts:
                } else
                        ext2fs_unmark_valid(fs);
        }
-       free(free_array);
+       ext2fs_free_mem((void **) &free_array);
 }
                        
 static void check_inode_bitmaps(e2fsck_t ctx)
@@ -219,8 +229,9 @@ static void check_inode_bitmaps(e2fsck_t ctx)
                pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
                pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
                fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
-               /* fatal */
-               fatal_error(0);
+
+               ctx->flags |= E2F_FLAG_ABORT; /* fatal */
+               return;
        }
        if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
            (fs->super->s_inodes_count > 
@@ -231,8 +242,9 @@ static void check_inode_bitmaps(e2fsck_t ctx)
                pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
                pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
                fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
-               /* fatal */
-               fatal_error(0);
+
+               ctx->flags |= E2F_FLAG_ABORT; /* fatal */
+               return;
        }
 
 redo_counts:
@@ -332,8 +344,8 @@ do_counts:
                } else
                        ext2fs_unmark_valid(fs);
        }
-       free(free_array);
-       free(dir_array);
+       ext2fs_free_mem((void **) &free_array);
+       ext2fs_free_mem((void **) &dir_array);
 }
 
 static void check_inode_end(e2fsck_t ctx)
@@ -350,7 +362,8 @@ static void check_inode_end(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.num = 1;
                fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT; /* fatal */
+               return;
        }
        if (save_inodes_count == end)
                return;
@@ -373,7 +386,8 @@ static void check_inode_end(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.num = 2;
                fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT; /* fatal */
+               return;
        }
 }
 
@@ -392,7 +406,8 @@ static void check_block_end(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.num = 3;
                fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT; /* fatal */
+               return;
        }
        if (save_blocks_count == end)
                return;
@@ -415,7 +430,8 @@ static void check_block_end(e2fsck_t ctx)
        if (pctx.errcode) {
                pctx.num = 4;
                fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT; /* fatal */
+               return;
        }
 }
 
index 40a272c..1b6fb04 100644 (file)
@@ -46,7 +46,7 @@ static void check_super_value(e2fsck_t ctx, const char *descr,
                pctx.num = value;
                pctx.str = descr;
                fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
-               fatal_error(0); /* never get here! */
+               ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
        }
 }
 
@@ -100,20 +100,24 @@ void check_super_block(e2fsck_t ctx)
                                              &should_be);
        if (pctx.errcode) {
                fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        if (should_be < s->s_blocks_count) {
                pctx.blk = s->s_blocks_count;
                pctx.blk2 = should_be;
-               if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx))
-                       fatal_error(0);
+               if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
+                       ctx->flags |= E2F_FLAG_ABORT;
+                       return;
+               }
        }
 
        if (s->s_log_block_size != s->s_log_frag_size) {
                pctx.blk = EXT2_BLOCK_SIZE(s);
                pctx.blk2 = EXT2_FRAG_SIZE(s);
                fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
 
        should_be = s->s_frags_per_group /
@@ -122,7 +126,8 @@ void check_super_block(e2fsck_t ctx)
                pctx.blk = s->s_blocks_per_group;
                pctx.blk2 = should_be;
                fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
 
        should_be = (s->s_log_block_size == 0) ? 1 : 0;
@@ -130,7 +135,8 @@ void check_super_block(e2fsck_t ctx)
                pctx.blk = s->s_first_data_block;
                pctx.blk2 = should_be;
                fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
 
        /*
index f6d3d70..ab012c7 100644 (file)
@@ -114,10 +114,10 @@ static void swap_inodes(e2fsck_t ctx)
        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,
+       retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
+                               (void **) &buf);
+       if (retval) {
+               com_err("swap_inodes", retval,
                        "while allocating inode buffer");
                fatal_error(0);
        }
@@ -168,8 +168,8 @@ static void swap_inodes(e2fsck_t ctx)
                        fatal_error(0);
                }
        }
-       free(buf);
-       free(block_buf);
+       ext2fs_free_mem((void **) &buf);
+       ext2fs_free_mem((void **) &block_buf);
        fs->read_inode = 0;
        fs->get_blocks = 0;
 }
index 9868e36..97bb33d 100644 (file)
@@ -55,8 +55,6 @@ static int possible_block_sizes[] = { 1024, 2048, 4096, 8192, 0};
 static int root_filesystem = 0;
 static int read_only_root = 0;
 
-int restart_e2fsck = 0;
-
 static void usage(e2fsck_t ctx)
 {
        fprintf(stderr,
@@ -414,7 +412,7 @@ int main (int argc, char *argv[])
        int             my_ver, lib_ver;
        e2fsck_t        ctx;
        struct problem_context pctx;
-       int flags;
+       int flags, run_result;
        
        clear_problem_context(&pctx);
 #ifdef MTRACE
@@ -459,7 +457,7 @@ int main (int argc, char *argv[])
            !(ctx->options & E2F_OPT_NO) &&
            !(ctx->options & E2F_OPT_YES)) {
                if (!isatty (0) || !isatty (1))
-                       die ("need terminal for interactive repairs");
+                       fatal_error("need terminal for interactive repairs");
        }
        ctx->superblock = ctx->use_superblock;
 restart:
@@ -595,12 +593,11 @@ restart:
                preenhalt(ctx);
                printf("This doesn't bode well, but we'll try to go on...\n");
        }
-       
-       pass1(ctx);
-       if (restart_e2fsck) {
+
+       run_result = e2fsck_run(ctx);
+       if (run_result == E2F_FLAG_RESTART) {
                ext2fs_close(fs);
                printf("Restarting e2fsck from the beginning...\n");
-               restart_e2fsck = 0;
                retval = e2fsck_reset_context(ctx);
                if (retval) {
                        com_err(ctx->program_name, retval,
@@ -609,10 +606,10 @@ restart:
                }
                goto restart;
        }
-       pass2(ctx);
-       pass3(ctx);
-       pass4(ctx);
-       pass5(ctx);
+       if (run_result & E2F_FLAG_ABORT)
+               exit(FSCK_ERROR);
+       if (run_result & E2F_FLAG_CANCEL)
+               ext2fs_unmark_valid(fs);
 
 #ifdef MTRACE
        mtrace_print("Cleanup");
index f676b26..46ceaa9 100644 (file)
@@ -238,12 +238,12 @@ void print_resource_track(const char *desc, struct resource_track *track)
 }
 #endif /* RESOURCE_TRACK */
 
-void e2fsck_read_inode(ext2_filsys fs, unsigned long ino,
+void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
                              struct ext2_inode * inode, const char *proc)
 {
        int retval;
 
-       retval = ext2fs_read_inode(fs, ino, inode);
+       retval = ext2fs_read_inode(ctx->fs, ino, inode);
        if (retval) {
                com_err("ext2fs_read_inode", retval,
                        "while reading inode %ld in %s", ino, proc);
@@ -251,12 +251,12 @@ void e2fsck_read_inode(ext2_filsys fs, unsigned long ino,
        }
 }
 
-extern void e2fsck_write_inode(ext2_filsys fs, unsigned long ino,
+extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
                               struct ext2_inode * inode, const char *proc)
 {
        int retval;
 
-       retval = ext2fs_write_inode(fs, ino, inode);
+       retval = ext2fs_write_inode(ctx->fs, ino, inode);
        if (retval) {
                com_err("ext2fs_write_inode", retval,
                        "while writing inode %ld in %s", ino, proc);