diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 0b449b69..20d61651 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -448,7 +448,8 @@ struct e2fsck_struct {
 	__u32			fs_ext_attr_inodes;
 	__u32			fs_ext_attr_blocks;
 	__u32			extent_depth_count[MAX_EXTENT_DEPTH_COUNT];
-
+	/* serialize fix operation for multiple threads */
+	pthread_mutex_t		 fs_fix_mutex;
 };
 
 #ifdef DEBUG_THREADS
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index c7b9cf72..f3b52103 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -132,6 +132,24 @@ static void process_inodes(e2fsck_t ctx, char *block_buf,
 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
 			    EXT2_MIN_BLOCK_LOG_SIZE + 1];
 
+static void e2fsck_pass1_fix_lock(e2fsck_t ctx)
+{
+	e2fsck_t global_ctx = ctx->global_ctx;
+	if (!global_ctx)
+		global_ctx = ctx;
+
+	pthread_mutex_lock(&global_ctx->fs_fix_mutex);
+}
+
+static void e2fsck_pass1_fix_unlock(e2fsck_t ctx)
+{
+	e2fsck_t global_ctx = ctx->global_ctx;
+	if (!global_ctx)
+		global_ctx = ctx;
+
+	pthread_mutex_unlock(&global_ctx->fs_fix_mutex);
+}
+
 /*
  * Free all memory allocated by pass1 in preparation for restarting
  * things.
@@ -282,8 +300,10 @@ static void check_extents_inlinedata(e2fsck_t ctx,
 	if (!fix_problem(ctx, PR_1_SPECIAL_EXTENTS_IDATA, pctx))
 		return;
 
+	e2fsck_pass1_fix_lock(ctx);
 	pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
 	e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
+	e2fsck_pass1_fix_unlock(ctx);
 }
 #undef BAD_SPECIAL_FLAGS
 
@@ -300,8 +320,10 @@ static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
 	if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
 		return;
 
+	e2fsck_pass1_fix_lock(ctx);
 	pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
 	e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
+	e2fsck_pass1_fix_unlock(ctx);
 }
 
 /*
@@ -318,8 +340,10 @@ static void check_size(e2fsck_t ctx, struct problem_context *pctx)
 	if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
 		return;
 
+	e2fsck_pass1_fix_lock(ctx);
 	ext2fs_inode_size_set(ctx->fs, inode, 0);
 	e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
+	e2fsck_pass1_fix_unlock(ctx);
 }
 
 /*
@@ -388,9 +412,11 @@ static problem_t check_large_ea_inode(e2fsck_t ctx,
 	if (!(inode.i_flags & EXT4_EA_INODE_FL)) {
 		pctx->num = entry->e_value_inum;
 		if (fix_problem(ctx, PR_1_ATTR_SET_EA_INODE_FL, pctx)) {
+			e2fsck_pass1_fix_lock(ctx);
 			inode.i_flags |= EXT4_EA_INODE_FL;
 			ext2fs_write_inode(ctx->fs, entry->e_value_inum,
 					   &inode);
+			e2fsck_pass1_fix_unlock(ctx);
 		} else {
 			return PR_1_ATTR_NO_EA_INODE_FL;
 		}
@@ -551,11 +577,13 @@ fix:
 	}
 
 	/* simply remove all possible EA(s) */
+	e2fsck_pass1_fix_lock(ctx);
 	*((__u32 *)header) = 0UL;
 	e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
 				EXT2_INODE_SIZE(sb), "pass1");
 	ea_ibody_quota->blocks = 0;
 	ea_ibody_quota->inodes = 0;
+	e2fsck_pass1_fix_unlock(ctx);
 }
 
 static int check_inode_extra_negative_epoch(__u32 xtime, __u32 extra) {
@@ -606,12 +634,14 @@ static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx,
 	     inode->i_extra_isize & 3)) {
 		if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
 			return;
+		e2fsck_pass1_fix_lock(ctx);
 		if (inode->i_extra_isize < min || inode->i_extra_isize > max)
 			inode->i_extra_isize = sb->s_want_extra_isize;
 		else
 			inode->i_extra_isize = (inode->i_extra_isize + 3) & ~3;
 		e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
 					EXT2_INODE_SIZE(sb), "pass1");
+		e2fsck_pass1_fix_unlock(ctx);
 	}
 
 	/* check if there is no place for an EA header */
@@ -640,6 +670,7 @@ static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx,
 		if (!fix_problem(ctx, PR_1_EA_TIME_OUT_OF_RANGE, pctx))
 			return;
 
+		e2fsck_pass1_fix_lock(ctx);
 		if (CHECK_INODE_EXTRA_NEGATIVE_EPOCH(inode, atime))
 			inode->i_atime_extra &= ~EXT4_EPOCH_MASK;
 		if (CHECK_INODE_EXTRA_NEGATIVE_EPOCH(inode, ctime))
@@ -650,6 +681,7 @@ static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx,
 			inode->i_mtime_extra &= ~EXT4_EPOCH_MASK;
 		e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
 					EXT2_INODE_SIZE(sb), "pass1");
+		e2fsck_pass1_fix_unlock(ctx);
 	}
 
 }
@@ -807,10 +839,12 @@ static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
 
 isdir:
 	if (fix_problem(ctx, PR_1_TREAT_AS_DIRECTORY, pctx)) {
+		e2fsck_pass1_fix_lock(ctx);
 		inode->i_mode = (inode->i_mode & 07777) | LINUX_S_IFDIR;
 		e2fsck_write_inode_full(ctx, pctx->ino, inode,
 					EXT2_INODE_SIZE(ctx->fs->super),
 					"check_is_really_dir");
+		e2fsck_pass1_fix_unlock(ctx);
 	}
 }
 
@@ -881,8 +915,11 @@ static errcode_t recheck_bad_inode_checksum(ext2_filsys fs, ext2_ino_t ino,
 	if (!fix_problem(ctx, PR_1_INODE_ONLY_CSUM_INVALID, pctx))
 		return 0;
 
+
+	e2fsck_pass1_fix_lock(ctx);
 	retval = ext2fs_write_inode_full(fs, ino, (struct ext2_inode *)&inode,
 					 sizeof(inode));
+	e2fsck_pass1_fix_unlock(ctx);
 	return retval;
 }
 
@@ -892,15 +929,19 @@ 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))
-		return;
+		goto out;
 
 	err = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
 	if (err)
-		return;
+		goto out;
 	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)
@@ -911,15 +952,19 @@ 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))
-		return;
+		goto out;
 
 	err = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
 	if (err)
-		return;
+		goto out;
 	ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
 	ctx->lnf_repair_block = blk;
+out:
+	e2fsck_pass1_fix_unlock(ctx);
+	return;
 }
 
 static errcode_t get_inline_data_ea_size(ext2_filsys fs, ext2_ino_t ino,
@@ -1018,8 +1063,10 @@ static int fix_inline_data_extents_file(e2fsck_t ctx,
 	if (ext2fs_extent_header_verify(inode->i_block,
 				 sizeof(inode->i_block)) == 0 &&
 	    fix_problem(ctx, PR_1_CLEAR_INLINE_DATA_FOR_EXTENT, pctx)) {
+		e2fsck_pass1_fix_lock(ctx);
 		inode->i_flags &= ~EXT4_INLINE_DATA_FL;
 		dirty = 1;
+		e2fsck_pass1_fix_unlock(ctx);
 		goto out;
 	}
 
@@ -1033,8 +1080,10 @@ static int fix_inline_data_extents_file(e2fsck_t ctx,
 	if (EXT2_I_SIZE(inode) <
 	    EXT4_MIN_INLINE_DATA_SIZE + max_inline_ea_size &&
 	    fix_problem(ctx, PR_1_CLEAR_EXTENT_FOR_INLINE_DATA, pctx)) {
+		e2fsck_pass1_fix_lock(ctx);
 		inode->i_flags &= ~EXT4_EXTENTS_FL;
 		dirty = 1;
+		e2fsck_pass1_fix_unlock(ctx);
 		goto out;
 	}
 
@@ -1044,6 +1093,7 @@ static int fix_inline_data_extents_file(e2fsck_t ctx,
 	 */
 	if (could_be_block_map(fs, inode) &&
 	    fix_problem(ctx, PR_1_CLEAR_EXTENT_INLINE_DATA_FLAGS, pctx)) {
+		e2fsck_pass1_fix_lock(ctx);
 #ifdef WORDS_BIGENDIAN
 		int i;
 
@@ -1053,18 +1103,24 @@ static int fix_inline_data_extents_file(e2fsck_t ctx,
 
 		inode->i_flags &= ~(EXT4_EXTENTS_FL | EXT4_INLINE_DATA_FL);
 		dirty = 1;
+		e2fsck_pass1_fix_unlock(ctx);
 		goto out;
 	}
 
 	/* Oh well, just clear the busted inode. */
 	if (fix_problem(ctx, PR_1_CLEAR_EXTENT_INLINE_DATA_INODE, pctx)) {
+		e2fsck_pass1_fix_lock(ctx);
 		e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
+		e2fsck_pass1_fix_unlock(ctx);
 		return -1;
 	}
 
 out:
-	if (dirty)
+	if (dirty) {
+		e2fsck_pass1_fix_lock(ctx);
 		e2fsck_write_inode(ctx, ino, inode, "pass1");
+		e2fsck_pass1_fix_unlock(ctx);
+	}
 
 	return 0;
 }
@@ -1408,7 +1464,9 @@ void _e2fsck_pass1(e2fsck_t ctx)
 					&pctx)) {
 				errcode_t err;
 
+				e2fsck_pass1_fix_lock(ctx);
 				e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
+				e2fsck_pass1_fix_unlock(ctx);
 				ext2fs_badblocks_list_free(ctx->fs->badblocks);
 				ctx->fs->badblocks = NULL;
 				err = ext2fs_read_bb_inode(ctx->fs,
@@ -1457,7 +1515,9 @@ void _e2fsck_pass1(e2fsck_t ctx)
 		    inode->i_links_count > 0 &&
 		    fix_problem(ctx, PR_1_INODE_IS_GARBAGE, &pctx)) {
 			pctx.errcode = 0;
+			e2fsck_pass1_fix_lock(ctx);
 			e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
+			e2fsck_pass1_fix_unlock(ctx);
 		}
 		failed_csum = pctx.errcode != 0;
 
@@ -1481,10 +1541,12 @@ void _e2fsck_pass1(e2fsck_t ctx)
 		if (inode->i_dtime && low_dtime_check &&
 		    inode->i_dtime < ctx->fs->super->s_inodes_count) {
 			if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
+				e2fsck_pass1_fix_lock(ctx);
 				inode->i_dtime = inode->i_links_count ?
 					0 : ctx->now;
 				e2fsck_write_inode(ctx, ino, inode,
 						   "pass1");
+				e2fsck_pass1_fix_unlock(ctx);
 				failed_csum = 0;
 			}
 		}
@@ -1503,9 +1565,11 @@ void _e2fsck_pass1(e2fsck_t ctx)
 			if (!inode->i_dtime && inode->i_mode) {
 				if (fix_problem(ctx,
 					    PR_1_ZERO_DTIME, &pctx)) {
+					e2fsck_pass1_fix_lock(ctx);
 					inode->i_dtime = ctx->now;
 					e2fsck_write_inode(ctx, ino, inode,
 							   "pass1");
+					e2fsck_pass1_fix_unlock(ctx);
 					failed_csum = 0;
 				}
 			}
@@ -1542,11 +1606,15 @@ void _e2fsck_pass1(e2fsck_t ctx)
 			pctx.errcode = get_inline_data_ea_size(fs, ino, &size);
 			if (!pctx.errcode &&
 			    fix_problem(ctx, PR_1_INLINE_DATA_FEATURE, &pctx)) {
+				e2fsck_pass1_fix_lock(ctx);
 				ext2fs_set_feature_inline_data(sb);
 				ext2fs_mark_super_dirty(fs);
+				e2fsck_pass1_fix_unlock(ctx);
 				inlinedata_fs = 1;
 			} else if (fix_problem(ctx, PR_1_INLINE_DATA_SET, &pctx)) {
+				e2fsck_pass1_fix_lock(ctx);
 				e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
+				e2fsck_pass1_fix_unlock(ctx);
 				/* skip FINISH_INODE_LOOP */
 				continue;
 			}
@@ -1588,10 +1656,12 @@ void _e2fsck_pass1(e2fsck_t ctx)
 				/* broken EA or no system.data EA; truncate */
 				if (fix_problem(ctx, PR_1_INLINE_DATA_NO_ATTR,
 						&pctx)) {
+					e2fsck_pass1_fix_lock(ctx);
 					err = ext2fs_inode_size_set(fs, inode, 0);
 					if (err) {
 						pctx.errcode = err;
 						ctx->flags |= E2F_FLAG_ABORT;
+						e2fsck_pass1_fix_unlock(ctx);
 						goto endit;
 					}
 					inode->i_flags &= ~EXT4_INLINE_DATA_FL;
@@ -1599,6 +1669,7 @@ void _e2fsck_pass1(e2fsck_t ctx)
 					       sizeof(inode->i_block));
 					e2fsck_write_inode(ctx, ino, inode,
 							   "pass1");
+					e2fsck_pass1_fix_unlock(ctx);
 					failed_csum = 0;
 				}
 				break;
@@ -1631,12 +1702,16 @@ void _e2fsck_pass1(e2fsck_t ctx)
 			if ((ext2fs_extent_header_verify(inode->i_block,
 						 sizeof(inode->i_block)) == 0) &&
 			    fix_problem(ctx, PR_1_EXTENT_FEATURE, &pctx)) {
+				e2fsck_pass1_fix_lock(ctx);
 				ext2fs_set_feature_extents(sb);
 				ext2fs_mark_super_dirty(fs);
 				extent_fs = 1;
+				e2fsck_pass1_fix_unlock(ctx);
 			} else if (fix_problem(ctx, PR_1_EXTENTS_SET, &pctx)) {
 			clear_inode:
+				e2fsck_pass1_fix_lock(ctx);
 				e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
+				e2fsck_pass1_fix_unlock(ctx);
 				if (ino == EXT2_BAD_INO)
 					ext2fs_mark_inode_bitmap2(ctx->inode_used_map,
 								 ino);
@@ -1671,12 +1746,14 @@ void _e2fsck_pass1(e2fsck_t ctx)
 			if ((ext2fs_extent_header_verify(ehp,
 					 sizeof(inode->i_block)) == 0) &&
 			    (fix_problem(ctx, PR_1_UNSET_EXTENT_FL, &pctx))) {
+				e2fsck_pass1_fix_lock(ctx);
 				inode->i_flags |= EXT4_EXTENTS_FL;
 #ifdef WORDS_BIGENDIAN
 				memcpy(inode->i_block, tmp_block,
 				       sizeof(inode->i_block));
 #endif
 				e2fsck_write_inode(ctx, ino, inode, "pass1");
+				e2fsck_pass1_fix_unlock(ctx);
 				failed_csum = 0;
 			}
 		}
@@ -1689,9 +1766,11 @@ void _e2fsck_pass1(e2fsck_t ctx)
 			     (inode->i_flags & EXT4_INLINE_DATA_FL) ||
 			     inode->i_file_acl) &&
 			    fix_problem(ctx, PR_1_INVALID_BAD_INODE, &pctx)) {
+				e2fsck_pass1_fix_lock(ctx);
 				memset(inode, 0, sizeof(struct ext2_inode));
 				e2fsck_write_inode(ctx, ino, inode,
 						   "clear bad inode");
+				e2fsck_pass1_fix_unlock(ctx);
 				failed_csum = 0;
 			}
 
@@ -1750,9 +1829,11 @@ void _e2fsck_pass1(e2fsck_t ctx)
 			 */
 			if (inode->i_dtime && inode->i_links_count) {
 				if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
+					e2fsck_pass1_fix_lock(ctx);
 					inode->i_dtime = 0;
 					e2fsck_write_inode(ctx, ino, inode,
 							   "pass1");
+					e2fsck_pass1_fix_unlock(ctx);
 					failed_csum = 0;
 				}
 			}
@@ -1762,9 +1843,11 @@ void _e2fsck_pass1(e2fsck_t ctx)
 				if (!LINUX_S_ISREG(inode->i_mode) &&
 				    fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
 						&pctx)) {
+					e2fsck_pass1_fix_lock(ctx);
 					inode->i_mode = LINUX_S_IFREG;
 					e2fsck_write_inode(ctx, ino, inode,
 							   "pass1");
+					e2fsck_pass1_fix_unlock(ctx);
 					failed_csum = 0;
 				}
 				check_blocks(ctx, &pctx, block_buf, NULL);
@@ -1778,8 +1861,10 @@ void _e2fsck_pass1(e2fsck_t ctx)
 				memset(inode, 0, inode_size);
 				ext2fs_icount_store(ctx->inode_link_info,
 						    ino, 0);
+				e2fsck_pass1_fix_lock(ctx);
 				e2fsck_write_inode_full(ctx, ino, inode,
 							inode_size, "pass1");
+				e2fsck_pass1_fix_unlock(ctx);
 				failed_csum = 0;
 			}
 		} else if (quota_inum_is_reserved(fs, ino)) {
@@ -1789,9 +1874,11 @@ void _e2fsck_pass1(e2fsck_t ctx)
 				if (!LINUX_S_ISREG(inode->i_mode) &&
 				    fix_problem(ctx, PR_1_QUOTA_BAD_MODE,
 							&pctx)) {
+					e2fsck_pass1_fix_lock(ctx);
 					inode->i_mode = LINUX_S_IFREG;
 					e2fsck_write_inode(ctx, ino, inode,
 							"pass1");
+					e2fsck_pass1_fix_unlock(ctx);
 					failed_csum = 0;
 				}
 				check_blocks(ctx, &pctx, block_buf, NULL);
@@ -1802,11 +1889,13 @@ void _e2fsck_pass1(e2fsck_t ctx)
 			     inode->i_blocks || inode->i_block[0]) &&
 			    fix_problem(ctx, PR_1_QUOTA_INODE_NOT_CLEAR,
 					&pctx)) {
-				memset(inode, 0, inode_size);
 				ext2fs_icount_store(ctx->inode_link_info,
 						    ino, 0);
+				e2fsck_pass1_fix_lock(ctx);
+				memset(inode, 0, inode_size);
 				e2fsck_write_inode_full(ctx, ino, inode,
 							inode_size, "pass1");
+				e2fsck_pass1_fix_unlock(ctx);
 				failed_csum = 0;
 			}
 		} else if (ino < EXT2_FIRST_INODE(fs->super)) {
@@ -1826,9 +1915,11 @@ void _e2fsck_pass1(e2fsck_t ctx)
 			}
 			if (problem) {
 				if (fix_problem(ctx, problem, &pctx)) {
+					e2fsck_pass1_fix_lock(ctx);
 					inode->i_mode = 0;
 					e2fsck_write_inode(ctx, ino, inode,
 							   "pass1");
+					e2fsck_pass1_fix_unlock(ctx);
 					failed_csum = 0;
 				}
 			}
@@ -1889,9 +1980,11 @@ void _e2fsck_pass1(e2fsck_t ctx)
 							 ino);
 			} else {
 				if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
+					e2fsck_pass1_fix_lock(ctx);
 					inode->i_flags &= ~EXT2_IMAGIC_FL;
 					e2fsck_write_inode(ctx, ino,
 							   inode, "pass1");
+					e2fsck_pass1_fix_unlock(ctx);
 					failed_csum = 0;
 				}
 			}
@@ -1908,8 +2001,10 @@ void _e2fsck_pass1(e2fsck_t ctx)
 		    LINUX_S_ISLNK(inode->i_mode) &&
 		    !ext2fs_inode_has_valid_blocks2(fs, inode) &&
 		    fix_problem(ctx, PR_1_FAST_SYMLINK_EXTENT_FL, &pctx)) {
+			e2fsck_pass1_fix_lock(ctx);
 			inode->i_flags &= ~EXT4_EXTENTS_FL;
 			e2fsck_write_inode(ctx, ino, inode, "pass1");
+			e2fsck_pass1_fix_unlock(ctx);
 			failed_csum = 0;
 		}
 
@@ -2042,8 +2137,11 @@ void _e2fsck_pass1(e2fsck_t ctx)
 		ctx->ea_block_quota_inodes = 0;
 	}
 
-	if (ctx->invalid_bitmaps)
+	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) {
@@ -2056,7 +2154,9 @@ void _e2fsck_pass1(e2fsck_t 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)) {
@@ -2068,9 +2168,11 @@ void _e2fsck_pass1(e2fsck_t ctx)
 		if (!pctx.errcode) {
 			e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
 					  "recreate inode");
+			e2fsck_pass1_fix_lock(ctx);
 			inode->i_mtime = ctx->now;
 			e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
 					   "recreate inode");
+			e2fsck_pass1_fix_unlock(ctx);
 		}
 		ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
 	}
@@ -2092,7 +2194,9 @@ void _e2fsck_pass1(e2fsck_t ctx)
 			clear_problem_context(&pctx);
 			fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
 		}
+		e2fsck_pass1_fix_lock(ctx);
 		e2fsck_pass1_dupblocks(ctx, block_buf);
+		e2fsck_pass1_fix_unlock(ctx);
 	}
 	ctx->flags |= E2F_FLAG_ALLOC_OK;
 	ext2fs_free_mem(&inodes_to_process);
@@ -2906,6 +3010,7 @@ static void e2fsck_pass1_multithread(e2fsck_t global_ctx)
 	unsigned flexbg_size = 1;
 	int max_threads;
 
+	pthread_mutex_init(&global_ctx->fs_fix_mutex, NULL);
 	if (ext2fs_has_feature_flex_bg(global_ctx->fs->super))
 		flexbg_size = 1 << global_ctx->fs->super->s_log_groups_per_flex;
 
@@ -3210,10 +3315,12 @@ static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
 		should_be = header->h_refcount + adjust_sign * (int)count;
 		pctx.num = should_be;
 		if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
+			e2fsck_pass1_fix_lock(ctx);
 			header->h_refcount = should_be;
 			pctx.errcode = ext2fs_write_ext_attr3(fs, blk,
 							     block_buf,
 							     pctx.ino);
+			e2fsck_pass1_fix_unlock(ctx);
 			if (pctx.errcode) {
 				fix_problem(ctx, PR_1_EXTATTR_WRITE_ABORT,
 					    &pctx);
@@ -3442,8 +3549,10 @@ static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
 	 */
 	if (failed_csum &&
 	    fix_problem(ctx, PR_1_EA_BLOCK_ONLY_CSUM_INVALID, pctx)) {
+		e2fsck_pass1_fix_lock(ctx);
 		pctx->errcode = ext2fs_write_ext_attr3(fs, blk, block_buf,
 						       pctx->ino);
+		e2fsck_pass1_fix_unlock(ctx);
 		if (pctx->errcode)
 			return 0;
 	}
@@ -3489,8 +3598,10 @@ refcount_fail:
 clear_extattr:
 	if (region)
 		region_free(region);
+	e2fsck_pass1_fix_lock(ctx);
 	ext2fs_file_acl_block_set(fs, inode, 0);
 	e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
+	e2fsck_pass1_fix_unlock(ctx);
 	return 0;
 }
 
@@ -3720,10 +3831,12 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 		if (try_repairs && is_dir && problem == 0 &&
 		    (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) &&
 		    fix_problem(ctx, PR_1_UNINIT_DBLOCK, pctx)) {
+			e2fsck_pass1_fix_lock(ctx);
 			extent.e_flags &= ~EXT2_EXTENT_FLAGS_UNINIT;
 			pb->inode_modified = 1;
 			pctx->errcode = ext2fs_extent_replace(ehandle, 0,
 							      &extent);
+			e2fsck_pass1_fix_unlock(ctx);
 			if (pctx->errcode)
 				return;
 			failed_csum = 0;
@@ -3767,13 +3880,17 @@ report_problem:
 				}
 				e2fsck_read_bitmaps(ctx);
 				pb->inode_modified = 1;
+				e2fsck_pass1_fix_lock(ctx);
 				pctx->errcode =
 					ext2fs_extent_delete(ehandle, 0);
+				e2fsck_pass1_fix_unlock(ctx);
 				if (pctx->errcode) {
 					pctx->str = "ext2fs_extent_delete";
 					return;
 				}
+				e2fsck_pass1_fix_lock(ctx);
 				pctx->errcode = ext2fs_extent_fix_parents(ehandle);
+				e2fsck_pass1_fix_unlock(ctx);
 				if (pctx->errcode &&
 				    pctx->errcode != EXT2_ET_NO_CURRENT_NODE) {
 					pctx->str = "ext2fs_extent_fix_parents";
@@ -3837,9 +3954,11 @@ report_problem:
 				pctx->num = e_info.curr_level - 1;
 				problem = PR_1_EXTENT_INDEX_START_INVALID;
 				if (fix_problem(ctx, problem, pctx)) {
+					e2fsck_pass1_fix_lock(ctx);
 					pb->inode_modified = 1;
 					pctx->errcode =
 						ext2fs_extent_fix_parents(ehandle);
+					e2fsck_pass1_fix_unlock(ctx);
 					if (pctx->errcode) {
 						pctx->str = "ext2fs_extent_fix_parents";
 						return;
@@ -3903,15 +4022,19 @@ report_problem:
 			pctx->blk = extent.e_lblk;
 			pctx->blk2 = new_lblk;
 			if (fix_problem(ctx, PR_1_COLLAPSE_DBLOCK, pctx)) {
+				e2fsck_pass1_fix_lock(ctx);
 				extent.e_lblk = new_lblk;
 				pb->inode_modified = 1;
 				pctx->errcode = ext2fs_extent_replace(ehandle,
 								0, &extent);
+				e2fsck_pass1_fix_unlock(ctx);
 				if (pctx->errcode) {
 					pctx->errcode = 0;
 					goto alloc_later;
 				}
+				e2fsck_pass1_fix_lock(ctx);
 				pctx->errcode = ext2fs_extent_fix_parents(ehandle);
+				e2fsck_pass1_fix_unlock(ctx);
 				if (pctx->errcode)
 					goto failed_add_dir_block;
 				pctx->errcode = ext2fs_extent_goto(ehandle,
@@ -4007,8 +4130,10 @@ alloc_later:
 	/* Failed csum but passes checks?  Ask to fix checksum. */
 	if (failed_csum &&
 	    fix_problem(ctx, PR_1_EXTENT_ONLY_CSUM_INVALID, pctx)) {
+		e2fsck_pass1_fix_lock(ctx);
 		pb->inode_modified = 1;
 		pctx->errcode = ext2fs_extent_replace(ehandle, 0, &extent);
+		e2fsck_pass1_fix_unlock(ctx);
 		if (pctx->errcode)
 			return;
 	}
@@ -4033,9 +4158,12 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
 	eh = (struct ext3_extent_header *) &inode->i_block[0];
 	retval = ext2fs_extent_header_verify(eh, sizeof(inode->i_block));
 	if (retval) {
-		if (fix_problem(ctx, PR_1_MISSING_EXTENT_HEADER, pctx))
+		if (fix_problem(ctx, PR_1_MISSING_EXTENT_HEADER, pctx)) {
+			e2fsck_pass1_fix_lock(ctx);
 			e2fsck_clear_inode(ctx, ino, inode, 0,
 					   "check_blocks_extents");
+			e2fsck_pass1_fix_unlock(ctx);
+		}
 		pctx->errcode = 0;
 		return;
 	}
@@ -4043,9 +4171,12 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
 	/* ...since this function doesn't fail if i_block is zeroed. */
 	pctx->errcode = ext2fs_extent_open2(fs, ino, inode, &ehandle);
 	if (pctx->errcode) {
-		if (fix_problem(ctx, PR_1_READ_EXTENT, pctx))
+		if (fix_problem(ctx, PR_1_READ_EXTENT, pctx)) {
+			e2fsck_pass1_fix_lock(ctx);
 			e2fsck_clear_inode(ctx, ino, inode, 0,
 					   "check_blocks_extents");
+			e2fsck_pass1_fix_unlock(ctx);
+		}
 		pctx->errcode = 0;
 		return;
 	}
@@ -4082,8 +4213,10 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
 	    fix_problem(ctx, PR_1_EXTENT_ITERATE_FAILURE, pctx)) {
 		pb->num_blocks = 0;
 		inode->i_blocks = 0;
+		e2fsck_pass1_fix_lock(ctx);
 		e2fsck_clear_inode(ctx, ino, inode, E2F_FLAG_RESTART,
 				   "check_blocks_extents");
+		e2fsck_pass1_fix_unlock(ctx);
 		pctx->errcode = 0;
 	}
 	ext2fs_extent_free(ehandle);
@@ -4259,8 +4392,10 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 	}
 
 	if (pb.clear) {
+		e2fsck_pass1_fix_lock(ctx);
 		e2fsck_clear_inode(ctx, ino, inode, E2F_FLAG_RESTART,
 				   "check_blocks");
+		e2fsck_pass1_fix_unlock(ctx);
 		return;
 	}
 
@@ -4276,7 +4411,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 	if (!pb.num_blocks && pb.is_dir &&
 	    !(inode->i_flags & EXT4_INLINE_DATA_FL)) {
 		if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
+			e2fsck_pass1_fix_lock(ctx);
 			e2fsck_clear_inode(ctx, ino, inode, 0, "check_blocks");
+			e2fsck_pass1_fix_unlock(ctx);
 			ctx->fs_directory_count--;
 			return;
 		}
@@ -4355,6 +4492,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 			pctx->num = (pb.last_block + 1) * fs->blocksize;
 		pctx->group = bad_size;
 		if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
+			e2fsck_pass1_fix_lock(ctx);
 			if (LINUX_S_ISDIR(inode->i_mode))
 				pctx->num &= 0xFFFFFFFFULL;
 			ext2fs_inode_size_set(fs, inode, pctx->num);
@@ -4365,6 +4503,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 				inode->i_flags &= ~EXT4_INLINE_DATA_FL;
 			}
 			dirty_inode++;
+			e2fsck_pass1_fix_unlock(ctx);
 		}
 		pctx->num = 0;
 	}
@@ -4378,8 +4517,10 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 	      (inode->osd2.linux2.l_i_blocks_hi != 0)))) {
 		pctx->num = pb.num_blocks;
 		if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
+			e2fsck_pass1_fix_lock(ctx);
 			inode->i_blocks = pb.num_blocks;
 			inode->osd2.linux2.l_i_blocks_hi = pb.num_blocks >> 32;
+			e2fsck_pass1_fix_unlock(ctx);
 			dirty_inode++;
 		}
 		pctx->num = 0;
@@ -4408,8 +4549,11 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 		e2fsck_rehash_dir_later(ctx, ino);
 
 out:
-	if (dirty_inode)
+	if (dirty_inode) {
+		e2fsck_pass1_fix_lock(ctx);
 		e2fsck_write_inode(ctx, ino, inode, "check_blocks");
+		e2fsck_pass1_fix_unlock(ctx);
+	}
 }
 
 #if 0
