1997-04-26 17:21:57 +04:00
|
|
|
/*
|
|
|
|
* util.c --- miscellaneous utilities
|
2008-08-28 07:07:54 +04:00
|
|
|
*
|
1997-04-29 20:15:03 +04:00
|
|
|
* Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
|
|
|
|
*
|
|
|
|
* %Begin-Header%
|
|
|
|
* This file may be redistributed under the terms of the GNU Public
|
|
|
|
* License.
|
|
|
|
* %End-Header%
|
1997-04-26 17:21:57 +04:00
|
|
|
*/
|
|
|
|
|
2011-09-19 01:34:37 +04:00
|
|
|
#include "config.h"
|
1997-04-26 17:21:57 +04:00
|
|
|
#include <stdlib.h>
|
2008-10-13 07:09:26 +04:00
|
|
|
#include <stdio.h>
|
1997-04-26 17:21:57 +04:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
2008-10-13 07:09:26 +04:00
|
|
|
#ifdef __linux__
|
|
|
|
#include <sys/utsname.h>
|
|
|
|
#endif
|
1999-10-20 22:24:31 +04:00
|
|
|
|
|
|
|
#ifdef HAVE_CONIO_H
|
|
|
|
#undef HAVE_TERMIOS_H
|
|
|
|
#include <conio.h>
|
1999-10-26 06:30:16 +04:00
|
|
|
#define read_a_char() getch()
|
1999-10-20 22:24:31 +04:00
|
|
|
#else
|
|
|
|
#ifdef HAVE_TERMIOS_H
|
1997-04-26 17:21:57 +04:00
|
|
|
#include <termios.h>
|
1999-10-20 22:24:31 +04:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
1999-03-16 22:32:52 +03:00
|
|
|
#ifdef HAVE_MALLOC_H
|
|
|
|
#include <malloc.h>
|
|
|
|
#endif
|
1997-04-26 17:21:57 +04:00
|
|
|
|
2007-10-22 06:04:03 +04:00
|
|
|
#ifdef HAVE_ERRNO_H
|
|
|
|
#include <errno.h>
|
|
|
|
#endif
|
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
#include "e2fsck.h"
|
|
|
|
|
2003-03-17 18:01:22 +03:00
|
|
|
extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
|
2002-07-24 15:42:02 +04:00
|
|
|
|
2012-03-18 07:21:00 +04:00
|
|
|
#include <stdarg.h>
|
2011-09-24 21:48:55 +04:00
|
|
|
#include <time.h>
|
1997-04-26 17:58:21 +04:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/resource.h>
|
|
|
|
|
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.
1997-11-14 08:23:04 +03:00
|
|
|
void fatal_error(e2fsck_t ctx, const char *msg)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
2011-11-01 11:32:28 +04:00
|
|
|
ext2_filsys fs = ctx->fs;
|
|
|
|
int exit_value = FSCK_ERROR;
|
|
|
|
|
2008-08-28 07:07:54 +04:00
|
|
|
if (msg)
|
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-03 21:48:10 +04:00
|
|
|
fprintf (stderr, "e2fsck: %s\n", msg);
|
2011-11-01 11:32:28 +04:00
|
|
|
if (!fs)
|
|
|
|
goto out;
|
2013-09-09 18:33:20 +04:00
|
|
|
if (fs->io && fs->super) {
|
2011-09-24 21:48:55 +04:00
|
|
|
ext2fs_mmp_stop(ctx->fs);
|
2001-05-05 10:47:24 +04:00
|
|
|
if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL)
|
2001-01-12 23:59:19 +03:00
|
|
|
io_channel_flush(ctx->fs->io);
|
|
|
|
else
|
2012-03-18 07:21:00 +04:00
|
|
|
log_err(ctx, "e2fsck: io manager magic bad!\n");
|
2001-01-12 23:59:19 +03:00
|
|
|
}
|
2011-11-01 11:32:28 +04:00
|
|
|
if (ext2fs_test_changed(fs)) {
|
|
|
|
exit_value |= FSCK_NONDESTRUCT;
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, _("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
|
2011-11-01 11:32:28 +04:00
|
|
|
ctx->device_name);
|
|
|
|
if (ctx->mount_flags & EXT2_MF_ISROOT)
|
|
|
|
exit_value |= FSCK_REBOOT;
|
|
|
|
}
|
|
|
|
if (!ext2fs_test_valid(fs)) {
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, _("\n%s: ********** WARNING: Filesystem still has "
|
|
|
|
"errors **********\n\n"), ctx->device_name);
|
2011-11-01 11:32:28 +04:00
|
|
|
exit_value |= FSCK_UNCORRECTED;
|
|
|
|
exit_value &= ~FSCK_NONDESTRUCT;
|
|
|
|
}
|
|
|
|
out:
|
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.
1997-11-14 08:23:04 +03:00
|
|
|
ctx->flags |= E2F_FLAG_ABORT;
|
|
|
|
if (ctx->flags & E2F_FLAG_SETJMP_OK)
|
|
|
|
longjmp(ctx->abort_loc, 1);
|
2011-11-01 11:32:28 +04:00
|
|
|
exit(exit_value);
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
|
|
|
|
2012-03-18 07:21:00 +04:00
|
|
|
void log_out(e2fsck_t ctx, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list pvar;
|
|
|
|
|
|
|
|
va_start(pvar, fmt);
|
|
|
|
vprintf(fmt, pvar);
|
|
|
|
va_end(pvar);
|
|
|
|
if (ctx->logf) {
|
|
|
|
va_start(pvar, fmt);
|
|
|
|
vfprintf(ctx->logf, fmt, pvar);
|
|
|
|
va_end(pvar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void log_err(e2fsck_t ctx, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list pvar;
|
|
|
|
|
|
|
|
va_start(pvar, fmt);
|
|
|
|
vfprintf(stderr, fmt, pvar);
|
|
|
|
va_end(pvar);
|
|
|
|
if (ctx->logf) {
|
|
|
|
va_start(pvar, fmt);
|
|
|
|
vfprintf(ctx->logf, fmt, pvar);
|
|
|
|
va_end(pvar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
1997-11-14 08:23:04 +03:00
|
|
|
void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
|
|
|
|
const char *description)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
|
|
|
void *ret;
|
|
|
|
char buf[256];
|
|
|
|
|
|
|
|
#ifdef DEBUG_ALLOCATE_MEMORY
|
2008-10-28 23:44:21 +03:00
|
|
|
printf("Allocating %u bytes for %s...\n", size, description);
|
1997-04-26 17:21:57 +04:00
|
|
|
#endif
|
|
|
|
ret = malloc(size);
|
|
|
|
if (!ret) {
|
2013-01-08 01:45:54 +04:00
|
|
|
sprintf(buf, "Can't allocate %u bytes for %s\n",
|
|
|
|
size, description);
|
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.
1997-11-14 08:23:04 +03:00
|
|
|
fatal_error(ctx, buf);
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
|
|
|
memset(ret, 0, size);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-08-28 07:07:54 +04:00
|
|
|
char *string_copy(e2fsck_t ctx EXT2FS_ATTR((unused)),
|
2003-12-07 09:28:50 +03:00
|
|
|
const char *str, int len)
|
2003-03-02 03:47:44 +03:00
|
|
|
{
|
|
|
|
char *ret;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2003-03-02 03:47:44 +03:00
|
|
|
if (!str)
|
|
|
|
return NULL;
|
|
|
|
if (!len)
|
|
|
|
len = strlen(str);
|
|
|
|
ret = malloc(len+1);
|
|
|
|
if (ret) {
|
|
|
|
strncpy(ret, str, len);
|
|
|
|
ret[len] = 0;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef HAVE_STRNLEN
|
|
|
|
/*
|
|
|
|
* Incredibly, libc5 doesn't appear to have strnlen. So we have to
|
|
|
|
* provide our own.
|
|
|
|
*/
|
|
|
|
int e2fsck_strnlen(const char * s, int count)
|
|
|
|
{
|
|
|
|
const char *cp = s;
|
|
|
|
|
|
|
|
while (count-- && *cp)
|
|
|
|
cp++;
|
|
|
|
return cp - s;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2002-07-24 15:42:02 +04:00
|
|
|
#ifndef HAVE_CONIO_H
|
2002-10-14 07:56:28 +04:00
|
|
|
static int read_a_char(void)
|
2002-07-24 15:42:02 +04:00
|
|
|
{
|
|
|
|
char c;
|
|
|
|
int r;
|
|
|
|
int fail = 0;
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
if (e2fsck_global_ctx &&
|
|
|
|
(e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
r = read(0, &c, 1);
|
|
|
|
if (r == 1)
|
|
|
|
return c;
|
|
|
|
if (fail++ > 100)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return EOF;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-03-18 07:21:00 +04:00
|
|
|
int ask_yn(e2fsck_t ctx, const char * string, int def)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
|
|
|
int c;
|
|
|
|
const char *defstr;
|
2001-01-06 08:55:58 +03:00
|
|
|
const char *short_yes = _("yY");
|
|
|
|
const char *short_no = _("nN");
|
1997-04-26 17:21:57 +04:00
|
|
|
|
1999-10-20 22:24:31 +04:00
|
|
|
#ifdef HAVE_TERMIOS_H
|
|
|
|
struct termios termios, tmp;
|
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
tcgetattr (0, &termios);
|
|
|
|
tmp = termios;
|
|
|
|
tmp.c_lflag &= ~(ICANON | ECHO);
|
1997-04-26 17:58:21 +04:00
|
|
|
tmp.c_cc[VMIN] = 1;
|
|
|
|
tmp.c_cc[VTIME] = 0;
|
1997-04-26 17:21:57 +04:00
|
|
|
tcsetattr (0, TCSANOW, &tmp);
|
1999-10-20 22:24:31 +04:00
|
|
|
#endif
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
if (def == 1)
|
2002-07-24 15:42:02 +04:00
|
|
|
defstr = _(_("<y>"));
|
1997-04-26 17:21:57 +04:00
|
|
|
else if (def == 0)
|
2002-07-24 15:42:02 +04:00
|
|
|
defstr = _(_("<n>"));
|
1997-04-26 17:21:57 +04:00
|
|
|
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 06:11:03 +03:00
|
|
|
defstr = _(" (y/n)");
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, "%s%s? ", string, defstr);
|
1997-04-26 17:21:57 +04:00
|
|
|
while (1) {
|
|
|
|
fflush (stdout);
|
1999-10-26 06:30:16 +04:00
|
|
|
if ((c = read_a_char()) == EOF)
|
1997-04-26 17:21:57 +04:00
|
|
|
break;
|
2002-07-24 15:42:02 +04:00
|
|
|
if (c == 3) {
|
|
|
|
#ifdef HAVE_TERMIOS_H
|
|
|
|
tcsetattr (0, TCSANOW, &termios);
|
|
|
|
#endif
|
2012-03-18 07:21:00 +04:00
|
|
|
if (ctx->flags & E2F_FLAG_SETJMP_OK) {
|
|
|
|
log_out(ctx, "\n");
|
2002-07-24 15:42:02 +04:00
|
|
|
longjmp(e2fsck_global_ctx->abort_loc, 1);
|
|
|
|
}
|
2013-12-16 07:11:40 +04:00
|
|
|
log_out(ctx, "%s", _("cancelled!\n"));
|
2002-07-24 15:42:02 +04:00
|
|
|
return 0;
|
|
|
|
}
|
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 06:11:03 +03:00
|
|
|
if (strchr(short_yes, (char) c)) {
|
1997-04-26 17:21:57 +04:00
|
|
|
def = 1;
|
|
|
|
break;
|
|
|
|
}
|
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 06:11:03 +03:00
|
|
|
else if (strchr(short_no, (char) c)) {
|
1997-04-26 17:21:57 +04:00
|
|
|
def = 0;
|
|
|
|
break;
|
|
|
|
}
|
e2fsck: make the "fs is mounted; continue?" prompt more paranoid
A user received the "file system is mounted; do you really want to
continue" prompt, and then instead of typing "n" for no, forgot that
he hadn't declined to continuation question, and typed the up-arrow
key, which in his locale, the 'A' in "^[[A" was interpreted as "yes",
and he lost data.
This was clearly the user's fault, but to make e2fsck a bit safer
against user stupidity/carelessness, we will change the "fs is
mounted; continue?" prompt to default to no, and treat the escape
character (along with the return and space characters, currently) as a
request for the default answer.
Addresses-Debian-Bug: #619859
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
2011-05-08 07:14:06 +04:00
|
|
|
else if ((c == 27 || c == ' ' || c == '\n') && (def != -1))
|
1997-04-26 17:21:57 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (def)
|
2013-12-16 07:11:40 +04:00
|
|
|
log_out(ctx, "%s", _("yes\n"));
|
1997-04-26 17:21:57 +04:00
|
|
|
else
|
2013-12-16 07:11:40 +04:00
|
|
|
log_out(ctx, "%s", _("no\n"));
|
1999-10-20 22:24:31 +04:00
|
|
|
#ifdef HAVE_TERMIOS_H
|
1997-04-26 17:21:57 +04:00
|
|
|
tcsetattr (0, TCSANOW, &termios);
|
1999-10-20 22:24:31 +04:00
|
|
|
#endif
|
1997-04-26 17:21:57 +04:00
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
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-03 21:48:10 +04:00
|
|
|
int ask (e2fsck_t ctx, const char * string, int def)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
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-03 21:48:10 +04:00
|
|
|
if (ctx->options & E2F_OPT_NO) {
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, _("%s? no\n\n"), string);
|
1997-04-26 17:21:57 +04:00
|
|
|
return 0;
|
|
|
|
}
|
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-03 21:48:10 +04:00
|
|
|
if (ctx->options & E2F_OPT_YES) {
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, _("%s? yes\n\n"), string);
|
1997-04-26 17:21:57 +04:00
|
|
|
return 1;
|
|
|
|
}
|
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-03 21:48:10 +04:00
|
|
|
if (ctx->options & E2F_OPT_PREEN) {
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, "%s? %s\n\n", string, def ? _("yes") : _("no"));
|
1997-04-26 17:21:57 +04:00
|
|
|
return def;
|
|
|
|
}
|
2012-03-18 07:21:00 +04:00
|
|
|
return ask_yn(ctx, string, def);
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
|
|
|
|
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.
1997-11-14 08:23:04 +03:00
|
|
|
void e2fsck_read_bitmaps(e2fsck_t ctx)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
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-03 21:48:10 +04:00
|
|
|
ext2_filsys fs = ctx->fs;
|
1997-04-26 17:21:57 +04:00
|
|
|
errcode_t retval;
|
2007-04-14 17:29:02 +04:00
|
|
|
const char *old_op;
|
2011-12-16 23:55:50 +04:00
|
|
|
unsigned int save_type;
|
1997-04-26 17:21:57 +04:00
|
|
|
|
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-03 21:48:10 +04:00
|
|
|
if (ctx->invalid_bitmaps) {
|
|
|
|
com_err(ctx->program_name, 0,
|
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 06:11:03 +03:00
|
|
|
_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
|
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-03 21:48:10 +04:00
|
|
|
ctx->device_name);
|
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.
1997-11-14 08:23:04 +03:00
|
|
|
fatal_error(ctx, 0);
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
1997-04-26 17:34:30 +04:00
|
|
|
|
2007-04-14 17:29:02 +04:00
|
|
|
old_op = ehandler_operation(_("reading inode and block bitmaps"));
|
2011-12-16 23:55:50 +04:00
|
|
|
e2fsck_set_bitmap_type(fs, EXT2FS_BMAP64_RBTREE, "fs_bitmaps",
|
|
|
|
&save_type);
|
1997-04-26 17:34:30 +04:00
|
|
|
retval = ext2fs_read_bitmaps(fs);
|
2011-12-16 23:55:50 +04:00
|
|
|
fs->default_bitmap_type = save_type;
|
2007-04-14 17:29:02 +04:00
|
|
|
ehandler_operation(old_op);
|
1997-04-26 17:34:30 +04:00
|
|
|
if (retval) {
|
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-03 21:48:10 +04:00
|
|
|
com_err(ctx->program_name, retval,
|
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 06:11:03 +03:00
|
|
|
_("while retrying to read bitmaps for %s"),
|
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-03 21:48:10 +04:00
|
|
|
ctx->device_name);
|
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.
1997-11-14 08:23:04 +03:00
|
|
|
fatal_error(ctx, 0);
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
1997-11-14 08:23:04 +03:00
|
|
|
void e2fsck_write_bitmaps(e2fsck_t ctx)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
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-03 21:48:10 +04:00
|
|
|
ext2_filsys fs = ctx->fs;
|
1997-04-26 17:21:57 +04:00
|
|
|
errcode_t retval;
|
2007-04-14 17:29:02 +04:00
|
|
|
const char *old_op;
|
1997-04-26 17:21:57 +04:00
|
|
|
|
2008-08-24 06:56:07 +04:00
|
|
|
old_op = ehandler_operation(_("writing block and inode bitmaps"));
|
|
|
|
retval = ext2fs_write_bitmaps(fs);
|
|
|
|
ehandler_operation(old_op);
|
|
|
|
if (retval) {
|
|
|
|
com_err(ctx->program_name, retval,
|
|
|
|
_("while rewriting block and inode bitmaps for %s"),
|
|
|
|
ctx->device_name);
|
|
|
|
fatal_error(ctx, 0);
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-03 21:48:10 +04:00
|
|
|
void preenhalt(e2fsck_t ctx)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
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-03 21:48:10 +04:00
|
|
|
ext2_filsys fs = ctx->fs;
|
|
|
|
|
|
|
|
if (!(ctx->options & E2F_OPT_PREEN))
|
1997-04-26 17:21:57 +04:00
|
|
|
return;
|
2012-03-18 07:21:00 +04:00
|
|
|
log_err(ctx, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
|
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 06:11:03 +03:00
|
|
|
"RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
|
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-03 21:48:10 +04:00
|
|
|
ctx->device_name);
|
2008-10-11 02:14:08 +04:00
|
|
|
ctx->flags |= E2F_FLAG_EXITING;
|
1997-04-26 17:58:21 +04:00
|
|
|
if (fs != NULL) {
|
|
|
|
fs->super->s_state |= EXT2_ERROR_FS;
|
|
|
|
ext2fs_mark_super_dirty(fs);
|
|
|
|
ext2fs_close(fs);
|
|
|
|
}
|
1997-04-26 17:21:57 +04:00
|
|
|
exit(FSCK_UNCORRECTED);
|
|
|
|
}
|
|
|
|
|
1997-10-20 05:38:32 +04:00
|
|
|
#ifdef RESOURCE_TRACK
|
2007-08-04 04:07:09 +04:00
|
|
|
void init_resource_track(struct resource_track *track, io_channel channel)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
1997-04-26 17:58:21 +04:00
|
|
|
#ifdef HAVE_GETRUSAGE
|
1997-04-26 17:21:57 +04:00
|
|
|
struct rusage r;
|
1997-04-26 17:58:21 +04:00
|
|
|
#endif
|
2007-08-04 04:07:09 +04:00
|
|
|
io_stats io_start = 0;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
track->brk_start = sbrk(0);
|
|
|
|
gettimeofday(&track->time_start, 0);
|
1997-04-26 17:58:21 +04:00
|
|
|
#ifdef HAVE_GETRUSAGE
|
2001-01-06 08:55:58 +03:00
|
|
|
#ifdef sun
|
|
|
|
memset(&r, 0, sizeof(struct rusage));
|
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-03 21:48:10 +04:00
|
|
|
#endif
|
1997-04-26 17:21:57 +04:00
|
|
|
getrusage(RUSAGE_SELF, &r);
|
|
|
|
track->user_start = r.ru_utime;
|
|
|
|
track->system_start = r.ru_stime;
|
1997-04-26 17:58:21 +04:00
|
|
|
#else
|
|
|
|
track->user_start.tv_sec = track->user_start.tv_usec = 0;
|
|
|
|
track->system_start.tv_sec = track->system_start.tv_usec = 0;
|
|
|
|
#endif
|
2007-08-04 04:07:09 +04:00
|
|
|
track->bytes_read = 0;
|
|
|
|
track->bytes_written = 0;
|
|
|
|
if (channel && channel->manager && channel->manager->get_stats)
|
|
|
|
channel->manager->get_stats(channel, &io_start);
|
|
|
|
if (io_start) {
|
|
|
|
track->bytes_read = io_start->bytes_read;
|
|
|
|
track->bytes_written = io_start->bytes_written;
|
|
|
|
}
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
|
|
|
|
1997-04-29 20:15:03 +04:00
|
|
|
#ifdef __GNUC__
|
|
|
|
#define _INLINE_ __inline__
|
|
|
|
#else
|
|
|
|
#define _INLINE_
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static _INLINE_ float timeval_subtract(struct timeval *tv1,
|
|
|
|
struct timeval *tv2)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
|
|
|
return ((tv1->tv_sec - tv2->tv_sec) +
|
|
|
|
((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
|
|
|
|
}
|
|
|
|
|
2009-05-28 17:55:10 +04:00
|
|
|
void print_resource_track(e2fsck_t ctx, const char *desc,
|
|
|
|
struct resource_track *track, io_channel channel)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
1997-04-26 17:58:21 +04:00
|
|
|
#ifdef HAVE_GETRUSAGE
|
1997-04-26 17:21:57 +04:00
|
|
|
struct rusage r;
|
1999-03-16 22:32:52 +03:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_MALLINFO
|
|
|
|
struct mallinfo malloc_info;
|
1997-04-26 17:58:21 +04:00
|
|
|
#endif
|
1997-04-26 17:21:57 +04:00
|
|
|
struct timeval time_end;
|
|
|
|
|
2009-05-28 17:55:10 +04:00
|
|
|
if ((desc && !(ctx->options & E2F_OPT_TIME2)) ||
|
|
|
|
(!desc && !(ctx->options & E2F_OPT_TIME)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
e2fsck_clear_progbar(ctx);
|
1997-04-26 17:21:57 +04:00
|
|
|
gettimeofday(&time_end, 0);
|
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-03 21:48:10 +04:00
|
|
|
|
|
|
|
if (desc)
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, "%s: ", desc);
|
1999-03-16 22:32:52 +03:00
|
|
|
|
|
|
|
#ifdef HAVE_MALLINFO
|
2009-05-28 10:47:37 +04:00
|
|
|
#define kbytes(x) (((unsigned long)(x) + 1023) / 1024)
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1999-03-16 22:32:52 +03:00
|
|
|
malloc_info = mallinfo();
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, _("Memory used: %luk/%luk (%luk/%luk), "),
|
|
|
|
kbytes(malloc_info.arena), kbytes(malloc_info.hblkhd),
|
|
|
|
kbytes(malloc_info.uordblks), kbytes(malloc_info.fordblks));
|
1999-03-16 22:32:52 +03:00
|
|
|
#else
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, _("Memory used: %lu, "),
|
|
|
|
(unsigned long) (((char *) sbrk(0)) -
|
|
|
|
((char *) track->brk_start)));
|
2008-08-28 07:07:54 +04:00
|
|
|
#endif
|
1997-04-26 17:58:21 +04:00
|
|
|
#ifdef HAVE_GETRUSAGE
|
1997-04-26 17:21:57 +04:00
|
|
|
getrusage(RUSAGE_SELF, &r);
|
|
|
|
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, _("time: %5.2f/%5.2f/%5.2f\n"),
|
|
|
|
timeval_subtract(&time_end, &track->time_start),
|
|
|
|
timeval_subtract(&r.ru_utime, &track->user_start),
|
|
|
|
timeval_subtract(&r.ru_stime, &track->system_start));
|
1997-04-26 17:58:21 +04:00
|
|
|
#else
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, _("elapsed time: %6.3f\n"),
|
|
|
|
timeval_subtract(&time_end, &track->time_start));
|
1997-04-26 17:58:21 +04:00
|
|
|
#endif
|
2007-08-04 04:07:09 +04:00
|
|
|
#define mbytes(x) (((x) + 1048575) / 1048576)
|
|
|
|
if (channel && channel->manager && channel->manager->get_stats) {
|
|
|
|
io_stats delta = 0;
|
|
|
|
unsigned long long bytes_read = 0;
|
|
|
|
unsigned long long bytes_written = 0;
|
|
|
|
|
|
|
|
if (desc)
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, "%s: ", desc);
|
2007-08-04 04:07:09 +04:00
|
|
|
|
|
|
|
channel->manager->get_stats(channel, &delta);
|
|
|
|
if (delta) {
|
|
|
|
bytes_read = delta->bytes_read - track->bytes_read;
|
2008-08-28 07:07:54 +04:00
|
|
|
bytes_written = delta->bytes_written -
|
2007-08-04 04:07:09 +04:00
|
|
|
track->bytes_written;
|
|
|
|
}
|
2012-03-18 07:21:00 +04:00
|
|
|
log_out(ctx, "I/O read: %lluMB, write: %lluMB, "
|
|
|
|
"rate: %.2fMB/s\n",
|
|
|
|
mbytes(bytes_read), mbytes(bytes_written),
|
|
|
|
(double)mbytes(bytes_read + bytes_written) /
|
|
|
|
timeval_subtract(&time_end, &track->time_start));
|
2007-08-04 04:07:09 +04:00
|
|
|
}
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
1997-10-20 05:38:32 +04:00
|
|
|
#endif /* RESOURCE_TRACK */
|
1997-04-26 17:21:57 +04:00
|
|
|
|
1997-11-03 22:42:40 +03:00
|
|
|
void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
|
1997-04-26 17:34:30 +04:00
|
|
|
struct ext2_inode * inode, const char *proc)
|
|
|
|
{
|
2013-12-03 06:37:10 +04:00
|
|
|
errcode_t retval;
|
1997-04-26 17:34:30 +04:00
|
|
|
|
1997-11-03 22:42:40 +03:00
|
|
|
retval = ext2fs_read_inode(ctx->fs, ino, inode);
|
1997-04-26 17:34:30 +04:00
|
|
|
if (retval) {
|
|
|
|
com_err("ext2fs_read_inode", retval,
|
2008-10-28 23:44:21 +03:00
|
|
|
_("while reading inode %lu in %s"), ino, proc);
|
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.
1997-11-14 08:23:04 +03:00
|
|
|
fatal_error(ctx, 0);
|
1997-04-26 17:34:30 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-02 11:16:32 +03:00
|
|
|
void e2fsck_read_inode_full(e2fsck_t ctx, unsigned long ino,
|
|
|
|
struct ext2_inode *inode, int bufsize,
|
|
|
|
const char *proc)
|
|
|
|
{
|
2013-12-03 06:37:10 +04:00
|
|
|
errcode_t retval;
|
2008-02-02 11:16:32 +03:00
|
|
|
|
|
|
|
retval = ext2fs_read_inode_full(ctx->fs, ino, inode, bufsize);
|
|
|
|
if (retval) {
|
|
|
|
com_err("ext2fs_read_inode_full", retval,
|
2008-10-28 23:44:21 +03:00
|
|
|
_("while reading inode %lu in %s"), ino, proc);
|
2008-02-02 11:16:32 +03:00
|
|
|
fatal_error(ctx, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-17 03:56:36 +04:00
|
|
|
void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
|
|
|
|
struct ext2_inode * inode, int bufsize,
|
|
|
|
const char *proc)
|
2005-03-21 21:15:45 +03:00
|
|
|
{
|
2013-12-03 06:37:10 +04:00
|
|
|
errcode_t retval;
|
2005-03-21 21:15:45 +03:00
|
|
|
|
|
|
|
retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
|
|
|
|
if (retval) {
|
|
|
|
com_err("ext2fs_write_inode", retval,
|
2008-10-28 23:44:21 +03:00
|
|
|
_("while writing inode %lu in %s"), ino, proc);
|
2005-03-21 21:15:45 +03:00
|
|
|
fatal_error(ctx, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-17 03:56:36 +04:00
|
|
|
void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
|
|
|
|
struct ext2_inode * inode, const char *proc)
|
1997-04-26 17:34:30 +04:00
|
|
|
{
|
2013-12-03 06:37:10 +04:00
|
|
|
errcode_t retval;
|
1997-04-26 17:34:30 +04:00
|
|
|
|
1997-11-03 22:42:40 +03:00
|
|
|
retval = ext2fs_write_inode(ctx->fs, ino, inode);
|
1997-04-26 17:34:30 +04:00
|
|
|
if (retval) {
|
|
|
|
com_err("ext2fs_write_inode", retval,
|
2008-10-28 23:44:21 +03:00
|
|
|
_("while writing inode %lu in %s"), ino, proc);
|
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.
1997-11-14 08:23:04 +03:00
|
|
|
fatal_error(ctx, 0);
|
1997-04-26 17:34:30 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
#ifdef MTRACE
|
|
|
|
void mtrace_print(char *mesg)
|
|
|
|
{
|
|
|
|
FILE *malloc_get_mallstream();
|
|
|
|
FILE *f = malloc_get_mallstream();
|
|
|
|
|
|
|
|
if (f)
|
|
|
|
fprintf(f, "============= %s\n", mesg);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-10-07 17:51:48 +04:00
|
|
|
blk64_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
|
|
|
|
io_manager manager)
|
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-03 21:48:10 +04:00
|
|
|
{
|
2001-12-24 06:27:52 +03:00
|
|
|
struct ext2_super_block *sb;
|
|
|
|
io_channel io = NULL;
|
2001-12-24 06:56:12 +03:00
|
|
|
void *buf = NULL;
|
2001-12-24 06:27:52 +03:00
|
|
|
int blocksize;
|
2013-10-07 17:51:48 +04:00
|
|
|
blk64_t superblock, ret_sb = 8193;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2001-12-24 06:27:52 +03:00
|
|
|
if (fs && fs->super) {
|
|
|
|
ret_sb = (fs->super->s_blocks_per_group +
|
|
|
|
fs->super->s_first_data_block);
|
|
|
|
if (ctx) {
|
|
|
|
ctx->superblock = ret_sb;
|
|
|
|
ctx->blocksize = fs->blocksize;
|
|
|
|
}
|
|
|
|
return ret_sb;
|
|
|
|
}
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2001-12-24 06:27:52 +03:00
|
|
|
if (ctx) {
|
|
|
|
if (ctx->blocksize) {
|
|
|
|
ret_sb = ctx->blocksize * 8;
|
|
|
|
if (ctx->blocksize == 1024)
|
|
|
|
ret_sb++;
|
|
|
|
ctx->superblock = ret_sb;
|
|
|
|
return ret_sb;
|
|
|
|
}
|
|
|
|
ctx->superblock = ret_sb;
|
|
|
|
ctx->blocksize = 1024;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!name || !manager)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (manager->open(name, 0, &io) != 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
|
|
|
|
goto cleanup;
|
|
|
|
sb = (struct ext2_super_block *) buf;
|
|
|
|
|
2002-05-16 13:20:07 +04:00
|
|
|
for (blocksize = EXT2_MIN_BLOCK_SIZE;
|
|
|
|
blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
|
2001-12-24 06:27:52 +03:00
|
|
|
superblock = blocksize*8;
|
|
|
|
if (blocksize == 1024)
|
|
|
|
superblock++;
|
|
|
|
io_channel_set_blksize(io, blocksize);
|
2009-09-08 05:14:24 +04:00
|
|
|
if (io_channel_read_blk64(io, superblock,
|
2001-12-24 06:27:52 +03:00
|
|
|
-SUPERBLOCK_SIZE, buf))
|
|
|
|
continue;
|
2007-08-11 10:57:31 +04:00
|
|
|
#ifdef WORDS_BIGENDIAN
|
2001-12-24 06:27:52 +03:00
|
|
|
if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
|
|
|
|
ext2fs_swap_super(sb);
|
|
|
|
#endif
|
e2fsck: Add blocksize sanity check when finding a backup superblock
I've been investigating why e2fsck refuses to restore the backup superblock
of a partition with a broken primary superblock.
The partition in question has a block size of 4096, and mke2fs reports that
backup superblocks were created on blocks 32768, 98304, 163840, ...
When running e2fsck, get_backup_sb starts by guessing a block size of 1024
and backup superblock at block 8193. I'm not sure why, but it actually finds
a superblock at this location, so returns a context with superblock 8193,
blocksize 1024.
Later on, ext2fs_open2() tries to process this superblock. It then realises
that the block size value stored in the superblock (4096) does not match what
it was told (1024), so it bails out with EXT2_ET_UNEXPECTED_BLOCK_SIZE. fsck
aborts without fixing the partition.
The following patch solves the problem by discounting superblocks which do
not meet the currently-sought block size.
As a result, block 32768 (blocksize=4096) is now used to restore the backup,
which agrees with the first location that mke2fs listed.
Signed-off-by: Daniel Drake <d.drake@mmm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
2007-05-31 19:56:17 +04:00
|
|
|
if ((sb->s_magic == EXT2_SUPER_MAGIC) &&
|
|
|
|
(EXT2_BLOCK_SIZE(sb) == blocksize)) {
|
2003-08-25 05:36:38 +04:00
|
|
|
ret_sb = superblock;
|
|
|
|
if (ctx) {
|
|
|
|
ctx->superblock = superblock;
|
|
|
|
ctx->blocksize = blocksize;
|
|
|
|
}
|
2001-12-24 06:27:52 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (io)
|
|
|
|
io_channel_close(io);
|
|
|
|
if (buf)
|
|
|
|
ext2fs_free_mem(&buf);
|
|
|
|
return (ret_sb);
|
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-03 21:48:10 +04:00
|
|
|
}
|
1997-04-26 17:21:57 +04:00
|
|
|
|
ChangeLog, e2fsck.h, pass1.c, pass2.c, pass3.c, problem.c, problem.h, util.c:
pass1.c (e2fsck_pass1): If the filesystem does not support imagic
inodes, if an inode has the imagic flag set, offer to clear the imagic
flag. If a valid device/fifo/socket has the immutable flag set, call
the new helper function check_immutable() to offerto clear the
immutable flag.
pass2.c (check_filetype): Use the new ext2_file_type() helper function
instead of calculating the file_type information manually.
pass3.c (e2fsck_reconnect_file): When adding a link to lost+found,
calculate the filetype information so that ext2fs_link() can use the
information if applicable. (get_lost_and_found): Create the
/lost+found directory with the correct filetype information if
applicable.
util.c (ext2_file_type), e2fsck.h: New function which returns the
directory entry file type information given the inode's mode bits.
problem.c, problem.h: Added new problem codes PR_1_SET_IMAGIC and
PR_1_SET_IMMUTABLE.
ChangeLog, mke2fs.8.in:
mke2fs.8.in: Update manual page so that the sparse_option filesystem
option is properly named.
1999-11-10 16:34:40 +03:00
|
|
|
/*
|
|
|
|
* Given a mode, return the ext2 file type
|
|
|
|
*/
|
|
|
|
int ext2_file_type(unsigned int mode)
|
|
|
|
{
|
|
|
|
if (LINUX_S_ISREG(mode))
|
|
|
|
return EXT2_FT_REG_FILE;
|
|
|
|
|
|
|
|
if (LINUX_S_ISDIR(mode))
|
|
|
|
return EXT2_FT_DIR;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
ChangeLog, e2fsck.h, pass1.c, pass2.c, pass3.c, problem.c, problem.h, util.c:
pass1.c (e2fsck_pass1): If the filesystem does not support imagic
inodes, if an inode has the imagic flag set, offer to clear the imagic
flag. If a valid device/fifo/socket has the immutable flag set, call
the new helper function check_immutable() to offerto clear the
immutable flag.
pass2.c (check_filetype): Use the new ext2_file_type() helper function
instead of calculating the file_type information manually.
pass3.c (e2fsck_reconnect_file): When adding a link to lost+found,
calculate the filetype information so that ext2fs_link() can use the
information if applicable. (get_lost_and_found): Create the
/lost+found directory with the correct filetype information if
applicable.
util.c (ext2_file_type), e2fsck.h: New function which returns the
directory entry file type information given the inode's mode bits.
problem.c, problem.h: Added new problem codes PR_1_SET_IMAGIC and
PR_1_SET_IMMUTABLE.
ChangeLog, mke2fs.8.in:
mke2fs.8.in: Update manual page so that the sparse_option filesystem
option is properly named.
1999-11-10 16:34:40 +03:00
|
|
|
if (LINUX_S_ISCHR(mode))
|
|
|
|
return EXT2_FT_CHRDEV;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
ChangeLog, e2fsck.h, pass1.c, pass2.c, pass3.c, problem.c, problem.h, util.c:
pass1.c (e2fsck_pass1): If the filesystem does not support imagic
inodes, if an inode has the imagic flag set, offer to clear the imagic
flag. If a valid device/fifo/socket has the immutable flag set, call
the new helper function check_immutable() to offerto clear the
immutable flag.
pass2.c (check_filetype): Use the new ext2_file_type() helper function
instead of calculating the file_type information manually.
pass3.c (e2fsck_reconnect_file): When adding a link to lost+found,
calculate the filetype information so that ext2fs_link() can use the
information if applicable. (get_lost_and_found): Create the
/lost+found directory with the correct filetype information if
applicable.
util.c (ext2_file_type), e2fsck.h: New function which returns the
directory entry file type information given the inode's mode bits.
problem.c, problem.h: Added new problem codes PR_1_SET_IMAGIC and
PR_1_SET_IMMUTABLE.
ChangeLog, mke2fs.8.in:
mke2fs.8.in: Update manual page so that the sparse_option filesystem
option is properly named.
1999-11-10 16:34:40 +03:00
|
|
|
if (LINUX_S_ISBLK(mode))
|
|
|
|
return EXT2_FT_BLKDEV;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
ChangeLog, e2fsck.h, pass1.c, pass2.c, pass3.c, problem.c, problem.h, util.c:
pass1.c (e2fsck_pass1): If the filesystem does not support imagic
inodes, if an inode has the imagic flag set, offer to clear the imagic
flag. If a valid device/fifo/socket has the immutable flag set, call
the new helper function check_immutable() to offerto clear the
immutable flag.
pass2.c (check_filetype): Use the new ext2_file_type() helper function
instead of calculating the file_type information manually.
pass3.c (e2fsck_reconnect_file): When adding a link to lost+found,
calculate the filetype information so that ext2fs_link() can use the
information if applicable. (get_lost_and_found): Create the
/lost+found directory with the correct filetype information if
applicable.
util.c (ext2_file_type), e2fsck.h: New function which returns the
directory entry file type information given the inode's mode bits.
problem.c, problem.h: Added new problem codes PR_1_SET_IMAGIC and
PR_1_SET_IMMUTABLE.
ChangeLog, mke2fs.8.in:
mke2fs.8.in: Update manual page so that the sparse_option filesystem
option is properly named.
1999-11-10 16:34:40 +03:00
|
|
|
if (LINUX_S_ISLNK(mode))
|
|
|
|
return EXT2_FT_SYMLINK;
|
|
|
|
|
|
|
|
if (LINUX_S_ISFIFO(mode))
|
|
|
|
return EXT2_FT_FIFO;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
ChangeLog, e2fsck.h, pass1.c, pass2.c, pass3.c, problem.c, problem.h, util.c:
pass1.c (e2fsck_pass1): If the filesystem does not support imagic
inodes, if an inode has the imagic flag set, offer to clear the imagic
flag. If a valid device/fifo/socket has the immutable flag set, call
the new helper function check_immutable() to offerto clear the
immutable flag.
pass2.c (check_filetype): Use the new ext2_file_type() helper function
instead of calculating the file_type information manually.
pass3.c (e2fsck_reconnect_file): When adding a link to lost+found,
calculate the filetype information so that ext2fs_link() can use the
information if applicable. (get_lost_and_found): Create the
/lost+found directory with the correct filetype information if
applicable.
util.c (ext2_file_type), e2fsck.h: New function which returns the
directory entry file type information given the inode's mode bits.
problem.c, problem.h: Added new problem codes PR_1_SET_IMAGIC and
PR_1_SET_IMMUTABLE.
ChangeLog, mke2fs.8.in:
mke2fs.8.in: Update manual page so that the sparse_option filesystem
option is properly named.
1999-11-10 16:34:40 +03:00
|
|
|
if (LINUX_S_ISSOCK(mode))
|
|
|
|
return EXT2_FT_SOCK;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
ChangeLog, e2fsck.h, pass1.c, pass2.c, pass3.c, problem.c, problem.h, util.c:
pass1.c (e2fsck_pass1): If the filesystem does not support imagic
inodes, if an inode has the imagic flag set, offer to clear the imagic
flag. If a valid device/fifo/socket has the immutable flag set, call
the new helper function check_immutable() to offerto clear the
immutable flag.
pass2.c (check_filetype): Use the new ext2_file_type() helper function
instead of calculating the file_type information manually.
pass3.c (e2fsck_reconnect_file): When adding a link to lost+found,
calculate the filetype information so that ext2fs_link() can use the
information if applicable. (get_lost_and_found): Create the
/lost+found directory with the correct filetype information if
applicable.
util.c (ext2_file_type), e2fsck.h: New function which returns the
directory entry file type information given the inode's mode bits.
problem.c, problem.h: Added new problem codes PR_1_SET_IMAGIC and
PR_1_SET_IMMUTABLE.
ChangeLog, mke2fs.8.in:
mke2fs.8.in: Update manual page so that the sparse_option filesystem
option is properly named.
1999-11-10 16:34:40 +03:00
|
|
|
return 0;
|
|
|
|
}
|
2007-10-22 06:04:03 +04:00
|
|
|
|
|
|
|
#define STRIDE_LENGTH 8
|
|
|
|
/*
|
|
|
|
* Helper function which zeros out _num_ blocks starting at _blk_. In
|
|
|
|
* case of an error, the details of the error is returned via _ret_blk_
|
|
|
|
* and _ret_count_ if they are non-NULL pointers. Returns 0 on
|
|
|
|
* success, and an error code on an error.
|
|
|
|
*
|
|
|
|
* As a special case, if the first argument is NULL, then it will
|
|
|
|
* attempt to free the static zeroizing buffer. (This is to keep
|
|
|
|
* programs that check for memory leaks happy.)
|
|
|
|
*/
|
|
|
|
errcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num,
|
|
|
|
blk_t *ret_blk, int *ret_count)
|
|
|
|
{
|
2013-01-01 22:28:27 +04:00
|
|
|
int j, count;
|
2007-10-22 06:04:03 +04:00
|
|
|
static char *buf;
|
|
|
|
errcode_t retval;
|
|
|
|
|
|
|
|
/* If fs is null, clean up the static buffer and return */
|
|
|
|
if (!fs) {
|
|
|
|
if (buf) {
|
|
|
|
free(buf);
|
|
|
|
buf = 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* Allocate the zeroizing buffer if necessary */
|
|
|
|
if (!buf) {
|
|
|
|
buf = malloc(fs->blocksize * STRIDE_LENGTH);
|
|
|
|
if (!buf) {
|
2013-12-16 07:11:40 +04:00
|
|
|
com_err("malloc", ENOMEM, "%s",
|
2007-10-22 06:04:03 +04:00
|
|
|
_("while allocating zeroizing buffer"));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
|
|
|
|
}
|
|
|
|
/* OK, do the write loop */
|
|
|
|
for (j = 0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) {
|
|
|
|
count = num - j;
|
|
|
|
if (count > STRIDE_LENGTH)
|
|
|
|
count = STRIDE_LENGTH;
|
2009-09-08 05:14:24 +04:00
|
|
|
retval = io_channel_write_blk64(fs->io, blk, count, buf);
|
2007-10-22 06:04:03 +04:00
|
|
|
if (retval) {
|
|
|
|
if (ret_count)
|
|
|
|
*ret_count = count;
|
|
|
|
if (ret_blk)
|
|
|
|
*ret_blk = blk;
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2008-10-13 07:09:26 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check to see if a filesystem is in /proc/filesystems.
|
|
|
|
* Returns 1 if found, 0 if not
|
|
|
|
*/
|
|
|
|
int fs_proc_check(const char *fs_name)
|
|
|
|
{
|
|
|
|
FILE *f;
|
|
|
|
char buf[80], *cp, *t;
|
|
|
|
|
|
|
|
f = fopen("/proc/filesystems", "r");
|
|
|
|
if (!f)
|
|
|
|
return (0);
|
|
|
|
while (!feof(f)) {
|
|
|
|
if (!fgets(buf, sizeof(buf), f))
|
|
|
|
break;
|
|
|
|
cp = buf;
|
|
|
|
if (!isspace(*cp)) {
|
|
|
|
while (*cp && !isspace(*cp))
|
|
|
|
cp++;
|
|
|
|
}
|
|
|
|
while (*cp && isspace(*cp))
|
|
|
|
cp++;
|
|
|
|
if ((t = strchr(cp, '\n')) != NULL)
|
|
|
|
*t = 0;
|
|
|
|
if ((t = strchr(cp, '\t')) != NULL)
|
|
|
|
*t = 0;
|
|
|
|
if ((t = strchr(cp, ' ')) != NULL)
|
|
|
|
*t = 0;
|
|
|
|
if (!strcmp(fs_name, cp)) {
|
|
|
|
fclose(f);
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check to see if a filesystem is available as a module
|
|
|
|
* Returns 1 if found, 0 if not
|
|
|
|
*/
|
|
|
|
int check_for_modules(const char *fs_name)
|
|
|
|
{
|
|
|
|
#ifdef __linux__
|
|
|
|
struct utsname uts;
|
|
|
|
FILE *f;
|
|
|
|
char buf[1024], *cp, *t;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (uname(&uts))
|
|
|
|
return (0);
|
|
|
|
snprintf(buf, sizeof(buf), "/lib/modules/%s/modules.dep", uts.release);
|
|
|
|
|
|
|
|
f = fopen(buf, "r");
|
|
|
|
if (!f)
|
|
|
|
return (0);
|
|
|
|
while (!feof(f)) {
|
|
|
|
if (!fgets(buf, sizeof(buf), f))
|
|
|
|
break;
|
|
|
|
if ((cp = strchr(buf, ':')) != NULL)
|
|
|
|
*cp = 0;
|
|
|
|
else
|
|
|
|
continue;
|
|
|
|
if ((cp = strrchr(buf, '/')) != NULL)
|
|
|
|
cp++;
|
2009-02-25 00:13:39 +03:00
|
|
|
else
|
|
|
|
cp = buf;
|
2008-10-13 07:09:26 +04:00
|
|
|
i = strlen(cp);
|
|
|
|
if (i > 3) {
|
|
|
|
t = cp + i - 3;
|
|
|
|
if (!strcmp(t, ".ko"))
|
|
|
|
*t = 0;
|
|
|
|
}
|
|
|
|
if (!strcmp(cp, fs_name)) {
|
|
|
|
fclose(f);
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
#endif /* __linux__ */
|
|
|
|
return (0);
|
|
|
|
}
|
2009-04-22 23:09:41 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper function that does the right thing if write returns a
|
|
|
|
* partial write, or an EGAIN/EINTR error.
|
|
|
|
*/
|
|
|
|
int write_all(int fd, char *buf, size_t count)
|
|
|
|
{
|
|
|
|
ssize_t ret;
|
|
|
|
int c = 0;
|
|
|
|
|
|
|
|
while (count > 0) {
|
|
|
|
ret = write(fd, buf, count);
|
|
|
|
if (ret < 0) {
|
|
|
|
if ((errno == EAGAIN) || (errno == EINTR))
|
|
|
|
continue;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
count -= ret;
|
|
|
|
buf += ret;
|
|
|
|
c += ret;
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
}
|
2011-09-24 21:48:55 +04:00
|
|
|
|
|
|
|
void dump_mmp_msg(struct mmp_struct *mmp, const char *msg)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (msg)
|
|
|
|
printf("MMP check failed: %s\n", msg);
|
|
|
|
if (mmp) {
|
|
|
|
time_t t = mmp->mmp_time;
|
|
|
|
|
|
|
|
printf("MMP error info: last update: %s node: %s device: %s\n",
|
|
|
|
ctime(&t), mmp->mmp_nodename, mmp->mmp_bdevname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
errcode_t e2fsck_mmp_update(ext2_filsys fs)
|
|
|
|
{
|
|
|
|
errcode_t retval;
|
|
|
|
|
|
|
|
retval = ext2fs_mmp_update(fs);
|
|
|
|
if (retval == EXT2_ET_MMP_CHANGE_ABORT)
|
|
|
|
dump_mmp_msg(fs->mmp_cmp,
|
|
|
|
_("UNEXPECTED INCONSISTENCY: the filesystem is "
|
|
|
|
"being modified while fsck is running.\n"));
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
2011-12-16 23:55:50 +04:00
|
|
|
|
|
|
|
void e2fsck_set_bitmap_type(ext2_filsys fs, unsigned int default_type,
|
|
|
|
const char *profile_name, unsigned int *old_type)
|
|
|
|
{
|
|
|
|
unsigned type;
|
2014-03-05 04:10:26 +04:00
|
|
|
e2fsck_t ctx = (e2fsck_t) fs->priv_data;
|
2011-12-16 23:55:50 +04:00
|
|
|
|
|
|
|
if (old_type)
|
|
|
|
*old_type = fs->default_bitmap_type;
|
2014-03-05 04:10:26 +04:00
|
|
|
profile_get_uint(ctx->profile, "bitmaps", profile_name, 0,
|
|
|
|
default_type, &type);
|
|
|
|
profile_get_uint(ctx->profile, "bitmaps", "all", 0, type, &type);
|
2011-12-16 23:55:50 +04:00
|
|
|
fs->default_bitmap_type = type ? type : default_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
errcode_t e2fsck_allocate_inode_bitmap(ext2_filsys fs, const char *descr,
|
|
|
|
int deftype,
|
|
|
|
const char *name,
|
|
|
|
ext2fs_inode_bitmap *ret)
|
|
|
|
{
|
|
|
|
errcode_t retval;
|
|
|
|
unsigned int save_type;
|
|
|
|
|
|
|
|
e2fsck_set_bitmap_type(fs, deftype, name, &save_type);
|
|
|
|
retval = ext2fs_allocate_inode_bitmap(fs, descr, ret);
|
|
|
|
fs->default_bitmap_type = save_type;
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
errcode_t e2fsck_allocate_block_bitmap(ext2_filsys fs, const char *descr,
|
|
|
|
int deftype,
|
|
|
|
const char *name,
|
|
|
|
ext2fs_block_bitmap *ret)
|
|
|
|
{
|
|
|
|
errcode_t retval;
|
|
|
|
unsigned int save_type;
|
|
|
|
|
|
|
|
e2fsck_set_bitmap_type(fs, deftype, name, &save_type);
|
|
|
|
retval = ext2fs_allocate_block_bitmap(fs, descr, ret);
|
|
|
|
fs->default_bitmap_type = save_type;
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
errcode_t e2fsck_allocate_subcluster_bitmap(ext2_filsys fs, const char *descr,
|
|
|
|
int deftype,
|
|
|
|
const char *name,
|
|
|
|
ext2fs_block_bitmap *ret)
|
|
|
|
{
|
|
|
|
errcode_t retval;
|
|
|
|
unsigned int save_type;
|
|
|
|
|
|
|
|
e2fsck_set_bitmap_type(fs, deftype, name, &save_type);
|
|
|
|
retval = ext2fs_allocate_subcluster_bitmap(fs, descr, ret);
|
|
|
|
fs->default_bitmap_type = save_type;
|
|
|
|
return retval;
|
|
|
|
}
|