From 88ce0b26b755525169a2738ebc405ec7bab05662 Mon Sep 17 00:00:00 2001 From: Li Xi Date: Wed, 21 Aug 2019 21:58:31 +0800 Subject: [PATCH] e2fsck: add start/end group for thread 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. E2fsprogs-commit: f64ff7f53c6fb22c7e4bebe86749b1be31439424 Change-Id: I904bedcbd02bca591665943cff5f2d7a6fa50fbe Signed-off-by: Li Xi Signed-off-by: Wang Shilong Reviewed-by: Andreas Dilger Signed-off-by: Theodore Ts'o --- e2fsck/e2fsck.h | 23 +++++++++++++++++++-- e2fsck/logfile.c | 3 ++- e2fsck/pass1.c | 51 ++++++++++++++++++++++++++++++++++++++++------- e2fsck/problem.c | 4 ++++ e2fsck/problem.h | 2 ++ lib/ext2fs/ext2_err.et.in | 3 +++ 6 files changed, 76 insertions(+), 10 deletions(-) diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index b5ff196..09a854a 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -261,6 +261,22 @@ struct e2fsck_fc_replay_state { __u16 fc_super_state; }; +#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; @@ -345,8 +361,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 diff --git a/e2fsck/logfile.c b/e2fsck/logfile.c index 9f92185..60ab95f 100644 --- a/e2fsck/logfile.c +++ b/e2fsck/logfile.c @@ -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); } diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index efe03df..b19c713 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -1386,6 +1386,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)) @@ -1429,6 +1446,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) { @@ -2246,12 +2265,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); @@ -2288,9 +2309,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; @@ -2513,7 +2540,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")); @@ -2598,6 +2625,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; @@ -2609,6 +2637,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; } diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 757b5d5..5eb7afe 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -1279,6 +1279,10 @@ static struct e2fsck_problem problem_table[] = { N_("@h %i uses SipHash, but should not. "), PROMPT_CLEAR_HTREE, PR_PREEN_OK, 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 */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 24cdcf9..c09fbf9 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -716,6 +716,8 @@ struct problem_context { /* Htree directory uses SipHash but should not */ #define PR_1_HTREE_CANNOT_SIPHASH 0x01008E +/* Failed to goto block group */ +#define PR_1_SCAN_GOTO 0x0100A0 /* * Pass 1b errors diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in index cf0e00e..860b570 100644 --- a/lib/ext2fs/ext2_err.et.in +++ b/lib/ext2fs/ext2_err.et.in @@ -551,4 +551,7 @@ ec EXT2_ET_NO_GDESC, ec EXT2_FILSYS_CORRUPTED, "The internal ext2_filsys data structure appears to be corrupted" +ec EXT2_ET_SCAN_FINISHED, + "Scanning finished" + end -- 1.8.3.1