linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
To: Theodore Ts'o <tytso@mit.edu>
Cc: linux-ext4@vger.kernel.org,
	Harshad Shirwadkar <harshadshirwadkar@gmail.com>,
	Wang Shilong <wshilong@ddn.com>,
	Andreas Dilger <adilger.kernel@dilger.ca>, Li Xi <lixi@ddn.com>,
	Ritesh Harjani <ritesh.list@gmail.com>
Subject: [RFCv1 44/72] e2fsck: move some fixes out of parallel pthreads
Date: Mon,  7 Nov 2022 17:51:32 +0530	[thread overview]
Message-ID: <0c454e13b21aadde5c5db1be3f76f2a87016a0bc.1667822611.git.ritesh.list@gmail.com> (raw)
In-Reply-To: <cover.1667822611.git.ritesh.list@gmail.com>

From: Wang Shilong <wshilong@ddn.com>

We could only use @found_map_block to find free blocks
after we have collectd all used blocks, so something like
handle_fs_bad_blocks(), ext2fs_create_resize_inode(),
e2fsck_pass1_dupblocks() really should be handled after
all threads has been finished.

Signed-off-by: Wang Shilong <wshilong@ddn.com>
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
 e2fsck/e2fsck.h                      |   4 +
 e2fsck/pass1.c                       | 296 ++++++++++++++++-----------
 e2fsck/util.c                        |  36 +++-
 tests/f_multithread/expect.1         |   2 +-
 tests/f_multithread_logfile/expect.1 |   2 +-
 tests/f_multithread_no/expect.1      |   2 +-
 6 files changed, 210 insertions(+), 132 deletions(-)

diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 5356e172..55f75042 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -487,6 +487,8 @@ struct e2fsck_struct {
 #ifdef HAVE_PTHREAD
 	/* serialize fix operation for multiple threads */
 	pthread_mutex_t		 fs_fix_mutex;
+	/* protect block_found_map, block_dup_map */
+	pthread_mutex_t		 fs_block_map_mutex;
 #endif
 	/* Fast commit replay state */
 	struct e2fsck_fc_replay_state fc_replay_state;
@@ -793,6 +795,8 @@ extern errcode_t e2fsck_allocate_subcluster_bitmap(ext2_filsys fs,
 unsigned long long get_memory_size(void);
 extern void e2fsck_pass1_fix_lock(e2fsck_t ctx);
 extern void e2fsck_pass1_fix_unlock(e2fsck_t ctx);
+extern void e2fsck_pass1_block_map_lock(e2fsck_t ctx);
+extern void e2fsck_pass1_block_map_unlock(e2fsck_t ctx);
 
 /* unix.c */
 extern void e2fsck_clear_progbar(e2fsck_t ctx);
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index c68e6957..f156d4e1 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -753,11 +753,15 @@ static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
 			if (i >= 4)
 				not_device++;
 
+			e2fsck_pass1_block_map_lock(ctx);
 			if (blk < ctx->fs->super->s_first_data_block ||
 			    blk >= ext2fs_blocks_count(ctx->fs->super) ||
 			    ext2fs_fast_test_block_bitmap2(ctx->block_found_map,
-							   blk))
+							   blk)) {
+				e2fsck_pass1_block_map_unlock(ctx);
 				return;	/* Invalid block, can't be dir */
+			}
+			e2fsck_pass1_block_map_unlock(ctx);
 		}
 		blk = inode->i_block[0];
 	}
@@ -891,19 +895,15 @@ static void reserve_block_for_root_repair(e2fsck_t ctx)
 	errcode_t	err;
 	ext2_filsys	fs = ctx->fs;
 
-	e2fsck_pass1_fix_lock(ctx);
 	ctx->root_repair_block = 0;
 	if (ext2fs_test_inode_bitmap2(ctx->inode_used_map, EXT2_ROOT_INO))
-		goto out;
+		return;
 
 	err = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
 	if (err)
-		goto out;
+		return;
 	ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
 	ctx->root_repair_block = blk;
-out:
-	e2fsck_pass1_fix_unlock(ctx);
-	return;
 }
 
 static void reserve_block_for_lnf_repair(e2fsck_t ctx)
@@ -914,18 +914,15 @@ static void reserve_block_for_lnf_repair(e2fsck_t ctx)
 	static const char name[] = "lost+found";
 	ext2_ino_t	ino;
 
-	e2fsck_pass1_fix_lock(ctx);
 	ctx->lnf_repair_block = 0;
 	if (!ext2fs_lookup(fs, EXT2_ROOT_INO, name, sizeof(name)-1, 0, &ino))
-		goto out;
+		return;
 
 	err = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
 	if (err)
-		goto out;
+		return;
 	ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
 	ctx->lnf_repair_block = blk;
-out:
-	e2fsck_pass1_fix_unlock(ctx);
 	return;
 }
 
@@ -1182,6 +1179,118 @@ static int e2fsck_should_abort(e2fsck_t ctx)
 	return 0;
 }
 
+/*
+ * We need call mark_table_blocks() before multiple
+ * thread start, since all known system blocks should be
+ * marked and checked later.
+ */
+static errcode_t e2fsck_pass1_prepare(e2fsck_t ctx)
+{
+	struct problem_context pctx;
+	ext2_filsys fs = ctx->fs;
+
+	clear_problem_context(&pctx);
+	if (!(ctx->options & E2F_OPT_PREEN))
+		fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
+
+	pctx.errcode = e2fsck_allocate_subcluster_bitmap(ctx->fs,
+			_("in-use block map"), EXT2FS_BMAP64_RBTREE,
+			"block_found_map", &ctx->block_found_map);
+	if (pctx.errcode) {
+		pctx.num = 1;
+		fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
+		ctx->flags |= E2F_FLAG_ABORT;
+		return pctx.errcode;
+	}
+	pctx.errcode = e2fsck_allocate_block_bitmap(ctx->fs,
+			_("metadata block map"), EXT2FS_BMAP64_RBTREE,
+			"block_metadata_map", &ctx->block_metadata_map);
+	if (pctx.errcode) {
+		pctx.num = 1;
+		fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
+		ctx->flags |= E2F_FLAG_ABORT;
+		return pctx.errcode;
+	}
+
+	mark_table_blocks(ctx);
+	pctx.errcode = ext2fs_convert_subcluster_bitmap(ctx->fs,
+						&ctx->block_found_map);
+	if (pctx.errcode) {
+		fix_problem(ctx, PR_1_CONVERT_SUBCLUSTER, &pctx);
+		ctx->flags |= E2F_FLAG_ABORT;
+		return pctx.errcode;
+	}
+
+	if (ext2fs_has_feature_mmp(fs->super) &&
+	    fs->super->s_mmp_block > fs->super->s_first_data_block &&
+	    fs->super->s_mmp_block < ext2fs_blocks_count(fs->super))
+		ext2fs_mark_block_bitmap2(ctx->block_found_map,
+					  fs->super->s_mmp_block);
+
+	return 0;
+}
+
+static void e2fsck_pass1_post(e2fsck_t ctx)
+{
+	struct problem_context pctx;
+	ext2_filsys fs = ctx->fs;
+	char *block_buf;
+
+	reserve_block_for_root_repair(ctx);
+	reserve_block_for_lnf_repair(ctx);
+
+	if (ctx->invalid_bitmaps)
+		handle_fs_bad_blocks(ctx);
+
+	if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
+		struct ext2_inode *inode;
+		int inode_size = EXT2_INODE_SIZE(fs->super);
+		inode = e2fsck_allocate_memory(ctx, inode_size,
+					       "scratch inode");
+
+		clear_problem_context(&pctx);
+		pctx.errcode = ext2fs_create_resize_inode(fs);
+		if (pctx.errcode) {
+			if (!fix_problem(ctx, PR_1_RESIZE_INODE_CREATE,
+					 &pctx)) {
+				ctx->flags |= E2F_FLAG_ABORT;
+				ext2fs_free_mem(&inode);
+				ext2fs_free_mem(&block_buf);
+				return;
+			}
+			pctx.errcode = 0;
+		}
+		if (!pctx.errcode) {
+			e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
+					  "recreate inode");
+			inode->i_mtime = ctx->now;
+			e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
+					   "recreate inode");
+		}
+		ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
+		ext2fs_free_mem(&inode);
+	}
+
+	if (ctx->flags & E2F_FLAG_RESTART) {
+		ext2fs_free_mem(&block_buf);
+		return;
+	}
+
+	if (ctx->block_dup_map) {
+		if (ctx->options & E2F_OPT_PREEN) {
+			clear_problem_context(&pctx);
+			fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
+		}
+		block_buf =
+			(char *)e2fsck_allocate_memory(ctx,
+					ctx->fs->blocksize * 3,
+					"block interate buffer");
+		e2fsck_pass1_dupblocks(ctx, block_buf);
+		ext2fs_free_mem(&block_buf);
+	}
+}
+
+
 void e2fsck_pass1_run(e2fsck_t ctx)
 {
 	int	i;
@@ -1220,9 +1329,6 @@ void e2fsck_pass1_run(e2fsck_t ctx)
 		ctx->readahead_kb = e2fsck_guess_readahead(ctx->fs);
 	pass1_readahead(ctx, &ra_group, &ino_threshold);
 
-	if (!(ctx->options & E2F_OPT_PREEN))
-		fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
-
 	if (ext2fs_has_feature_dir_index(fs->super) &&
 	    !(ctx->options & E2F_OPT_NO)) {
 		if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
@@ -1271,24 +1377,6 @@ void e2fsck_pass1_run(e2fsck_t ctx)
 		ctx->flags |= E2F_FLAG_ABORT;
 		return;
 	}
-	pctx.errcode = e2fsck_allocate_subcluster_bitmap(fs,
-			_("in-use block map"), EXT2FS_BMAP64_RBTREE,
-			"block_found_map", &ctx->block_found_map);
-	if (pctx.errcode) {
-		pctx.num = 1;
-		fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
-		ctx->flags |= E2F_FLAG_ABORT;
-		return;
-	}
-	pctx.errcode = e2fsck_allocate_block_bitmap(fs,
-			_("metadata block map"), EXT2FS_BMAP64_RBTREE,
-			"block_metadata_map", &ctx->block_metadata_map);
-	if (pctx.errcode) {
-		pctx.num = 1;
-		fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
-		ctx->flags |= E2F_FLAG_ABORT;
-		return;
-	}
 	if (casefold_fs) {
 		pctx.errcode =
 			e2fsck_allocate_inode_bitmap(fs,
@@ -1344,14 +1432,6 @@ void e2fsck_pass1_run(e2fsck_t ctx)
 		}
 	}
 
-	mark_table_blocks(ctx);
-	pctx.errcode = ext2fs_convert_subcluster_bitmap(fs,
-						&ctx->block_found_map);
-	if (pctx.errcode) {
-		fix_problem(ctx, PR_1_CONVERT_SUBCLUSTER, &pctx);
-		ctx->flags |= E2F_FLAG_ABORT;
-		goto endit;
-	}
 	block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
 						    "block interate buffer");
 	if (EXT2_INODE_SIZE(fs->super) == EXT2_GOOD_OLD_INODE_SIZE)
@@ -1385,12 +1465,6 @@ void e2fsck_pass1_run(e2fsck_t ctx)
 	     fs->super->s_mkfs_time < fs->super->s_inodes_count))
 		low_dtime_check = 0;
 
-	if (ext2fs_has_feature_mmp(fs->super) &&
-	    fs->super->s_mmp_block > fs->super->s_first_data_block &&
-	    fs->super->s_mmp_block < ext2fs_blocks_count(fs->super))
-		ext2fs_mark_block_bitmap2(ctx->block_found_map,
-					  fs->super->s_mmp_block);
-
 	/* Set up ctx->lost_and_found if possible */
 	(void) e2fsck_get_lost_and_found(ctx, 0);
 
@@ -1721,8 +1795,10 @@ void e2fsck_pass1_run(e2fsck_t ctx)
 				failed_csum = 0;
 			}
 
+			e2fsck_pass1_block_map_lock(ctx);
 			pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
 							  &pb.fs_meta_blocks);
+			e2fsck_pass1_block_map_unlock(ctx);
 			if (pctx.errcode) {
 				pctx.num = 4;
 				fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
@@ -2069,9 +2145,6 @@ void e2fsck_pass1_run(e2fsck_t ctx)
 	ext2fs_close_inode_scan(scan);
 	scan = NULL;
 
-	reserve_block_for_root_repair(ctx);
-	reserve_block_for_lnf_repair(ctx);
-
 	/*
 	 * If any extended attribute blocks' reference counts need to
 	 * be adjusted, either up (ctx->refcount_extra), or down
@@ -2099,11 +2172,6 @@ void e2fsck_pass1_run(e2fsck_t ctx)
 		ctx->ea_block_quota_inodes = 0;
 	}
 
-	if (ctx->invalid_bitmaps) {
-		e2fsck_pass1_fix_lock(ctx);
-		handle_fs_bad_blocks(ctx);
-		e2fsck_pass1_fix_unlock(ctx);
-	}
 
 	/* We don't need the block_ea_map any more */
 	if (ctx->block_ea_map) {
@@ -2114,29 +2182,6 @@ void e2fsck_pass1_run(e2fsck_t ctx)
 	/* We don't need the encryption policy => ID map any more */
 	destroy_encryption_policy_map(ctx);
 
-	if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
-		clear_problem_context(&pctx);
-		e2fsck_pass1_fix_lock(ctx);
-		pctx.errcode = ext2fs_create_resize_inode(fs);
-		e2fsck_pass1_fix_unlock(ctx);
-		if (pctx.errcode) {
-			if (!fix_problem(ctx, PR_1_RESIZE_INODE_CREATE,
-					 &pctx)) {
-				ctx->flags |= E2F_FLAG_ABORT;
-				goto endit;
-			}
-			pctx.errcode = 0;
-		}
-		if (!pctx.errcode) {
-			e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
-					  "recreate inode");
-			inode->i_mtime = ctx->now;
-			e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
-					   "recreate inode");
-		}
-		ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
-	}
-
 	if (ctx->flags & E2F_FLAG_RESTART) {
 		/*
 		 * Only the master copy of the superblock and block
@@ -2161,13 +2206,6 @@ void e2fsck_pass1_run(e2fsck_t ctx)
 		}
 	}
 
-	if (ctx->block_dup_map) {
-		if (ctx->options & E2F_OPT_PREEN) {
-			clear_problem_context(&pctx);
-			fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
-		}
-		e2fsck_pass1_dupblocks(ctx, block_buf);
-	}
 	ctx->flags |= E2F_FLAG_ALLOC_OK;
 endit:
 	e2fsck_use_inode_shortcuts(ctx, 0);
@@ -2288,10 +2326,10 @@ static errcode_t e2fsck_pass1_thread_prepare(e2fsck_t global_ctx, e2fsck_t *thre
 	assert(global_ctx->inode_reg_map == NULL);
 	assert(global_ctx->inodes_to_rebuild == NULL);
 
-	assert(global_ctx->block_found_map == NULL);
+	assert(global_ctx->block_found_map != NULL);
+	assert(global_ctx->block_metadata_map != NULL);
 	assert(global_ctx->block_dup_map == NULL);
 	assert(global_ctx->block_ea_map == NULL);
-	assert(global_ctx->block_metadata_map == NULL);
 	assert(global_ctx->fs->dblist == NULL);
 
 	retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &thread_context);
@@ -2455,10 +2493,8 @@ static int e2fsck_pass1_thread_join_one(e2fsck_t global_ctx, e2fsck_t thread_ctx
 	ext2fs_inode_bitmap inode_bb_map = global_ctx->inode_bb_map;
 	ext2fs_inode_bitmap inode_imagic_map = global_ctx->inode_imagic_map;
 	ext2fs_inode_bitmap inode_reg_map = global_ctx->inode_reg_map;
-	ext2fs_block_bitmap block_found_map = global_ctx->block_found_map;
 	ext2fs_block_bitmap block_dup_map = global_ctx->block_dup_map;
 	ext2fs_block_bitmap block_ea_map = global_ctx->block_ea_map;
-	ext2fs_block_bitmap block_metadata_map = global_ctx->block_metadata_map;
 	ext2fs_block_bitmap inodes_to_rebuild = global_ctx->inodes_to_rebuild;
 	ext2_icount_t inode_count = global_ctx->inode_count;
 	ext2_icount_t inode_link_info = global_ctx->inode_link_info;
@@ -2501,10 +2537,8 @@ static int e2fsck_pass1_thread_join_one(e2fsck_t global_ctx, e2fsck_t thread_ctx
 	global_ctx->inode_imagic_map = inode_imagic_map;
 	global_ctx->inodes_to_rebuild = inodes_to_rebuild;
 	global_ctx->inode_reg_map = inode_reg_map;
-	global_ctx->block_found_map = block_found_map;
-	global_ctx->block_dup_map = block_dup_map;
 	global_ctx->block_ea_map = block_ea_map;
-	global_ctx->block_metadata_map = block_metadata_map;
+	global_ctx->block_dup_map = block_dup_map;
 	global_ctx->dir_info = dir_info;
 	e2fsck_pass1_merge_dir_info(global_ctx, thread_ctx);
 	global_ctx->dx_dir_info = dx_dir_info;
@@ -2601,26 +2635,11 @@ static int e2fsck_pass1_thread_join_one(e2fsck_t global_ctx, e2fsck_t thread_ctx
 				&global_ctx->inodes_to_rebuild);
 	if (retval)
 		return retval;
-	retval = e2fsck_pass1_merge_bitmap(global_fs,
-				&thread_ctx->block_found_map,
-				&global_ctx->block_found_map);
-	if (retval)
-		return retval;
-	retval = e2fsck_pass1_merge_bitmap(global_fs,
-				&thread_ctx->block_dup_map,
-				&global_ctx->block_dup_map);
-	if (retval)
-		return retval;
 	retval = e2fsck_pass1_merge_bitmap(global_fs,
 				&thread_ctx->block_ea_map,
 				&global_ctx->block_ea_map);
 	if (retval)
 		return retval;
-	retval = e2fsck_pass1_merge_bitmap(global_fs,
-				&thread_ctx->block_metadata_map,
-				&global_ctx->block_metadata_map);
-	if (retval)
-		return retval;
 
 	return retval;
 }
@@ -2637,10 +2656,7 @@ static int e2fsck_pass1_thread_join(e2fsck_t global_ctx, e2fsck_t thread_ctx)
 	e2fsck_pass1_free_bitmap(&thread_ctx->inode_imagic_map);
 	e2fsck_pass1_free_bitmap(&thread_ctx->inode_reg_map);
 	e2fsck_pass1_free_bitmap(&thread_ctx->inodes_to_rebuild);
-	e2fsck_pass1_free_bitmap(&thread_ctx->block_found_map);
-	e2fsck_pass1_free_bitmap(&thread_ctx->block_dup_map);
 	e2fsck_pass1_free_bitmap(&thread_ctx->block_ea_map);
-	e2fsck_pass1_free_bitmap(&thread_ctx->block_metadata_map);
 	e2fsck_free_dir_info(thread_ctx);
 	ext2fs_free_icount(thread_ctx->inode_count);
 	ext2fs_free_icount(thread_ctx->inode_link_info);
@@ -2827,6 +2843,7 @@ static void e2fsck_pass1_multithread(e2fsck_t global_ctx)
 	errcode_t retval;
 
 	pthread_mutex_init(&global_ctx->fs_fix_mutex, NULL);
+	pthread_mutex_init(&global_ctx->fs_block_map_mutex, NULL);
 	retval = e2fsck_pass1_threads_start(&infos, num_threads, global_ctx);
 	if (retval) {
 		com_err(global_ctx->program_name, retval,
@@ -2881,13 +2898,19 @@ static int multiple_threads_supported(e2fsck_t ctx)
 
 void e2fsck_pass1(e2fsck_t ctx)
 {
+	errcode_t retval;
+
 	init_ext2_max_sizes();
+	retval = e2fsck_pass1_prepare(ctx);
+	if (retval)
+		return;
 #ifdef HAVE_PTHREAD
 	if (ctx->options & E2F_OPT_MULTITHREAD && multiple_threads_supported(ctx))
 		e2fsck_pass1_multithread(ctx);
 	else
 #endif
 		e2fsck_pass1_run(ctx);
+	e2fsck_pass1_post(ctx);
 }
 
 #undef FINISH_INODE_LOOP
@@ -3094,9 +3117,14 @@ static void alloc_imagic_map(e2fsck_t ctx)
  * WARNING: Assumes checks have already been done to make sure block
  * is valid.  This is true in both process_block and process_bad_block.
  */
-static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
+static _INLINE_ void mark_block_used_unlocked(e2fsck_t ctx, blk64_t block)
 {
-	struct		problem_context pctx;
+	struct problem_context pctx;
+	e2fsck_t global_ctx;
+
+	global_ctx = ctx->global_ctx;
+	if (!global_ctx)
+		global_ctx = ctx;
 
 	clear_problem_context(&pctx);
 
@@ -3105,11 +3133,15 @@ static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
 		    !(ctx->options & E2F_OPT_UNSHARE_BLOCKS)) {
 			return;
 		}
-		if (!ctx->block_dup_map) {
+		/**
+		 * this should be safe because this operation has
+		 * been serialized by mutex.
+		 */
+		if (!global_ctx->block_dup_map) {
 			pctx.errcode = e2fsck_allocate_block_bitmap(ctx->fs,
 					_("multiply claimed block map"),
 					EXT2FS_BMAP64_RBTREE, "block_dup_map",
-					&ctx->block_dup_map);
+					&global_ctx->block_dup_map);
 			if (pctx.errcode) {
 				pctx.num = 3;
 				fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
@@ -3119,12 +3151,20 @@ static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
 				return;
 			}
 		}
-		ext2fs_fast_mark_block_bitmap2(ctx->block_dup_map, block);
+		ext2fs_fast_mark_block_bitmap2(global_ctx->block_dup_map, block);
 	} else {
 		ext2fs_fast_mark_block_bitmap2(ctx->block_found_map, block);
 	}
 }
 
+static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
+{
+	e2fsck_pass1_block_map_lock(ctx);
+	mark_block_used_unlocked(ctx, block);
+	e2fsck_pass1_block_map_unlock(ctx);
+
+}
+
 /*
  * When cluster size is greater than one block, it is caller's responsibility
  * to make sure block parameter starts at a cluster boundary.
@@ -3132,14 +3172,16 @@ static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
 static _INLINE_ void mark_blocks_used(e2fsck_t ctx, blk64_t block,
 				      unsigned int num)
 {
-	if (ext2fs_test_block_bitmap_range2(ctx->block_found_map, block, num))
+	e2fsck_pass1_block_map_lock(ctx);
+	if (ext2fs_test_block_bitmap_range2(ctx->block_found_map, block, num)) {
 		ext2fs_mark_block_bitmap_range2(ctx->block_found_map, block, num);
-	else {
+	} else {
 		unsigned int i;
 
 		for (i = 0; i < num; i += EXT2FS_CLUSTER_RATIO(ctx->fs))
-			mark_block_used(ctx, block + i);
+			mark_block_used_unlocked(ctx, block + i);
 	}
+	e2fsck_pass1_block_map_unlock(ctx);
 }
 
 static errcode_t _INLINE_ e2fsck_write_ext_attr3(e2fsck_t ctx, blk64_t block,
@@ -4747,10 +4789,12 @@ static int process_bad_block(ext2_filsys fs,
 	}
 
 	if (blockcnt < 0) {
+		e2fsck_pass1_block_map_lock(ctx);
 		if (ext2fs_test_block_bitmap2(p->fs_meta_blocks, blk)) {
 			p->bbcheck = 1;
 			if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
 				*block_nr = 0;
+				e2fsck_pass1_block_map_unlock(ctx);
 				return BLOCK_CHANGED;
 			}
 		} else if (ext2fs_test_block_bitmap2(ctx->block_found_map,
@@ -4759,12 +4803,17 @@ static int process_bad_block(ext2_filsys fs,
 			if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
 					pctx)) {
 				*block_nr = 0;
+				e2fsck_pass1_block_map_unlock(ctx);
 				return BLOCK_CHANGED;
 			}
-			if (e2fsck_should_abort(ctx))
+			if (e2fsck_should_abort(ctx)) {
+				e2fsck_pass1_block_map_unlock(ctx);
 				return BLOCK_ABORT;
-		} else
-			mark_block_used(ctx, blk);
+			}
+		} else {
+			mark_block_used_unlocked(ctx, blk);
+		}
+		e2fsck_pass1_block_map_unlock(ctx);
 		return 0;
 	}
 #if 0
@@ -4777,10 +4826,13 @@ static int process_bad_block(ext2_filsys fs,
 	 * there's an overlap between the filesystem table blocks
 	 * (bitmaps and inode table) and the bad block list.
 	 */
+	e2fsck_pass1_block_map_lock(ctx);
 	if (!ext2fs_test_block_bitmap2(ctx->block_found_map, blk)) {
 		ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
+		e2fsck_pass1_block_map_unlock(ctx);
 		return 0;
 	}
+	e2fsck_pass1_block_map_unlock(ctx);
 	/*
 	 * Try to find the where the filesystem block was used...
 	 */
@@ -4935,6 +4987,7 @@ static void new_table_block(e2fsck_t ctx, blk64_t first_block, dgrp_t group,
 	fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
 			  PR_1_RELOC_TO), &pctx);
 	pctx.blk2 = 0;
+	e2fsck_pass1_block_map_lock(ctx);
 	for (i = 0; i < num; i++) {
 		pctx.blk = i;
 		ext2fs_mark_block_bitmap2(ctx->block_found_map, (*new_block)+i);
@@ -4955,6 +5008,7 @@ static void new_table_block(e2fsck_t ctx, blk64_t first_block, dgrp_t group,
 		if (pctx.errcode)
 			fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
 	}
+	e2fsck_pass1_block_map_unlock(ctx);
 	ext2fs_free_mem(&buf);
 }
 
diff --git a/e2fsck/util.c b/e2fsck/util.c
index 9470068f..93cd96c7 100644
--- a/e2fsck/util.c
+++ b/e2fsck/util.c
@@ -575,23 +575,34 @@ void e2fsck_read_inode_full(e2fsck_t ctx, unsigned long ino,
 }
 
 #ifdef HAVE_PTHREAD
+#define e2fsck_get_lock_context(ctx)		\
+	e2fsck_t global_ctx = ctx->global_ctx;	\
+	if (!global_ctx)			\
+		global_ctx = ctx;		\
+
 void e2fsck_pass1_fix_lock(e2fsck_t ctx)
 {
-	e2fsck_t global_ctx = ctx->global_ctx;
-	if (!global_ctx)
-		global_ctx = ctx;
-
+	e2fsck_get_lock_context(ctx);
 	pthread_mutex_lock(&global_ctx->fs_fix_mutex);
 }
 
 void e2fsck_pass1_fix_unlock(e2fsck_t ctx)
 {
-	e2fsck_t global_ctx = ctx->global_ctx;
-	if (!global_ctx)
-		global_ctx = ctx;
-
+	e2fsck_get_lock_context(ctx);
 	pthread_mutex_unlock(&global_ctx->fs_fix_mutex);
 }
+
+void e2fsck_pass1_block_map_lock(e2fsck_t ctx)
+{
+	e2fsck_get_lock_context(ctx);
+	pthread_mutex_lock(&global_ctx->fs_block_map_mutex);
+}
+
+void e2fsck_pass1_block_map_unlock(e2fsck_t ctx)
+{
+	e2fsck_get_lock_context(ctx);
+	pthread_mutex_unlock(&global_ctx->fs_block_map_mutex);
+}
 #else
 void e2fsck_pass1_fix_lock(e2fsck_t ctx)
 {
@@ -601,6 +612,15 @@ void e2fsck_pass1_fix_lock(e2fsck_t ctx)
 void e2fsck_pass1_fix_unlock(e2fsck_t ctx)
 {
 
+}
+
+void e2fsck_pass1_block_map_lock(e2fsck_t ctx)
+{
+
+}
+
+void e2fsck_pass1_block_map_unlock(e2fsck_t ctx)
+{
 }
 #endif
 
diff --git a/tests/f_multithread/expect.1 b/tests/f_multithread/expect.1
index 8d2acd2b..4db68d9e 100644
--- a/tests/f_multithread/expect.1
+++ b/tests/f_multithread/expect.1
@@ -1,7 +1,7 @@
 ext2fs_open2: Bad magic number in super-block
 ../e2fsck/e2fsck: Superblock invalid, trying backup blocks...
+Pass 1: Checking inodes, blocks, and sizes
 [Thread 0] Scan group range [0, 2)
-[Thread 0] Pass 1: Checking inodes, blocks, and sizes
 [Thread 0] Scanned group range [0, 2), inodes 3008
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
diff --git a/tests/f_multithread_logfile/expect.1 b/tests/f_multithread_logfile/expect.1
index 8d2acd2b..4db68d9e 100644
--- a/tests/f_multithread_logfile/expect.1
+++ b/tests/f_multithread_logfile/expect.1
@@ -1,7 +1,7 @@
 ext2fs_open2: Bad magic number in super-block
 ../e2fsck/e2fsck: Superblock invalid, trying backup blocks...
+Pass 1: Checking inodes, blocks, and sizes
 [Thread 0] Scan group range [0, 2)
-[Thread 0] Pass 1: Checking inodes, blocks, and sizes
 [Thread 0] Scanned group range [0, 2), inodes 3008
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
diff --git a/tests/f_multithread_no/expect.1 b/tests/f_multithread_no/expect.1
index f85a3382..eda2fcac 100644
--- a/tests/f_multithread_no/expect.1
+++ b/tests/f_multithread_no/expect.1
@@ -1,7 +1,7 @@
 ext2fs_open2: Bad magic number in super-block
 ../e2fsck/e2fsck: Superblock invalid, trying backup blocks...
+Pass 1: Checking inodes, blocks, and sizes
 [Thread 0] Scan group range [0, 2)
-[Thread 0] Pass 1: Checking inodes, blocks, and sizes
 [Thread 0] Scanned group range [0, 2), inodes 3008
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
-- 
2.37.3


  parent reply	other threads:[~2022-11-07 12:26 UTC|newest]

Thread overview: 104+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-07 12:20 [RFCv1 00/72] e2fsprogs: Parallel fsck support Ritesh Harjani (IBM)
2022-11-07 12:20 ` [RFCv1 01/72] e2fsck: Fix unbalanced mutex unlock for BOUNCE_MTX Ritesh Harjani (IBM)
2022-11-17 16:02   ` Theodore Ts'o
2022-11-17 18:45     ` Ritesh Harjani (IBM)
2022-11-18 10:34   ` Andreas Dilger
2022-11-18 11:37     ` Ritesh Harjani (IBM)
2022-11-18 13:20       ` Andreas Dilger
2022-11-19  3:46         ` Ritesh Harjani (IBM)
2023-01-24 16:40   ` Theodore Ts'o
2022-11-07 12:20 ` [RFCv1 02/72] gen_bitmaps: Fix ext2fs_compare_generic_bmap/bitmap logic Ritesh Harjani (IBM)
2022-11-23  5:04   ` Andreas Dilger
2023-01-24 16:59     ` Theodore Ts'o
2022-11-07 12:20 ` [RFCv1 03/72] blkmap64_ba: Add common helper for bits size calculation Ritesh Harjani (IBM)
2022-11-18 10:40   ` Andreas Dilger
2022-11-07 12:20 ` [RFCv1 04/72] badblocks: Remove unused badblocks_flags Ritesh Harjani (IBM)
2022-11-18 13:26   ` Andreas Dilger
2022-11-07 12:20 ` [RFCv1 05/72] badblocks: Add badblocks merge logic Ritesh Harjani (IBM)
2022-11-18 13:31   ` Andreas Dilger
2022-11-07 12:20 ` [RFCv1 06/72] dblist: add dblist " Ritesh Harjani (IBM)
2022-11-18 13:34   ` Andreas Dilger
2022-11-07 12:20 ` [RFCv1 07/72] libext2fs: Add rbtree bitmap " Ritesh Harjani (IBM)
2022-11-07 12:20 ` [RFCv1 08/72] libext2fs: Add bitmaps merge ops Ritesh Harjani (IBM)
2022-11-18 13:36   ` Andreas Dilger
2022-11-07 12:20 ` [RFCv1 09/72] libext2fs: Add flush cleanup API Ritesh Harjani (IBM)
2022-11-18 13:39   ` Andreas Dilger
2022-11-07 12:20 ` [RFCv1 10/72] libext2fs: merge icounts after thread finishes Ritesh Harjani (IBM)
2022-11-18 13:40   ` Andreas Dilger
2022-11-07 12:20 ` [RFCv1 11/72] libext2fs: merge quota context after threads finish Ritesh Harjani (IBM)
2022-11-18 13:42   ` Andreas Dilger
2022-11-07 12:21 ` [RFCv1 12/72] libext2fs: dupfs: Add fs clone & merge api Ritesh Harjani (IBM)
2022-11-18 19:46   ` Andreas Dilger
2022-11-19  5:02     ` Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 13/72] tst_badblocks: Add unit test to verify badblocks list " Ritesh Harjani (IBM)
2022-12-12 20:35   ` Andreas Dilger
2022-11-07 12:21 ` [RFCv1 14/72] tst_bitmaps_standalone: Add copy and merge bitmaps test Ritesh Harjani (IBM)
2022-12-12 20:40   ` Andreas Dilger
2022-12-14  5:12     ` Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 15/72] tst_bitmaps_pthread: Add merge bitmaps test using pthreads Ritesh Harjani (IBM)
2022-12-14 21:15   ` Andreas Dilger
2022-11-07 12:21 ` [RFCv1 16/72] tst_libext2fs_pthread: Add libext2fs merge/clone unit tests Ritesh Harjani (IBM)
2022-12-14 21:17   ` Andreas Dilger
2022-11-07 12:21 ` [RFCv1 17/72] libext2fs: Add support for ext2fs_test_block_bitmap_range2_valid() Ritesh Harjani (IBM)
2022-12-14 21:21   ` Andreas Dilger
2022-11-07 12:21 ` [RFCv1 18/72] libext2fs: Add support to get average group count Ritesh Harjani (IBM)
2022-12-14 21:24   ` Andreas Dilger
2022-11-07 12:21 ` [RFCv1 19/72] libext2fs: Misc fixes for struct_ext2_filsys Ritesh Harjani (IBM)
2022-12-14 21:22   ` Andreas Dilger
2022-11-07 12:21 ` [RFCv1 20/72] libext2fs: avoid too much memory allocation in case fs_num_threads Ritesh Harjani (IBM)
2022-11-18 13:37   ` Andreas Dilger
2022-11-07 12:21 ` [RFCv1 21/72] e2fsck: add -m option for multithread Ritesh Harjani (IBM)
2022-12-14 21:32   ` Andreas Dilger
2022-11-07 12:21 ` [RFCv1 22/72] e2fsck: copy context when using multi-thread fsck Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 23/72] e2fsck: create logs for multi-threads Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 24/72] e2fsck: configure one pfsck thread Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 25/72] e2fsck: Add e2fsck_pass1_thread_join return value Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 26/72] e2fsck: Use merge/clone apis of libext2fs Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 27/72] e2fsck: Add e2fsck_pass1_merge_bitmap() api Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 28/72] e2fsck: Add asserts in open_channel_fs Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 29/72] e2fsck: add start/end group for thread Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 30/72] e2fsck: split groups to different threads Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 31/72] e2fsck: print thread log properly Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 32/72] e2fsck: do not change global variables Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 33/72] e2fsck: optimize the inserting of dir_info_db Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 34/72] e2fsck: merge dir_info after thread finishes Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 35/72] e2fsck: rbtree bitmap for dir Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 36/72] e2fsck: merge icounts after thread finishes Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 37/72] e2fsck: add debug codes for multiple threads Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 38/72] e2fsck: merge counts after threads finish Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 39/72] e2fsck: merge dx_dir_info " Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 40/72] e2fsck: merge dirs_to_hash when " Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 41/72] e2fsck: merge context flags properly Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 42/72] e2fsck: merge quota context after threads finish Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 43/72] e2fsck: serialize fix operations Ritesh Harjani (IBM)
2022-11-07 12:21 ` Ritesh Harjani (IBM) [this message]
2022-11-07 12:21 ` [RFCv1 45/72] e2fsck: split and merge invalid bitmaps Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 46/72] e2fsck: merge EA blocks properly Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 47/72] e2fsck: kickoff mutex lock for block found map Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 48/72] e2fsck: allow admin specify number of threads Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 49/72] e2fsck: adjust " Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 50/72] e2fsck: fix readahead for pfsck of pass1 Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 51/72] e2fsck: merge options after threads finish Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 52/72] e2fsck: reset lost_and_found " Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 53/72] e2fsck: merge extent depth count " Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 54/72] e2fsck: simplify e2fsck context merging codes Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 55/72] e2fsck: set E2F_FLAG_ALLOC_OK after threads Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 56/72] e2fsck: wait fix thread finish before checking Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 57/72] e2fsck: cleanup e2fsck_pass1_thread_join() Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 58/72] e2fsck: make default smallest RA size to 1M Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 59/72] e2fsck: update mmp block in one thread Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 60/72] e2fsck: reset @inodes_to_rebuild if restart Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 61/72] tests: add pfsck test Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 62/72] e2fsck: fix memory leaks with pfsck enabled Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 63/72] e2fsck: misc cleanups for pfsck Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 64/72] e2fsck: propagate number of threads Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 65/72] e2fsck: Annotating fields in e2fsck_struct Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 66/72] e2fsck: merge casefolded dir lists after thread finish Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 67/72] sec: support encrypted files handling in pfsck mode Ritesh Harjani (IBM)
2022-11-07 19:22   ` Eric Biggers
2022-11-07 12:21 ` [RFCv1 68/72] e2fsck: Fix io->align assert check Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 69/72] e2fsck: Fix double free of inodes_to_process Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 70/72] e2fsck: Fix and simplify update_mmp in case of pfsck Ritesh Harjani (IBM)
2022-11-07 12:21 ` [RFCv1 71/72] e2fsck: Make threads call log_out after pthread_join Ritesh Harjani (IBM)
2022-11-07 12:22 ` [RFCv1 72/72] tests/f_multithread: Fix f_multithread related tests Ritesh Harjani (IBM)
     [not found] ` <B4ED1C86-D3EC-4A0A-97B3-CFCB46617E1A@dilger.ca>
2022-11-19  5:39   ` [RFCv1 00/72] e2fsprogs: Parallel fsck support Ritesh Harjani

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=0c454e13b21aadde5c5db1be3f76f2a87016a0bc.1667822611.git.ritesh.list@gmail.com \
    --to=ritesh.list@gmail.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=harshadshirwadkar@gmail.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=lixi@ddn.com \
    --cc=tytso@mit.edu \
    --cc=wshilong@ddn.com \
    /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).