From 08b213017f8371ce4b56ad4d368eb0f92211d04e Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 3 Nov 1997 19:42:40 +0000 Subject: [PATCH] Many 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. --- e2fsck/ChangeLog | 16 ++++++++ e2fsck/Makefile.in | 40 ++++++++++-------- e2fsck/Makefile.pq | 4 +- e2fsck/dirinfo.c | 90 +++++++++++++++++++++------------------- e2fsck/e2fsck.c | 60 +++++++++++++++++++++++---- e2fsck/e2fsck.h | 95 ++++++++++++++++++++++++++++-------------- e2fsck/message.c | 2 +- e2fsck/pass1.c | 118 ++++++++++++++++++++++++++++++++++------------------- e2fsck/pass1b.c | 24 +++++------ e2fsck/pass2.c | 84 ++++++++++++++++++++++---------------- e2fsck/pass3.c | 61 +++++++++++++++------------ e2fsck/pass4.c | 12 +++--- e2fsck/pass5.c | 48 ++++++++++++++-------- e2fsck/super.c | 20 +++++---- e2fsck/swapfs.c | 12 +++--- e2fsck/unix.c | 21 ++++------ e2fsck/util.c | 8 ++-- 17 files changed, 448 insertions(+), 267 deletions(-) diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index aaa3ec4..083d7ac 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,19 @@ +Mon Nov 3 14:35:29 1997 Theodore Ts'o + + * [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 * pass1.c, pass3.c: Rename new error codes to _ET_ in them for diff --git a/e2fsck/Makefile.in b/e2fsck/Makefile.in index 40595e6..82acdb9 100644 --- a/e2fsck/Makefile.in +++ b/e2fsck/Makefile.in @@ -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 - diff --git a/e2fsck/Makefile.pq b/e2fsck/Makefile.pq index a5e5b49..6388e6c 100644 --- a/e2fsck/Makefile.pq +++ b/e2fsck/Makefile.pq @@ -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 diff --git a/e2fsck/dirinfo.c b/e2fsck/dirinfo.c index 5218234..8d37544 100644 --- a/e2fsck/dirinfo.c +++ b/e2fsck/dirinfo.c @@ -8,12 +8,9 @@ #include #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)++); } diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c index 592541b..c80036e 100644 --- a/e2fsck/e2fsck.c +++ b/e2fsck/e2fsck.c @@ -22,11 +22,13 @@ 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; +} + + + + + + diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 83c5d61..a497fb2 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -16,6 +16,9 @@ #ifdef HAVE_SYS_TIME_H #include #endif +#ifdef HAVE_SETJMP_H +#include +#endif #ifdef HAVE_LINUX_FS_H #include @@ -24,12 +27,8 @@ #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); diff --git a/e2fsck/message.c b/e2fsck/message.c index 673c463..e7bdd51 100644 --- a/e2fsck/message.c +++ b/e2fsck/message.c @@ -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); } } diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 6a2681a..ea443b8 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -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; } diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c index e965217..1aa586b 100644 --- a/e2fsck/pass1b.c +++ b/e2fsck/pass1b.c @@ -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", diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index edb2482..4facc60 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -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 diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index 48d3c7c..f85d9bd 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -25,10 +25,10 @@ * 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; } diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c index 9b814b4..6aca7d4 100644 --- a/e2fsck/pass4.c +++ b/e2fsck/pass4.c @@ -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"); } } } diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c index be2edd9..9dcb7fd 100644 --- a/e2fsck/pass5.c +++ b/e2fsck/pass5.c @@ -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; } } diff --git a/e2fsck/super.c b/e2fsck/super.c index 40a272c..1b6fb04 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -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; } /* diff --git a/e2fsck/swapfs.c b/e2fsck/swapfs.c index f6d3d70..ab012c7 100644 --- a/e2fsck/swapfs.c +++ b/e2fsck/swapfs.c @@ -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; } diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 9868e36..97bb33d 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -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"); diff --git a/e2fsck/util.c b/e2fsck/util.c index f676b26..46ceaa9 100644 --- a/e2fsck/util.c +++ b/e2fsck/util.c @@ -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); -- 1.8.3.1