From: Konstantin Khlebnikov Subject: Re: [PATCH RFC v1 2/4] resize2fs: add option -I for reserving more special inodes Date: Fri, 13 Mar 2015 13:52:33 +0300 Message-ID: <5502C171.2080806@yandex-team.ru> References: <20150312161341.17173.96760.stgit@buzz> <20150312162013.17173.71244.stgit@buzz> <20150312192623.GE11031@birch.djwong.org> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Cc: Andreas Dilger , linux-ext4@vger.kernel.org, Theodore Ts'o , Li Xi To: "Darrick J. Wong" Return-path: Received: from forward-corp1f.mail.yandex.net ([95.108.130.40]:56681 "EHLO forward-corp1f.mail.yandex.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750874AbbCMKwi (ORCPT ); Fri, 13 Mar 2015 06:52:38 -0400 In-Reply-To: <20150312192623.GE11031@birch.djwong.org> Sender: linux-ext4-owner@vger.kernel.org List-ID: On 12.03.2015 22:26, Darrick J. Wong wrote: > On Thu, Mar 12, 2015 at 07:20:13PM +0300, Konstantin Khlebnikov wrote: >> Resize2fs relocates last inodes when it shinks filesystem. >> This patch reuses this code for relocating first inodes, >> it adds option '-I' for changing first normal inode. >> >> Signed-off-by: Konstantin Khlebnikov >> --- >> resize/main.c | 38 ++++++++++++++++++++++++++++++++---- >> resize/resize2fs.8.in | 8 ++++++++ >> resize/resize2fs.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++-- >> resize/resize2fs.h | 3 +++ >> 4 files changed, 95 insertions(+), 6 deletions(-) >> >> diff --git a/resize/main.c b/resize/main.c >> index 16f48d438cb0..eae7146f41ab 100644 >> --- a/resize/main.c >> +++ b/resize/main.c -cut >> @@ -507,6 +513,28 @@ int main (int argc, char ** argv) >> "feature.\n")); >> exit(1); >> } >> + } else if (flags & RESIZE_SPECIAL_INODES) { >> + if (rfs->first_ino > fs->super->s_inodes_count) { > > An FS with rfs->first_ino == fs->super->s_inodes_count isn't going to be > very useful... presumably you'd want at least one regular inode, right? In this case there will be exactly one regular inode: s_inodes_count is index of last inode on the filesystem. > >> + fprintf(stderr, _("First inode too big\n")); > > "Cannot reserve more than ($s_inodes_count - 1) inodes"? So, you're suggest to rephrase option as "reserve special inodes" instead of "set first normal inode"? > >> + exit(1); >> + } >> + if (rfs->first_ino < EXT2_FIRST_INO(fs->super)) { >> + fprintf(stderr, _("The filesystem has %d special inodes." >> + "Reducing isn't supported.\n\n"), >> + EXT2_FIRST_INO(fs->super)); >> + exit(1); >> + } >> + if (rfs->first_ino == EXT2_FIRST_INO(fs->super)) { >> + fprintf(stderr, _("The filesystem already has %d " >> + "special inodes. Nothing to do!\n\n"), >> + EXT2_FIRST_INO(fs->super)); >> + exit(0); >> + } >> + if (mount_flags & EXT2_MF_MOUNTED) { >> + fprintf(stderr, _("Cannot change count of special " >> + "inodes while the filesystem is mounted.\n")); >> + exit(1); >> + } >> } else if (new_size == ext2fs_blocks_count(fs->super)) { >> fprintf(stderr, _("The filesystem is already %llu (%dk) " >> "blocks long. Nothing to do!\n\n"), new_size, >> @@ -532,6 +560,8 @@ int main (int argc, char ** argv) >> printf(_("Converting the filesystem to 64-bit.\n")); >> else if (flags & RESIZE_DISABLE_64BIT) >> printf(_("Converting the filesystem to 32-bit.\n")); >> + else if (flags & RESIZE_SPECIAL_INODES) >> + printf(_("Reserving special inodes.\n")); >> else >> printf(_("Resizing the filesystem on " >> "%s to %llu (%dk) blocks.\n"), >> diff --git a/resize/resize2fs.8.in b/resize/resize2fs.8.in >> index 0129bfcafa3b..f22563fe07e1 100644 >> --- a/resize/resize2fs.8.in >> +++ b/resize/resize2fs.8.in >> @@ -18,6 +18,10 @@ resize2fs \- ext2/ext3/ext4 file system resizer >> .B \-S >> .I RAID-stride >> ] >> +[ >> +.B \-I >> +.I first-inode >> +] >> .I device >> [ >> .I size >> @@ -101,6 +105,10 @@ to resize the filesystem concurrent with changing the 64bit status. >> Turns on the 64bit feature, resizes the group descriptors as necessary, and >> moves other metadata out of the way. >> .TP >> +.B \-I \fI >> +This changes first normal inode and relocates inuse inodes into vacant slots. >> +Inodes below that are reserved for internal use. Reducing isn't supported. > > "Increases the number of reserved inodes, moving any in-use inodes into vacant > slots."? > > --D > >> +.TP >> .B \-d \fIdebug-flags >> Turns on various resize2fs debugging features, if they have been compiled >> into the binary. >> diff --git a/resize/resize2fs.c b/resize/resize2fs.c >> index dead364bf4bf..2fb653b76dd8 100644 >> --- a/resize/resize2fs.c >> +++ b/resize/resize2fs.c >> @@ -48,6 +48,7 @@ static errcode_t block_mover(ext2_resize_t rfs); >> static errcode_t inode_scan_and_fix(ext2_resize_t rfs); >> static errcode_t inode_ref_fix(ext2_resize_t rfs); >> static errcode_t move_itables(ext2_resize_t rfs); >> +static errcode_t zero_new_special_inodes(ext2_resize_t rfs); >> static errcode_t fix_resize_inode(ext2_filsys fs); >> static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs); >> static errcode_t fix_sb_journal_backup(ext2_filsys fs); >> @@ -112,6 +113,11 @@ errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs) >> if (retval) >> goto errout; >> >> + if (flags & RESIZE_SPECIAL_INODES) { >> + ext2fs_update_dynamic_rev(rfs->new_fs); >> + EXT2_SB(rfs->new_fs->super)->s_first_ino = rfs->first_ino; >> + } >> + >> init_resource_track(&rtrack, "resize_group_descriptors", fs->io); >> retval = resize_group_descriptors(rfs); >> if (retval) >> @@ -177,6 +183,12 @@ errcode_t resize_fs(ext2_filsys fs, ext2_resize_t rfs) >> goto errout; >> print_resource_track(rfs, &rtrack, fs->io); >> >> + init_resource_track(&rtrack, "zero_new_special_inodes", fs->io); >> + retval = zero_new_special_inodes(rfs); >> + if (retval) >> + goto errout; >> + print_resource_track(rfs, &rtrack, fs->io); >> + >> init_resource_track(&rtrack, "move_itables", fs->io); >> retval = move_itables(rfs); >> if (retval) >> @@ -1963,7 +1975,8 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs) >> >> if ((rfs->old_fs->group_desc_count <= >> rfs->new_fs->group_desc_count) && >> - !rfs->bmap) >> + !rfs->bmap && >> + !(rfs->flags & RESIZE_SPECIAL_INODES)) >> return 0; >> >> set_com_err_hook(quiet_com_err_proc); >> @@ -2018,7 +2031,11 @@ static errcode_t inode_scan_and_fix(ext2_resize_t rfs) >> goto errout; >> >> new_inode = ino; >> - if (ino <= start_to_move) >> + if (ino >= EXT2_FIRST_INO(rfs->old_fs->super) && >> + ino < EXT2_FIRST_INO(rfs->new_fs->super)) { >> + ext2fs_inode_alloc_stats2(rfs->new_fs, ino, -1, >> + pb.is_dir); >> + } else if (ino <= start_to_move) >> goto remap_blocks; /* Don't need to move inode. */ >> >> /* >> @@ -2552,6 +2569,37 @@ static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs, >> } >> >> /* >> + * Clear new special inodes >> + */ >> +static errcode_t zero_new_special_inodes(ext2_resize_t rfs) >> +{ >> + ext2_filsys fs = rfs->new_fs; >> + int inode_size; >> + struct ext2_inode *inode; >> + errcode_t retval; >> + ext2_ino_t ino; >> + >> + if (!(rfs->flags & RESIZE_SPECIAL_INODES)) >> + return 0; >> + >> + inode_size = EXT2_INODE_SIZE(fs->super); >> + retval = ext2fs_get_memzero(inode_size, &inode); >> + if (retval) >> + return retval; >> + >> + for (ino = EXT2_FIRST_INO(rfs->old_fs->super); >> + ino < EXT2_FIRST_INO(fs->super); ino++) { >> + /* All special inodes are marked as inuse */ >> + ext2fs_inode_alloc_stats2(fs, ino, +1, 0); >> + retval = ext2fs_write_inode_full(fs, ino, inode, inode_size); >> + if (retval) >> + break; >> + } >> + ext2fs_free_mem(&inode); >> + return retval; >> +} >> + >> +/* >> * Fix the resize inode >> */ >> static errcode_t fix_resize_inode(ext2_filsys fs) >> diff --git a/resize/resize2fs.h b/resize/resize2fs.h >> index c5377e2b06c3..84f83b09f237 100644 >> --- a/resize/resize2fs.h >> +++ b/resize/resize2fs.h >> @@ -85,6 +85,8 @@ typedef struct ext2_sim_progress *ext2_sim_progmeter; >> #define RESIZE_ENABLE_64BIT 0x0400 >> #define RESIZE_DISABLE_64BIT 0x0800 >> >> +#define RESIZE_SPECIAL_INODES 0x1000 >> + >> /* >> * This structure is used for keeping track of how much resources have >> * been used for a particular resize2fs pass. >> @@ -130,6 +132,7 @@ struct ext2_resize_struct { >> void *prog_data; >> >> blk64_t new_size; >> + ext2_ino_t first_ino; >> }; >> >> /* >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html -- Konstantin