almost all fsck errors fixed ("primary superblock features different from backup, check forced" left)
parent
a33f91e388
commit
97dc1bef18
100
realloc-inodes.c
100
realloc-inodes.c
|
@ -173,6 +173,7 @@ int shrink_move_inodes(realloc_data *rd)
|
|||
{
|
||||
goto out;
|
||||
}
|
||||
ext2fs_mark_ib_dirty(rd->fs);
|
||||
// Remember mapping
|
||||
realloc_add_inode_map(rd, ino, new_ino);
|
||||
}
|
||||
|
@ -238,7 +239,9 @@ int change_inode_numbers(realloc_data *rd)
|
|||
int change_super_and_bgd(realloc_data *rd)
|
||||
{
|
||||
blk64_t it_start, blk;
|
||||
dgrp_t grp, n_flex, last_grp;
|
||||
dgrp_t grp, n_flex, n_grp;
|
||||
__u32 unus;
|
||||
int i_per_g_diff;
|
||||
int flexbg_size = 0, i, retval = 0;
|
||||
void *buf = NULL;
|
||||
ext2fs_flush(rd->fs);
|
||||
|
@ -255,14 +258,16 @@ int change_super_and_bgd(realloc_data *rd)
|
|||
{
|
||||
goto out;
|
||||
}
|
||||
i_per_g_diff = rd->new_inodes_per_group - EXT2_INODES_PER_GROUP(rd->fs->super);
|
||||
for (n_flex = 0; n_flex < rd->fs->group_desc_count/flexbg_size; n_flex++)
|
||||
{
|
||||
last_grp = (n_flex+1)*flexbg_size;
|
||||
if (last_grp > rd->fs->group_desc_count)
|
||||
n_grp = flexbg_size;
|
||||
if (n_flex*flexbg_size+n_grp > rd->fs->group_desc_count)
|
||||
{
|
||||
last_grp = rd->fs->group_desc_count;
|
||||
n_grp = rd->fs->group_desc_count-n_flex*flexbg_size;
|
||||
}
|
||||
for (grp = n_flex*flexbg_size, i = 0; grp < last_grp; grp++, i++)
|
||||
// Read inode tables
|
||||
for (grp = n_flex*flexbg_size, i = 0; i < n_grp; grp++, i++)
|
||||
{
|
||||
if (!ext2fs_bg_flags_test(rd->fs, grp, EXT2_BG_INODE_UNINIT))
|
||||
{
|
||||
|
@ -275,37 +280,44 @@ int change_super_and_bgd(realloc_data *rd)
|
|||
}
|
||||
}
|
||||
}
|
||||
// Write inode table to the new place
|
||||
it_start = ext2fs_inode_table_loc(rd->fs, n_flex*flexbg_size);
|
||||
blk = rd->new_inode_blocks_per_group * (last_grp-n_flex*flexbg_size);
|
||||
blk = rd->new_inode_blocks_per_group * n_grp;
|
||||
retval = io_channel_write_blk64(rd->fs->io, it_start, blk, buf);
|
||||
if (retval)
|
||||
{
|
||||
// The FS is badly corrupted now :-(
|
||||
printf("Error moving inode tables for %u groups, starting from %u\n", last_grp-n_flex*flexbg_size, n_flex*flexbg_size);
|
||||
printf("Error moving inode tables for %u groups, starting from %u\n", n_grp, n_flex*flexbg_size);
|
||||
goto out;
|
||||
}
|
||||
// Mark/unmark extra inode table blocks
|
||||
if (rd->new_inode_blocks_per_group < rd->fs->inode_blocks_per_group)
|
||||
{
|
||||
ext2fs_unmark_block_bitmap_range2(rd->fs->block_map, it_start+blk, (rd->fs->inode_blocks_per_group-rd->new_inode_blocks_per_group)*flexbg_size);
|
||||
ext2fs_unmark_block_bitmap_range2(rd->fs->block_map, it_start+blk,
|
||||
(rd->fs->inode_blocks_per_group-rd->new_inode_blocks_per_group)*n_grp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ext2fs_mark_block_bitmap_range2(rd->fs->block_map, it_start+blk, (rd->new_inode_blocks_per_group-rd->fs->inode_blocks_per_group)*flexbg_size);
|
||||
ext2fs_mark_block_bitmap_range2(rd->fs->block_map, it_start+blk,
|
||||
(rd->new_inode_blocks_per_group-rd->fs->inode_blocks_per_group)*n_grp);
|
||||
}
|
||||
// Change inode table locations and free block/inode counts
|
||||
for (grp = n_flex*flexbg_size, i = 0; grp < last_grp; grp++, i++)
|
||||
if (!ext2fs_bg_flags_test(rd->fs, n_flex*flexbg_size, EXT2_BG_INODE_UNINIT))
|
||||
{
|
||||
if (!ext2fs_bg_flags_test(rd->fs, grp, EXT2_BG_INODE_UNINIT))
|
||||
{
|
||||
blk = it_start + rd->new_inode_blocks_per_group*i;
|
||||
ext2fs_inode_table_loc_set(rd->fs, grp, blk);
|
||||
ext2fs_bg_free_blocks_count_set(rd->fs, grp, ext2fs_bg_free_blocks_count(rd->fs, grp) +
|
||||
rd->new_inode_blocks_per_group - rd->fs->inode_blocks_per_group);
|
||||
ext2fs_bg_free_inodes_count_set(rd->fs, grp, ext2fs_bg_free_inodes_count(rd->fs, grp) +
|
||||
rd->new_inodes_per_group - EXT2_INODES_PER_GROUP(rd->fs->super));
|
||||
ext2fs_bg_itable_unused_set(rd->fs, grp, 0); // Is it correct?..
|
||||
}
|
||||
ext2fs_bg_free_blocks_count_set(rd->fs, n_flex*flexbg_size,
|
||||
ext2fs_bg_free_blocks_count(rd->fs, n_flex*flexbg_size) -
|
||||
(rd->new_inode_blocks_per_group - rd->fs->inode_blocks_per_group)*flexbg_size);
|
||||
}
|
||||
// Change inode table locations and free inode counts
|
||||
for (grp = n_flex*flexbg_size, i = 0; i < n_grp; grp++, i++)
|
||||
{
|
||||
blk = it_start + rd->new_inode_blocks_per_group*i;
|
||||
ext2fs_inode_table_loc_set(rd->fs, grp, blk);
|
||||
ext2fs_bg_free_inodes_count_set(rd->fs, grp,
|
||||
ext2fs_bg_free_inodes_count(rd->fs, grp) + i_per_g_diff);
|
||||
unus = ext2fs_bg_itable_unused(rd->fs, grp);
|
||||
unus = unus < i_per_g_diff ? 0 : unus - i_per_g_diff;
|
||||
ext2fs_bg_itable_unused_set(rd->fs, grp, unus);
|
||||
ext2fs_group_desc_csum_set(rd->fs, grp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,31 +326,40 @@ int change_super_and_bgd(realloc_data *rd)
|
|||
// Mark/unmark extra inode table blocks (without flex_bg)
|
||||
for (grp = 0; grp < rd->fs->group_desc_count; grp++)
|
||||
{
|
||||
if (!ext2fs_bg_flags_test(rd->fs, grp, EXT2_BG_INODE_UNINIT))
|
||||
it_start = ext2fs_inode_table_loc(rd->fs, grp);
|
||||
if (rd->new_inode_blocks_per_group < rd->fs->inode_blocks_per_group)
|
||||
{
|
||||
it_start = ext2fs_inode_table_loc(rd->fs, grp);
|
||||
if (rd->new_inode_blocks_per_group < rd->fs->inode_blocks_per_group)
|
||||
{
|
||||
ext2fs_unmark_block_bitmap_range2(rd->fs->block_map, it_start, rd->fs->inode_blocks_per_group-rd->new_inode_blocks_per_group);
|
||||
}
|
||||
else
|
||||
{
|
||||
ext2fs_mark_block_bitmap_range2(rd->fs->block_map, it_start, rd->new_inode_blocks_per_group-rd->fs->inode_blocks_per_group);
|
||||
}
|
||||
// Update free block/inode counts
|
||||
ext2fs_bg_free_blocks_count_set(rd->fs, grp, ext2fs_bg_free_blocks_count(rd->fs, grp) +
|
||||
rd->new_inode_blocks_per_group - rd->fs->inode_blocks_per_group);
|
||||
ext2fs_bg_free_inodes_count_set(rd->fs, grp, ext2fs_bg_free_inodes_count(rd->fs, grp) +
|
||||
rd->new_inodes_per_group - EXT2_INODES_PER_GROUP(rd->fs->super));
|
||||
ext2fs_bg_itable_unused_set(rd->fs, grp, 0); // Is it correct?..
|
||||
ext2fs_unmark_block_bitmap_range2(rd->fs->block_map, it_start,
|
||||
rd->fs->inode_blocks_per_group-rd->new_inode_blocks_per_group);
|
||||
}
|
||||
else
|
||||
{
|
||||
ext2fs_mark_block_bitmap_range2(rd->fs->block_map, it_start,
|
||||
rd->new_inode_blocks_per_group-rd->fs->inode_blocks_per_group);
|
||||
}
|
||||
ext2fs_bg_free_blocks_count_set(rd->fs, grp, ext2fs_bg_free_blocks_count(rd->fs, grp) -
|
||||
rd->new_inode_blocks_per_group + rd->fs->inode_blocks_per_group);
|
||||
ext2fs_bg_free_inodes_count_set(rd->fs, grp, ext2fs_bg_free_inodes_count(rd->fs, grp) +
|
||||
rd->new_inodes_per_group - EXT2_INODES_PER_GROUP(rd->fs->super));
|
||||
unus = ext2fs_bg_itable_unused(rd->fs, grp);
|
||||
unus = unus < i_per_g_diff ? 0 : unus - i_per_g_diff;
|
||||
ext2fs_bg_itable_unused_set(rd->fs, grp, unus);
|
||||
ext2fs_group_desc_csum_set(rd->fs, grp);
|
||||
}
|
||||
}
|
||||
}
|
||||
ext2fs_free_blocks_count_add(rd->fs->super, rd->fs->group_desc_count * (rd->new_inode_blocks_per_group - rd->fs->inode_blocks_per_group));
|
||||
ext2fs_mark_bb_dirty(rd->fs);
|
||||
retval = rd->fs->write_bitmaps(rd->fs);
|
||||
if (retval)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
rd->fs->write_bitmaps = NULL;
|
||||
ext2fs_free_blocks_count_add(rd->fs->super, rd->fs->group_desc_count * (rd->fs->inode_blocks_per_group - rd->new_inode_blocks_per_group));
|
||||
rd->fs->super->s_free_inodes_count += rd->fs->group_desc_count * (rd->new_inodes_per_group - EXT2_INODES_PER_GROUP(rd->fs->super));
|
||||
rd->fs->super->s_inodes_per_group = rd->new_inodes_per_group;
|
||||
rd->fs->super->s_inodes_count = rd->fs->group_desc_count * rd->new_inodes_per_group;
|
||||
ext2fs_mark_super_dirty(rd->fs);
|
||||
out:
|
||||
if (buf)
|
||||
{
|
||||
|
@ -354,9 +375,10 @@ int do_realloc(realloc_data *rd)
|
|||
{
|
||||
int retval;
|
||||
rd->new_inodes_per_group = rd->new_inode_count / rd->fs->group_desc_count;
|
||||
rd->new_inodes_per_group &= ~7;
|
||||
if (rd->new_inodes_per_group < 16)
|
||||
{
|
||||
printf("Too small number of inodes requested, min inodes per group = 16\n");
|
||||
printf("Too small number of inodes requested (%u), min inodes per group = 16\n", rd->new_inodes_per_group);
|
||||
return ENOENT;
|
||||
}
|
||||
rd->new_inode_blocks_per_group =
|
||||
|
|
Loading…
Reference in New Issue