1997-04-26 17:21:57 +04:00
|
|
|
/*
|
|
|
|
* pass3.c -- pass #3 of e2fsck: Check for directory connectivity
|
|
|
|
*
|
1999-09-15 00:00:54 +04:00
|
|
|
* Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999 Theodore Ts'o.
|
1997-04-29 20:15:03 +04:00
|
|
|
*
|
|
|
|
* %Begin-Header%
|
|
|
|
* This file may be redistributed under the terms of the GNU Public
|
|
|
|
* License.
|
|
|
|
* %End-Header%
|
2008-08-28 07:07:54 +04:00
|
|
|
*
|
1997-04-26 17:21:57 +04:00
|
|
|
* Pass #3 assures that all directories are connected to the
|
|
|
|
* filesystem tree, using the following algorithm:
|
|
|
|
*
|
|
|
|
* First, the root directory is checked to make sure it exists; if
|
|
|
|
* not, e2fsck will offer to create a new one. It is then marked as
|
|
|
|
* "done".
|
2008-08-28 07:07:54 +04:00
|
|
|
*
|
1997-04-26 17:21:57 +04:00
|
|
|
* Then, pass3 interates over all directory inodes; for each directory
|
|
|
|
* it attempts to trace up the filesystem tree, using dirinfo.parent
|
|
|
|
* until it reaches a directory which has been marked "done". If it
|
|
|
|
* can not do so, then the directory must be disconnected, and e2fsck
|
|
|
|
* will offer to reconnect it to /lost+found. While it is chasing
|
|
|
|
* parent pointers up the filesystem tree, if pass3 sees a directory
|
|
|
|
* twice, then it has detected a filesystem loop, and it will again
|
|
|
|
* offer to reconnect the directory to /lost+found in to break the
|
|
|
|
* filesystem loop.
|
2008-08-28 07:07:54 +04:00
|
|
|
*
|
1997-11-03 22:42:40 +03:00
|
|
|
* Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
|
|
|
|
* reconnect inodes to /lost+found; this subroutine is also used by
|
|
|
|
* pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
|
|
|
|
* is responsible for creating /lost+found if it does not exist.
|
1997-04-26 17:21:57 +04:00
|
|
|
*
|
|
|
|
* Pass 3 frees the following data structures:
|
|
|
|
* - The dirinfo directory information cache.
|
|
|
|
*/
|
|
|
|
|
2011-09-19 01:34:37 +04:00
|
|
|
#include "config.h"
|
1997-04-26 17:58:21 +04:00
|
|
|
#ifdef HAVE_ERRNO_H
|
|
|
|
#include <errno.h>
|
|
|
|
#endif
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
#include "e2fsck.h"
|
1997-04-29 20:15:03 +04:00
|
|
|
#include "problem.h"
|
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
|
|
|
static void check_root(e2fsck_t ctx);
|
2007-04-05 06:33:31 +04:00
|
|
|
static int check_directory(e2fsck_t ctx, ext2_ino_t ino,
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
struct problem_context *pctx);
|
2007-04-05 06:33:31 +04:00
|
|
|
static void fix_dotdot(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent);
|
1997-04-26 17:21:57 +04:00
|
|
|
|
1998-02-24 23:22:23 +03:00
|
|
|
static ext2fs_inode_bitmap inode_loop_detect = 0;
|
|
|
|
static ext2fs_inode_bitmap inode_done_map = 0;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1997-11-03 22:42:40 +03:00
|
|
|
void e2fsck_pass3(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;
|
2013-12-12 21:57:48 +04:00
|
|
|
struct dir_info_iter *iter = NULL;
|
1997-10-20 05:38:32 +04:00
|
|
|
#ifdef RESOURCE_TRACK
|
1997-04-26 17:21:57 +04:00
|
|
|
struct resource_track rtrack;
|
1997-10-20 05:38:32 +04:00
|
|
|
#endif
|
1997-04-29 20:15:03 +04:00
|
|
|
struct problem_context pctx;
|
|
|
|
struct dir_info *dir;
|
1998-09-03 05:26:03 +04:00
|
|
|
unsigned long maxdirs, count;
|
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
|
|
|
|
2007-08-04 04:07:09 +04:00
|
|
|
init_resource_track(&rtrack, ctx->fs->io);
|
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
|
|
|
clear_problem_context(&pctx);
|
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
#ifdef MTRACE
|
|
|
|
mtrace_print("Pass 3");
|
|
|
|
#endif
|
|
|
|
|
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))
|
|
|
|
fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate some bitmaps to do loop detection.
|
|
|
|
*/
|
2011-12-16 23:55:50 +04:00
|
|
|
pctx.errcode = e2fsck_allocate_inode_bitmap(fs, _("inode done bitmap"),
|
|
|
|
EXT2FS_BMAP64_AUTODIR,
|
|
|
|
"inode_done_map", &inode_done_map);
|
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 (pctx.errcode) {
|
|
|
|
pctx.num = 2;
|
|
|
|
fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
|
1997-11-03 22:42:40 +03:00
|
|
|
ctx->flags |= E2F_FLAG_ABORT;
|
1998-02-24 23:22:23 +03:00
|
|
|
goto abort_exit;
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
2009-05-28 17:55:10 +04:00
|
|
|
print_resource_track(ctx, _("Peak memory"), &ctx->global_rtrack, NULL);
|
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
|
|
|
check_root(ctx);
|
1998-02-24 23:22:23 +03:00
|
|
|
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
|
|
|
|
goto abort_exit;
|
1997-11-03 22:42:40 +03:00
|
|
|
|
2009-08-23 06:29:02 +04:00
|
|
|
ext2fs_mark_inode_bitmap2(inode_done_map, EXT2_ROOT_INO);
|
1997-04-26 17:21:57 +04:00
|
|
|
|
1998-09-03 05:26:03 +04:00
|
|
|
maxdirs = e2fsck_get_num_dirinfo(ctx);
|
1998-08-01 08:18:06 +04:00
|
|
|
count = 1;
|
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
|
|
|
|
1998-08-01 08:18:06 +04:00
|
|
|
if (ctx->progress)
|
1998-09-03 05:26:03 +04:00
|
|
|
if ((ctx->progress)(ctx, 3, 0, maxdirs))
|
1998-08-01 08:18:06 +04:00
|
|
|
goto abort_exit;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2007-04-05 06:33:31 +04:00
|
|
|
iter = e2fsck_dir_info_iter_begin(ctx);
|
|
|
|
while ((dir = e2fsck_dir_info_iter(ctx, iter)) != 0) {
|
2002-07-21 22:14:03 +04:00
|
|
|
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
|
|
|
|
goto abort_exit;
|
|
|
|
if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
|
|
|
|
goto abort_exit;
|
2009-08-23 06:29:02 +04:00
|
|
|
if (ext2fs_test_inode_bitmap2(ctx->inode_dir_map, dir->ino))
|
2007-04-05 06:33:31 +04:00
|
|
|
if (check_directory(ctx, dir->ino, &pctx))
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
goto abort_exit;
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
1998-02-24 23:22:23 +03:00
|
|
|
|
1998-12-03 19:40:38 +03:00
|
|
|
/*
|
|
|
|
* Force the creation of /lost+found if not present
|
|
|
|
*/
|
2013-12-19 22:55:51 +04:00
|
|
|
if ((ctx->options & E2F_OPT_READONLY) == 0)
|
2002-07-25 08:00:08 +04:00
|
|
|
e2fsck_get_lost_and_found(ctx, 1);
|
1998-12-03 19:40:38 +03:00
|
|
|
|
2002-07-25 08:00:08 +04:00
|
|
|
/*
|
|
|
|
* If there are any directories that need to be indexed or
|
|
|
|
* optimized, do it here.
|
|
|
|
*/
|
|
|
|
e2fsck_rehash_directories(ctx);
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1998-02-24 23:22:23 +03:00
|
|
|
abort_exit:
|
2013-12-12 21:57:48 +04:00
|
|
|
if (iter)
|
|
|
|
e2fsck_dir_info_iter_end(ctx, iter);
|
1997-11-03 22:42:40 +03:00
|
|
|
e2fsck_free_dir_info(ctx);
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
if (inode_loop_detect) {
|
1998-02-24 23:22:23 +03:00
|
|
|
ext2fs_free_inode_bitmap(inode_loop_detect);
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
inode_loop_detect = 0;
|
|
|
|
}
|
|
|
|
if (inode_done_map) {
|
1998-02-24 23:22:23 +03:00
|
|
|
ext2fs_free_inode_bitmap(inode_done_map);
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
inode_done_map = 0;
|
|
|
|
}
|
2002-07-20 08:28:07 +04:00
|
|
|
|
2014-07-26 04:33:45 +04:00
|
|
|
if (ctx->lnf_repair_block) {
|
|
|
|
ext2fs_unmark_block_bitmap2(ctx->block_found_map,
|
|
|
|
ctx->lnf_repair_block);
|
|
|
|
ctx->lnf_repair_block = 0;
|
|
|
|
}
|
|
|
|
if (ctx->root_repair_block) {
|
|
|
|
ext2fs_unmark_block_bitmap2(ctx->block_found_map,
|
|
|
|
ctx->root_repair_block);
|
|
|
|
ctx->root_repair_block = 0;
|
|
|
|
}
|
|
|
|
|
2009-05-28 17:55:10 +04:00
|
|
|
print_resource_track(ctx, _("Pass 3"), &rtrack, ctx->fs->io);
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This makes sure the root inode is present; if not, we ask if the
|
|
|
|
* user wants us to create it. Not creating it is a fatal error.
|
|
|
|
*/
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-03 21:48:10 +04:00
|
|
|
static void check_root(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;
|
2009-08-23 06:29:02 +04:00
|
|
|
blk64_t blk;
|
1997-04-26 17:21:57 +04:00
|
|
|
struct ext2_inode inode;
|
|
|
|
char * block;
|
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
|
|
|
struct problem_context pctx;
|
2008-08-28 07:07:54 +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
|
|
|
clear_problem_context(&pctx);
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2009-08-23 06:29:02 +04:00
|
|
|
if (ext2fs_test_inode_bitmap2(ctx->inode_used_map, EXT2_ROOT_INO)) {
|
1997-04-26 17:21:57 +04:00
|
|
|
/*
|
1997-11-03 22:42:40 +03:00
|
|
|
* If the root inode is not a directory, die here. The
|
1997-04-26 17:21:57 +04:00
|
|
|
* user must have answered 'no' in pass1 when we
|
|
|
|
* offered to clear it.
|
|
|
|
*/
|
2009-08-23 06:29:02 +04:00
|
|
|
if (!(ext2fs_test_inode_bitmap2(ctx->inode_dir_map,
|
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
|
|
|
EXT2_ROOT_INO))) {
|
|
|
|
fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
|
|
|
|
ctx->flags |= E2F_FLAG_ABORT;
|
|
|
|
}
|
1997-04-26 17:21:57 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
|
|
|
|
fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
|
|
|
|
ctx->flags |= E2F_FLAG_ABORT;
|
|
|
|
return;
|
|
|
|
}
|
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
|
|
|
e2fsck_read_bitmaps(ctx);
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
/*
|
|
|
|
* First, find a free block
|
|
|
|
*/
|
2014-07-26 04:33:45 +04:00
|
|
|
if (ctx->root_repair_block) {
|
|
|
|
blk = ctx->root_repair_block;
|
|
|
|
ctx->root_repair_block = 0;
|
|
|
|
goto skip_new_block;
|
|
|
|
}
|
2009-08-23 06:29:02 +04:00
|
|
|
pctx.errcode = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
|
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 (pctx.errcode) {
|
|
|
|
pctx.str = "ext2fs_new_block";
|
|
|
|
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
|
1997-11-03 22:42:40 +03:00
|
|
|
ctx->flags |= E2F_FLAG_ABORT;
|
|
|
|
return;
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
2009-08-23 06:29:02 +04:00
|
|
|
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
|
2014-07-26 04:33:45 +04:00
|
|
|
skip_new_block:
|
2009-08-23 06:29:02 +04:00
|
|
|
ext2fs_mark_block_bitmap2(fs->block_map, blk);
|
1997-04-26 17:21:57 +04:00
|
|
|
ext2fs_mark_bb_dirty(fs);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up the inode structure
|
|
|
|
*/
|
|
|
|
memset(&inode, 0, sizeof(inode));
|
|
|
|
inode.i_mode = 040755;
|
|
|
|
inode.i_size = fs->blocksize;
|
2005-04-14 22:07:53 +04:00
|
|
|
inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
|
1997-04-26 17:21:57 +04:00
|
|
|
inode.i_links_count = 2;
|
2008-04-09 19:39:11 +04:00
|
|
|
ext2fs_iblk_set(fs, &inode, 1);
|
1997-04-26 17:21:57 +04:00
|
|
|
inode.i_block[0] = blk;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write out the inode.
|
|
|
|
*/
|
2005-03-21 04:05:22 +03:00
|
|
|
pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
|
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 (pctx.errcode) {
|
|
|
|
pctx.str = "ext2fs_write_inode";
|
|
|
|
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
|
1997-11-03 22:42:40 +03:00
|
|
|
ctx->flags |= E2F_FLAG_ABORT;
|
|
|
|
return;
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2014-07-27 01:14:40 +04:00
|
|
|
/*
|
|
|
|
* Now let's create the actual data block for the inode.
|
|
|
|
* Due to metadata_csum, we must write the dir blocks AFTER
|
|
|
|
* the inode has been written to disk!
|
|
|
|
*/
|
|
|
|
pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
|
|
|
|
&block);
|
|
|
|
if (pctx.errcode) {
|
|
|
|
pctx.str = "ext2fs_new_dir_block";
|
|
|
|
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
|
|
|
|
ctx->flags |= E2F_FLAG_ABORT;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pctx.errcode = ext2fs_write_dir_block4(fs, blk, block, 0,
|
|
|
|
EXT2_ROOT_INO);
|
|
|
|
ext2fs_free_mem(&block);
|
|
|
|
if (pctx.errcode) {
|
|
|
|
pctx.str = "ext2fs_write_dir_block4";
|
|
|
|
fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
|
|
|
|
ctx->flags |= E2F_FLAG_ABORT;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
/*
|
|
|
|
* Miscellaneous bookkeeping...
|
|
|
|
*/
|
1997-11-03 22:42:40 +03:00
|
|
|
e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
|
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
|
|
|
ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
|
|
|
|
ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
|
1997-04-26 17:21:57 +04:00
|
|
|
|
2009-08-23 06:29:02 +04:00
|
|
|
ext2fs_mark_inode_bitmap2(ctx->inode_used_map, EXT2_ROOT_INO);
|
|
|
|
ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, EXT2_ROOT_INO);
|
|
|
|
ext2fs_mark_inode_bitmap2(fs->inode_map, EXT2_ROOT_INO);
|
1997-04-26 17:21:57 +04:00
|
|
|
ext2fs_mark_ib_dirty(fs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This subroutine is responsible for making sure that a particular
|
|
|
|
* directory is connected to the root; if it isn't we trace it up as
|
|
|
|
* far as we can go, and then offer to connect the resulting parent to
|
|
|
|
* the lost+found. We have to do loop detection; if we ever discover
|
|
|
|
* a loop, we treat that as a disconnected directory and offer to
|
|
|
|
* reparent it to lost+found.
|
2008-08-28 07:07:54 +04:00
|
|
|
*
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
* However, loop detection is expensive, because for very large
|
|
|
|
* filesystems, the inode_loop_detect bitmap is huge, and clearing it
|
|
|
|
* is non-trivial. Loops in filesystems are also a rare error case,
|
|
|
|
* and we shouldn't optimize for error cases. So we try two passes of
|
|
|
|
* the algorithm. The first time, we ignore loop detection and merely
|
|
|
|
* increment a counter; if the counter exceeds some extreme threshold,
|
|
|
|
* then we try again with the loop detection bitmap enabled.
|
1997-04-26 17:21:57 +04:00
|
|
|
*/
|
2007-04-05 06:33:31 +04:00
|
|
|
static int check_directory(e2fsck_t ctx, ext2_ino_t dir,
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
struct problem_context *pctx)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
ext2_filsys fs = ctx->fs;
|
2007-04-05 06:33:31 +04:00
|
|
|
ext2_ino_t ino = dir, parent;
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
int loop_pass = 0, parent_count = 0;
|
1997-04-26 17:21:57 +04:00
|
|
|
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
while (1) {
|
1997-04-26 17:21:57 +04:00
|
|
|
/*
|
|
|
|
* Mark this inode as being "done"; by the time we
|
|
|
|
* return from this function, the inode we either be
|
|
|
|
* verified as being connected to the directory tree,
|
|
|
|
* or we will have offered to reconnect this to
|
|
|
|
* lost+found.
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
*
|
|
|
|
* If it was marked done already, then we've reached a
|
|
|
|
* parent we've already checked.
|
1997-04-26 17:21:57 +04:00
|
|
|
*/
|
2009-08-23 06:29:02 +04:00
|
|
|
if (ext2fs_mark_inode_bitmap2(inode_done_map, ino))
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
break;
|
1998-09-03 05:26:03 +04:00
|
|
|
|
2007-04-05 06:33:31 +04:00
|
|
|
if (e2fsck_dir_info_get_parent(ctx, ino, &parent)) {
|
|
|
|
fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
/*
|
|
|
|
* If this directory doesn't have a parent, or we've
|
|
|
|
* seen the parent once already, then offer to
|
|
|
|
* reparent it to lost+found
|
|
|
|
*/
|
2007-04-05 06:33:31 +04:00
|
|
|
if (!parent ||
|
2008-08-28 07:07:54 +04:00
|
|
|
(loop_pass &&
|
2009-08-23 06:29:02 +04:00
|
|
|
(ext2fs_test_inode_bitmap2(inode_loop_detect,
|
2007-04-05 06:33:31 +04:00
|
|
|
parent)))) {
|
|
|
|
pctx->ino = ino;
|
1998-09-03 05:26:03 +04:00
|
|
|
if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
|
2003-12-12 11:00:56 +03:00
|
|
|
if (e2fsck_reconnect_file(ctx, pctx->ino))
|
1998-09-03 05:26:03 +04:00
|
|
|
ext2fs_unmark_valid(fs);
|
|
|
|
else {
|
2008-08-28 07:07:54 +04:00
|
|
|
fix_dotdot(ctx, pctx->ino,
|
2007-04-05 06:33:31 +04:00
|
|
|
ctx->lost_and_found);
|
|
|
|
parent = ctx->lost_and_found;
|
1998-09-03 05:26:03 +04:00
|
|
|
}
|
|
|
|
}
|
1997-04-26 17:21:57 +04:00
|
|
|
break;
|
1998-09-03 05:26:03 +04:00
|
|
|
}
|
2007-04-05 06:33:31 +04:00
|
|
|
ino = parent;
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
if (loop_pass) {
|
2009-08-23 06:29:02 +04:00
|
|
|
ext2fs_mark_inode_bitmap2(inode_loop_detect, ino);
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
} else if (parent_count++ > 2048) {
|
|
|
|
/*
|
|
|
|
* If we've run into a path depth that's
|
|
|
|
* greater than 2048, try again with the inode
|
|
|
|
* loop bitmap turned on and start from the
|
|
|
|
* top.
|
|
|
|
*/
|
|
|
|
loop_pass = 1;
|
|
|
|
if (inode_loop_detect)
|
|
|
|
ext2fs_clear_inode_bitmap(inode_loop_detect);
|
|
|
|
else {
|
2011-12-16 23:55:50 +04:00
|
|
|
pctx->errcode = e2fsck_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), EXT2FS_BMAP64_AUTODIR, "inode_loop_detect", &inode_loop_detect);
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
if (pctx->errcode) {
|
|
|
|
pctx->num = 1;
|
2008-08-28 07:07:54 +04:00
|
|
|
fix_problem(ctx,
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
|
|
|
|
ctx->flags |= E2F_FLAG_ABORT;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2007-04-05 06:33:31 +04:00
|
|
|
ino = dir;
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
1997-04-29 20:15:03 +04:00
|
|
|
}
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure that .. and the parent directory are the same;
|
|
|
|
* offer to fix it if not.
|
|
|
|
*/
|
2007-04-05 06:33:31 +04:00
|
|
|
pctx->ino = dir;
|
|
|
|
if (e2fsck_dir_info_get_dotdot(ctx, dir, &pctx->ino2) ||
|
|
|
|
e2fsck_dir_info_get_parent(ctx, dir, &pctx->dir)) {
|
|
|
|
fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (pctx->ino2 != pctx->dir) {
|
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 (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
|
2007-04-05 06:33:31 +04:00
|
|
|
fix_dotdot(ctx, dir, pctx->dir);
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
ChangeLog, bitops.h:
bitops.h (ext2fs_mark_generic_bitmap, ext2fs_unmark_generic_bitmap,
ext2fs_mark_block_bitmap, ext2fs_unmark_block_bitmap,
ext2fs_mark_inode_bitmap, ext2fs_unmark_inode_bitmap): Change to
return the previous state of the bit that is being marked or unmarked.
For speed optimization.
ChangeLog, pass3.c:
pass3.c (check_directory): Only do the loop detection algorithm if
we've searched over 2048 parent directories and haven't found the end
yet. This means that in the common case, we don't allocate or clear
the inode_loop_detection bitmap, which for large systems, merely
clearing the bitmap for each directory was turning out to be quite
expensive. Thanks to Jani Jaakkola (jjaakkol@cs.helsinki.fi) for
identifying this problem.
ChangeLog, Makefile.in, e2fsck.h, unix.c:
Makefile.in: Call sync after finishing building all in this directory.
unix.c (PRS): sync the filesystem before trying to use BLKFLSBUF, to
minimize the chance of causing dirty blocks to get dropped.
e2fsck.h: Manually define BLKFLSBUF if not defined, and we're on a
Linux/i386 system.
2000-02-08 22:14:02 +03:00
|
|
|
return 0;
|
2002-07-20 08:28:07 +04:00
|
|
|
}
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This routine gets the lost_and_found inode, making it a directory
|
|
|
|
* if necessary
|
|
|
|
*/
|
2002-07-25 08:00:08 +04:00
|
|
|
ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
|
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;
|
Many files:
dirinfo.c, e2fsck.h, emptydir.c, iscan.c, jfs_user.h, journal.c,
message.c, pass1.c, pass1b.c, pass2.c, pass3.c, pass4.c, pass5.c,
problem.h, scantest.c, super.c, swapfs.c: Change ino_t to ext2_ino_t.
2001-01-11 18:12:14 +03:00
|
|
|
ext2_ino_t ino;
|
2009-08-23 06:29:02 +04:00
|
|
|
blk64_t blk;
|
1997-04-26 17:21:57 +04:00
|
|
|
errcode_t retval;
|
|
|
|
struct ext2_inode inode;
|
|
|
|
char * block;
|
2001-01-06 08:55:58 +03:00
|
|
|
static const char name[] = "lost+found";
|
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
|
|
|
struct problem_context pctx;
|
1997-04-26 17:21:57 +04:00
|
|
|
|
2002-07-25 08:00:08 +04:00
|
|
|
if (ctx->lost_and_found)
|
|
|
|
return ctx->lost_and_found;
|
|
|
|
|
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
|
|
|
clear_problem_context(&pctx);
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1997-04-29 20:15:03 +04:00
|
|
|
retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
|
|
|
|
sizeof(name)-1, 0, &ino);
|
2002-07-25 08:00:08 +04:00
|
|
|
if (retval && !fix)
|
|
|
|
return 0;
|
1999-03-16 22:32:52 +03:00
|
|
|
if (!retval) {
|
2014-03-03 10:02:52 +04:00
|
|
|
/* Lost+found shouldn't have inline data */
|
|
|
|
retval = ext2fs_read_inode(fs, ino, &inode);
|
|
|
|
if (fix && retval)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (fix && (inode.i_flags & EXT4_INLINE_DATA_FL)) {
|
|
|
|
if (!fix_problem(ctx, PR_3_LPF_INLINE_DATA, &pctx))
|
|
|
|
return 0;
|
|
|
|
goto unlink;
|
|
|
|
}
|
|
|
|
|
2012-08-15 21:00:14 +04:00
|
|
|
if (ext2fs_check_directory(fs, ino) == 0) {
|
2002-07-25 08:00:08 +04:00
|
|
|
ctx->lost_and_found = ino;
|
1999-03-16 22:32:52 +03:00
|
|
|
return ino;
|
2002-07-25 08:00:08 +04:00
|
|
|
}
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1999-03-16 22:32:52 +03:00
|
|
|
/* Lost+found isn't a directory! */
|
2002-07-25 08:00:08 +04:00
|
|
|
if (!fix)
|
|
|
|
return 0;
|
1999-03-16 22:32:52 +03:00
|
|
|
pctx.ino = ino;
|
|
|
|
if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
|
|
|
|
return 0;
|
|
|
|
|
2014-03-03 10:02:52 +04:00
|
|
|
unlink:
|
1999-07-03 11:20:06 +04:00
|
|
|
/* OK, unlink the old /lost+found file. */
|
1999-03-16 22:32:52 +03:00
|
|
|
pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
|
|
|
|
if (pctx.errcode) {
|
|
|
|
pctx.str = "ext2fs_unlink";
|
|
|
|
fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
|
|
|
|
return 0;
|
|
|
|
}
|
2007-04-05 06:33:31 +04:00
|
|
|
(void) e2fsck_dir_info_set_parent(ctx, ino, 0);
|
2003-03-14 09:43:56 +03:00
|
|
|
e2fsck_adjust_inode_count(ctx, ino, -1);
|
1999-03-16 22:32:52 +03:00
|
|
|
} else if (retval != EXT2_ET_FILE_NOT_FOUND) {
|
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
|
|
|
pctx.errcode = retval;
|
|
|
|
fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
|
|
|
|
}
|
|
|
|
if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
|
1997-04-26 17:21:57 +04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read the inode and block bitmaps in; we'll be messing with
|
|
|
|
* them.
|
|
|
|
*/
|
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
|
|
|
e2fsck_read_bitmaps(ctx);
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
/*
|
|
|
|
* First, find a free block
|
|
|
|
*/
|
2014-07-26 04:33:45 +04:00
|
|
|
if (ctx->lnf_repair_block) {
|
|
|
|
blk = ctx->lnf_repair_block;
|
|
|
|
ctx->lnf_repair_block = 0;
|
|
|
|
goto skip_new_block;
|
|
|
|
}
|
2009-08-23 06:29:02 +04:00
|
|
|
retval = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
|
2014-08-03 06:18:30 +04:00
|
|
|
if (retval == EXT2_ET_BLOCK_ALLOC_FAIL &&
|
|
|
|
fix_problem(ctx, PR_3_LPF_NO_SPACE, &pctx)) {
|
2014-08-11 02:21:15 +04:00
|
|
|
fix_problem(ctx, PR_3_NO_SPACE_TO_RECOVER, &pctx);
|
2014-08-03 06:18:30 +04:00
|
|
|
ctx->lost_and_found = EXT2_ROOT_INO;
|
|
|
|
return 0;
|
|
|
|
}
|
1997-04-26 17:21:57 +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
|
|
|
pctx.errcode = retval;
|
|
|
|
fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
|
1997-04-26 17:21:57 +04:00
|
|
|
return 0;
|
|
|
|
}
|
2009-08-23 06:29:02 +04:00
|
|
|
ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
|
2014-07-26 04:33:45 +04:00
|
|
|
skip_new_block:
|
2009-10-26 04:46:58 +03:00
|
|
|
ext2fs_block_alloc_stats2(fs, blk, +1);
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Next find a free inode.
|
|
|
|
*/
|
2003-03-14 09:43:56 +03:00
|
|
|
retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
|
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->inode_used_map, &ino);
|
2014-08-03 06:18:30 +04:00
|
|
|
if (retval == EXT2_ET_INODE_ALLOC_FAIL &&
|
|
|
|
fix_problem(ctx, PR_3_LPF_NO_SPACE, &pctx)) {
|
2014-08-11 02:21:15 +04:00
|
|
|
fix_problem(ctx, PR_3_NO_SPACE_TO_RECOVER, &pctx);
|
2014-08-03 06:18:30 +04:00
|
|
|
ctx->lost_and_found = EXT2_ROOT_INO;
|
|
|
|
return 0;
|
|
|
|
}
|
1997-04-26 17:21:57 +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
|
|
|
pctx.errcode = retval;
|
|
|
|
fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
|
1997-04-26 17:21:57 +04:00
|
|
|
return 0;
|
|
|
|
}
|
2009-08-23 06:29:02 +04:00
|
|
|
ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
|
|
|
|
ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino);
|
2002-08-17 18:19:44 +04:00
|
|
|
ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up the inode structure
|
|
|
|
*/
|
|
|
|
memset(&inode, 0, sizeof(inode));
|
2002-10-12 01:44:12 +04:00
|
|
|
inode.i_mode = 040700;
|
1997-04-26 17:21:57 +04:00
|
|
|
inode.i_size = fs->blocksize;
|
2005-04-14 22:07:53 +04:00
|
|
|
inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
|
1997-04-26 17:21:57 +04:00
|
|
|
inode.i_links_count = 2;
|
2008-04-09 19:39:11 +04:00
|
|
|
ext2fs_iblk_set(fs, &inode, 1);
|
1997-04-26 17:21:57 +04:00
|
|
|
inode.i_block[0] = blk;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Next, write out the inode.
|
|
|
|
*/
|
2005-03-21 04:05:22 +03:00
|
|
|
pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
|
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 (pctx.errcode) {
|
|
|
|
pctx.str = "ext2fs_write_inode";
|
|
|
|
fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
|
1997-04-26 17:21:57 +04:00
|
|
|
return 0;
|
|
|
|
}
|
2014-07-27 01:14:40 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Now let's create the actual data block for the inode.
|
|
|
|
* Due to metadata_csum, the directory block MUST be written
|
|
|
|
* after the inode is written to disk!
|
|
|
|
*/
|
|
|
|
retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
|
|
|
|
if (retval) {
|
|
|
|
pctx.errcode = retval;
|
|
|
|
fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
|
|
|
|
ext2fs_free_mem(&block);
|
|
|
|
if (retval) {
|
|
|
|
pctx.errcode = retval;
|
|
|
|
fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
/*
|
|
|
|
* Finally, create the directory link
|
|
|
|
*/
|
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
|
|
|
pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
|
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 (pctx.errcode) {
|
|
|
|
pctx.str = "ext2fs_link";
|
|
|
|
fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
|
1997-04-26 17:21:57 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Miscellaneous bookkeeping that needs to be kept straight.
|
|
|
|
*/
|
1997-11-03 22:42:40 +03:00
|
|
|
e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
|
2003-03-14 09:43:56 +03:00
|
|
|
e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 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
|
|
|
ext2fs_icount_store(ctx->inode_count, ino, 2);
|
|
|
|
ext2fs_icount_store(ctx->inode_link_info, ino, 2);
|
2002-07-25 08:00:08 +04:00
|
|
|
ctx->lost_and_found = ino;
|
2011-07-20 22:40:06 +04:00
|
|
|
quota_data_add(ctx->qctx, &inode, ino, fs->blocksize);
|
|
|
|
quota_data_inodes(ctx->qctx, &inode, ino, +1);
|
1997-04-26 17:21:57 +04:00
|
|
|
#if 0
|
1997-04-26 17:34:30 +04:00
|
|
|
printf("/lost+found created; inode #%lu\n", ino);
|
1997-04-26 17:21:57 +04:00
|
|
|
#endif
|
|
|
|
return ino;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This routine will connect a file to lost+found
|
|
|
|
*/
|
Many files:
dirinfo.c, e2fsck.h, emptydir.c, iscan.c, jfs_user.h, journal.c,
message.c, pass1.c, pass1b.c, pass2.c, pass3.c, pass4.c, pass5.c,
problem.h, scantest.c, super.c, swapfs.c: Change ino_t to ext2_ino_t.
2001-01-11 18:12:14 +03:00
|
|
|
int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
|
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;
|
|
|
|
char name[80];
|
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
|
|
|
struct problem_context pctx;
|
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
|
|
|
struct ext2_inode inode;
|
|
|
|
int file_type = 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
|
|
|
|
|
|
|
clear_problem_context(&pctx);
|
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
|
|
|
pctx.ino = ino;
|
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
|
|
|
|
2002-07-25 08:00:08 +04:00
|
|
|
if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
|
|
|
|
if (e2fsck_get_lost_and_found(ctx, 1) == 0)
|
|
|
|
ctx->bad_lost_and_found++;
|
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
|
|
|
}
|
2002-07-25 08:00:08 +04:00
|
|
|
if (ctx->bad_lost_and_found) {
|
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
|
|
|
fix_problem(ctx, PR_3_NO_LPF, &pctx);
|
1997-04-26 17:21:57 +04:00
|
|
|
return 1;
|
|
|
|
}
|
2008-08-28 07:07:54 +04:00
|
|
|
|
Many files:
dirinfo.c, e2fsck.h, emptydir.c, iscan.c, jfs_user.h, journal.c,
message.c, pass1.c, pass1b.c, pass2.c, pass3.c, pass4.c, pass5.c,
problem.h, scantest.c, super.c, swapfs.c: Change ino_t to ext2_ino_t.
2001-01-11 18:12:14 +03:00
|
|
|
sprintf(name, "#%u", ino);
|
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 (ext2fs_read_inode(fs, ino, &inode) == 0)
|
|
|
|
file_type = ext2_file_type(inode.i_mode);
|
2002-07-25 08:00:08 +04:00
|
|
|
retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
|
1997-04-26 17:21:57 +04:00
|
|
|
if (retval == EXT2_ET_DIR_NO_SPACE) {
|
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 (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
|
1997-04-26 17:21:57 +04:00
|
|
|
return 1;
|
2008-08-28 07:07:54 +04:00
|
|
|
retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
|
2002-07-25 08:00:08 +04:00
|
|
|
1, 0);
|
1997-04-26 17:21:57 +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
|
|
|
pctx.errcode = retval;
|
|
|
|
fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
|
1997-04-26 17:21:57 +04:00
|
|
|
return 1;
|
|
|
|
}
|
2002-07-25 08:00:08 +04:00
|
|
|
retval = ext2fs_link(fs, ctx->lost_and_found, name,
|
|
|
|
ino, file_type);
|
1997-04-26 17:21:57 +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
|
|
|
pctx.errcode = retval;
|
|
|
|
fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
|
1997-04-26 17:21:57 +04:00
|
|
|
return 1;
|
|
|
|
}
|
2003-03-14 09:43:56 +03:00
|
|
|
e2fsck_adjust_inode_count(ctx, ino, 1);
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Utility routine to adjust the inode counts on an inode.
|
|
|
|
*/
|
2003-03-14 09:43:56 +03:00
|
|
|
errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
|
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;
|
|
|
|
struct ext2_inode inode;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
if (!ino)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
retval = ext2fs_read_inode(fs, ino, &inode);
|
|
|
|
if (retval)
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
#if 0
|
1997-04-26 17:34:30 +04:00
|
|
|
printf("Adjusting link count for inode %lu by %d (from %d)\n", ino, adj,
|
1997-04-26 17:21:57 +04:00
|
|
|
inode.i_links_count);
|
|
|
|
#endif
|
|
|
|
|
1997-04-29 20:15:03 +04:00
|
|
|
if (adj == 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
|
|
|
ext2fs_icount_increment(ctx->inode_count, ino, 0);
|
1999-09-15 00:00:54 +04:00
|
|
|
if (inode.i_links_count == (__u16) ~0)
|
|
|
|
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
|
|
|
ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
|
1999-09-15 00:00:54 +04:00
|
|
|
inode.i_links_count++;
|
|
|
|
} else if (adj == -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
|
|
|
ext2fs_icount_decrement(ctx->inode_count, ino, 0);
|
1999-09-15 00:00:54 +04:00
|
|
|
if (inode.i_links_count == 0)
|
|
|
|
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
|
|
|
ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
|
1999-09-15 00:00:54 +04:00
|
|
|
inode.i_links_count--;
|
1997-04-29 20:15:03 +04:00
|
|
|
}
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
retval = ext2fs_write_inode(fs, ino, &inode);
|
|
|
|
if (retval)
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Fix parent --- this routine fixes up the parent of a directory.
|
|
|
|
*/
|
|
|
|
struct fix_dotdot_struct {
|
|
|
|
ext2_filsys fs;
|
Many files:
dirinfo.c, e2fsck.h, emptydir.c, iscan.c, jfs_user.h, journal.c,
message.c, pass1.c, pass1b.c, pass2.c, pass3.c, pass4.c, pass5.c,
problem.h, scantest.c, super.c, swapfs.c: Change ino_t to ext2_ino_t.
2001-01-11 18:12:14 +03:00
|
|
|
ext2_ino_t parent;
|
1997-04-26 17:21:57 +04:00
|
|
|
int done;
|
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
|
|
|
e2fsck_t ctx;
|
1997-04-26 17:21:57 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
|
2003-12-07 09:28:50 +03:00
|
|
|
int offset EXT2FS_ATTR((unused)),
|
|
|
|
int blocksize EXT2FS_ATTR((unused)),
|
|
|
|
char *buf EXT2FS_ATTR((unused)),
|
Many files:
e2fsck.h: If EXT2_FLAT_INCLUDES is defined, then assume all of
the ext2-specific header files are in a flat directory.
dirinfo.c, ehandler.c, pass1.c, pass1b.c, pass2.c, pass5.c,
super.c, swapfs.c, unix.c: Explicitly cast all assignments
from void * to be compatible with C++.
unix.c (sync_disk): Remove sync_disk and calls to that function,
since ext2fs_close() now takes care of this.
pass1.c, pass1b.c, pass2.c, pass3.c, swapfs, badblocks.c,
ehandler.c, unix.c: Change use of private to be priv_data, to
avoid C++ reserved name clash.
1998-01-19 17:50:49 +03:00
|
|
|
void *priv_data)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
Many files:
e2fsck.h: If EXT2_FLAT_INCLUDES is defined, then assume all of
the ext2-specific header files are in a flat directory.
dirinfo.c, ehandler.c, pass1.c, pass1b.c, pass2.c, pass5.c,
super.c, swapfs.c, unix.c: Explicitly cast all assignments
from void * to be compatible with C++.
unix.c (sync_disk): Remove sync_disk and calls to that function,
since ext2fs_close() now takes care of this.
pass1.c, pass1b.c, pass2.c, pass3.c, swapfs, badblocks.c,
ehandler.c, unix.c: Change use of private to be priv_data, to
avoid C++ reserved name clash.
1998-01-19 17:50:49 +03:00
|
|
|
struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
|
1997-04-26 17:21:57 +04:00
|
|
|
errcode_t 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
|
|
|
struct problem_context pctx;
|
1997-04-26 17:21:57 +04:00
|
|
|
|
2013-06-08 19:26:14 +04:00
|
|
|
if (ext2fs_dirent_name_len(dirent) != 2)
|
1997-04-26 17:21:57 +04:00
|
|
|
return 0;
|
|
|
|
if (strncmp(dirent->name, "..", 2))
|
|
|
|
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
|
|
|
clear_problem_context(&pctx);
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2003-03-14 09:43:56 +03:00
|
|
|
retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -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 (retval) {
|
|
|
|
pctx.errcode = retval;
|
|
|
|
fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
|
|
|
|
}
|
2003-03-14 09:43:56 +03:00
|
|
|
retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 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 (retval) {
|
|
|
|
pctx.errcode = retval;
|
|
|
|
fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
|
|
|
|
}
|
1997-04-26 17:21:57 +04:00
|
|
|
dirent->inode = fp->parent;
|
2007-04-01 03:18:24 +04:00
|
|
|
if (fp->ctx->fs->super->s_feature_incompat &
|
|
|
|
EXT2_FEATURE_INCOMPAT_FILETYPE)
|
2013-06-08 19:26:14 +04:00
|
|
|
ext2fs_dirent_set_file_type(dirent, EXT2_FT_DIR);
|
2007-04-01 03:18:24 +04:00
|
|
|
else
|
2013-06-08 19:26:14 +04:00
|
|
|
ext2fs_dirent_set_file_type(dirent, EXT2_FT_UNKNOWN);
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
fp->done++;
|
|
|
|
return DIRENT_ABORT | DIRENT_CHANGED;
|
|
|
|
}
|
|
|
|
|
2007-04-05 06:33:31 +04:00
|
|
|
static void fix_dotdot(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
|
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;
|
|
|
|
struct fix_dotdot_struct fp;
|
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
|
|
|
struct problem_context pctx;
|
e2fsck: correctly preserve fs flags when modifying ignore-csum-error flag
When we need to modify the "ignore checksum error" behavior flag to
get us past a library call, it's possible that the library call can
result in other flag bits being changed. Therefore, it is not correct
to restore unconditionally the previous flags value, since this will
have unintended side effects on the other fs->flags; nor is it correct
to assume that we can unconditionally set (or clear) the "ignore csum
error" flag bit. Therefore, we must merge the previous value of the
"ignore csum error" flag with the value of flags after the call.
Note that we want to leave checksum verification on as much as
possible because doing so exposes e2fsck bugs where two metadata
blocks are "sharing" the same disk block, and attempting to fix one
before relocating the other causes major filesystem damage. The
damage is much more obvious when a previously checked piece of
metadata suddenly fails in a subsequent pass.
The modifications to the pass 2, 3, and 3A code are justified as
follows: When e2fsck encounters a block of directory entries and
cannot find the placeholder entry at the end that contains the
checksum, it will try to insert the placeholder. If that fails, it
will schedule the directory for a pass 3A reconstruction. Until that
happens, we don't want directory block writing (pass 2), block
iteration (pass 3), or block reading (pass 3A) to fail due to checksum
errors, because failing to find the placeholder is itself a checksum
verification error, which causes e2fsck to abort without fixing
anything.
The e2fsck call to ext2fs_read_bitmaps must never fail due to a
checksum error because e2fsck subsequently (a) verifies the bitmaps
itself; or (b) decides that they don't match what has been observed,
and rewrites them.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2014-08-03 06:48:21 +04:00
|
|
|
int flags, will_rehash;
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
fp.fs = fs;
|
|
|
|
fp.parent = parent;
|
|
|
|
fp.done = 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
|
|
|
fp.ctx = ctx;
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
#if 0
|
2007-04-05 06:33:31 +04:00
|
|
|
printf("Fixing '..' of inode %lu to be %lu...\n", ino, parent);
|
1997-04-26 17:21:57 +04:00
|
|
|
#endif
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2007-04-05 06:33:31 +04:00
|
|
|
clear_problem_context(&pctx);
|
|
|
|
pctx.ino = ino;
|
e2fsck: correctly preserve fs flags when modifying ignore-csum-error flag
When we need to modify the "ignore checksum error" behavior flag to
get us past a library call, it's possible that the library call can
result in other flag bits being changed. Therefore, it is not correct
to restore unconditionally the previous flags value, since this will
have unintended side effects on the other fs->flags; nor is it correct
to assume that we can unconditionally set (or clear) the "ignore csum
error" flag bit. Therefore, we must merge the previous value of the
"ignore csum error" flag with the value of flags after the call.
Note that we want to leave checksum verification on as much as
possible because doing so exposes e2fsck bugs where two metadata
blocks are "sharing" the same disk block, and attempting to fix one
before relocating the other causes major filesystem damage. The
damage is much more obvious when a previously checked piece of
metadata suddenly fails in a subsequent pass.
The modifications to the pass 2, 3, and 3A code are justified as
follows: When e2fsck encounters a block of directory entries and
cannot find the placeholder entry at the end that contains the
checksum, it will try to insert the placeholder. If that fails, it
will schedule the directory for a pass 3A reconstruction. Until that
happens, we don't want directory block writing (pass 2), block
iteration (pass 3), or block reading (pass 3A) to fail due to checksum
errors, because failing to find the placeholder is itself a checksum
verification error, which causes e2fsck to abort without fixing
anything.
The e2fsck call to ext2fs_read_bitmaps must never fail due to a
checksum error because e2fsck subsequently (a) verifies the bitmaps
itself; or (b) decides that they don't match what has been observed,
and rewrites them.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2014-08-03 06:48:21 +04:00
|
|
|
will_rehash = e2fsck_dir_will_be_rehashed(ctx, ino);
|
|
|
|
if (will_rehash) {
|
|
|
|
flags = ctx->fs->flags;
|
2012-08-03 01:27:43 +04:00
|
|
|
ctx->fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
|
e2fsck: correctly preserve fs flags when modifying ignore-csum-error flag
When we need to modify the "ignore checksum error" behavior flag to
get us past a library call, it's possible that the library call can
result in other flag bits being changed. Therefore, it is not correct
to restore unconditionally the previous flags value, since this will
have unintended side effects on the other fs->flags; nor is it correct
to assume that we can unconditionally set (or clear) the "ignore csum
error" flag bit. Therefore, we must merge the previous value of the
"ignore csum error" flag with the value of flags after the call.
Note that we want to leave checksum verification on as much as
possible because doing so exposes e2fsck bugs where two metadata
blocks are "sharing" the same disk block, and attempting to fix one
before relocating the other causes major filesystem damage. The
damage is much more obvious when a previously checked piece of
metadata suddenly fails in a subsequent pass.
The modifications to the pass 2, 3, and 3A code are justified as
follows: When e2fsck encounters a block of directory entries and
cannot find the placeholder entry at the end that contains the
checksum, it will try to insert the placeholder. If that fails, it
will schedule the directory for a pass 3A reconstruction. Until that
happens, we don't want directory block writing (pass 2), block
iteration (pass 3), or block reading (pass 3A) to fail due to checksum
errors, because failing to find the placeholder is itself a checksum
verification error, which causes e2fsck to abort without fixing
anything.
The e2fsck call to ext2fs_read_bitmaps must never fail due to a
checksum error because e2fsck subsequently (a) verifies the bitmaps
itself; or (b) decides that they don't match what has been observed,
and rewrites them.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2014-08-03 06:48:21 +04:00
|
|
|
}
|
2007-04-05 06:33:31 +04:00
|
|
|
retval = ext2fs_dir_iterate(fs, ino, DIRENT_FLAG_INCLUDE_EMPTY,
|
1997-04-26 17:21:57 +04:00
|
|
|
0, fix_dotdot_proc, &fp);
|
e2fsck: correctly preserve fs flags when modifying ignore-csum-error flag
When we need to modify the "ignore checksum error" behavior flag to
get us past a library call, it's possible that the library call can
result in other flag bits being changed. Therefore, it is not correct
to restore unconditionally the previous flags value, since this will
have unintended side effects on the other fs->flags; nor is it correct
to assume that we can unconditionally set (or clear) the "ignore csum
error" flag bit. Therefore, we must merge the previous value of the
"ignore csum error" flag with the value of flags after the call.
Note that we want to leave checksum verification on as much as
possible because doing so exposes e2fsck bugs where two metadata
blocks are "sharing" the same disk block, and attempting to fix one
before relocating the other causes major filesystem damage. The
damage is much more obvious when a previously checked piece of
metadata suddenly fails in a subsequent pass.
The modifications to the pass 2, 3, and 3A code are justified as
follows: When e2fsck encounters a block of directory entries and
cannot find the placeholder entry at the end that contains the
checksum, it will try to insert the placeholder. If that fails, it
will schedule the directory for a pass 3A reconstruction. Until that
happens, we don't want directory block writing (pass 2), block
iteration (pass 3), or block reading (pass 3A) to fail due to checksum
errors, because failing to find the placeholder is itself a checksum
verification error, which causes e2fsck to abort without fixing
anything.
The e2fsck call to ext2fs_read_bitmaps must never fail due to a
checksum error because e2fsck subsequently (a) verifies the bitmaps
itself; or (b) decides that they don't match what has been observed,
and rewrites them.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2014-08-03 06:48:21 +04:00
|
|
|
if (will_rehash)
|
|
|
|
ctx->fs->flags = (flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
|
|
|
|
(ctx->fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
|
1997-04-26 17:21:57 +04:00
|
|
|
if (retval || !fp.done) {
|
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
|
|
|
pctx.errcode = retval;
|
|
|
|
fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
|
|
|
|
PR_3_FIX_PARENT_NOFIND, &pctx);
|
1997-04-26 17:21:57 +04:00
|
|
|
ext2fs_unmark_valid(fs);
|
|
|
|
}
|
2007-04-05 06:33:31 +04:00
|
|
|
(void) e2fsck_dir_info_set_dotdot(ctx, ino, parent);
|
|
|
|
if (e2fsck_dir_info_set_parent(ctx, ino, ctx->lost_and_found))
|
|
|
|
fix_problem(ctx, PR_3_NO_DIRINFO, &pctx);
|
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These routines are responsible for expanding a /lost+found if it is
|
|
|
|
* too small.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct expand_dir_struct {
|
2010-06-14 01:00:00 +04:00
|
|
|
blk64_t num;
|
|
|
|
e2_blkcnt_t guaranteed_size;
|
|
|
|
blk64_t newblocks;
|
|
|
|
blk64_t last_block;
|
1999-09-15 00:00:54 +04:00
|
|
|
errcode_t err;
|
|
|
|
e2fsck_t ctx;
|
2012-08-03 01:27:43 +04:00
|
|
|
ext2_ino_t dir;
|
1997-04-26 17:21:57 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
static int expand_dir_proc(ext2_filsys fs,
|
2010-06-14 01:00:00 +04:00
|
|
|
blk64_t *blocknr,
|
ChangeLog, message.c, pass1b.c, pass2.c, pass3.c, problem.c, problem.h:
pass1b.c: Change routines to use PR_1B_BLOCK_ITERATE when reporting
problems rather than using com_err directly.
problem.c, problem.h (PR_1B_BLOCK_ITERATE): Add new problem code.
message.c (expand_percent_expression): Add safety check. If ctx->str
is NULL, print "NULL" instead of dereferencing the null pointer.
pass1b.c, pass2.c, pass3.c: Change calls to ext2fs_block_iterate to
ext2fs_block_iterate2, to support 64-bit filesizes and to speed things
up slightly by avoiding the use of the ext2fs_block_iterate's
compatibility shim layer.
version.h:
Update for WIP release.
2000-11-17 08:40:49 +03:00
|
|
|
e2_blkcnt_t blockcnt,
|
2010-06-14 01:00:00 +04:00
|
|
|
blk64_t ref_block EXT2FS_ATTR((unused)),
|
2003-12-07 09:28:50 +03:00
|
|
|
int ref_offset EXT2FS_ATTR((unused)),
|
Many files:
e2fsck.h: If EXT2_FLAT_INCLUDES is defined, then assume all of
the ext2-specific header files are in a flat directory.
dirinfo.c, ehandler.c, pass1.c, pass1b.c, pass2.c, pass5.c,
super.c, swapfs.c, unix.c: Explicitly cast all assignments
from void * to be compatible with C++.
unix.c (sync_disk): Remove sync_disk and calls to that function,
since ext2fs_close() now takes care of this.
pass1.c, pass1b.c, pass2.c, pass3.c, swapfs, badblocks.c,
ehandler.c, unix.c: Change use of private to be priv_data, to
avoid C++ reserved name clash.
1998-01-19 17:50:49 +03:00
|
|
|
void *priv_data)
|
1997-04-26 17:21:57 +04:00
|
|
|
{
|
Many files:
e2fsck.h: If EXT2_FLAT_INCLUDES is defined, then assume all of
the ext2-specific header files are in a flat directory.
dirinfo.c, ehandler.c, pass1.c, pass1b.c, pass2.c, pass5.c,
super.c, swapfs.c, unix.c: Explicitly cast all assignments
from void * to be compatible with C++.
unix.c (sync_disk): Remove sync_disk and calls to that function,
since ext2fs_close() now takes care of this.
pass1.c, pass1b.c, pass2.c, pass3.c, swapfs, badblocks.c,
ehandler.c, unix.c: Change use of private to be priv_data, to
avoid C++ reserved name clash.
1998-01-19 17:50:49 +03:00
|
|
|
struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
|
2009-08-23 06:29:02 +04:00
|
|
|
blk64_t new_blk;
|
2010-06-14 01:00:00 +04:00
|
|
|
static blk64_t last_blk = 0;
|
1997-04-26 17:21:57 +04:00
|
|
|
char *block;
|
|
|
|
errcode_t 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
|
|
|
e2fsck_t ctx;
|
|
|
|
|
|
|
|
ctx = es->ctx;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2002-07-20 08:28:07 +04:00
|
|
|
if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
|
|
|
|
return BLOCK_ABORT;
|
|
|
|
|
|
|
|
if (blockcnt > 0)
|
|
|
|
es->last_block = blockcnt;
|
1997-04-26 17:21:57 +04:00
|
|
|
if (*blocknr) {
|
|
|
|
last_blk = *blocknr;
|
|
|
|
return 0;
|
|
|
|
}
|
2013-12-16 08:54:07 +04:00
|
|
|
|
|
|
|
if (blockcnt &&
|
|
|
|
(EXT2FS_B2C(fs, last_blk) == EXT2FS_B2C(fs, last_blk + 1)))
|
|
|
|
new_blk = last_blk + 1;
|
|
|
|
else {
|
|
|
|
last_blk &= ~EXT2FS_CLUSTER_MASK(fs);
|
|
|
|
retval = ext2fs_new_block2(fs, last_blk, ctx->block_found_map,
|
|
|
|
&new_blk);
|
|
|
|
if (retval) {
|
|
|
|
es->err = retval;
|
|
|
|
return BLOCK_ABORT;
|
|
|
|
}
|
|
|
|
es->newblocks++;
|
|
|
|
ext2fs_block_alloc_stats2(fs, new_blk, +1);
|
1997-04-26 17:21:57 +04:00
|
|
|
}
|
2013-12-16 08:54:07 +04:00
|
|
|
last_blk = new_blk;
|
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
if (blockcnt > 0) {
|
|
|
|
retval = ext2fs_new_dir_block(fs, 0, 0, &block);
|
|
|
|
if (retval) {
|
|
|
|
es->err = retval;
|
|
|
|
return BLOCK_ABORT;
|
|
|
|
}
|
2002-07-20 08:28:07 +04:00
|
|
|
es->num--;
|
2012-08-03 01:27:43 +04:00
|
|
|
retval = ext2fs_write_dir_block4(fs, new_blk, block, 0,
|
|
|
|
es->dir);
|
1997-04-26 17:21:57 +04:00
|
|
|
} else {
|
2003-08-01 17:41:07 +04:00
|
|
|
retval = ext2fs_get_mem(fs->blocksize, &block);
|
1997-11-03 22:42:40 +03:00
|
|
|
if (retval) {
|
|
|
|
es->err = retval;
|
1997-04-26 17:21:57 +04:00
|
|
|
return BLOCK_ABORT;
|
|
|
|
}
|
|
|
|
memset(block, 0, fs->blocksize);
|
2009-09-08 05:14:24 +04:00
|
|
|
retval = io_channel_write_blk64(fs->io, new_blk, 1, block);
|
2008-08-28 07:07:54 +04:00
|
|
|
}
|
1997-04-26 17:21:57 +04:00
|
|
|
if (retval) {
|
|
|
|
es->err = retval;
|
|
|
|
return BLOCK_ABORT;
|
|
|
|
}
|
2003-08-01 17:41:07 +04:00
|
|
|
ext2fs_free_mem(&block);
|
1997-04-26 17:21:57 +04:00
|
|
|
*blocknr = new_blk;
|
2009-08-23 06:29:02 +04:00
|
|
|
ext2fs_mark_block_bitmap2(ctx->block_found_map, new_blk);
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2002-07-20 08:28:07 +04:00
|
|
|
if (es->num == 0)
|
1997-04-26 17:21:57 +04:00
|
|
|
return (BLOCK_CHANGED | BLOCK_ABORT);
|
|
|
|
else
|
|
|
|
return BLOCK_CHANGED;
|
|
|
|
}
|
|
|
|
|
2002-07-20 08:28:07 +04:00
|
|
|
errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
|
|
|
|
int num, int guaranteed_size)
|
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;
|
|
|
|
struct expand_dir_struct es;
|
|
|
|
struct ext2_inode inode;
|
2014-08-24 20:16:23 +04:00
|
|
|
blk64_t sz;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
if (!(fs->flags & EXT2_FLAG_RW))
|
|
|
|
return EXT2_ET_RO_FILSYS;
|
|
|
|
|
1997-11-21 00:52:43 +03:00
|
|
|
/*
|
|
|
|
* Read the inode and block bitmaps in; we'll be messing with
|
|
|
|
* them.
|
|
|
|
*/
|
|
|
|
e2fsck_read_bitmaps(ctx);
|
1999-09-15 00:00:54 +04:00
|
|
|
|
1997-04-26 17:21:57 +04:00
|
|
|
retval = ext2fs_check_directory(fs, dir);
|
|
|
|
if (retval)
|
|
|
|
return retval;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2002-07-20 08:28:07 +04:00
|
|
|
es.num = num;
|
|
|
|
es.guaranteed_size = guaranteed_size;
|
|
|
|
es.last_block = 0;
|
1997-04-26 17:21:57 +04:00
|
|
|
es.err = 0;
|
1999-09-15 00:00:54 +04:00
|
|
|
es.newblocks = 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
|
|
|
es.ctx = ctx;
|
2012-08-03 01:27:43 +04:00
|
|
|
es.dir = dir;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2010-06-14 01:00:00 +04:00
|
|
|
retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,
|
ChangeLog, message.c, pass1b.c, pass2.c, pass3.c, problem.c, problem.h:
pass1b.c: Change routines to use PR_1B_BLOCK_ITERATE when reporting
problems rather than using com_err directly.
problem.c, problem.h (PR_1B_BLOCK_ITERATE): Add new problem code.
message.c (expand_percent_expression): Add safety check. If ctx->str
is NULL, print "NULL" instead of dereferencing the null pointer.
pass1b.c, pass2.c, pass3.c: Change calls to ext2fs_block_iterate to
ext2fs_block_iterate2, to support 64-bit filesizes and to speed things
up slightly by avoiding the use of the ext2fs_block_iterate's
compatibility shim layer.
version.h:
Update for WIP release.
2000-11-17 08:40:49 +03:00
|
|
|
0, expand_dir_proc, &es);
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
if (es.err)
|
|
|
|
return es.err;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Update the size and block count fields in the inode.
|
|
|
|
*/
|
|
|
|
retval = ext2fs_read_inode(fs, dir, &inode);
|
|
|
|
if (retval)
|
|
|
|
return retval;
|
2008-08-28 07:07:54 +04:00
|
|
|
|
2013-10-07 17:51:48 +04:00
|
|
|
sz = (es.last_block + 1) * fs->blocksize;
|
2014-07-26 22:34:56 +04:00
|
|
|
retval = ext2fs_inode_size_set(fs, &inode, sz);
|
|
|
|
if (retval)
|
|
|
|
return retval;
|
2008-04-09 19:39:11 +04:00
|
|
|
ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
|
2011-07-20 22:40:06 +04:00
|
|
|
quota_data_add(ctx->qctx, &inode, dir, es.newblocks * fs->blocksize);
|
1997-04-26 17:21:57 +04:00
|
|
|
|
1997-11-03 22:42:40 +03:00
|
|
|
e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
|
1997-04-26 17:21:57 +04:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2002-07-20 08:28:07 +04:00
|
|
|
|