Many files:

Makefile.in: Update the make dependencies
  problem.c, problem.h: Add the problem codes:
  	PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
  	PR_0_ORPHAN_ILLEGAL_HEAD_INODE, PR_0_ORPHAN_ILLEGAL_INODE,
  	PR_0_ORPHAN_INODE_INUSE
  super.c (release_inode_blocks, release_orphan_inodes,
  	check_super_block): Add support for clearing orphaned inodes from the
  	unmounted filesystem.
  journal.c (e2fsck_recover_ext3_journal): Remove the last orphan check;
  	this is now handled in check_super_block --- non-journaled filesystems
  	can use the orphan list in the future.  Also, move the the re-opening
  	of the filesystem to e2fsck_run_ext3_journal().
debugfs.c:
  debugfs.c (finish_range): Make sure the pager FILE pointer to use.
configure, configure.in, ChangeLog:
  configure.in (JFS_DEBUG): Add support for --enable-jfs-debug
bitmap-optimize
Theodore Ts'o 2000-08-18 15:08:37 +00:00
parent bd09eff9b2
commit 80bfaa3e40
12 changed files with 554 additions and 302 deletions

View File

@ -1,3 +1,7 @@
2000-08-18 <tytso@valinux.com>
* configure.in (JFS_DEBUG): Add support for --enable-jfs-debug
2000-08-14 <tytso@valinux.com>
* e2fsprogs.spec (Summary): Add description of resize2fs to the

393
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -198,6 +198,21 @@ echo "Disabling BSD shared libraries by default"
AC_SUBST(BSDLIB_CMT)
AC_SUBST_FILE(MAKEFILE_BSDLIB)
dnl
dnl handle --enable-jfs-debug
dnl
AC_ARG_ENABLE([jfs-debug],
[ --enable-jfs-debug enable journal debugging],
if test "$enableval" = "no"
then
echo "Disabling journal debugging"
else
AC_DEFINE(JFS_DEBUG)
echo "Enabling journal debugging"
fi
,
echo "Disabling journal debugging by default"
)
dnl
dnl Add internationalization support, using gettext.
dnl
PACKAGE=e2fsprogs

View File

@ -337,7 +337,7 @@ static void finish_range(struct list_blocks_struct *lb)
if (lb->first)
lb->first = 0;
else
printf(", ");
fprintf(lb->f, ", ");
if (lb->first_block == lb->last_block)
fprintf(lb->f, "(%d):%d", lb->first_bcnt, lb->first_block);
else

View File

@ -1,3 +1,23 @@
2000-08-18 <tytso@valinux.com>
* Makefile.in: Update the make dependencies
* problem.c, problem.h: Add the problem codes:
PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
PR_0_ORPHAN_ILLEGAL_INODE, PR_0_ORPHAN_INODE_INUSE
* super.c (release_inode_blocks, release_orphan_inodes,
check_super_block): Add support for clearing orphaned
inodes from the unmounted filesystem.
* journal.c (e2fsck_recover_ext3_journal): Remove the last orphan
check; this is now handled in check_super_block ---
non-journaled filesystems can use the orphan list in the
future. Also, move the the re-opening of the filesystem
to e2fsck_run_ext3_journal().
2000-07-12 Andreas Dilger <adilger@turbolinux.com>
* journal.c: implement loading of ext3 journal for recovery code

View File

@ -158,64 +158,79 @@ distclean: clean
# Makefile dependencies follow. This must be the last section in
# the Makefile.in file
#
e2fsck.o: $(srcdir)/e2fsck.c $(srcdir)/e2fsck.h $(srcdir)/jfs_compat.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h $(srcdir)/jfs.h
e2fsck.o: $(srcdir)/e2fsck.c $(srcdir)/e2fsck.h \
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(srcdir)/problem.h
super.o: $(srcdir)/super.c $(top_srcdir)/lib/uuid/uuid.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
pass1.o: $(srcdir)/pass1.c $(srcdir)/e2fsck.h $(srcdir)/jfs_compat.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(srcdir)/problem.h
pass1.o: $(srcdir)/pass1.c $(srcdir)/e2fsck.h \
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(srcdir)/problem.h
pass1b.o: $(srcdir)/pass1b.c $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
$(srcdir)/e2fsck.h $(top_srcdir)/include/linux/ext2_fs.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(srcdir)/problem.h
pass2.o: $(srcdir)/pass2.c $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(srcdir)/problem.h
pass3.o: $(srcdir)/pass3.c $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(srcdir)/problem.h
pass4.o: $(srcdir)/pass4.c $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(srcdir)/problem.h
pass5.o: $(srcdir)/pass5.c $(srcdir)/e2fsck.h \
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(srcdir)/problem.h
journal.o: $(srcdir)/journal.c $(srcdir)/jfs.h $(srcdir)/jfs_compat.h \
$(srcdir)/e2fsck.h $(top_srcdir)/include/linux/ext2_fs.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h
journal.o: $(srcdir)/journal.c $(srcdir)/jfs_compat.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h \
$(top_srcdir)/lib/uuid/uuid.h
recovery.o: $(srcdir)/recovery.c $(srcdir)/jfs.h $(srcdir)/jfs_compat.h \
$(srcdir)/e2fsck.h $(top_srcdir)/include/linux/ext2_fs.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(srcdir)/jfs.h
recovery.o: $(srcdir)/recovery.c $(srcdir)/jfs_compat.h $(srcdir)/e2fsck.h \
$(srcdir)/jfs.h
badblocks.o: $(srcdir)/badblocks.c $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h
util.o: $(srcdir)/util.c $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
badblocks.o: $(srcdir)/badblocks.c $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/e2fsck.h $(top_srcdir)/include/linux/ext2_fs.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
util.o: $(srcdir)/util.c $(srcdir)/e2fsck.h \
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
unix.o: $(srcdir)/unix.c $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(srcdir)/problem.h $(srcdir)/../version.h
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h $(srcdir)/../version.h
dirinfo.o: $(srcdir)/dirinfo.c $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
ehandler.o: $(srcdir)/ehandler.c $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
problem.o: $(srcdir)/problem.c $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/problem.h $(srcdir)/problemP.h
$(top_srcdir)/include/linux/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
$(srcdir)/problem.h $(srcdir)/problemP.h

View File

@ -120,6 +120,7 @@ void wait_on_buffer(struct buffer_head *bh)
ll_rw_block(READ, 1, bh);
}
static void e2fsck_clear_recover(e2fsck_t ctx, int error)
{
struct ext2fs_sb *s = (struct ext2fs_sb *)ctx->fs->super;
@ -465,11 +466,9 @@ no_has_journal:
return retval;
}
static int e2fsck_recover_ext3_journal(e2fsck_t ctx)
static int recover_ext3_journal(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
io_manager io_ptr = fs->io->manager;
int blocksize = fs->blocksize;
journal_t *journal;
int retval;
@ -486,53 +485,25 @@ static int e2fsck_recover_ext3_journal(e2fsck_t ctx)
if (retval)
goto exit;
/* Reload the filesystem context to get up-to-date data from disk
* because journal recovery will change the filesystem under us.
*/
ext2fs_close(fs);
retval = ext2fs_open(ctx->device_name, EXT2_FLAG_RW,
ctx->superblock, blocksize, io_ptr, &fs);
if (retval) {
com_err(ctx->program_name, retval,
_("while trying to re-open %s"),
ctx->device_name);
exit(FSCK_ERROR);
}
ctx->fs = fs;
fs->priv_data = ctx;
/* FIXME - In the future we will clean up the ophans here.
* For now, we need to force a full fsck to clean them up.
* We shouldn't have this problem in normal circumstances
* as the kernel recovery code should save us.
*/
if (fs->super->s_last_orphan)
fs->super->s_state &= ~EXT2_VALID_FS;
else
jfs_debug(1, "no orphan inodes to clean up\n");
exit:
e2fsck_clear_recover(ctx, retval);
ext2fs_close(ctx->fs);
return retval;
}
#if 0
#define TEMPLATE "/tmp/ext3.XXXXXX"
/*
* This function attempts to mount and unmount an ext3 filesystem,
* which is a cheap way to force the kernel to run the journal and
* handle the recovery for us. If that fails, we need to recover
* the journal ourselves manually.
* handle the recovery for us.
*/
int e2fsck_run_ext3_journal(e2fsck_t ctx)
static int recover_ext3_journal_via_mount(e2fsck_t ctx)
{
#ifdef __linux__
ext2_filsys fs = ctx->fs;
char *dirlist[] = {"/mnt","/lost+found","/tmp","/root","/boot",0};
int retval = 0;
errcode_t retval, retval2;
int count = 0;
char template[] = TEMPLATE;
struct stat buf;
@ -544,10 +515,6 @@ int e2fsck_run_ext3_journal(e2fsck_t ctx)
return EXT2_ET_FILE_RO;
}
/* For now, non-root users and loop devices can't use kernel recovery */
if (geteuid()||stat(ctx->device_name, &buf)||!S_ISBLK(buf.st_mode))
goto manual_recover;
printf(_("%s: trying for ext3 kernel journal recovery\n"),
ctx->device_name);
/*
@ -558,16 +525,15 @@ newtemp:
tmpdir = mktemp(template);
if (tmpdir) {
jfs_debug(2, "trying %s as ext3 temp mount point\n", tmpdir);
retval = mkdir(template, 0700);
if (retval) {
if (mkdir(template, 0700)) {
if (errno == EROFS) {
tmpdir = NULL;
template[0] = '\0';
} else if (errno == EEXIST && count++ < 10) {
strcpy(template, TEMPLATE);
goto newtemp;
} else
goto manual_recover;
}
return errno;
}
}
@ -580,7 +546,7 @@ newtemp:
char **cpp, *dir;
if (stat("/", &buf))
goto manual_recover;
return errno;
rootdev = buf.st_dev;
@ -601,35 +567,20 @@ newtemp:
int blocksize = fs->blocksize;
jfs_debug(2, "using %s for ext3 mount\n", tmpdir);
ext2fs_close(fs);
/* FIXME - need to handle loop devices here */
retval = mount(ctx->device_name, tmpdir, "ext3", MNT_FL, NULL);
if (retval) {
if (mount(ctx->device_name, tmpdir, "ext3", MNT_FL, NULL)) {
retval = errno;
com_err(ctx->program_name, errno,
"when mounting %s", ctx->device_name);
if (template[0])
rmdir(tmpdir);
retval = ext2fs_open(ctx->device_name, EXT2_FLAG_RW,
ctx->superblock, blocksize, io_ptr,
&fs);
if (retval) {
com_err(ctx->program_name, retval,
_("while trying to re-open %s"),
ctx->device_name);
exit(FSCK_ERROR);
}
fs->priv_data = ctx;
ctx->fs = fs;
goto manual_recover;
return retval;
}
/*
* Now that it mounted cleanly, the filesystem will have been
* recovered, so we can now unmount it.
*/
retval = umount(tmpdir);
if (retval)
if (umount(tmpdir))
return errno;
/*
@ -639,8 +590,34 @@ newtemp:
rmdir(tmpdir);
return 0;
}
manual_recover:
#endif /* __linux__ */
return e2fsck_recover_ext3_journal(ctx);
}
#endif
int e2fsck_run_ext3_journal(e2fsck_t ctx)
{
io_manager io_ptr = ctx->fs->io->manager;
int blocksize = ctx->fs->blocksize;
errcode_t retval;
if ((retval = recover_ext3_journal(ctx)))
return retval;
/*
* Reload the filesystem context to get up-to-date data from disk
* because journal recovery will change the filesystem under us.
*/
ext2fs_close(ctx->fs);
retval = ext2fs_open(ctx->device_name, EXT2_FLAG_RW,
ctx->superblock, blocksize, io_ptr,
&ctx->fs);
if (retval) {
com_err(ctx->program_name, retval,
_("while trying to re-open %s"),
ctx->device_name);
exit(FSCK_ERROR);
}
ctx->fs->priv_data = ctx;
return 0;
}

View File

@ -64,10 +64,11 @@
* @g group
* @l lost+found
* @L is a link
* @u unattached
* @o orphaned
* @r root inode
* @s should be
* @S superblock
* @u unattached
* @z zero-length
*/
@ -110,10 +111,11 @@ static const char *abbrevs[] = {
N_("ggroup"),
N_("llost+found"),
N_("Lis a link"),
N_("uunattached"),
N_("oorphaned"),
N_("rroot @i"),
N_("sshould be"),
N_("Ssuper@b"),
N_("uunattached"),
N_("zzero-length"),
"@@",
0

View File

@ -229,6 +229,31 @@ static const struct e2fsck_problem problem_table[] = {
N_("ext3 recovery flag clear, but journal has data.\n"),
PROMPT_CLEAR, PR_PREEN_OK|PR_PREEN_NOMSG },
/* Illegal block found in orphaned inode */
{ PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
N_("@I @b #%B (%b) found in @o @i %i.\n"),
PROMPT_NONE, 0 },
/* Already cleared block found in orphaned inode */
{ PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
PROMPT_NONE, 0 },
/* Illegal orphan inode in superblock */
{ PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
N_("@I @o @i %i in @S.\n"),
PROMPT_NONE, 0 },
/* Illegal inode in orphaned inode list */
{ PR_0_ORPHAN_ILLEGAL_INODE,
N_("@I @i %i in @o @i list.\n"),
PROMPT_NONE, 0 },
/* Orphan inode has a non-zero link count */
{ PR_0_ORPHAN_INODE_INUSE,
N_("@o @i %i has a non-zero link count.\n"),
PROMPT_NONE, 0 },
/* Pass 1 errors */
/* Pass 1: Checking inodes, blocks, and sizes */
@ -300,7 +325,7 @@ static const struct e2fsck_problem problem_table[] = {
N_("@i %i, i_@bs is %Ib, @s %N. "),
PROMPT_FIX, PR_PREEN_OK },
/* Illegal block number in inode */
/* Illegal blocknumber in inode */
{ PR_1_ILLEGAL_BLOCK_NUM,
N_("@I @b #%B (%b) in @i %i. "),
PROMPT_CLEAR, PR_LATCH_BLOCK },

View File

@ -127,6 +127,22 @@ struct problem_context {
/* Superblock recovery flag clear - journal needs to be reset */
#define PR_0_JOURNAL_RESET_PROMPT 0x000019
/* Illegal block found in orphaned inode */
#define PR_0_ORPHAN_ILLEGAL_BLOCK_NUM 0x000020
/* Already cleared block found in orphaned inode */
#define PR_0_ORPHAN_ALREADY_CLEARED_BLOCK 0x000021
/* Illegal orphan inode in superblock */
#define PR_0_ORPHAN_ILLEGAL_HEAD_INODE 0x000022
/* Illegal inode in orphaned inode list */
#define PR_0_ORPHAN_ILLEGAL_INODE 0x000023
/* Orphan inode has a non-zero link count */
#define PR_0_ORPHAN_INODE_INUSE 0x000024
/*
* Pass 1 errors
*/

View File

@ -51,6 +51,149 @@ errcode_t e2fsck_get_device_size(e2fsck_t ctx)
}
#endif
/*
* helper function to release an inode
*/
struct process_block_struct {
ino_t ino;
e2fsck_t ctx;
struct problem_context *pctx;
int abort;
};
static int release_inode_block(ext2_filsys fs,
blk_t *block_nr,
int blockcnt,
void *priv_data)
{
struct process_block_struct *pb;
e2fsck_t ctx;
struct problem_context *pctx;
blk_t blk = *block_nr;
pb = (struct process_block_struct *) priv_data;
ctx = pb->ctx;
pctx = pb->pctx;
pctx->blk = blk;
pctx->blkcount = blockcnt;
if (HOLE_BLKADDR(blk))
return 0;
if ((blk < fs->super->s_first_data_block) ||
(blk >= fs->super->s_blocks_count)) {
fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
pb->abort = 1;
return BLOCK_ABORT;
}
if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
pb->abort = 1;
return BLOCK_ABORT;
}
ext2fs_unmark_block_bitmap(fs->block_map, blk);
return 0;
}
/*
* This function releases an inode. Returns 1 if an inconsistency was
* found.
*/
static int release_inode_blocks(e2fsck_t ctx, ino_t ino, char* block_buf,
struct problem_context *pctx)
{
ext2_filsys fs = ctx->fs;
errcode_t retval;
struct process_block_struct pb;
pb.ino = ino;
pb.ctx = ctx;
pb.abort = 0;
pb.pctx = pctx;
retval = ext2fs_block_iterate(fs, ino, 0, block_buf,
release_inode_block, &pb);
if (retval) {
com_err("delete_file", retval,
_("while calling ext2fs_block_iterate for inode %d"),
ino);
return 1;
}
if (pb.abort)
return 1;
ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
ext2fs_mark_ib_dirty(fs);
ext2fs_mark_bb_dirty(fs);
return 0;
}
/*
* This function releases all of the orphan inodes. It returns 1 if
* it hit some error, and 0 on success.
*/
static int release_orphan_inodes(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
ino_t ino, next_ino;
struct ext2_inode inode;
struct problem_context pctx;
char *block_buf;
if ((ino = fs->super->s_last_orphan) == 0)
return 0;
if ((ino < EXT2_FIRST_INODE(fs->super)) ||
(ino > fs->super->s_inodes_count)) {
clear_problem_context(&pctx);
pctx.ino;
fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
return 1;
}
block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
"block interate buffer");
e2fsck_read_bitmaps(ctx);
while (ino) {
#ifdef JFS_DEBUG
printf("Clearing orphan inode %d\n", ino);
#endif
e2fsck_read_inode(ctx, ino, &inode, "delete_file");
clear_problem_context(&pctx);
pctx.ino;
pctx.inode = &inode;
if (inode.i_links_count) {
fix_problem(ctx, PR_0_ORPHAN_INODE_INUSE, &pctx);
goto abort;
}
next_ino = inode.i_dtime;
if (next_ino &&
((ino < EXT2_FIRST_INODE(fs->super)) ||
(ino > fs->super->s_inodes_count))) {
fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
goto abort;
}
if (release_inode_blocks(ctx, ino, block_buf, &pctx))
goto abort;
inode.i_dtime = time(0);
e2fsck_write_inode(ctx, ino, &inode, "delete_file");
ino = next_ino;
}
return 0;
abort:
ext2fs_free_mem((void **) &block_buf);
return 1;
}
void check_super_block(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
@ -223,7 +366,8 @@ void check_super_block(e2fsck_t ctx)
* For the Hurd, check to see if the filetype option is set,
* since it doesn't support it.
*/
if (fs->super->s_creator_os == EXT2_OS_HURD &&
if (!(ctx->options & E2F_OPT_READONLY) &&
fs->super->s_creator_os == EXT2_OS_HURD &&
(fs->super->s_feature_incompat &
EXT2_FEATURE_INCOMPAT_FILETYPE)) {
if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
@ -233,5 +377,16 @@ void check_super_block(e2fsck_t ctx)
}
}
/*
* Clean up any orphan inodes, if present.
*/
if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
fs->super->s_state &= ~EXT2_VALID_FS;
ext2fs_mark_super_dirty(ctx->fs);
}
return;
}

View File

@ -817,6 +817,8 @@ restart:
ctx->device_name);
exit(FSCK_ERROR);
}
ext2fs_close(ctx->fs);
ctx->fs = 0;
goto restart;
}