Re: [ext2resize] Patches for ext2resize?
Status: Inactive
Brought to you by:
adilger
From: Takashi S. <sh...@tn...> - 2006-06-16 09:53:46
|
Hi, I had gone out for three days so the reply to you was delayed. > Can you explain why the rest of the patch is needed? This is the > patch updated to the current CVS version. OK, I described comments below. > Index: src/ext2.h > =================================================================== > RCS file: /cvsroot/ext2resize/ext2resize/src/ext2.h,v > retrieving revision 1.28 > diff -u -3 -p -u -r1.28 ext2.h > --- src/ext2.h 10 Jun 2006 07:45:55 -0000 1.28 > +++ src/ext2.h 10 Jun 2006 14:27:56 -0000 > @@ -264,7 +264,7 @@ static __inline__ int ext2_is_data_block > group = blk / fs->sb.s_blocks_per_group; > blk %= fs->sb.s_blocks_per_group; > > - if (ext2_bg_has_super(fs, group) && blk <= fs->gdblocks) > + if (ext2_bg_has_super(fs, group) && blk <= fs->gdblocks + fs->resgdblocks) > return 0; If blk belongs to group descriptor blocks(GDB) or reserved GDB, ext2_is_data_block should return 0. Without this fix, it would return 1 though blk belongs to reserved GDB. > if (block == fs->gd[group].bg_block_bitmap || > Index: src/ext2_block_relocator.c > =================================================================== > RCS file: /cvsroot/ext2resize/ext2resize/src/ext2_block_relocator.c,v > retrieving revision 1.22 > diff -u -3 -p -u -r1.22 ext2_block_relocator.c > --- src/ext2_block_relocator.c 10 Jun 2006 07:45:55 -0000 1.22 > +++ src/ext2_block_relocator.c 10 Jun 2006 14:27:56 -0000 > @@ -497,6 +497,10 @@ static int ext2_block_relocator_grab_blo > int raid_bb, raid_ib; > int itend = state->new_alloc_offset; > > + if (!ext2_bg_has_super(fs, group)) > + itend = fs->gd[group].bg_inode_table > + +fs->inodeblocks - start; > + state->new_alloc_offset is set to the offset of the first data block in the block group which has a super block. So, if the target group doesn't have a super block, it should be re-calculated. > bpg = fs->sb.s_blocks_per_group; > if (start + bpg > fs->newblocks) > bpg = fs->newblocks - start; > Index: src/ext2_meta.c > =================================================================== > RCS file: /cvsroot/ext2resize/ext2resize/src/ext2_meta.c,v > retrieving revision 1.14 > diff -u -3 -p -u -r1.14 ext2_meta.c > --- src/ext2_meta.c 17 Feb 2006 12:04:09 -0000 1.14 > +++ src/ext2_meta.c 10 Jun 2006 14:27:56 -0000 > @@ -192,7 +192,8 @@ int ext2_metadata_push(struct ext2_fs *f > group + 1, fs->numgroups); > } > > - fs->itoffset = new_itoffset; > + fs->itoffset = fs->newgdblocks + 3; > + fs->itoffset should be set to the offset of an inode table in a group which has a super block. Without this fix, fs->itoffset is possible to be set to the offset in a group which doesn't have a super block and following procedure runs incorrectly. > if (fs->flags & FL_VERBOSE) > printf("\n"); > Index: src/ext2_resize.c > =================================================================== > RCS file: /cvsroot/ext2resize/ext2resize/src/ext2_resize.c,v > retrieving revision 1.19 > diff -u -3 -p -u -r1.19 ext2_resize.c > --- src/ext2_resize.c 10 Jun 2006 06:45:22 -0000 1.19 > +++ src/ext2_resize.c 10 Jun 2006 14:27:56 -0000 > @@ -157,7 +157,7 @@ static int ext2_add_group(struct ext2_fs > return 1; > } > > -static int ext2_del_group(struct ext2_fs *fs) > +static int ext2_del_group(struct ext2_fs *fs, int old_gdblocks) > { > blk_t admin; > int group = fs->numgroups - 1; > @@ -170,7 +170,7 @@ static int ext2_del_group(struct ext2_fs > > has_sb = ext2_bg_has_super(fs, group); > > - admin = fs->inodeblocks + (has_sb ? fs->gdblocks + 3 : 2); > + admin = fs->inodeblocks + (has_sb ? old_gdblocks + 3 : 2); > > bpg = fs->sb.s_blocks_count - fs->sb.s_first_data_block - > group * fs->sb.s_blocks_per_group; > @@ -407,6 +407,7 @@ static int ext2_grow_fs(struct ext2_fs * > > static int ext2_shrink_fs(struct ext2_fs *fs) > { > + int old_gdblocks; > if (fs->flags & FL_DEBUG) > printf("%s\n", __FUNCTION__); > > @@ -432,8 +433,7 @@ static int ext2_shrink_fs(struct ext2_fs > if (!ext2_inode_relocate(fs)) > return 0; > > - if (!ext2_block_relocate(fs)) > - return 0; > + old_gdblocks = fs->gdblocks; Until the size of a filesystem becomes the expected size, groups will be removed at the following loop. 1. ext2_del_group() decreases the number of GDB(fs->gdblocks) after deleting all groups on one GBD. 2. When ext2_del_group() is called at the next iteration, it calculates the number of meta-data blocks in a group by using fs->gdblocks, so the result of the calculation is less than the actual meta-data blocks and following procedure runs incorrectly. So we fixed this to save the original number of GDB(fs->gdblocks) before deleting groups and passed the saved number to ext2_del_group() as an argument. > while (fs->sb.s_blocks_count > fs->newblocks) { > blk_t sizelast = (fs->sb.s_blocks_count - > @@ -445,7 +445,7 @@ static int ext2_shrink_fs(struct ext2_fs > fs->sb.s_blocks_count)) > return 0; > } else { > - if (!ext2_del_group(fs)) > + if (!ext2_del_group(fs, old_gdblocks)) > return 0; > } > } Cheers, sho |