]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
e2fsck: add debug codes for multiple threads
authorLi Xi <lixi@ddn.com>
Thu, 5 Sep 2019 11:40:36 +0000 (19:40 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 25 Jan 2021 20:17:30 +0000 (15:17 -0500)
These debug codes are added to run the multiple pass1 check
thread one by one in order. If all the codes are correct,
fsck of multiple threads should have exactly the same outcome
with single thread.

Signed-off-by: Li Xi <lixi@ddn.com>
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 531a353e9f244a6c4c97edaf742081ee2383d95e..349395b1e443c91836a3c1fffe46b2d24a118f2a 100644 (file)
@@ -450,6 +450,18 @@ struct e2fsck_struct {
 };
 
 #ifdef HAVE_PTHREAD
+#ifdef DEBUG_THREADS
+/*
+ * Enabling DEBUG_THREADS would cause the parallel
+ * fsck threads run sequentially.
+ */
+struct e2fsck_thread_debug {
+       pthread_mutex_t etd_mutex;
+       pthread_cond_t  etd_cond;
+       int             etd_finished_threads;
+};
+#endif
+
 struct e2fsck_thread_info {
        /* ID returned by pthread_create() */
        pthread_t                eti_thread_id;
@@ -459,7 +471,11 @@ struct e2fsck_thread_info {
        int                      eti_started;
        /* Context used for this thread */
        e2fsck_t                 eti_thread_ctx;
+#ifdef DEBUG_THREADS
+       struct e2fsck_thread_debug      *eti_debug;
+#endif
 };
+
 #endif
 
 /* Data structures to evaluate whether an extent tree needs rebuilding. */
index b01b415a6b7bbce72d9e30f92bfc57b253bd2919..e0a671b06a6e09d14e1a616f6cc4200ba3532d76 100644 (file)
@@ -2641,6 +2641,18 @@ static void *e2fsck_pass1_thread(void *arg)
 {
        struct e2fsck_thread_info       *info = arg;
        e2fsck_t                         thread_ctx = info->eti_thread_ctx;
+#ifdef DEBUG_THREADS
+       struct e2fsck_thread_debug      *thread_debug = info->eti_debug;
+#endif
+
+#ifdef DEBUG_THREADS
+       pthread_mutex_lock(&thread_debug->etd_mutex);
+       while (info->eti_thread_index > thread_debug->etd_finished_threads) {
+               pthread_cond_wait(&thread_debug->etd_cond,
+                                 &thread_debug->etd_mutex);
+       }
+       pthread_mutex_unlock(&thread_debug->etd_mutex);
+#endif
 
 #ifdef HAVE_SETJMP_H
        /*
@@ -2665,6 +2677,14 @@ out:
                        thread_ctx->thread_info.et_group_start,
                        thread_ctx->thread_info.et_group_end,
                        thread_ctx->thread_info.et_inode_number);
+
+#ifdef DEBUG_THREADS
+       pthread_mutex_lock(&thread_debug->etd_mutex);
+       thread_debug->etd_finished_threads++;
+       pthread_cond_broadcast(&thread_debug->etd_cond);
+       pthread_mutex_unlock(&thread_debug->etd_mutex);
+#endif
+
        return NULL;
 }
 
@@ -2678,6 +2698,12 @@ static int e2fsck_pass1_threads_start(struct e2fsck_thread_info **pinfo,
        struct e2fsck_thread_info       *tmp_pinfo;
        int                              i;
        e2fsck_t                         thread_ctx;
+#ifdef DEBUG_THREADS
+       struct e2fsck_thread_debug       thread_debug =
+               {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
+
+       thread_debug.etd_finished_threads = 0;
+#endif
 
        retval = pthread_attr_init(&attr);
        if (retval) {
@@ -2698,6 +2724,9 @@ static int e2fsck_pass1_threads_start(struct e2fsck_thread_info **pinfo,
        for (i = 0; i < num_threads; i++) {
                tmp_pinfo = &infos[i];
                tmp_pinfo->eti_thread_index = i;
+#ifdef DEBUG_THREADS
+               tmp_pinfo->eti_debug = &thread_debug;
+#endif
                retval = e2fsck_pass1_thread_prepare(global_ctx, &thread_ctx,
                                                     i, num_threads);
                if (retval) {