Whamcloud - gitweb
e2fsck: update mmp block in one thread
authorWang Shilong <wshilong@ddn.com>
Wed, 23 Sep 2020 14:36:41 +0000 (22:36 +0800)
committerLi Dongyang <dongyangli@ddn.com>
Fri, 28 Apr 2023 00:47:13 +0000 (10:47 +1000)
For multiple threads, different threads will try to
update mmp block at the same time, only allow one
thread to update it.

E2fsprogs-commit: 1806140014cbce395d0ca4a51d46fa21e2833241

Change-Id: Id78b949d338c384a64828b955ed7477aa816f8ee
Signed-off-by: Wang Shilong <wshilong@ddn.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/e2fsck.h
e2fsck/pass1.c

index 2b32067..7ad5cd7 100644 (file)
@@ -491,6 +491,7 @@ struct e2fsck_struct {
        struct e2fsck_fc_replay_state fc_replay_state;
 #ifdef HAVE_PTHREAD
        __u32                    fs_num_threads;
+       __u32                    mmp_update_thread;
        int                      fs_need_locking;
        /* serialize fix operation for multiple threads */
        pthread_rwlock_t         fs_fix_rwlock;
index 5fb0353..f00d355 100644 (file)
@@ -1509,7 +1509,8 @@ void e2fsck_pass1_run(e2fsck_t ctx)
        dgrp_t          ra_group = 0;
        struct ea_quota ea_ibody_quota;
        struct process_inode_block *inodes_to_process;
-       int             process_inode_count;
+       int             process_inode_count, check_mmp;
+       e2fsck_t        global_ctx = ctx->global_ctx ? ctx->global_ctx : ctx;
 
        init_resource_track(&rtrack, ctx->fs->io);
        clear_problem_context(&pctx);
@@ -1672,8 +1673,30 @@ void e2fsck_pass1_run(e2fsck_t ctx)
 #endif
 
        while (1) {
+               check_mmp = 0;
                e2fsck_pass1_check_lock(ctx);
-               if (ino % (fs->super->s_inodes_per_group * 4) == 1) {
+#ifdef HAVE_PTHREAD
+               if (!global_ctx->mmp_update_thread) {
+                       e2fsck_pass1_block_map_w_lock(ctx);
+                       if (!global_ctx->mmp_update_thread) {
+                               global_ctx->mmp_update_thread =
+                                       ctx->thread_info.et_thread_index + 1;
+                               check_mmp = 1;
+                       }
+                       e2fsck_pass1_block_map_w_unlock(ctx);
+               }
+
+               /* only one active thread could update mmp block. */
+               e2fsck_pass1_block_map_r_lock(ctx);
+               if (global_ctx->mmp_update_thread ==
+                   ctx->thread_info.et_thread_index + 1)
+                       check_mmp = 1;
+               e2fsck_pass1_block_map_r_unlock(ctx);
+#else
+               check_mmp = 1;
+#endif
+
+               if (check_mmp && (ino % (fs->super->s_inodes_per_group * 4) == 1)) {
                        if (e2fsck_mmp_update(fs))
                                fatal_error(ctx, 0);
                }
@@ -2436,6 +2459,13 @@ endit:
                print_resource_track(ctx, _("Pass 1"), &rtrack, ctx->fs->io);
        else
                ctx->invalid_bitmaps++;
+#ifdef HAVE_PTHREAD
+       /* reset update_thread after this thread exit */
+       e2fsck_pass1_block_map_w_lock(ctx);
+       if (check_mmp)
+               global_ctx->mmp_update_thread = 0;
+       e2fsck_pass1_block_map_w_unlock(ctx);
+#endif
 }
 
 #ifdef HAVE_PTHREAD