mirror of
https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
synced 2025-01-19 23:13:43 +08:00
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
This commit is contained in:
parent
bd09eff9b2
commit
80bfaa3e40
@ -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
|
||||
|
15
configure.in
15
configure.in
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
111
e2fsck/journal.c
111
e2fsck/journal.c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 },
|
||||
|
@ -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
|
||||
*/
|
||||
|
157
e2fsck/super.c
157
e2fsck/super.c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -817,6 +817,8 @@ restart:
|
||||
ctx->device_name);
|
||||
exit(FSCK_ERROR);
|
||||
}
|
||||
ext2fs_close(ctx->fs);
|
||||
ctx->fs = 0;
|
||||
goto restart;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user