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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
ext2fs_mark_ib_dirty(rd->fs);
|
||||||
// Remember mapping
|
// Remember mapping
|
||||||
realloc_add_inode_map(rd, ino, new_ino);
|
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)
|
int change_super_and_bgd(realloc_data *rd)
|
||||||
{
|
{
|
||||||
blk64_t it_start, blk;
|
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;
|
int flexbg_size = 0, i, retval = 0;
|
||||||
void *buf = NULL;
|
void *buf = NULL;
|
||||||
ext2fs_flush(rd->fs);
|
ext2fs_flush(rd->fs);
|
||||||
|
@ -255,14 +258,16 @@ int change_super_and_bgd(realloc_data *rd)
|
||||||
{
|
{
|
||||||
goto out;
|
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++)
|
for (n_flex = 0; n_flex < rd->fs->group_desc_count/flexbg_size; n_flex++)
|
||||||
{
|
{
|
||||||
last_grp = (n_flex+1)*flexbg_size;
|
n_grp = flexbg_size;
|
||||||
if (last_grp > rd->fs->group_desc_count)
|
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))
|
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);
|
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);
|
retval = io_channel_write_blk64(rd->fs->io, it_start, blk, buf);
|
||||||
if (retval)
|
if (retval)
|
||||||
{
|
{
|
||||||
// The FS is badly corrupted now :-(
|
// 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;
|
goto out;
|
||||||
}
|
}
|
||||||
// Mark/unmark extra inode table blocks
|
// Mark/unmark extra inode table blocks
|
||||||
if (rd->new_inode_blocks_per_group < rd->fs->inode_blocks_per_group)
|
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
|
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
|
if (!ext2fs_bg_flags_test(rd->fs, n_flex*flexbg_size, EXT2_BG_INODE_UNINIT))
|
||||||
for (grp = n_flex*flexbg_size, i = 0; grp < last_grp; grp++, i++)
|
|
||||||
{
|
{
|
||||||
if (!ext2fs_bg_flags_test(rd->fs, grp, EXT2_BG_INODE_UNINIT))
|
ext2fs_bg_free_blocks_count_set(rd->fs, n_flex*flexbg_size,
|
||||||
{
|
ext2fs_bg_free_blocks_count(rd->fs, n_flex*flexbg_size) -
|
||||||
blk = it_start + rd->new_inode_blocks_per_group*i;
|
(rd->new_inode_blocks_per_group - rd->fs->inode_blocks_per_group)*flexbg_size);
|
||||||
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) +
|
// Change inode table locations and free inode counts
|
||||||
rd->new_inode_blocks_per_group - rd->fs->inode_blocks_per_group);
|
for (grp = n_flex*flexbg_size, i = 0; i < n_grp; grp++, i++)
|
||||||
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));
|
blk = it_start + rd->new_inode_blocks_per_group*i;
|
||||||
ext2fs_bg_itable_unused_set(rd->fs, grp, 0); // Is it correct?..
|
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)
|
// Mark/unmark extra inode table blocks (without flex_bg)
|
||||||
for (grp = 0; grp < rd->fs->group_desc_count; grp++)
|
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);
|
ext2fs_unmark_block_bitmap_range2(rd->fs->block_map, it_start,
|
||||||
if (rd->new_inode_blocks_per_group < rd->fs->inode_blocks_per_group)
|
rd->fs->inode_blocks_per_group-rd->new_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?..
|
|
||||||
}
|
}
|
||||||
|
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_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_per_group = rd->new_inodes_per_group;
|
||||||
rd->fs->super->s_inodes_count = rd->fs->group_desc_count * 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:
|
out:
|
||||||
if (buf)
|
if (buf)
|
||||||
{
|
{
|
||||||
|
@ -354,9 +375,10 @@ int do_realloc(realloc_data *rd)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
rd->new_inodes_per_group = rd->new_inode_count / rd->fs->group_desc_count;
|
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)
|
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;
|
return ENOENT;
|
||||||
}
|
}
|
||||||
rd->new_inode_blocks_per_group =
|
rd->new_inode_blocks_per_group =
|
||||||
|
|
Loading…
Reference in New Issue