e2fsck: Teach new_table_block() to allocate new itables/bitmaps with FLEX_BG

If the filesystem feature FLEX_BG is enabled, the inode table and
bitmap blocks can be located anywhere in the inode table.  So for
FLEX_BG filesystems, new_table_block() now tries allocate in the block
group's flex_bg first, and if there is no space in the local flex_bg,
then try to allocate from the whole filesystem.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
bitmap-optimize
Theodore Ts'o 2009-08-18 22:27:42 -04:00
parent 334cfccbca
commit 617446e4aa
1 changed files with 29 additions and 3 deletions

View File

@ -2376,9 +2376,10 @@ static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
const char *name, int num, blk_t *new_block)
{
ext2_filsys fs = ctx->fs;
dgrp_t last_grp;
blk_t old_block = *new_block;
blk_t last_block;
int i;
int i, is_flexbg, flexbg, flexbg_size;
char *buf;
struct problem_context pctx;
@ -2388,19 +2389,44 @@ static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
pctx.blk = old_block;
pctx.str = name;
last_block = ext2fs_group_last_block(fs, group);
/*
* For flex_bg filesystems, first try to allocate the metadata
* within the flex_bg, and if that fails then try finding the
* space anywhere in the filesystem.
*/
is_flexbg = EXT2_HAS_INCOMPAT_FEATURE(fs->super,
EXT4_FEATURE_INCOMPAT_FLEX_BG);
if (is_flexbg) {
flexbg_size = 1 << fs->super->s_log_groups_per_flex;
flexbg = group / flexbg_size;
first_block = ext2fs_group_first_block(fs,
flexbg_size * flexbg);
last_grp = group | (flexbg_size - 1);
if (last_grp > fs->group_desc_count)
last_grp = fs->group_desc_count;
last_block = ext2fs_group_last_block(fs, last_grp);
} else
last_block = ext2fs_group_last_block(fs, group);
pctx.errcode = ext2fs_get_free_blocks(fs, first_block, last_block,
num, ctx->block_found_map, new_block);
num, ctx->block_found_map,
new_block);
if (is_flexbg && (pctx.errcode == EXT2_ET_BLOCK_ALLOC_FAIL))
pctx.errcode = ext2fs_get_free_blocks(fs,
fs->super->s_first_data_block,
fs->super->s_blocks_count,
num, ctx->block_found_map, new_block);
if (pctx.errcode) {
pctx.num = num;
fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
ext2fs_unmark_valid(fs);
ctx->flags |= E2F_FLAG_ABORT;
return;
}
pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
if (pctx.errcode) {
fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
ext2fs_unmark_valid(fs);
ctx->flags |= E2F_FLAG_ABORT;
return;
}
ext2fs_mark_super_dirty(fs);