linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Theodore Ts'o" <tytso@mit.edu>
To: Ext4 Developers List <linux-ext4@vger.kernel.org>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Subject: [PATCH 3/3] resize2fs: optimize resize2fs_calculate_summary_stats()
Date: Tue, 14 Sep 2021 15:11:04 -0400	[thread overview]
Message-ID: <20210914191104.2283033-3-tytso@mit.edu> (raw)
In-Reply-To: <20210914191104.2283033-1-tytso@mit.edu>

Speed up an off-line resize of a 10GB file system to 64TB located on
tmpfs from 90 seconds to 16 seconds by extracting block group bitmaps
using a population count function to count the blocks in use instead
checking each bit in the block bitmap.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
 resize/resize2fs.c | 74 ++++++++++++++--------------------------------
 1 file changed, 23 insertions(+), 51 deletions(-)

diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 5ed0c9ee..f7ffaac5 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -2844,67 +2844,39 @@ errout:
  */
 static errcode_t resize2fs_calculate_summary_stats(ext2_filsys fs)
 {
-	blk64_t		blk;
+	errcode_t	retval;
+	blk64_t		blk = fs->super->s_first_data_block;
 	ext2_ino_t	ino;
-	unsigned int	group = 0;
-	unsigned int	count = 0;
+	unsigned int	n, c, group, count;
 	blk64_t		total_blocks_free = 0;
 	int		total_inodes_free = 0;
 	int		group_free = 0;
 	int		uninit = 0;
-	blk64_t		super_blk, old_desc_blk, new_desc_blk;
-	int		old_desc_blocks;
+	char		*bitmap_buf;
 
 	/*
 	 * First calculate the block statistics
 	 */
-	uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT);
-	ext2fs_super_and_bgd_loc2(fs, group, &super_blk, &old_desc_blk,
-				  &new_desc_blk, 0);
-	if (ext2fs_has_feature_meta_bg(fs->super))
-		old_desc_blocks = fs->super->s_first_meta_bg;
-	else
-		old_desc_blocks = fs->desc_blocks +
-			fs->super->s_reserved_gdt_blocks;
-	for (blk = B2C(fs->super->s_first_data_block);
-	     blk < ext2fs_blocks_count(fs->super);
-	     blk += EXT2FS_CLUSTER_RATIO(fs)) {
-		if ((uninit &&
-		     !(EQ_CLSTR(blk, super_blk) ||
-		       ((old_desc_blk && old_desc_blocks &&
-			 GE_CLSTR(blk, old_desc_blk) &&
-			 LT_CLSTR(blk, old_desc_blk + old_desc_blocks))) ||
-		       ((new_desc_blk && EQ_CLSTR(blk, new_desc_blk))) ||
-		       EQ_CLSTR(blk, ext2fs_block_bitmap_loc(fs, group)) ||
-		       EQ_CLSTR(blk, ext2fs_inode_bitmap_loc(fs, group)) ||
-		       ((GE_CLSTR(blk, ext2fs_inode_table_loc(fs, group)) &&
-			 LT_CLSTR(blk, ext2fs_inode_table_loc(fs, group)
-				  + fs->inode_blocks_per_group))))) ||
-		    (!ext2fs_fast_test_block_bitmap2(fs->block_map, blk))) {
-			group_free++;
-			total_blocks_free++;
-		}
-		count++;
-		if ((count == fs->super->s_clusters_per_group) ||
-		    EQ_CLSTR(blk, ext2fs_blocks_count(fs->super)-1)) {
-			ext2fs_bg_free_blocks_count_set(fs, group, group_free);
-			ext2fs_group_desc_csum_set(fs, group);
-			group++;
-			if (group >= fs->group_desc_count)
-				break;
-			count = 0;
-			group_free = 0;
-			uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT);
-			ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
-						  &old_desc_blk,
-						  &new_desc_blk, 0);
-			if (ext2fs_has_feature_meta_bg(fs->super))
-				old_desc_blocks = fs->super->s_first_meta_bg;
-			else
-				old_desc_blocks = fs->desc_blocks +
-					fs->super->s_reserved_gdt_blocks;
+	bitmap_buf = malloc(fs->blocksize);
+	if (!bitmap_buf)
+		return ENOMEM;
+	for (group = 0; group < fs->group_desc_count;
+	     group++) {
+		retval = ext2fs_get_block_bitmap_range2(fs->block_map,
+			C2B(blk), fs->super->s_clusters_per_group, bitmap_buf);
+		if (retval) {
+			free(bitmap_buf);
+			return retval;
 		}
-	}
+		n = ext2fs_bitcount(bitmap_buf,
+				    fs->super->s_clusters_per_group / 8);
+		group_free = fs->super->s_clusters_per_group - n;
+		total_blocks_free += group_free;
+		ext2fs_bg_free_blocks_count_set(fs, group, group_free);
+		ext2fs_group_desc_csum_set(fs, group);
+		blk += EXT2FS_NUM_B2C(fs, fs->super->s_clusters_per_group);
+	}
+	free(bitmap_buf);
 	total_blocks_free = C2B(total_blocks_free);
 	ext2fs_free_blocks_count_set(fs->super, total_blocks_free);
 
-- 
2.31.0


  parent reply	other threads:[~2021-09-14 19:11 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-14 19:11 [PATCH 1/3] resize2fs: attempt to keep the # of inodes valid by removing the last bg Theodore Ts'o
2021-09-14 19:11 ` [PATCH 2/3] resize2fs: adjust new size of the file system to allow a successful resize Theodore Ts'o
2021-09-16 17:59   ` Leah Rumancik
2021-09-14 19:11 ` Theodore Ts'o [this message]
2021-09-14 20:09   ` [PATCH 3/3] resize2fs: optimize resize2fs_calculate_summary_stats() Theodore Ts'o
2021-09-16 17:57 ` [PATCH 1/3] resize2fs: attempt to keep the # of inodes valid by removing the last bg Leah Rumancik

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=20210914191104.2283033-3-tytso@mit.edu \
    --to=tytso@mit.edu \
    --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).