1997-04-26 21:21:57 +08:00
|
|
|
/*
|
|
|
|
* ehandler.c --- handle bad block errors which come up during the
|
|
|
|
* course of an e2fsck session.
|
|
|
|
*
|
|
|
|
* Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
|
|
|
|
* under the terms of the GNU Public License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <termios.h>
|
|
|
|
|
|
|
|
#include "e2fsck.h"
|
|
|
|
|
1997-04-26 21:58:21 +08:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/resource.h>
|
|
|
|
|
1997-04-26 21:21:57 +08:00
|
|
|
static const char *operation;
|
|
|
|
|
|
|
|
static errcode_t e2fsck_handle_read_error(io_channel channel,
|
|
|
|
unsigned long block,
|
|
|
|
int count,
|
|
|
|
void *data,
|
|
|
|
size_t size,
|
|
|
|
int actual,
|
|
|
|
errcode_t error)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
char *p;
|
Many files:
e2fsck.h: If EXT2_FLAT_INCLUDES is defined, then assume all of
the ext2-specific header files are in a flat directory.
dirinfo.c, ehandler.c, pass1.c, pass1b.c, pass2.c, pass5.c,
super.c, swapfs.c, unix.c: Explicitly cast all assignments
from void * to be compatible with C++.
unix.c (sync_disk): Remove sync_disk and calls to that function,
since ext2fs_close() now takes care of this.
pass1.c, pass1b.c, pass2.c, pass3.c, swapfs, badblocks.c,
ehandler.c, unix.c: Change use of private to be priv_data, to
avoid C++ reserved name clash.
1998-01-19 22:50:49 +08:00
|
|
|
ext2_filsys fs = (ext2_filsys) channel->app_data;
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
e2fsck_t ctx;
|
|
|
|
|
Many files:
e2fsck.h: If EXT2_FLAT_INCLUDES is defined, then assume all of
the ext2-specific header files are in a flat directory.
dirinfo.c, ehandler.c, pass1.c, pass1b.c, pass2.c, pass5.c,
super.c, swapfs.c, unix.c: Explicitly cast all assignments
from void * to be compatible with C++.
unix.c (sync_disk): Remove sync_disk and calls to that function,
since ext2fs_close() now takes care of this.
pass1.c, pass1b.c, pass2.c, pass3.c, swapfs, badblocks.c,
ehandler.c, unix.c: Change use of private to be priv_data, to
avoid C++ reserved name clash.
1998-01-19 22:50:49 +08:00
|
|
|
ctx = (e2fsck_t) fs->priv_data;
|
1997-04-26 21:21:57 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If more than one block was read, try reading each block
|
|
|
|
* separately. We could use the actual bytes read to figure
|
|
|
|
* out where to start, but we don't bother.
|
|
|
|
*/
|
|
|
|
if (count > 1) {
|
|
|
|
p = (char *) data;
|
|
|
|
for (i=0; i < count; i++, p += channel->block_size, block++) {
|
|
|
|
error = io_channel_read_blk(channel, block,
|
|
|
|
1, p);
|
|
|
|
if (error)
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (operation)
|
Many files:
badblocks.c, e2fsck.h, ehandler.c, emptydir.c, extend.c, flushb.c,
iscan.c, message.c, pass1.c, pass1b.c, pass3.c pass4.c, pass5.c,
problem.c, scantest.c, swapfs.c, unix.c, util.c: Add
Internationalization support as suggested by Marco d'Itri
<md@linux.it>.
2000-02-07 11:11:03 +08:00
|
|
|
printf(_("Error reading block %lu (%s) while %s. "), block,
|
1997-04-26 21:21:57 +08:00
|
|
|
error_message(error), operation);
|
|
|
|
else
|
Many files:
badblocks.c, e2fsck.h, ehandler.c, emptydir.c, extend.c, flushb.c,
iscan.c, message.c, pass1.c, pass1b.c, pass3.c pass4.c, pass5.c,
problem.c, scantest.c, swapfs.c, unix.c, util.c: Add
Internationalization support as suggested by Marco d'Itri
<md@linux.it>.
2000-02-07 11:11:03 +08:00
|
|
|
printf(_("Error reading block %lu (%s). "), block,
|
1997-04-26 21:21:57 +08:00
|
|
|
error_message(error));
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
preenhalt(ctx);
|
2002-08-31 14:35:35 +08:00
|
|
|
if (ask(ctx, _("Ignore error"), 1)) {
|
|
|
|
if (ask(ctx, _("Force rewrite"), 1))
|
|
|
|
io_channel_write_blk(channel, block, 1, data);
|
1997-04-26 21:21:57 +08:00
|
|
|
return 0;
|
2002-08-31 14:35:35 +08:00
|
|
|
}
|
1997-04-26 21:21:57 +08:00
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
static errcode_t e2fsck_handle_write_error(io_channel channel,
|
|
|
|
unsigned long block,
|
|
|
|
int count,
|
|
|
|
const void *data,
|
|
|
|
size_t size,
|
|
|
|
int actual,
|
|
|
|
errcode_t error)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
const char *p;
|
Many files:
e2fsck.h: If EXT2_FLAT_INCLUDES is defined, then assume all of
the ext2-specific header files are in a flat directory.
dirinfo.c, ehandler.c, pass1.c, pass1b.c, pass2.c, pass5.c,
super.c, swapfs.c, unix.c: Explicitly cast all assignments
from void * to be compatible with C++.
unix.c (sync_disk): Remove sync_disk and calls to that function,
since ext2fs_close() now takes care of this.
pass1.c, pass1b.c, pass2.c, pass3.c, swapfs, badblocks.c,
ehandler.c, unix.c: Change use of private to be priv_data, to
avoid C++ reserved name clash.
1998-01-19 22:50:49 +08:00
|
|
|
ext2_filsys fs = (ext2_filsys) channel->app_data;
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
e2fsck_t ctx;
|
1997-04-26 21:21:57 +08:00
|
|
|
|
Many files:
e2fsck.h: If EXT2_FLAT_INCLUDES is defined, then assume all of
the ext2-specific header files are in a flat directory.
dirinfo.c, ehandler.c, pass1.c, pass1b.c, pass2.c, pass5.c,
super.c, swapfs.c, unix.c: Explicitly cast all assignments
from void * to be compatible with C++.
unix.c (sync_disk): Remove sync_disk and calls to that function,
since ext2fs_close() now takes care of this.
pass1.c, pass1b.c, pass2.c, pass3.c, swapfs, badblocks.c,
ehandler.c, unix.c: Change use of private to be priv_data, to
avoid C++ reserved name clash.
1998-01-19 22:50:49 +08:00
|
|
|
ctx = (e2fsck_t) fs->priv_data;
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
|
1997-04-26 21:21:57 +08:00
|
|
|
/*
|
|
|
|
* If more than one block was written, try writing each block
|
|
|
|
* separately. We could use the actual bytes read to figure
|
|
|
|
* out where to start, but we don't bother.
|
|
|
|
*/
|
|
|
|
if (count > 1) {
|
|
|
|
p = (const char *) data;
|
|
|
|
for (i=0; i < count; i++, p += channel->block_size, block++) {
|
|
|
|
error = io_channel_write_blk(channel, block,
|
|
|
|
1, p);
|
|
|
|
if (error)
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (operation)
|
Many files:
badblocks.c, e2fsck.h, ehandler.c, emptydir.c, extend.c, flushb.c,
iscan.c, message.c, pass1.c, pass1b.c, pass3.c pass4.c, pass5.c,
problem.c, scantest.c, swapfs.c, unix.c, util.c: Add
Internationalization support as suggested by Marco d'Itri
<md@linux.it>.
2000-02-07 11:11:03 +08:00
|
|
|
printf(_("Error writing block %lu (%s) while %s. "), block,
|
1997-04-26 21:21:57 +08:00
|
|
|
error_message(error), operation);
|
|
|
|
else
|
Many files:
badblocks.c, e2fsck.h, ehandler.c, emptydir.c, extend.c, flushb.c,
iscan.c, message.c, pass1.c, pass1b.c, pass3.c pass4.c, pass5.c,
problem.c, scantest.c, swapfs.c, unix.c, util.c: Add
Internationalization support as suggested by Marco d'Itri
<md@linux.it>.
2000-02-07 11:11:03 +08:00
|
|
|
printf(_("Error writing block %lu (%s). "), block,
|
1997-04-26 21:21:57 +08:00
|
|
|
error_message(error));
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
preenhalt(ctx);
|
Many files:
badblocks.c, e2fsck.h, ehandler.c, emptydir.c, extend.c, flushb.c,
iscan.c, message.c, pass1.c, pass1b.c, pass3.c pass4.c, pass5.c,
problem.c, scantest.c, swapfs.c, unix.c, util.c: Add
Internationalization support as suggested by Marco d'Itri
<md@linux.it>.
2000-02-07 11:11:03 +08:00
|
|
|
if (ask(ctx, _("Ignore error"), 1))
|
1997-04-26 21:21:57 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *ehandler_operation(const char *op)
|
|
|
|
{
|
|
|
|
const char *ret = operation;
|
|
|
|
|
|
|
|
operation = op;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ehandler_init(io_channel channel)
|
|
|
|
{
|
|
|
|
channel->read_error = e2fsck_handle_read_error;
|
|
|
|
channel->write_error = e2fsck_handle_write_error;
|
|
|
|
}
|