mirror of https://github.com/vitalif/e2fsprogs
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.bitmap-optimize
parent
d36d835b48
commit
f8188fff23
|
@ -1,3 +1,36 @@
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <i> in the table below.
|
||||
*/
|
||||
static const char *abbrevs[] = {
|
||||
"Aerror allocating",
|
||||
"bblock",
|
||||
"Bbitmap",
|
||||
"Cconflicts with some other fs @b",
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 >
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
@ -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) {
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -20,14 +20,18 @@
|
|||
#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];
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,3 @@ OBJS= alloc.obj \
|
|||
|
||||
!include $(TOPSRC)\powerquest\MCONFIG
|
||||
|
||||
ALL:: $(OBJS)
|
||||
|
||||
!include $(TOPSRC)\powerquest\MAKEFILE.STD
|
||||
|
|
|
@ -7,9 +7,5 @@ OBJS= extent.obj \
|
|||
ext2_inode_move.obj \
|
||||
resize2fs.obj
|
||||
|
||||
ALL:: $(OBJS)
|
||||
|
||||
!include $(TOPSRC)\powerquest\MCONFIG
|
||||
|
||||
|
||||
!include $(TOPSRC)\powerquest\MAKEFILE.STD
|
||||
|
|
|
@ -8,5 +8,3 @@ libecho.exe: libecho.c
|
|||
|
||||
clean::
|
||||
$(RM) libecho.exe
|
||||
|
||||
!include $(TOPSRC)\powerquest\MAKEFILE.STD
|
||||
|
|
Loading…
Reference in New Issue