From: Li Xi Date: Fri, 30 Aug 2019 04:20:11 +0000 (+0800) Subject: LU-8465 e2fsck: do not change global variables X-Git-Tag: v1.45.6.wc2~47 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=1f6e8b81c2d964f54c6615ff775a3f6c3a9bbe1f;p=tools%2Fe2fsprogs.git LU-8465 e2fsck: do not change global variables Global variables used in pass1 check are changed to local variables in this patch. This will avoid conflict between threads. Change-Id: I7f8dea6281c8c7f19b0b8d4b3c8f211ab8aa6924 Signed-off-by: Li Xi Signed-off-by: Wang Shilong Reviewed-on: https://review.whamcloud.com/36001 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo --- diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index e9661d9..5859dfe 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -87,7 +87,6 @@ static void alloc_bb_map(e2fsck_t ctx); static void alloc_imagic_map(e2fsck_t ctx); static void add_encrypted_dir(e2fsck_t ctx, ino_t ino); static void handle_fs_bad_blocks(e2fsck_t ctx); -static void process_inodes(e2fsck_t ctx, char *block_buf); static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b); static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan, dgrp_t group, void * priv_data); @@ -122,30 +121,20 @@ struct process_inode_block { }; struct scan_callback_struct { - e2fsck_t ctx; - char *block_buf; + e2fsck_t ctx; + char *block_buf; + struct process_inode_block *inodes_to_process; + int *process_inode_count; }; -/* - * For the inodes to process list. - */ -static struct process_inode_block *inodes_to_process; -static int process_inode_count; +static void process_inodes(e2fsck_t ctx, char *block_buf, + struct process_inode_block *inodes_to_process, + int *process_inode_count); static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE + 1]; /* - * Free all memory allocated by pass1 in preparation for restarting - * things. - */ -static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused))) -{ - ext2fs_free_mem(&inodes_to_process); - inodes_to_process = 0; -} - -/* * Check to make sure a device inode is real. Returns 1 if the device * checks out, 0 if not. * @@ -1382,7 +1371,6 @@ static int e2fsck_should_abort(e2fsck_t ctx) void e2fsck_pass1_run(e2fsck_t ctx) { int i; - __u64 max_sizes; ext2_filsys fs = ctx->fs; ext2_ino_t ino = 0; struct ext2_inode *inode = NULL; @@ -1406,6 +1394,8 @@ void e2fsck_pass1_run(e2fsck_t ctx) dgrp_t ra_group = 0; struct ea_quota ea_ibody_quota; int inode_exp = 0; + struct process_inode_block *inodes_to_process; + int process_inode_count; init_resource_track(&rtrack, ctx->fs->io); clear_problem_context(&pctx); @@ -1430,17 +1420,6 @@ void e2fsck_pass1_run(e2fsck_t ctx) mtrace_print("Pass 1"); #endif -#define EXT2_BPP(bits) (1ULL << ((bits) - 2)) - - for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) { - max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i); - max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i); - max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i); - max_sizes = (max_sizes * (1UL << i)); - ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes; - } -#undef EXT2_BPP - imagic_fs = ext2fs_has_feature_imagic_inodes(sb); extent_fs = ext2fs_has_feature_extents(sb); inlinedata_fs = ext2fs_has_feature_inline_data(sb); @@ -1564,6 +1543,8 @@ void e2fsck_pass1_run(e2fsck_t ctx) ctx->stashed_inode = inode; scan_struct.ctx = ctx; scan_struct.block_buf = block_buf; + scan_struct.inodes_to_process = inodes_to_process; + scan_struct.process_inode_count = &process_inode_count; ext2fs_set_inode_callback(scan, scan_callback, &scan_struct); if (ctx->progress && ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))) @@ -2258,13 +2239,15 @@ void e2fsck_pass1_run(e2fsck_t ctx) goto endit; if (process_inode_count >= ctx->process_inode_size) { - process_inodes(ctx, block_buf); + process_inodes(ctx, block_buf, inodes_to_process, + &process_inode_count); if (e2fsck_should_abort(ctx)) goto endit; } } - process_inodes(ctx, block_buf); + process_inodes(ctx, block_buf, inodes_to_process, + &process_inode_count); ext2fs_close_inode_scan(scan); scan = NULL; @@ -2336,7 +2319,6 @@ void e2fsck_pass1_run(e2fsck_t ctx) * master superblock. */ ctx->use_superblock = 0; - unwind_pass1(fs); goto endit; } @@ -2371,6 +2353,27 @@ endit: ctx->invalid_bitmaps++; } +static void init_ext2_max_sizes() +{ + int i; + __u64 max_sizes; + + /* + * Init ext2_max_sizes which will be immutable and shared between + * threads + */ +#define EXT2_BPP(bits) (1ULL << ((bits) - 2)) + + for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) { + max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i); + max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i); + max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i); + max_sizes = (max_sizes * (1UL << i)); + ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes; + } +#undef EXT2_BPP +} + #ifdef CONFIG_PFSCK static errcode_t e2fsck_pass1_copy_bitmap(ext2_filsys fs, ext2fs_generic_bitmap *src, ext2fs_generic_bitmap *dest) @@ -2914,6 +2917,7 @@ out_abort: void e2fsck_pass1(e2fsck_t ctx) { + init_ext2_max_sizes(); #ifdef CONFIG_PFSCK e2fsck_pass1_multithread(ctx); #else @@ -2938,7 +2942,9 @@ static errcode_t scan_callback(ext2_filsys fs, scan_struct = (struct scan_callback_struct *) priv_data; ctx = scan_struct->ctx; - process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf); + process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf, + scan_struct->inodes_to_process, + scan_struct->process_inode_count); if (ctx->progress) if ((ctx->progress)(ctx, 1, group+1, @@ -2964,7 +2970,9 @@ static errcode_t scan_callback(ext2_filsys fs, /* * Process the inodes in the "inodes to process" list. */ -static void process_inodes(e2fsck_t ctx, char *block_buf) +static void process_inodes(e2fsck_t ctx, char *block_buf, + struct process_inode_block *inodes_to_process, + int *process_inode_count) { int i; struct ext2_inode *old_stashed_inode; @@ -2976,15 +2984,15 @@ static void process_inodes(e2fsck_t ctx, char *block_buf) #if 0 printf("begin process_inodes: "); #endif - if (process_inode_count == 0) + if (*process_inode_count == 0) return; old_operation = ehandler_operation(0); old_stashed_inode = ctx->stashed_inode; old_stashed_ino = ctx->stashed_ino; - qsort(inodes_to_process, process_inode_count, + qsort(inodes_to_process, *process_inode_count, sizeof(struct process_inode_block), process_inode_cmp); clear_problem_context(&pctx); - for (i=0; i < process_inode_count; i++) { + for (i=0; i < *process_inode_count; i++) { pctx.inode = ctx->stashed_inode = (struct ext2_inode *) &inodes_to_process[i].inode; pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino; @@ -3002,7 +3010,7 @@ static void process_inodes(e2fsck_t ctx, char *block_buf) } ctx->stashed_inode = old_stashed_inode; ctx->stashed_ino = old_stashed_ino; - process_inode_count = 0; + *process_inode_count = 0; #if 0 printf("end process inodes\n"); #endif