linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Theodore Y. Ts'o" <tytso@mit.edu>
To: Artem Blagodarenko <artem.blagodarenko@gmail.com>
Cc: linux-ext4@vger.kernel.org, adilger.kernel@dilger.ca
Subject: Re: [PATCH] ext2fs: add ext2fs_read_sb that returns superblock
Date: Tue, 22 Oct 2019 18:56:48 -0400	[thread overview]
Message-ID: <20191022225648.GD13621@mit.edu> (raw)
In-Reply-To: <20190905110110.32627-1-c17828@cray.com>

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@cray.com>
> 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@mit.edu>
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@mit.edu>
    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;

      parent reply	other threads:[~2019-10-22 22:56 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-05 11:01 [PATCH] ext2fs: add ext2fs_read_sb that returns superblock Artem Blagodarenko
2019-09-17 18:22 ` Благодаренко Артём
2019-09-17 20:20   ` Andreas Dilger
2019-10-03 15:47 ` Благодаренко Артём
2019-10-03 15:55   ` Andreas Dilger
2019-10-03 15:58     ` Благодаренко Артём
2019-10-03 16:01 ` Darrick J. Wong
2019-10-03 16:18   ` Благодаренко Артём
2019-10-22 22:56 ` Theodore Y. Ts'o [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191022225648.GD13621@mit.edu \
    --to=tytso@mit.edu \
    --cc=adilger.kernel@dilger.ca \
    --cc=artem.blagodarenko@gmail.com \
    --cc=linux-ext4@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).