aboutsummaryrefslogtreecommitdiff
path: root/e2fsck/pass5.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2006-05-08 20:17:26 -0400
committerTheodore Ts'o <tytso@mit.edu>2006-05-08 20:17:26 -0400
commitf5fa20078bfc05b554294fe9c5505375d7913e8c (patch)
treef51fd572f2a76eaab495e7559ba40dee09067dd2 /e2fsck/pass5.c
parent49c6b4e9472f53c252126f1c9a5a6e9629967d1f (diff)
downloade2fsprogs-f5fa20078bfc05b554294fe9c5505375d7913e8c.tar.gz
Add support for EXT2_FEATURE_COMPAT_LAZY_BG
This feature is initially intended for testing purposes; it allows an ext2/ext3 developer to create very large filesystems using sparse files where most of the block groups are not initialized and so do not require much disk space. Eventually it could be used as a way of speeding up mke2fs and e2fsck for large filesystem, but that would be best done by adding an RO_COMPAT extension to the filesystem to allow the inode table to be lazily initialized on a per-block basis, instead of being entirely initialized or entirely unused on a per-blockgroup basis. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'e2fsck/pass5.c')
-rw-r--r--e2fsck/pass5.c73
1 files changed, 63 insertions, 10 deletions
diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c
index e708fa41..eb3ebf02 100644
--- a/e2fsck/pass5.c
+++ b/e2fsck/pass5.c
@@ -111,7 +111,7 @@ static void print_bitmap_problem(e2fsck_t ctx, int problem,
static void check_block_bitmaps(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
- blk_t i;
+ blk_t i, super;
int *free_array;
int group = 0;
unsigned int blocks = 0;
@@ -121,6 +121,8 @@ static void check_block_bitmaps(e2fsck_t ctx)
struct problem_context pctx;
int problem, save_problem, fixit, had_problem;
errcode_t retval;
+ int lazy_bg = 0;
+ int skip_group = 0;
clear_problem_context(&pctx);
free_array = (int *) e2fsck_allocate_memory(ctx,
@@ -156,19 +158,45 @@ static void check_block_bitmaps(e2fsck_t ctx)
return;
}
+ if (EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_LAZY_BG))
+ lazy_bg++;
+
redo_counts:
had_problem = 0;
save_problem = 0;
pctx.blk = pctx.blk2 = NO_BLK;
+ if (lazy_bg && (fs->group_desc[group].bg_flags &
+ EXT2_BG_BLOCK_UNINIT))
+ skip_group++;
+ super = fs->super->s_first_data_block;
for (i = fs->super->s_first_data_block;
i < fs->super->s_blocks_count;
i++) {
actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
- bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
+
+ if (skip_group) {
+ if ((i >= super) &&
+ (i <= super + fs->desc_blocks) &&
+ ext2fs_bg_has_super(fs, group))
+ bitmap = 1;
+ else if (i == fs->group_desc[group].bg_block_bitmap)
+ bitmap = 1;
+ else if (i == fs->group_desc[group].bg_inode_bitmap)
+ bitmap = 1;
+ else if (i >= fs->group_desc[group].bg_inode_table &&
+ (i < fs->group_desc[group].bg_inode_table
+ + fs->inode_blocks_per_group))
+ bitmap = 1;
+ else
+ bitmap = 0;
+ actual = (actual != 0);
+ } else
+ bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
if (actual == bitmap)
goto do_counts;
-
+
if (!actual && bitmap) {
/*
* Block not used, but marked in use in the bitmap.
@@ -197,7 +225,7 @@ redo_counts:
had_problem++;
do_counts:
- if (!bitmap) {
+ if (!bitmap && !skip_group) {
group_free++;
free_blocks++;
}
@@ -208,10 +236,17 @@ redo_counts:
group ++;
blocks = 0;
group_free = 0;
+ skip_group = 0;
+ super += fs->super->s_blocks_per_group;
if (ctx->progress)
if ((ctx->progress)(ctx, 5, group,
fs->group_desc_count*2))
return;
+ if (lazy_bg &&
+ (i != fs->super->s_blocks_count-1) &&
+ (fs->group_desc[group].bg_flags &
+ EXT2_BG_BLOCK_UNINIT))
+ skip_group++;
}
}
if (pctx.blk != NO_BLK)
@@ -286,6 +321,8 @@ static void check_inode_bitmaps(e2fsck_t ctx)
errcode_t retval;
struct problem_context pctx;
int problem, save_problem, fixit, had_problem;
+ int lazy_bg = 0;
+ int skip_group = 0;
clear_problem_context(&pctx);
free_array = (int *) e2fsck_allocate_memory(ctx,
@@ -321,14 +358,24 @@ static void check_inode_bitmaps(e2fsck_t ctx)
return;
}
+ if (EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_LAZY_BG))
+ lazy_bg++;
+
redo_counts:
had_problem = 0;
save_problem = 0;
pctx.ino = pctx.ino2 = 0;
+ if (lazy_bg && (fs->group_desc[group].bg_flags &
+ EXT2_BG_INODE_UNINIT))
+ skip_group++;
+
for (i = 1; i <= fs->super->s_inodes_count; i++) {
actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
- bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
-
+ if (skip_group)
+ bitmap = 0;
+ else
+ bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
if (actual == bitmap)
goto do_counts;
@@ -360,12 +407,12 @@ redo_counts:
had_problem++;
do_counts:
- if (!bitmap) {
- group_free++;
- free_inodes++;
- } else {
+ if (bitmap) {
if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
dirs_count++;
+ } else if (!skip_group) {
+ group_free++;
+ free_inodes++;
}
inodes++;
if ((inodes == fs->super->s_inodes_per_group) ||
@@ -374,6 +421,7 @@ do_counts:
dir_array[group] = dirs_count;
group ++;
inodes = 0;
+ skip_group = 0;
group_free = 0;
dirs_count = 0;
if (ctx->progress)
@@ -381,6 +429,11 @@ do_counts:
group + fs->group_desc_count,
fs->group_desc_count*2))
return;
+ if (lazy_bg &&
+ (i != fs->super->s_inodes_count) &&
+ (fs->group_desc[group].bg_flags &
+ EXT2_BG_INODE_UNINIT))
+ skip_group++;
}
}
if (pctx.ino)