+Thu Nov 6 16:10:20 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * 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 <tytso@rsts-11.mit.edu>
+
+ * 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 <tytso@rsts-11.mit.edu>
* unix.c (main): Add a special case check for the error code EROFS
!include $(TOPSRC)\powerquest\MCONFIG
-ALL:: $(OBJS)
-
-!include $(TOPSRC)\powerquest\MAKEFILE.STD
FILE *f;
char buf[1024];
- read_bitmaps(ctx);
+ e2fsck_read_bitmaps(ctx);
/*
* Make sure the bad block inode is sane. If there are any
if (retval) {
com_err("ext2fs_block_iterate", retval,
"while sanity checking the bad blocks inode");
- fatal_error(0);
+ goto fatal;
}
/*
if (retval) {
com_err("ext2fs_read_bb_inode", retval,
"while reading the bad blocks inode");
- fatal_error(0);
+ goto fatal;
}
}
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,
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);
if (retval) {
com_err("ext2fs_read_bb_FILE", retval,
"while reading in list of bad blocks from file");
- fatal_error(0);
+ goto fatal;
}
/*
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)
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) {
}
/*
+ * 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
*/
struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
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);
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 */
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,
#ifdef BLKFLSBUF
flush = 1;
#else
- fatal_error ("-F not supported");
+ fprintf(stderr, "-F not supported");
+ exit(1);
#endif
break;
case 'I':
}
close(fd);
#else
- fatal_error ("BLKFLSBUF not supported");
+ fprintf(stderr, "BLKFLSBUF not supported");
+ exit(1);
#endif /* BLKFLSBUF */
}
}
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) {
if (retval) {
com_err(program_name, retval,
"while getting next inode");
- fatal_error(0);
+ exit(1);
}
if (ino == 0)
break;
*
* The following '@' expansions are supported:
*
+ * @A error allocating
* @b block
* @B bitmap
* @C conflicts with some other fs block
* letter <i> in the table below.
*/
static const char *abbrevs[] = {
+ "Aerror allocating",
"bblock",
"Bbitmap",
"Cconflicts with some other fs @b",
struct ext2_inode inode;
};
+struct scan_callback_struct {
+ e2fsck_t ctx;
+ char *block_buf;
+};
+
/*
* For the inodes to process list.
*/
#endif
unsigned char frag, fsize;
struct problem_context pctx;
+ struct scan_callback_struct scan_struct;
#ifdef RESOURCE_TRACK
init_resource_track(&rtrack);
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);
}
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;
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;
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;
}
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);
ctx = p->ctx;
pctx = p->pctx;
+ pctx->ino = EXT2_BAD_INO;
pctx->blk = blk;
pctx->blkcount = blockcnt;
"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);
&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;
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;
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);
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;
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;
struct check_dir_struct {
char *buf;
struct problem_context pctx;
+ int count, max;
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
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);
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;
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
/*
* 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)
* 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
#endif
struct problem_context pctx;
struct dir_info *dir;
-
+ unsigned long max, count;
+
#ifdef RESOURCE_TRACK
init_resource_track(&rtrack);
#endif
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);
* 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
* 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
/*
* 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);
#endif
struct problem_context pctx;
__u16 link_count, link_counted;
+ int group, max, j;
#ifdef RESOURCE_TRACK
init_resource_track(&rtrack);
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;
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);
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)
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);
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)) ||
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 >
#include "e2fsck.h"
#include "problem.h"
+#include "problemP.h"
#define PROMPT_NONE 0
#define PROMPT_FIX 1
#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
"Continue", /* 13 */
"Clone duplicate/bad blocks", /* 14 */
"Delete file", /* 15 */
+ "Suppress messages", /* 16 */
};
/*
"CONTINUING", /* 13 */
"DUPLICATE/BAD BLOCKS CLONED", /* 14 */
"FILE DELETED", /* 15 */
+ "SUPPRESSED", /* 16 */
};
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 */
"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 */
/* 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 */
/* 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 },
/* '.' 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 */
/* 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 */
/* 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 */
"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 */
preenhalt(ctx);
if (ptr->flags & PR_FATAL)
- fatal_error(0);
+ fatal_error(ctx, 0);
if (ptr->prompt == PROMPT_NONE) {
if (ptr->flags & PR_NOCOLLATE)
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;
}
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
/* 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 */
/* Error while reading inode (for clearing) */
#define PR_1_READ_INODE 0x010002C
+/* Suppress messages prompt */
+#define PR_1_SUPPRESS_MESSAGES 0x010002D
/*
* Pass 1b errors
/* Error deallocating inode */
#define PR_2_DEALLOC_INODE 0x020023
+/* Directory entry for '.' is big. Split? */
+#define PR_2_SPLIT_DOT 0x0200024
+
/*
* Pass 3 errors
*/
/* 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
*/
--- /dev/null
+/*
+ * 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 */
+
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);
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) {
* 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;
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;
}
}
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,
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;
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);
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);
"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|
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|
}
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
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);
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':
#ifdef BLKFLSBUF
flush = 1;
#else
- fatal_error ("-F not supported");
+ fatal_error(ctx, "-F not supported");
#endif
break;
case 'v':
}
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;
!(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:
#endif
else
fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
- fatal_error(0);
+ exit(FSCK_ERROR);
}
ctx->fs = fs;
fs->private = ctx;
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
/*
(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,
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
}
show_stats(ctx);
- write_bitmaps(ctx);
+ e2fsck_write_bitmaps(ctx);
ext2fs_close(fs);
sync_disks();
#include <sys/time.h>
#include <sys/resource.h>
-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];
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;
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");
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;
com_err(ctx->program_name, retval,
"while retrying to write block bitmaps for %s",
ctx->device_name);
- fatal_error(0);
+ fatal_error(ctx, 0);
}
}
com_err(ctx->program_name, retval,
"while retrying to write inode bitmaps for %s",
ctx->device_name);
- fatal_error(0);
+ fatal_error(ctx, 0);
}
}
}
if (retval) {
com_err("ext2fs_read_inode", retval,
"while reading inode %ld in %s", ino, proc);
- fatal_error(0);
+ fatal_error(ctx, 0);
}
}
if (retval) {
com_err("ext2fs_write_inode", retval,
"while writing inode %ld in %s", ino, proc);
- fatal_error(0);
+ fatal_error(ctx, 0);
}
}
!include $(TOPSRC)\powerquest\MCONFIG
-ALL:: $(OBJS)
-
-!include $(TOPSRC)\powerquest\MAKEFILE.STD
ext2_inode_move.obj \
resize2fs.obj
-ALL:: $(OBJS)
-
!include $(TOPSRC)\powerquest\MCONFIG
-
-!include $(TOPSRC)\powerquest\MAKEFILE.STD
clean::
$(RM) libecho.exe
-
-!include $(TOPSRC)\powerquest\MAKEFILE.STD