]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
e2fsck: add start/end group for thread
authorLi Xi <lixi@ddn.com>
Wed, 21 Aug 2019 13:58:31 +0000 (21:58 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 25 Jan 2021 20:16:50 +0000 (15:16 -0500)
When multi-threads are used for check, each thread needs to jump
to different group in pass1 check. This patch adds the group
jumping support. But still, only one thread is used to check.

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/logfile.c
e2fsck/pass1.c
e2fsck/problem.c
e2fsck/problem.h
lib/ext2fs/ext2_err.et.in

index 3bc79212c13f635faa0255e88cb964a62a37fc08..eacd9197d206547df027a2e824ec4e06642fe456 100644 (file)
@@ -227,6 +227,22 @@ typedef struct e2fsck_struct *e2fsck_t;
 
 #define MAX_EXTENT_DEPTH_COUNT 5
 
+#ifdef HAVE_PTHREAD
+/*
+ * Fields that used for multi-thread
+ */
+struct e2fsck_thread {
+       /* Thread index */
+       int             et_thread_index;
+       /* The start group number for this thread */
+       dgrp_t          et_group_start;
+       /* The end (not included) group number for this thread*/
+       dgrp_t          et_group_end;
+       /* The next group number to check */
+       dgrp_t          et_group_next;
+};
+#endif
+
 struct e2fsck_struct {
        /* Global context to get the cancel flag */
        e2fsck_t                global_ctx;
@@ -310,8 +326,11 @@ struct e2fsck_struct {
         */
        ext2_ino_t              stashed_ino;
        struct ext2_inode       *stashed_inode;
-       /* Thread index, if global_ctx is null, this field is unused */
-       int                     thread_index;
+
+       /* if @global_ctx is null, this field is unused */
+#ifdef HAVE_PTHREAD
+       struct e2fsck_thread     thread_info;
+#endif
 
        /*
         * Location of the lost and found directory
index 9f9218550b221fe5a047e27c9b7738663bc793fd..60ab95f9c642b144b5255ed821aad10aa1dc8c90 100644 (file)
@@ -312,7 +312,8 @@ static FILE *set_up_log_file(e2fsck_t ctx, const char *key, const char *fn)
        expand_logfn(ctx, log_fn, &s);
 #ifdef HAVE_PTHREAD
        if (ctx->global_ctx) {
-               sprintf(string_index, "%d", ctx->thread_index);
+               sprintf(string_index, "%d",
+                       ctx->thread_info.et_thread_index);
                append_string(&s, ".", 1);
                append_string(&s, string_index, 0);
        }
index 88099ac2b1f04afd33ba6c1b866d85dfa221cf2a..fe85c294237f71b3dd075efa6d52f63548618fb4 100644 (file)
@@ -1370,6 +1370,23 @@ void e2fsck_pass1_run(e2fsck_t ctx)
        /* Set up ctx->lost_and_found if possible */
        (void) e2fsck_get_lost_and_found(ctx, 0);
 
+#ifdef HAVE_PTHREAD
+       if (ctx->global_ctx) {
+               if (ctx->options & E2F_OPT_DEBUG &&
+                   ctx->options & E2F_OPT_MULTITHREAD)
+                       fprintf(stderr, "thread %d jumping to group %d\n",
+                                       ctx->thread_info.et_thread_index,
+                                       ctx->thread_info.et_group_start);
+               pctx.errcode = ext2fs_inode_scan_goto_blockgroup(scan,
+                                       ctx->thread_info.et_group_start);
+               if (pctx.errcode) {
+                       fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
+                       ctx->flags |= E2F_FLAG_ABORT;
+                       goto endit;
+               }
+       }
+#endif
+
        while (1) {
                if (ino % (fs->super->s_inodes_per_group * 4) == 1) {
                        if (e2fsck_mmp_update(fs))
@@ -1413,6 +1430,8 @@ void e2fsck_pass1_run(e2fsck_t ctx)
                        ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
                        continue;
                }
+               if (pctx.errcode == EXT2_ET_SCAN_FINISHED)
+                       break;
                if (pctx.errcode &&
                    pctx.errcode != EXT2_ET_INODE_CSUM_INVALID &&
                    pctx.errcode != EXT2_ET_INODE_IS_GARBAGE) {
@@ -2212,12 +2231,14 @@ static int e2fsck_pass1_merge_fs(ext2_filsys dest, ext2_filsys src)
        return retval;
 }
 
-static errcode_t e2fsck_pass1_thread_prepare(e2fsck_t global_ctx, e2fsck_t *thread_ctx)
+static errcode_t e2fsck_pass1_thread_prepare(e2fsck_t global_ctx, e2fsck_t *thread_ctx,
+                                            int thread_index)
 {
-       errcode_t       retval;
-       e2fsck_t        thread_context;
-       ext2_filsys     thread_fs;
-       ext2_filsys     global_fs = global_ctx->fs;
+       errcode_t               retval;
+       e2fsck_t                thread_context;
+       ext2_filsys             thread_fs;
+       ext2_filsys             global_fs = global_ctx->fs;
+       struct e2fsck_thread    *tinfo;
 
        assert(global_ctx->inode_used_map == NULL);
        assert(global_ctx->inode_dir_map == NULL);
@@ -2254,9 +2275,15 @@ static errcode_t e2fsck_pass1_thread_prepare(e2fsck_t global_ctx, e2fsck_t *thre
        }
        thread_fs->priv_data = thread_context;
 
-       thread_context->thread_index = 0;
+       thread_context->thread_info.et_thread_index = thread_index;
        set_up_logging(thread_context);
 
+       assert(thread_index == 0);
+       tinfo = &thread_context->thread_info;
+       tinfo->et_group_start = 0;
+       tinfo->et_group_next = 0;
+       tinfo->et_group_end = thread_fs->group_desc_count;
+
        thread_context->fs = thread_fs;
        *thread_ctx = thread_context;
        return 0;
@@ -2479,7 +2506,7 @@ 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;
-               retval = e2fsck_pass1_thread_prepare(global_ctx, &thread_ctx);
+               retval = e2fsck_pass1_thread_prepare(global_ctx, &thread_ctx, i);
                if (retval) {
                        com_err(global_ctx->program_name, retval,
                                _("while preparing pass1 thread\n"));
@@ -2564,6 +2591,7 @@ static errcode_t scan_callback(ext2_filsys fs,
 {
        struct scan_callback_struct *scan_struct;
        e2fsck_t ctx;
+       struct e2fsck_thread *tinfo;
 
        scan_struct = (struct scan_callback_struct *) priv_data;
        ctx = scan_struct->ctx;
@@ -2575,6 +2603,15 @@ static errcode_t scan_callback(ext2_filsys fs,
                                    ctx->fs->group_desc_count))
                        return EXT2_ET_CANCEL_REQUESTED;
 
+#ifdef HAVE_PTHREAD
+       if (ctx->global_ctx) {
+               tinfo = &ctx->thread_info;
+               tinfo->et_group_next++;
+               if (tinfo->et_group_next >= tinfo->et_group_end)
+                       return EXT2_ET_SCAN_FINISHED;
+       }
+#endif
+
        return 0;
 }
 
index e79c853b20962d2b8058b39c510bc743e2bf83fb..22c2652c195abcb8ad11fc432c68116f6ba75379 100644 (file)
@@ -1269,6 +1269,11 @@ static struct e2fsck_problem problem_table[] = {
          N_("Encrypted @i %i has corrupt encryption @a.\n"),
          PROMPT_CLEAR_INODE, 0, 0, 0, 0 },
 
+       /* Failed to goto block group */
+       { PR_1_SCAN_GOTO,
+         N_("failed to goto block group"),
+          PROMPT_NONE, PR_FATAL, 0, 0, 0 },
+
        /* Pass 1b errors */
 
        /* Pass 1B: Rescan for duplicate/bad blocks */
index 4185e5175cabca25e897db66f258a20ee2bac233..e28adebbf93c530d990ca7b793647916602dc8b2 100644 (file)
@@ -707,6 +707,9 @@ struct problem_context {
 /* Encrypted inode has corrupt encryption extended attribute */
 #define PR_1_CORRUPT_ENCRYPTION_XATTR          0x01008B
 
+/* Failed to goto block group */
+#define PR_1_SCAN_GOTO                         0x0100A0
+
 /*
  * Pass 1b errors
  */
index 0c76fee6424862375e9c293c2f2c2c5972907b5a..cdb37423f666263e110d7c3ad6f58b5b825d86ba 100644 (file)
@@ -548,4 +548,7 @@ ec  EXT2_ET_EA_INODE_CORRUPTED,
 ec     EXT2_ET_NO_GDESC,
        "Group descriptors not loaded"
 
+ec     EXT2_ET_SCAN_FINISHED,
+       "Scanning finished"
+
        end