From f8188fff23dc2d9c9f858fb21264e46b17672825 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 14 Nov 1997 05:23:04 +0000 Subject: [PATCH] Many files: pass1.c, pass2.c, pass3.c, pass4.c, pass5.c: Add calls to the progress indicator function. pass1.c (scan_callback): Add call to the progress feedback function (if it exists). super.c (check_super_block): Skip the device size check if the get_device_size returns EXT2_EXT_UNIMPLEMENTED. iscan.c (main): Don't use fatal_error() anymore. pass1b.c, swapfs.c, badblocks.c: Set E2F_FLAG_ABORT instead of calling fatal_error(0). problem.c, pass3.c (PR_3_ROOT_NOT_DIR_ABORT, PR_3_NO_ROOT_INODE_ABORT): New problem codes. problem.c, pass2.c (PR_2_SPLIT_DOT): New problem code. problem.c, pass1.c (PR_1_SUPPRESS_MESSAGES): New problem code. problemP.h: New file which separates out the private fix_problem data structures. util.c, dirinfo.c, pass1.c, pass1b.c, pass2.c, pass5.c, super.c, swapfs.c util.c: allocate_memory() now takes a e2fsck context as its first argument, and rename it to be e2fsck_allocate_memory(). problemP.h: New file which contains the private problem abstraction definitions. Makefile.pq: Remove include of MAKEFILE.STD, which doesn't exist at this point. --- e2fsck/ChangeLog | 33 +++++++++++++++++++ e2fsck/Makefile.pq | 3 -- e2fsck/badblocks.c | 19 +++++++---- e2fsck/dirinfo.c | 14 ++++++-- e2fsck/e2fsck.h | 12 ++++--- e2fsck/iscan.c | 10 +++--- e2fsck/message.c | 2 ++ e2fsck/pass1.c | 35 ++++++++++++++++---- e2fsck/pass1b.c | 27 ++++++++------- e2fsck/pass2.c | 16 ++++++--- e2fsck/pass3.c | 30 ++++++++++++----- e2fsck/pass4.c | 15 ++++++++- e2fsck/pass5.c | 23 +++++++++---- e2fsck/problem.c | 75 +++++++++++++++++++++++++++--------------- e2fsck/problem.h | 40 ++++++++-------------- e2fsck/problemP.h | 36 ++++++++++++++++++++ e2fsck/super.c | 41 +++++++++++------------ e2fsck/swapfs.c | 36 +++++++++++++------- e2fsck/unix.c | 40 +++++++++++++--------- e2fsck/util.c | 28 +++++++++------- lib/ext2fs/Makefile.pq | 3 -- resize/Makefile.pq | 4 --- util/Makefile.pq | 2 -- 23 files changed, 360 insertions(+), 184 deletions(-) create mode 100644 e2fsck/problemP.h diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 42a9023f..c5942c73 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,36 @@ +Thu Nov 6 16:10:20 1997 Theodore Ts'o + + * pass1.c, pass2.c, pass3.c, pass4.c, pass5.c: Add calls to the + progress indicator function. + + * pass1.c (scan_callback): Add call to the progress feedback + function (if it exists). + +Tue Nov 4 09:45:36 1997 Theodore Ts'o + + * super.c (check_super_block): Skip the device size check if the + get_device_size returns EXT2_EXT_UNIMPLEMENTED. + + * iscan.c (main): Don't use fatal_error() anymore. + + * pass1b.c, swapfs.c, badblocks.c: Set E2F_FLAG_ABORT instead of + calling fatal_error(0). + + * problem.c, pass3.c (PR_3_ROOT_NOT_DIR_ABORT, + PR_3_NO_ROOT_INODE_ABORT): New problem codes. + + * problem.c, pass2.c (PR_2_SPLIT_DOT): New problem code. + + * problem.c, pass1.c (PR_1_SUPPRESS_MESSAGES): New problem code. + + * problemP.h: New file which separates out the private fix_problem + data structures. + + * util.c, dirinfo.c, pass1.c, pass1b.c, pass2.c, pass5.c, super.c, + swapfs.c util.c: allocate_memory() now takes a e2fsck + context as its first argument, and rename it to be + e2fsck_allocate_memory(). + Mon Nov 3 14:35:29 1997 Theodore Ts'o * unix.c (main): Add a special case check for the error code EROFS diff --git a/e2fsck/Makefile.pq b/e2fsck/Makefile.pq index 86b2c483..18a3cd31 100644 --- a/e2fsck/Makefile.pq +++ b/e2fsck/Makefile.pq @@ -7,6 +7,3 @@ OBJS= e2fsck.obj super.obj pass1.obj pass2.obj pass3.obj \ !include $(TOPSRC)\powerquest\MCONFIG -ALL:: $(OBJS) - -!include $(TOPSRC)\powerquest\MAKEFILE.STD diff --git a/e2fsck/badblocks.c b/e2fsck/badblocks.c index a9addf75..b9b7ccaa 100644 --- a/e2fsck/badblocks.c +++ b/e2fsck/badblocks.c @@ -32,7 +32,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, FILE *f; char buf[1024]; - read_bitmaps(ctx); + e2fsck_read_bitmaps(ctx); /* * Make sure the bad block inode is sane. If there are any @@ -43,7 +43,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, if (retval) { com_err("ext2fs_block_iterate", retval, "while sanity checking the bad blocks inode"); - fatal_error(0); + goto fatal; } /* @@ -55,7 +55,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, if (retval) { com_err("ext2fs_read_bb_inode", retval, "while reading the bad blocks inode"); - fatal_error(0); + goto fatal; } } @@ -69,7 +69,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, if (!f) { com_err("read_bad_blocks_file", errno, "while trying to open %s", bad_blocks_file); - fatal_error(0); + goto fatal; } } else { sprintf(buf, "badblocks -b %d %s%s %d", fs->blocksize, @@ -79,7 +79,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, if (!f) { com_err("read_bad_blocks_file", errno, "while trying popen '%s'", buf); - fatal_error(0); + goto fatal; } } retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block); @@ -90,7 +90,7 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, if (retval) { com_err("ext2fs_read_bb_FILE", retval, "while reading in list of bad blocks from file"); - fatal_error(0); + goto fatal; } /* @@ -100,11 +100,16 @@ void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, if (retval) { com_err("ext2fs_update_bb_inode", retval, "while updating bad block inode"); - fatal_error(0); + goto fatal; } badblocks_list_free(bb_list); return; + +fatal: + ctx->flags |= E2F_FLAG_ABORT; + return; + } void test_disk(e2fsck_t ctx) diff --git a/e2fsck/dirinfo.c b/e2fsck/dirinfo.c index 8d37544e..38a8e437 100644 --- a/e2fsck/dirinfo.c +++ b/e2fsck/dirinfo.c @@ -38,9 +38,9 @@ void e2fsck_add_dir_info(e2fsck_t ctx, ino_t ino, ino_t parent) ctx->dir_info_count = 0; ctx->dir_info_size = e2fsck_get_num_dirs(ctx) + 10; - ctx->dir_info = allocate_memory(ctx->dir_info_size * - sizeof (struct dir_info), - "directory map"); + ctx->dir_info = e2fsck_allocate_memory(ctx, + ctx->dir_info_size * sizeof (struct dir_info), + "directory map"); } if (ctx->dir_info_count >= ctx->dir_info_size) { @@ -124,6 +124,14 @@ void e2fsck_free_dir_info(e2fsck_t ctx) ctx->dir_info_count = 0; } +/* + * Return the count of number of directories in the dir_info structure + */ +int e2fsck_get_num_dirinfo(e2fsck_t ctx) +{ + return ctx->dir_info_count; +} + /* * A simple interator function */ diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index a497fb24..d83c8cb8 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -117,10 +117,12 @@ struct e2fsck_struct { int options; blk_t use_superblock; /* sb requested by user */ blk_t superblock; /* sb used to open fs */ + blk_t num_blocks; /* Total number of blocks */ #ifdef HAVE_SETJMP_H jmp_buf abort_loc; #endif + unsigned long abort_code; void (*progress)(e2fsck_t ctx, int pass, unsigned long cur, unsigned long max); @@ -236,6 +238,7 @@ 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 int e2fsck_get_num_dirinfo(e2fsck_t ctx); extern struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control); /* ehandler.c */ @@ -249,12 +252,13 @@ void check_super_block(e2fsck_t ctx); void swap_filesys(e2fsck_t ctx); /* util.c */ -extern void *allocate_memory(int size, const char *description); +extern void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, + const char *description); extern int ask(e2fsck_t ctx, const char * string, int def); extern int ask_yn(const char * string, int def); -extern void fatal_error (const char * fmt_string); -extern void read_bitmaps(e2fsck_t ctx); -extern void write_bitmaps(e2fsck_t ctx); +extern void fatal_error(e2fsck_t ctx, const char * fmt_string); +extern void e2fsck_read_bitmaps(e2fsck_t ctx); +extern void e2fsck_write_bitmaps(e2fsck_t ctx); extern void preenhalt(e2fsck_t ctx); #ifdef RESOURCE_TRACK extern void print_resource_track(const char *desc, diff --git a/e2fsck/iscan.c b/e2fsck/iscan.c index 5a67b945..72acb016 100644 --- a/e2fsck/iscan.c +++ b/e2fsck/iscan.c @@ -66,7 +66,8 @@ static void PRS(int argc, char *argv[]) #ifdef BLKFLSBUF flush = 1; #else - fatal_error ("-F not supported"); + fprintf(stderr, "-F not supported"); + exit(1); #endif break; case 'I': @@ -92,7 +93,8 @@ static void PRS(int argc, char *argv[]) } close(fd); #else - fatal_error ("BLKFLSBUF not supported"); + fprintf(stderr, "BLKFLSBUF not supported"); + exit(1); #endif /* BLKFLSBUF */ } } @@ -124,7 +126,7 @@ int main (int argc, char *argv[]) retval = ext2fs_open_inode_scan(fs, inode_buffer_blocks, &scan); if (retval) { com_err(program_name, retval, "while opening inode scan"); - fatal_error(0); + exit(1); } while (1) { @@ -132,7 +134,7 @@ int main (int argc, char *argv[]) if (retval) { com_err(program_name, retval, "while getting next inode"); - fatal_error(0); + exit(1); } if (ino == 0) break; diff --git a/e2fsck/message.c b/e2fsck/message.c index e7bdd51d..c4641316 100644 --- a/e2fsck/message.c +++ b/e2fsck/message.c @@ -46,6 +46,7 @@ * * The following '@' expansions are supported: * + * @A error allocating * @b block * @B bitmap * @C conflicts with some other fs block @@ -90,6 +91,7 @@ * letter in the table below. */ static const char *abbrevs[] = { + "Aerror allocating", "bblock", "Bbitmap", "Cconflicts with some other fs @b", diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index ea443b8b..c973fdbb 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -84,6 +84,11 @@ struct process_inode_block { struct ext2_inode inode; }; +struct scan_callback_struct { + e2fsck_t ctx; + char *block_buf; +}; + /* * For the inodes to process list. */ @@ -126,6 +131,7 @@ void e2fsck_pass1(e2fsck_t ctx) #endif unsigned char frag, fsize; struct problem_context pctx; + struct scan_callback_struct scan_struct; #ifdef RESOURCE_TRACK init_resource_track(&rtrack); @@ -181,9 +187,9 @@ void e2fsck_pass1(e2fsck_t ctx) ctx->flags |= E2F_FLAG_ABORT; return; } - inodes_to_process = allocate_memory(ctx->process_inode_size * - sizeof(struct process_inode_block), - "array of inodes to process"); + inodes_to_process = e2fsck_allocate_memory(ctx, + ctx->process_inode_size * sizeof(struct process_inode_block), + "array of inodes to process"); process_inode_count = 0; pctx.errcode = ext2fs_init_dblist(fs, 0); @@ -194,7 +200,8 @@ void e2fsck_pass1(e2fsck_t ctx) } mark_table_blocks(ctx); - block_buf = allocate_memory(fs->blocksize * 3, "block interate buffer"); + block_buf = e2fsck_allocate_memory(ctx, fs->blocksize * 3, + "block interate buffer"); fs->get_blocks = pass1_get_blocks; fs->check_directory = pass1_check_directory; fs->read_inode = pass1_read_inode; @@ -215,7 +222,11 @@ void e2fsck_pass1(e2fsck_t ctx) return; } ctx->stashed_inode = &inode; - ext2fs_set_inode_callback(scan, scan_callback, block_buf); + scan_struct.ctx = ctx; + scan_struct.block_buf = block_buf; + ext2fs_set_inode_callback(scan, scan_callback, &scan_struct); + if (ctx->progress) + (ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count); while (ino) { pctx.ino = ino; pctx.inode = &inode; @@ -471,7 +482,16 @@ endit: static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan, dgrp_t group, void * private) { - process_inodes((e2fsck_t) fs->private, (char *) private); + struct scan_callback_struct *scan_struct = private; + e2fsck_t ctx; + + ctx = scan_struct->ctx; + + process_inodes((e2fsck_t) fs->private, scan_struct->block_buf); + + if (ctx->progress) + (ctx->progress)(ctx, 1, group+1, ctx->fs->group_desc_count); + return 0; } @@ -826,7 +846,7 @@ int process_block(ext2_filsys fs, p->clear = 1; return BLOCK_ABORT; } - if (ask(ctx, "Suppress messages", 0)) { + if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) { p->suppress = 1; set_latch_flags(PR_LATCH_BLOCK, PRL_SUPPRESS, 0); @@ -897,6 +917,7 @@ int process_bad_block(ext2_filsys fs, ctx = p->ctx; pctx = p->pctx; + pctx->ino = EXT2_BAD_INO; pctx->blk = blk; pctx->blkcount = blockcnt; diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c index 1aa586b2..fbd43eed 100644 --- a/e2fsck/pass1b.c +++ b/e2fsck/pass1b.c @@ -118,7 +118,8 @@ void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf) "multiply claimed inode map", &inode_dup_map); if (pctx.errcode) { fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx); - fatal_error(0); + ctx->flags |= E2F_FLAG_ABORT; + return; } pass1b(ctx, block_buf); @@ -172,12 +173,14 @@ static void pass1b(e2fsck_t ctx, char *block_buf) &scan); if (pctx.errcode) { fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx); - fatal_error(0); + ctx->flags |= E2F_FLAG_ABORT; + return; } pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode); if (pctx.errcode) { fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx); - fatal_error(0); + ctx->flags |= E2F_FLAG_ABORT; + return; } ctx->stashed_inode = &inode; pb.ctx = ctx; @@ -195,8 +198,9 @@ static void pass1b(e2fsck_t ctx, char *block_buf) process_pass1b_block, &pb); if (pb.dup_blocks) { end_problem_latch(ctx, PR_LATCH_DBLOCK); - dp = allocate_memory(sizeof(struct dup_inode), - "duplicate inode record"); + dp = e2fsck_allocate_memory(ctx, + sizeof(struct dup_inode), + "duplicate inode record"); dp->ino = ino; dp->dir = 0; dp->inode = inode; @@ -216,7 +220,8 @@ static void pass1b(e2fsck_t ctx, char *block_buf) goto next; if (pctx.errcode) { fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx); - fatal_error(0); + ctx->flags |= E2F_FLAG_ABORT; + return; } } ext2fs_close_inode_scan(scan); @@ -248,8 +253,8 @@ int process_pass1b_block(ext2_filsys fs, p->dup_blocks++; ext2fs_mark_block_bitmap(ctx->block_dup_map, *block_nr); ext2fs_mark_inode_bitmap(inode_dup_map, p->ino); - dp = allocate_memory(sizeof(struct dup_block), - "duplicate block record"); + dp = e2fsck_allocate_memory(ctx, sizeof(struct dup_block), + "duplicate block record"); dp->block = *block_nr; dp->ino = p->ino; dp->num_bad = 0; @@ -371,12 +376,12 @@ static void pass1d(e2fsck_t ctx, char *block_buf) clear_problem_context(&pctx); fix_problem(ctx, PR_1D_PASS_HEADER, &pctx); - read_bitmaps(ctx); + e2fsck_read_bitmaps(ctx); pctx.num = dup_inode_count; fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx); - shared = allocate_memory(sizeof(ino_t) * dup_inode_count, - "Shared inode list"); + shared = e2fsck_allocate_memory(ctx, sizeof(ino_t) * dup_inode_count, + "Shared inode list"); for (p = dup_ino; p; p = p->next) { shared_len = 0; file_ok = 1; diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 4facc601..85a857bf 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -63,6 +63,7 @@ static int update_dir_block(ext2_filsys fs, struct check_dir_struct { char *buf; struct problem_context pctx; + int count, max; e2fsck_t ctx; }; @@ -97,7 +98,8 @@ void e2fsck_pass2(e2fsck_t ctx) ctx->flags |= E2F_FLAG_ABORT; return; } - buf = allocate_memory(fs->blocksize, "directory scan buffer"); + buf = e2fsck_allocate_memory(ctx, fs->blocksize, + "directory scan buffer"); /* * Set up the parent pointer for the root directory, if @@ -110,6 +112,8 @@ void e2fsck_pass2(e2fsck_t ctx) cd.buf = buf; cd.ctx = ctx; + cd.count = 0; + cd.max = ext2fs_dblist_count(fs->dblist); cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block, &cd); @@ -177,9 +181,8 @@ static int check_dot(e2fsck_t ctx, if (dirent->rec_len > 12) { new_len = dirent->rec_len - 12; if (new_len > 12) { - preenhalt(ctx); if (created || - ask(ctx, "Directory entry for '.' is big. Split", 1)) { + fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) { nextdir = (struct ext2_dir_entry *) ((char *) dirent + 12); dirent->rec_len = 12; @@ -280,6 +283,9 @@ static int check_dir_block(ext2_filsys fs, buf = cd->buf; ctx = cd->ctx; + + if (ctx->progress) + (ctx->progress)(ctx, 2, cd->count++, cd->max); /* * Make sure the inode is still in use (could have been @@ -553,7 +559,7 @@ static void deallocate_inode(e2fsck_t ctx, ino_t ino, /* * Fix up the bitmaps... */ - read_bitmaps(ctx); + e2fsck_read_bitmaps(ctx); ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); if (ctx->inode_bad_map) @@ -691,7 +697,7 @@ static int allocate_dir_block(e2fsck_t ctx, * Read the inode and block bitmaps in; we'll be messing with * them. */ - read_bitmaps(ctx); + e2fsck_read_bitmaps(ctx); /* * First, find a free block diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index f85d9bd7..9af3be77 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -64,7 +64,8 @@ void e2fsck_pass3(e2fsck_t ctx) #endif struct problem_context pctx; struct dir_info *dir; - + unsigned long max, count; + #ifdef RESOURCE_TRACK init_resource_track(&rtrack); #endif @@ -108,11 +109,19 @@ void e2fsck_pass3(e2fsck_t ctx) ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO); + max = e2fsck_get_num_dirinfo(ctx); + count = 0; + + if (ctx->progress) + (ctx->progress)(ctx, 3, 0, max); for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) { + if (ctx->progress) + (ctx->progress)(ctx, 3, count++, max); if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino)) check_directory(ctx, dir, &pctx); } - + if (ctx->progress) + (ctx->progress)(ctx, 3, max, max); e2fsck_free_dir_info(ctx); ext2fs_free_inode_bitmap(inode_loop_detect); @@ -144,15 +153,20 @@ static void check_root(e2fsck_t ctx) * offered to clear it. */ if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map, - EXT2_ROOT_INO))) - fatal_error("Root inode not directory"); + EXT2_ROOT_INO))) { + fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx); + ctx->flags |= E2F_FLAG_ABORT; + } return; } - if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) - fatal_error("Cannot proceed without a root inode."); + if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) { + fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx); + ctx->flags |= E2F_FLAG_ABORT; + return; + } - read_bitmaps(ctx); + e2fsck_read_bitmaps(ctx); /* * First, find a free block @@ -330,7 +344,7 @@ ino_t get_lost_and_found(e2fsck_t ctx) * Read the inode and block bitmaps in; we'll be messing with * them. */ - read_bitmaps(ctx); + e2fsck_read_bitmaps(ctx); /* * First, find a free block diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c index 6aca7d43..a140be76 100644 --- a/e2fsck/pass4.c +++ b/e2fsck/pass4.c @@ -47,7 +47,7 @@ static int disconnect_inode(e2fsck_t ctx, ino_t i) /* * Fix up the bitmaps... */ - read_bitmaps(ctx); + e2fsck_read_bitmaps(ctx); ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i); ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i); ext2fs_unmark_inode_bitmap(fs->inode_map, i); @@ -85,6 +85,7 @@ void e2fsck_pass4(e2fsck_t ctx) #endif struct problem_context pctx; __u16 link_count, link_counted; + int group, max, j; #ifdef RESOURCE_TRACK init_resource_track(&rtrack); @@ -99,7 +100,17 @@ void e2fsck_pass4(e2fsck_t ctx) if (!(ctx->options & E2F_OPT_PREEN)) fix_problem(ctx, PR_4_PASS_HEADER, &pctx); + group = 0; + max = fs->group_desc_count; + if (ctx->progress) + (ctx->progress)(ctx, 4, 0, max); + for (i=1; i <= fs->super->s_inodes_count; i++) { + if ((i % fs->super->s_inodes_per_group) == 0) { + group++; + if (ctx->progress) + (ctx->progress)(ctx, 4, group, max); + } if (i == EXT2_BAD_INO || (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super))) continue; @@ -137,6 +148,8 @@ void e2fsck_pass4(e2fsck_t ctx) ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0; ext2fs_free_inode_bitmap(ctx->inode_bb_map); ctx->inode_bb_map = 0; + if (ctx->progress) + (ctx->progress)(ctx, 4, max, max); #ifdef RESOURCE_TRACK if (ctx->options & E2F_OPT_TIME2) print_resource_track("Pass 4", &rtrack); diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c index 9dcb7fd9..3afd2ed2 100644 --- a/e2fsck/pass5.c +++ b/e2fsck/pass5.c @@ -38,7 +38,13 @@ void e2fsck_pass5(e2fsck_t ctx) if (!(ctx->options & E2F_OPT_PREEN)) fix_problem(ctx, PR_5_PASS_HEADER, &pctx); - read_bitmaps(ctx); + if (ctx->progress) + (ctx->progress)(ctx, 5, 0, 3); + + e2fsck_read_bitmaps(ctx); + + if (ctx->progress) + (ctx->progress)(ctx, 5, 2, 3); check_block_bitmaps(ctx); if (ctx->flags & E2F_FLAG_ABORT) @@ -53,6 +59,9 @@ void e2fsck_pass5(e2fsck_t ctx) if (ctx->flags & E2F_FLAG_ABORT) return; + if (ctx->progress) + (ctx->progress)(ctx, 5, 3, 3); + ext2fs_free_inode_bitmap(ctx->inode_used_map); ctx->inode_used_map = 0; ext2fs_free_inode_bitmap(ctx->inode_dir_map); @@ -81,8 +90,8 @@ static void check_block_bitmaps(e2fsck_t ctx) errcode_t retval; clear_problem_context(&pctx); - free_array = allocate_memory(fs->group_desc_count * sizeof(int), - "free block count array"); + free_array = e2fsck_allocate_memory(ctx, + fs->group_desc_count * sizeof(int), "free block count array"); if ((fs->super->s_first_data_block < ext2fs_get_block_bitmap_start(ctx->block_found_map)) || @@ -214,11 +223,11 @@ static void check_inode_bitmaps(e2fsck_t ctx) int problem, fixit; clear_problem_context(&pctx); - free_array = allocate_memory(fs->group_desc_count * sizeof(int), - "free inode count array"); + free_array = e2fsck_allocate_memory(ctx, + fs->group_desc_count * sizeof(int), "free inode count array"); - dir_array = allocate_memory(fs->group_desc_count * sizeof(int), - "directory count array"); + dir_array = e2fsck_allocate_memory(ctx, + fs->group_desc_count * sizeof(int), "directory count array"); if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) || (fs->super->s_inodes_count > diff --git a/e2fsck/problem.c b/e2fsck/problem.c index eae98b11..503e61ea 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -18,6 +18,7 @@ #include "e2fsck.h" #include "problem.h" +#include "problemP.h" #define PROMPT_NONE 0 #define PROMPT_FIX 1 @@ -35,6 +36,7 @@ #define PROMPT_CONTINUE 13 #define PROMPT_CLONE 14 #define PROMPT_DELETE 15 +#define PROMPT_SUPPRESS 16 /* * These are the prompts which are used to ask the user if they want @@ -57,6 +59,7 @@ static const char *prompt[] = { "Continue", /* 13 */ "Clone duplicate/bad blocks", /* 14 */ "Delete file", /* 15 */ + "Suppress messages", /* 16 */ }; /* @@ -80,6 +83,7 @@ static const char *preen_msg[] = { "CONTINUING", /* 13 */ "DUPLICATE/BAD BLOCKS CLONED", /* 14 */ "FILE DELETED", /* 15 */ + "SUPPRESSED", /* 16 */ }; static const struct e2fsck_problem problem_table[] = { @@ -297,7 +301,7 @@ static const struct e2fsck_problem problem_table[] = { /* Bad primary block group descriptors */ { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, "Block %b in the primary @g descriptors " - "is on the bad block list\n", + "is on the bad @b list\n", PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK }, /* Bad superblock in group */ @@ -317,14 +321,14 @@ static const struct e2fsck_problem problem_table[] = { "process_bad_@b.\n", PROMPT_NONE, PR_PREEN_OK }, - /* Could not allocate blocks for relocating metadata */ + /* Error allocating blocks for relocating metadata */ { PR_1_RELOC_BLOCK_ALLOCATE, - "Could not allocate %N @b(s) for %s: %m\n", + "@A %N @b(s) for %s: %m\n", PROMPT_NONE, PR_PREEN_OK }, - /* Could not allocate memory during relocation process */ + /* Error allocating block buffer during relocation process */ { PR_1_RELOC_MEMORY_ALLOCATE, - "Could not allocate @b buffer for relocating %s\n", + "@A @b buffer for relocating %s\n", PROMPT_NONE, PR_PREEN_OK }, /* Relocating metadata group information from X to Y */ @@ -349,49 +353,52 @@ static const struct e2fsck_problem problem_table[] = { /* Error allocating inode bitmap */ { PR_1_ALLOCATE_IBITMAP_ERROR, - "Error allocating @i @B (%N): %m\n", + "@A @i @B (%N): %m\n", PROMPT_NONE, PR_FATAL }, /* Error allocating block bitmap */ { PR_1_ALLOCATE_BBITMAP_ERROR, - "Error allocating @b @B (%N): %m\n", + "@A @b @B (%N): %m\n", PROMPT_NONE, PR_FATAL }, /* Error allocating icount structure */ { PR_1_ALLOCATE_ICOUNT, - "Error allocating icount link information: %m\n", + "@A icount link information: %m\n", PROMPT_NONE, PR_FATAL }, /* Error allocating dbcount */ { PR_1_ALLOCATE_DBCOUNT, - "Error allocating directory @b array: %m\n", + "@A @d @b array: %m\n", PROMPT_NONE, PR_FATAL }, /* Error while scanning inodes */ { PR_1_ISCAN_ERROR, - "Error while scanning inodes (%i): %m\n", + "Error while scanning @is (%i): %m\n", PROMPT_NONE, PR_FATAL }, /* Error while iterating over blocks */ { PR_1_BLOCK_ITERATE, - "Error while iterating over blocks in inode %i: %m\n", + "Error while iterating over blocks in @i %i: %m\n", PROMPT_NONE, PR_FATAL }, /* Error while storing inode count information */ { PR_1_ICOUNT_STORE, - "Error storing inode count information (inode=%i, count=%N): %m\n", + "Error storing @i count information (inode=%i, count=%N): %m\n", PROMPT_NONE, PR_FATAL }, /* Error while storing directory block information */ { PR_1_ADD_DBLOCK, - "Error storing dir block information " + "Error storing @d @b information " "(inode=%i, block=%b, num=%N): %m\n", PROMPT_NONE, PR_FATAL }, /* Error while reading inode (for clearing) */ { PR_1_READ_INODE, - "Error reading inode %i: %m\n", + "Error reading @i %i: %m\n", PROMPT_NONE, PR_FATAL }, + + /* Suppress messages prompt */ + { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK }, /* Pass 1b errors */ @@ -423,7 +430,7 @@ static const struct e2fsck_problem problem_table[] = { /* Error allocating inode bitmap */ { PR_1B_ALLOCATE_IBITMAP_ERROR, - "Error allocating @i @B (inode_dup_map): %m\n", + "@A @i @B (inode_dup_map): %m\n", PROMPT_NONE, PR_FATAL }, @@ -590,12 +597,12 @@ static const struct e2fsck_problem problem_table[] = { /* '.' is not NULL terminated */ { PR_2_DOT_NULL_TERM, - "'.' directory entry in @d @i %i is not NULL terminated\n", + "'.' @d @e in @d @i %i is not NULL terminated\n", PROMPT_FIX, 0 }, /* '..' is not NULL terminated */ { PR_2_DOT_DOT_NULL_TERM, - "'..' directory entry in @d @i %i is not NULL terminated\n", + "'..' @d @e in @d @i %i is not NULL terminated\n", PROMPT_FIX, 0 }, /* Illegal character device inode */ @@ -630,34 +637,38 @@ static const struct e2fsck_problem problem_table[] = { /* Error allocating icount structure */ { PR_2_ALLOCATE_ICOUNT, - "Error allocating icount structure: %m\n", + "@A icount structure: %m\n", PROMPT_NONE, PR_FATAL }, /* Error iterating over directory blocks */ { PR_2_DBLIST_ITERATE, - "Error interating over directory blocks: %m\n", + "Error interating over @d @bs: %m\n", PROMPT_NONE, PR_FATAL }, /* Error reading directory block */ { PR_2_READ_DIRBLOCK, - "Error reading directory block %b (inode %i): %m\n", + "Error reading @d @b %b (@i %i): %m\n", PROMPT_CONTINUE, 0 }, /* Error writing directory block */ { PR_2_WRITE_DIRBLOCK, - "Error writing directory block %b (inode %i): %m\n", + "Error writing @d @b %b (@i %i): %m\n", PROMPT_CONTINUE, 0 }, /* Error allocating new directory block */ { PR_2_ALLOC_DIRBOCK, - "Error allocating new directory block for inode %i (%s): %m\n", + "@A new @d @b for @i %i (%s): %m\n", PROMPT_NONE, 0 }, /* Error deallocating inode */ { PR_2_DEALLOC_INODE, - "Error deallocating inode %i: %m\n", + "Error deallocating @i %i: %m\n", PROMPT_NONE, PR_FATAL }, + /* Directory entry for '.' is big. Split? */ + { PR_2_SPLIT_DOT, + "@d @e for '.' is big. ", + PROMPT_SPLIT, PR_NO_OK }, /* Pass 3 errors */ @@ -748,7 +759,7 @@ static const struct e2fsck_problem problem_table[] = { /* Error allocating inode bitmap */ { PR_3_ALLOCATE_IBITMAP_ERROR, - "Error allocating @i @B (%N): %m\n", + "@A @i @B (%N): %m\n", PROMPT_NONE, PR_FATAL }, /* Error creating root directory */ @@ -761,6 +772,16 @@ static const struct e2fsck_problem problem_table[] = { "Error creating /@l @d (%s): %m\n", PROMPT_NONE, PR_FATAL }, + /* Root inode is not directory; aborting */ + { PR_3_ROOT_NOT_DIR_ABORT, + "@r is not a @d; aborting.\n", + PROMPT_NONE, PR_FATAL }, + + /* Cannot proceed without a root inode. */ + { PR_3_NO_ROOT_INODE_ABORT, + "Cannot proceed without a @r.\n", + PROMPT_NONE, PR_FATAL }, + /* Pass 4 errors */ /* Pass 4: Checking reference counts */ @@ -1021,7 +1042,7 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) preenhalt(ctx); if (ptr->flags & PR_FATAL) - fatal_error(0); + fatal_error(ctx, 0); if (ptr->prompt == PROMPT_NONE) { if (ptr->flags & PR_NOCOLLATE) @@ -1055,8 +1076,8 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) if (ptr->flags & PR_AFTER_CODE) (void) fix_problem(ctx, ptr->second_code, pctx); - if (ptr->prompt == PROMPT_ABORT) - fatal_error(0); + if ((ptr->prompt == PROMPT_ABORT) && answer) + fatal_error(ctx, 0); return answer; } diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 3fbbb2ad..57887031 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -22,31 +22,6 @@ struct problem_context { const char *str; }; -struct e2fsck_problem { - problem_t e2p_code; - const char * e2p_description; - char prompt; - short flags; - problem_t second_code; -}; - -struct latch_descr { - int latch_code; - problem_t question; - problem_t end_message; - int flags; -}; - -#define PR_PREEN_OK 0x0001 /* Don't need to do preenhalt */ -#define PR_NO_OK 0x0002 /* If user answers no, don't make fs invalid */ -#define PR_NO_DEFAULT 0x0004 /* Default to no */ -#define PR_MSG_ONLY 0x0008 /* Print message only */ -#define PR_FATAL 0x0080 /* Fatal error */ -#define PR_AFTER_CODE 0x0100 /* After asking the first question, */ - /* ask another */ -#define PR_PREEN_NOMSG 0x0200 /* Don't print a message if we're preening */ -#define PR_NOCOLLATE 0x0400 /* Don't collate answers for this latch */ - /* * We define a set of "latch groups"; these are problems which are * handled as a set. The user answers once for a particular latch @@ -206,10 +181,10 @@ struct latch_descr { /* Block claimed for no reason */ #define PR_1_PROGERR_CLAIMED_BLOCK 0x010001D -/* Could not allocate blocks for relocating metadata */ +/* Error allocating blocks for relocating metadata */ #define PR_1_RELOC_BLOCK_ALLOCATE 0x010001E -/* Could not allocate memory during relocation process */ +/* Error allocating block buffer during relocation process */ #define PR_1_RELOC_MEMORY_ALLOCATE 0x010001F /* Relocating metadata group information from X to Y */ @@ -251,6 +226,8 @@ struct latch_descr { /* Error while reading inode (for clearing) */ #define PR_1_READ_INODE 0x010002C +/* Suppress messages prompt */ +#define PR_1_SUPPRESS_MESSAGES 0x010002D /* * Pass 1b errors @@ -418,6 +395,9 @@ struct latch_descr { /* Error deallocating inode */ #define PR_2_DEALLOC_INODE 0x020023 +/* Directory entry for '.' is big. Split? */ +#define PR_2_SPLIT_DOT 0x0200024 + /* * Pass 3 errors */ @@ -482,6 +462,12 @@ struct latch_descr { /* Error creating lost and found directory */ #define PR_3_CREATE_LPF_ERROR 0x030013 +/* Root inode is not directory; aborting */ +#define PR_3_ROOT_NOT_DIR_ABORT 0x030014 + +/* Cannot proceed without a root inode. */ +#define PR_3_NO_ROOT_INODE_ABORT 0x030015 + /* * Pass 4 errors */ diff --git a/e2fsck/problemP.h b/e2fsck/problemP.h new file mode 100644 index 00000000..ceb7bd3d --- /dev/null +++ b/e2fsck/problemP.h @@ -0,0 +1,36 @@ +/* + * problemP.h --- Private header file for fix_problem() + * + * Copyright 1997 by Theodore Ts'o + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +struct e2fsck_problem { + problem_t e2p_code; + const char * e2p_description; + char prompt; + short flags; + problem_t second_code; +}; + +struct latch_descr { + int latch_code; + problem_t question; + problem_t end_message; + int flags; +}; + +#define PR_PREEN_OK 0x0001 /* Don't need to do preenhalt */ +#define PR_NO_OK 0x0002 /* If user answers no, don't make fs invalid */ +#define PR_NO_DEFAULT 0x0004 /* Default to no */ +#define PR_MSG_ONLY 0x0008 /* Print message only */ +#define PR_FATAL 0x0080 /* Fatal error */ +#define PR_AFTER_CODE 0x0100 /* After asking the first question, */ + /* ask another */ +#define PR_PREEN_NOMSG 0x0200 /* Don't print a message if we're preening */ +#define PR_NOCOLLATE 0x0400 /* Don't collate answers for this latch */ + diff --git a/e2fsck/super.c b/e2fsck/super.c index 1b6fb04a..a0a2f190 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -60,15 +60,12 @@ void check_super_block(e2fsck_t ctx) blk_t should_be; struct problem_context pctx; - ctx->invalid_inode_bitmap_flag = allocate_memory(sizeof(int) * - fs->group_desc_count, - "invalid_inode_bitmap"); - ctx->invalid_block_bitmap_flag = allocate_memory(sizeof(int) * - fs->group_desc_count, - "invalid_block_bitmap"); - ctx->invalid_inode_table_flag = allocate_memory(sizeof(int) * - fs->group_desc_count, - "invalid_inode_table"); + ctx->invalid_inode_bitmap_flag = e2fsck_allocate_memory(ctx, + sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap"); + ctx->invalid_block_bitmap_flag = e2fsck_allocate_memory(ctx, + sizeof(int) * fs->group_desc_count, "invalid_block_bitmap"); + ctx->invalid_inode_table_flag = e2fsck_allocate_memory(ctx, + sizeof(int) * fs->group_desc_count, "invalid_inode_table"); clear_problem_context(&pctx); @@ -95,21 +92,23 @@ void check_super_block(e2fsck_t ctx) check_super_value(ctx, "r_blocks_count", s->s_r_blocks_count, MAX_CHECK, 0, s->s_blocks_count); - pctx.errcode = ext2fs_get_device_size(ctx->filesystem_name, - EXT2_BLOCK_SIZE(s), - &should_be); - if (pctx.errcode) { - fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx); - 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)) { + if (!ctx->num_blocks) { + pctx.errcode = ext2fs_get_device_size(ctx->filesystem_name, + EXT2_BLOCK_SIZE(s), &ctx->num_blocks); + if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) { + fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx); ctx->flags |= E2F_FLAG_ABORT; return; } + if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) && + (ctx->num_blocks < s->s_blocks_count)) { + pctx.blk = s->s_blocks_count; + pctx.blk2 = ctx->num_blocks; + 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) { diff --git a/e2fsck/swapfs.c b/e2fsck/swapfs.c index ab012c70..209a57a0 100644 --- a/e2fsck/swapfs.c +++ b/e2fsck/swapfs.c @@ -75,7 +75,7 @@ static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt, * This function is responsible for byte-swapping all of the indirect, * block pointers. It is also responsible for byte-swapping directories. */ -static void swap_inode_blocks(ext2_filsys fs, ino_t ino, char *block_buf, +static void swap_inode_blocks(e2fsck_t ctx, ino_t ino, char *block_buf, struct ext2_inode *inode) { errcode_t retval; @@ -83,22 +83,25 @@ static void swap_inode_blocks(ext2_filsys fs, ino_t ino, char *block_buf, sb.ino = ino; sb.inode = inode; - sb.dir_buf = block_buf + fs->blocksize*3; + sb.dir_buf = block_buf + ctx->fs->blocksize*3; sb.errcode = 0; sb.isdir = 0; if (LINUX_S_ISDIR(inode->i_mode)) sb.isdir = 1; - retval = ext2fs_block_iterate(fs, ino, 0, block_buf, swap_block, &sb); + retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf, + swap_block, &sb); if (retval) { com_err("swap_inode_blocks", retval, "while calling ext2fs_block_iterate"); - fatal_error(0); + ctx->flags |= E2F_FLAG_ABORT; + return; } if (sb.errcode) { com_err("swap_inode_blocks", sb.errcode, "while calling iterator function"); - fatal_error(0); + ctx->flags |= E2F_FLAG_ABORT; + return; } } @@ -119,10 +122,11 @@ static void swap_inodes(e2fsck_t ctx) if (retval) { com_err("swap_inodes", retval, "while allocating inode buffer"); - fatal_error(0); + ctx->flags |= E2F_FLAG_ABORT; + return; } - block_buf = allocate_memory(fs->blocksize * 4, - "block interate buffer"); + block_buf = e2fsck_allocate_memory(ctx, fs->blocksize * 4, + "block interate buffer"); for (group = 0; group < fs->group_desc_count; group++) { retval = io_channel_read_blk(fs->io, fs->group_desc[group].bg_inode_table, @@ -131,7 +135,8 @@ static void swap_inodes(e2fsck_t ctx) com_err("swap_inodes", retval, "while reading inode table (group %d)", group); - fatal_error(0); + ctx->flags |= E2F_FLAG_ABORT; + return; } inode = (struct ext2_inode *) buf; for (i=0; i < fs->super->s_inodes_per_group; @@ -153,7 +158,10 @@ static void swap_inodes(e2fsck_t ctx) inode->i_block[EXT2_DIND_BLOCK] || inode->i_block[EXT2_TIND_BLOCK]) && ext2fs_inode_has_valid_blocks(inode))) - swap_inode_blocks(fs, ino, block_buf, inode); + swap_inode_blocks(ctx, ino, block_buf, inode); + + if (ctx->flags & E2F_FLAG_ABORT) + return; if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE) ext2fs_swap_inode(fs, inode, inode, 1); @@ -165,7 +173,8 @@ static void swap_inodes(e2fsck_t ctx) com_err("swap_inodes", retval, "while writing inode table (group %d)", group); - fatal_error(0); + ctx->flags |= E2F_FLAG_ABORT; + return; } } ext2fs_free_mem((void **) &buf); @@ -195,7 +204,8 @@ void swap_filesys(e2fsck_t ctx) "checked using fsck\n" "and not mounted before trying to " "byte-swap it.\n", ctx->device_name); - fatal_error(0); + ctx->flags |= E2F_FLAG_ABORT; + return; } if (fs->flags & EXT2_FLAG_SWAP_BYTES) { fs->flags &= ~(EXT2_FLAG_SWAP_BYTES| @@ -206,6 +216,8 @@ void swap_filesys(e2fsck_t ctx) fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE; } swap_inodes(ctx); + if (ctx->flags & E2F_FLAG_ABORT) + return; if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE) fs->flags |= EXT2_FLAG_SWAP_BYTES; fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ| diff --git a/e2fsck/unix.c b/e2fsck/unix.c index f5c31913..7c27a2aa 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -170,8 +170,8 @@ static void check_mount(e2fsck_t ctx) } printf("%s is mounted.\n\n", ctx->device_name); - printf("\a\a\a\aWARNING!!! Running e2fsck on a mounted filesystem " - "may cause\nSEVERE filesystem damage.\a\a\a\n\n"); + printf("\007\007\007\007WARNING!!! Running e2fsck on a mounted filesystem " + "may cause\nSEVERE filesystem damage.\007\007\007\n\n"); if (isatty (0) && isatty (1)) cont = ask_yn("Do you really want to continue", -1); else @@ -254,7 +254,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) newpath = malloc(sizeof (PATH_SET) + 1 + strlen (oldpath)); if (!newpath) - fatal_error("Couldn't malloc() newpath"); + fatal_error(ctx, "Couldn't malloc() newpath"); strcpy (newpath, PATH_SET); strcat (newpath, ":"); strcat (newpath, oldpath); @@ -320,7 +320,8 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) case 'l': bad_blocks_file = malloc(strlen(optarg)+1); if (!bad_blocks_file) - fatal_error("Couldn't malloc bad_blocks_file"); + fatal_error(ctx, + "Couldn't malloc bad_blocks_file"); strcpy(bad_blocks_file, optarg); break; case 'd': @@ -333,7 +334,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) #ifdef BLKFLSBUF flush = 1; #else - fatal_error ("-F not supported"); + fatal_error(ctx, "-F not supported"); #endif break; case 'v': @@ -384,14 +385,14 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) } close(fd); #else - fatal_error ("BLKFLSBUF not supported"); + fatal_error(ctx, "BLKFLSBUF not supported"); #endif /* BLKFLSBUF */ } if (swapfs) { if (cflag || bad_blocks_file) { fprintf(stderr, "Incompatible options not " "allowed when byte-swapping.\n"); - fatal_error(0); + exit(FSCK_ERROR); } } return 0; @@ -457,7 +458,8 @@ int main (int argc, char *argv[]) !(ctx->options & E2F_OPT_NO) && !(ctx->options & E2F_OPT_YES)) { if (!isatty (0) || !isatty (1)) - fatal_error("need terminal for interactive repairs"); + fatal_error(ctx, + "need terminal for interactive repairs"); } ctx->superblock = ctx->use_superblock; restart: @@ -520,7 +522,7 @@ restart: #endif else fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); - fatal_error(0); + exit(FSCK_ERROR); } ctx->fs = fs; fs->private = ctx; @@ -529,7 +531,8 @@ restart: com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH, "while trying to open %s", ctx->filesystem_name); - goto get_newer; + get_newer: + fatal_error(ctx, "Get a newer version of e2fsck!"); } #endif /* @@ -541,9 +544,7 @@ restart: (s->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) { com_err(ctx->program_name, EXT2_ET_UNSUPP_FEATURE, "(%s)", ctx->filesystem_name); - get_newer: - printf ("Get a newer version of e2fsck!\n"); - fatal_error(0); + goto get_newer; } if (s->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) { com_err(ctx->program_name, EXT2_ET_RO_UNSUPP_FEATURE, @@ -571,22 +572,29 @@ restart: if (ctx->superblock) set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0); check_super_block(ctx); + if (ctx->flags & E2F_FLAG_ABORT) + exit(FSCK_ERROR); check_if_skip(ctx); if (bad_blocks_file) read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks); else if (cflag) test_disk(ctx); + if (ctx->flags & E2F_FLAG_ABORT) + exit(FSCK_ERROR); if (normalize_swapfs) { if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == ext2fs_native_flag()) { fprintf(stderr, "%s: Filesystem byte order " "already normalized.\n", ctx->device_name); - fatal_error(0); + exit(FSCK_ERROR); } } - if (swapfs) + if (swapfs) { swap_filesys(ctx); + if (ctx->flags & E2F_FLAG_ABORT) + exit(FSCK_ERROR); + } /* * Mark the system as valid, 'til proven otherwise @@ -649,7 +657,7 @@ restart: } show_stats(ctx); - write_bitmaps(ctx); + e2fsck_write_bitmaps(ctx); ext2fs_close(fs); sync_disks(); diff --git a/e2fsck/util.c b/e2fsck/util.c index 46ceaa9b..37509c8e 100644 --- a/e2fsck/util.c +++ b/e2fsck/util.c @@ -20,14 +20,18 @@ #include #include -void fatal_error (const char *msg) +void fatal_error(e2fsck_t ctx, const char *msg) { if (msg) fprintf (stderr, "e2fsck: %s\n", msg); + ctx->flags |= E2F_FLAG_ABORT; + if (ctx->flags & E2F_FLAG_SETJMP_OK) + longjmp(ctx->abort_loc, 1); exit(FSCK_ERROR); } -void *allocate_memory(int size, const char *description) +void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, + const char *description) { void *ret; char buf[256]; @@ -38,7 +42,7 @@ void *allocate_memory(int size, const char *description) ret = malloc(size); if (!ret) { sprintf(buf, "Can't allocate %s\n", description); - fatal_error(buf); + fatal_error(ctx, buf); } memset(ret, 0, size); return ret; @@ -105,16 +109,16 @@ int ask (e2fsck_t ctx, const char * string, int def) return ask_yn(string, def); } -void read_bitmaps(e2fsck_t ctx) +void e2fsck_read_bitmaps(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; errcode_t retval; if (ctx->invalid_bitmaps) { com_err(ctx->program_name, 0, - "read_bitmaps: illegal bitmap block(s) for %s", + "e2fsck_read_bitmaps: illegal bitmap block(s) for %s", ctx->device_name); - fatal_error(0); + fatal_error(ctx, 0); } ehandler_operation("reading inode and block bitmaps"); @@ -124,11 +128,11 @@ void read_bitmaps(e2fsck_t ctx) com_err(ctx->program_name, retval, "while retrying to read bitmaps for %s", ctx->device_name); - fatal_error(0); + fatal_error(ctx, 0); } } -void write_bitmaps(e2fsck_t ctx) +void e2fsck_write_bitmaps(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; errcode_t retval; @@ -141,7 +145,7 @@ void write_bitmaps(e2fsck_t ctx) com_err(ctx->program_name, retval, "while retrying to write block bitmaps for %s", ctx->device_name); - fatal_error(0); + fatal_error(ctx, 0); } } @@ -153,7 +157,7 @@ void write_bitmaps(e2fsck_t ctx) com_err(ctx->program_name, retval, "while retrying to write inode bitmaps for %s", ctx->device_name); - fatal_error(0); + fatal_error(ctx, 0); } } } @@ -247,7 +251,7 @@ void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino, if (retval) { com_err("ext2fs_read_inode", retval, "while reading inode %ld in %s", ino, proc); - fatal_error(0); + fatal_error(ctx, 0); } } @@ -260,7 +264,7 @@ extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino, if (retval) { com_err("ext2fs_write_inode", retval, "while writing inode %ld in %s", ino, proc); - fatal_error(0); + fatal_error(ctx, 0); } } diff --git a/lib/ext2fs/Makefile.pq b/lib/ext2fs/Makefile.pq index 6afe1b42..2f7b654b 100644 --- a/lib/ext2fs/Makefile.pq +++ b/lib/ext2fs/Makefile.pq @@ -47,6 +47,3 @@ OBJS= alloc.obj \ !include $(TOPSRC)\powerquest\MCONFIG -ALL:: $(OBJS) - -!include $(TOPSRC)\powerquest\MAKEFILE.STD diff --git a/resize/Makefile.pq b/resize/Makefile.pq index 5421c6d8..bc60e092 100644 --- a/resize/Makefile.pq +++ b/resize/Makefile.pq @@ -7,9 +7,5 @@ OBJS= extent.obj \ ext2_inode_move.obj \ resize2fs.obj -ALL:: $(OBJS) - !include $(TOPSRC)\powerquest\MCONFIG - -!include $(TOPSRC)\powerquest\MAKEFILE.STD diff --git a/util/Makefile.pq b/util/Makefile.pq index 3ec35895..ccde1183 100644 --- a/util/Makefile.pq +++ b/util/Makefile.pq @@ -8,5 +8,3 @@ libecho.exe: libecho.c clean:: $(RM) libecho.exe - -!include $(TOPSRC)\powerquest\MAKEFILE.STD