On Thu, Sep 05, 2019 at 02:01:10PM +0300, Artem Blagodarenko wrote: > tune2fs is used to make e2label duties. ext2fs_open2() reads group > descriptors which are not used during disk label obtaining, but takes > a lot of time on large partitions. > > This patch adds ext2fs_read_sb(), there only initialized superblock > is returned This saves time dramatically. > > Signed-off-by: Artem Blagodarenko <c17828@xxxxxxxx> > Cray-bug-id: LUS-5777 Sorry for the delay in getting back to you on this. I've been thinking about this, and I've found a better to support this functionality by reusing the pre-existing EXT2_FLAG_SUPER_ONLY flag. Unlike the previous version of this patch which defined EXT2_FLAG_JOURNAL_ONLY (which was always a bit strangely named), this avoids reading *any* block group descriptors when the file system is open. Instead, we read the block group descriptors on demand when ext2fs_group_desc() is called. So this speeds up "dumpe2fs -h" as well "e2label", and we don't have to read any block group descriptors at all. Oh, and it even works when setting a label using e2label. What do you think? - Ted commit 639e310d64dd0a2c1302eba8c3f5d0def7eacbf2 Author: Theodore Ts'o <tytso@xxxxxxx> Date: Tue Oct 22 18:42:25 2019 -0400 Teach ext2fs_open2() to honor the EXT2_FLAG_SUPER_ONLY flag Opening the file system with EXT2_FLAG_SUPER_ONLY will leave fs->group_desc to be NULL and modify "dumpe2fs -h" and tune2fs when it is emulating e2label to use this flag. This speeds up "dumpe2fs -h" and "e2label" when operating on very large file systems. To allow other libext2fs functions to work without too many surprises, ext2fs_group_desc() will read in the block group descriptors on demand. This allows "dumpe2fs -h" to be able to read the journal inode, for example. Signed-off-by: Theodore Ts'o <tytso@xxxxxxx> Cray-bug-id: LUS-5777 diff --git a/lib/ext2fs/blknum.c b/lib/ext2fs/blknum.c index 9ee5c66e..fdd51df6 100644 --- a/lib/ext2fs/blknum.c +++ b/lib/ext2fs/blknum.c @@ -185,9 +185,45 @@ struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs, struct opaque_ext2_group_desc *gdp, dgrp_t group) { - int desc_size = EXT2_DESC_SIZE(fs->super) & ~7; + struct ext2_group_desc *ret_gdp; + errcode_t retval; + static char *buf = 0; + static int bufsize = 0; + blk64_t blk; + int desc_size = EXT2_DESC_SIZE(fs->super) & ~7; + int desc_per_blk = EXT2_DESC_PER_BLOCK(fs->super); + + if (group > fs->group_desc_count) + return NULL; + if (gdp) + return (struct ext2_group_desc *)((char *)gdp + + group * desc_size); + + /* + * If fs->group_desc wasn't read in when the file system was + * opened, then read it on demand here. + */ + if (bufsize < fs->blocksize) + ext2fs_free_mem(&buf); + if (!buf) { + retval = ext2fs_get_mem(fs->blocksize, &buf); + if (retval) + return NULL; + bufsize = fs->blocksize; + } - return (struct ext2_group_desc *)((char *)gdp + group * desc_size); + blk = ext2fs_descriptor_block_loc2(fs, fs->super->s_first_data_block, + group / desc_per_blk); + retval = io_channel_read_blk(fs->io, blk, 1, buf); + if (retval) + return NULL; + + ret_gdp = (struct ext2_group_desc *) + (buf + ((group % desc_per_blk) * desc_size)); +#ifdef WORDS_BIGENDIAN + ext2fs_swap_group_desc2(fs, ret_gdp); +#endif + return ret_gdp; } /* Do the same but as an ext4 group desc for internal use here */ diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c index 51b54a44..ec2d6cb4 100644 --- a/lib/ext2fs/openfs.c +++ b/lib/ext2fs/openfs.c @@ -393,6 +393,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, } fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count, EXT2_DESC_PER_BLOCK(fs->super)); + if (flags & EXT2_FLAG_SUPER_ONLY) + goto skip_read_bg; retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize, &fs->group_desc); if (retval) @@ -479,7 +481,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, if (fs->flags & EXT2_FLAG_RW) ext2fs_mark_super_dirty(fs); } - +skip_read_bg: if (ext2fs_has_feature_mmp(fs->super) && !(flags & EXT2_FLAG_SKIP_MMP) && (flags & (EXT2_FLAG_RW | EXT2_FLAG_EXCLUSIVE))) { diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index 384ce925..18148e2a 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -666,6 +666,8 @@ int main (int argc, char ** argv) flags |= EXT2_FLAG_FORCE; if (image_dump) flags |= EXT2_FLAG_IMAGE_FILE; + if (header_only) + flags |= EXT2_FLAG_SUPER_ONLY; try_open_again: if (use_superblock && !use_blocksize) { for (use_blocksize = EXT2_MIN_BLOCK_SIZE; diff --git a/misc/tune2fs.c b/misc/tune2fs.c index 39fce4a9..77a45875 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -1698,7 +1698,7 @@ static void parse_e2label_options(int argc, char ** argv) argv[1]); exit(1); } - open_flag = EXT2_FLAG_JOURNAL_DEV_OK; + open_flag = EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SUPER_ONLY; if (argc == 3) { open_flag |= EXT2_FLAG_RW; L_flag = 1;