X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Fpass1.c;h=922de3dadb62e24d87e58e53aa7bfb4b34345d47;hb=7d6322473386e6b0f3586bb3d3ce6a97fb1bfb3c;hp=36b60db5ba77faf45b250533da48112deea00e7f;hpb=43e7ce0317e8f124c1fcd08740d44e053b07452f;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 36b60db..922de3d 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -2279,6 +2279,7 @@ static int e2fsck_pass1_merge_fs(ext2_filsys dest, ext2_filsys src) ext2fs_block_bitmap block_map; ext2_badblocks_list badblocks; ext2_dblist dblist; + int flags; dest_io = dest->io; dest_image_io = dest->image_io; @@ -2286,6 +2287,7 @@ static int e2fsck_pass1_merge_fs(ext2_filsys dest, ext2_filsys src) block_map = dest->block_map; badblocks = dest->badblocks; dblist = dest->dblist; + flags = dest->flags; memcpy(dest, src, sizeof(struct struct_ext2_filsys)); dest->io = dest_io; @@ -2297,6 +2299,9 @@ static int e2fsck_pass1_merge_fs(ext2_filsys dest, ext2_filsys src) dest->dblist = dblist; if (dest->dblist) dest->dblist->fs = dest; + dest->flags = src->flags | flags; + if (!(src->flags & EXT2_FLAG_VALID) || !(flags & EXT2_FLAG_VALID)) + ext2fs_unmark_valid(dest); if (src->icache) { ext2fs_free_inode_cache(src->icache); @@ -2441,6 +2446,22 @@ static void e2fsck_pass1_merge_dir_info(e2fsck_t global_ctx, e2fsck_t thread_ctx global_ctx->dir_info); } +static void e2fsck_pass1_merge_dx_dir(e2fsck_t global_ctx, e2fsck_t thread_ctx) +{ + if (thread_ctx->dx_dir_info == NULL) + return; + + if (global_ctx->dx_dir_info == NULL) { + global_ctx->dx_dir_info = thread_ctx->dx_dir_info; + global_ctx->dx_dir_info_size = thread_ctx->dx_dir_info_size; + global_ctx->dx_dir_info_count = thread_ctx->dx_dir_info_count; + thread_ctx->dx_dir_info = NULL; + return; + } + + e2fsck_merge_dx_dir(global_ctx, thread_ctx); +} + static inline errcode_t e2fsck_pass1_merge_icount(ext2_icount_t *dest_icount, ext2_icount_t *src_icount) @@ -2476,6 +2497,25 @@ static errcode_t e2fsck_pass1_merge_icounts(e2fsck_t global_ctx, e2fsck_t thread return ret; } +static errcode_t e2fsck_pass1_merge_dirs_to_hash(e2fsck_t global_ctx, + e2fsck_t thread_ctx) +{ + errcode_t retval = 0; + + if (!thread_ctx->dirs_to_hash) + return 0; + + if (!global_ctx->dirs_to_hash) + retval = ext2fs_badblocks_copy(thread_ctx->dirs_to_hash, + &global_ctx->dirs_to_hash); + else + retval = ext2fs_badblocks_merge(thread_ctx->dirs_to_hash, + global_ctx->dirs_to_hash); + + return retval; +} + + static int e2fsck_pass1_thread_join_one(e2fsck_t global_ctx, e2fsck_t thread_ctx) { errcode_t retval; @@ -2486,6 +2526,7 @@ static int e2fsck_pass1_thread_join_one(e2fsck_t global_ctx, e2fsck_t thread_ctx FILE *global_problem_logf = global_ctx->problem_logf; ext2fs_inode_bitmap inode_bad_map = global_ctx->inode_bad_map; struct dir_info_db *dir_info = global_ctx->dir_info; + struct dx_dir_info *dx_dir_info = global_ctx->dx_dir_info; ext2fs_inode_bitmap inode_used_map = global_ctx->inode_used_map; ext2fs_inode_bitmap inode_dir_map = global_ctx->inode_dir_map; ext2fs_inode_bitmap inode_bb_map = global_ctx->inode_bb_map; @@ -2498,6 +2539,26 @@ static int e2fsck_pass1_thread_join_one(e2fsck_t global_ctx, e2fsck_t thread_ctx ext2fs_block_bitmap inodes_to_rebuild = global_ctx->inodes_to_rebuild; ext2_icount_t inode_count = global_ctx->inode_count; ext2_icount_t inode_link_info = global_ctx->inode_link_info; + __u32 fs_directory_count = global_ctx->fs_directory_count; + __u32 fs_regular_count = global_ctx->fs_regular_count; + __u32 fs_blockdev_count = global_ctx->fs_blockdev_count; + __u32 fs_chardev_count = global_ctx->fs_chardev_count; + __u32 fs_links_count = global_ctx->fs_links_count; + __u32 fs_symlinks_count = global_ctx->fs_symlinks_count; + __u32 fs_fast_symlinks_count = global_ctx->fs_fast_symlinks_count; + __u32 fs_fifo_count = global_ctx->fs_fifo_count; + __u32 fs_total_count = global_ctx->fs_total_count; + __u32 fs_badblocks_count = global_ctx->fs_badblocks_count; + __u32 fs_sockets_count = global_ctx->fs_sockets_count; + __u32 fs_ind_count = global_ctx->fs_ind_count; + __u32 fs_dind_count = global_ctx->fs_dind_count; + __u32 fs_tind_count = global_ctx->fs_tind_count; + __u32 fs_fragmented = global_ctx->fs_fragmented; + __u32 fs_fragmented_dir = global_ctx->fs_fragmented_dir; + __u32 large_files = global_ctx->large_files; + ext2_ino_t dx_dir_info_size = global_ctx->dx_dir_info_size; + ext2_ino_t dx_dir_info_count = global_ctx->dx_dir_info_count; + ext2_u32_list dirs_to_hash = global_ctx->dirs_to_hash; #ifdef HAVE_SETJMP_H jmp_buf old_jmp; @@ -2522,8 +2583,29 @@ static int e2fsck_pass1_thread_join_one(e2fsck_t global_ctx, e2fsck_t thread_ctx global_ctx->block_metadata_map = block_metadata_map; global_ctx->dir_info = dir_info; e2fsck_pass1_merge_dir_info(global_ctx, thread_ctx); + global_ctx->dx_dir_info = dx_dir_info; + global_ctx->dx_dir_info_count = dx_dir_info_count; + global_ctx->dx_dir_info_size = dx_dir_info_size; + e2fsck_pass1_merge_dx_dir(global_ctx, thread_ctx); global_ctx->inode_count = inode_count; global_ctx->inode_link_info = inode_link_info; + global_ctx->fs_directory_count += fs_directory_count; + global_ctx->fs_regular_count += fs_regular_count; + global_ctx->fs_blockdev_count += fs_blockdev_count; + global_ctx->fs_chardev_count += fs_chardev_count; + global_ctx->fs_links_count += fs_links_count; + global_ctx->fs_symlinks_count += fs_symlinks_count; + global_ctx->fs_fast_symlinks_count += fs_fast_symlinks_count; + global_ctx->fs_fifo_count += fs_fifo_count; + global_ctx->fs_total_count += fs_total_count; + global_ctx->fs_badblocks_count += fs_badblocks_count; + global_ctx->fs_sockets_count += fs_sockets_count; + global_ctx->fs_ind_count += fs_ind_count; + global_ctx->fs_dind_count += fs_dind_count; + global_ctx->fs_tind_count += fs_tind_count; + global_ctx->fs_fragmented += fs_fragmented; + global_ctx->fs_fragmented_dir += fs_fragmented_dir; + global_ctx->large_files += large_files; /* Keep the global singal flags*/ global_ctx->flags |= (flags & E2F_FLAG_SIGNAL_MASK) | @@ -2546,6 +2628,14 @@ static int e2fsck_pass1_thread_join_one(e2fsck_t global_ctx, e2fsck_t thread_ctx return retval; } + global_ctx->dirs_to_hash = dirs_to_hash; + retval = e2fsck_pass1_merge_dirs_to_hash(global_ctx, thread_ctx); + if (retval) { + com_err(global_ctx->program_name, 0, + _("while merging dirs to hash\n")); + return retval; + } + retval = e2fsck_pass1_merge_bitmap(global_fs, &thread_ctx->inode_used_map, &global_ctx->inode_used_map); @@ -2632,6 +2722,8 @@ static int e2fsck_pass1_thread_join(e2fsck_t global_ctx, e2fsck_t thread_ctx) e2fsck_free_dir_info(thread_ctx); ext2fs_free_icount(thread_ctx->inode_count); ext2fs_free_icount(thread_ctx->inode_link_info); + if (thread_ctx->dirs_to_hash) + ext2fs_badblocks_list_free(thread_ctx->dirs_to_hash); ext2fs_free_mem(&thread_ctx); return retval; @@ -2675,6 +2767,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 /* @@ -2699,6 +2803,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; } @@ -2712,6 +2824,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) { @@ -2732,6 +2850,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) {