e2fsprogs: Parallel fsck support
RFC 61/72 tests: add pfsck test
In reply to Ritesh Harjani (IBM)From: Wang Shilong <[email protected]>
pfsck run on a clean fs should not return any errors.
Generate an image with possible features enabled,
especially EA shared blocks etc.
--- tests/f_multithread_ok/expect.1 | 7 +++++++ tests/f_multithread_ok/image.gz | Bin 0 -> 796311 bytes tests/f_multithread_ok/name | 1 + tests/f_multithread_ok/script | 21 +++++++++++++++++++++ 4 files changed, 29 insertions(+) create mode 100644 tests/f_multithread_ok/expect.1 create mode 100644 tests/f_multithread_ok/image.gz create mode 100644 tests/f_multithread_ok/name create mode 100644 tests/f_multithread_ok/script
tests/f_multithread_ok/expect.1 new file +7 -0
@@ -0,0 +1,7 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 10251/32768 files (0.0% non-contiguous), 2218/131072 blocks +Exit status is 0
tests/f_multithread_ok/image.gz new file binary +0 -0
tests/f_multithread_ok/name new file +1 -0
@@ -0,0 +1 @@ +multiple threads checking on clean fs
tests/f_multithread_ok/script new file +21 -0
@@ -0,0 +1,21 @@ +FSCK_OPT="-fym4" +SKIP_VERIFY="true" +ONE_PASS_ONLY="true" +SKIP_CLEANUP="true" + +. $cmd_dir/run_e2fsck + +grep -v Thread $OUT1 > $OUT1.tmp +cmp -s $EXP1 $OUT1.tmp +status1=$? +if [ "$status1" -eq 0 ]; then + echo "$test_name: $test_description: ok" + touch $test_name.ok +else + echo "$test_name: $test_description: failed" + diff $DIFF_OPTS $EXP1 $OUT1.tmp > $test_name.failed +fi + +unset IMAGE FSCK_OPT SECOND_FSCK_OPT OUT1 OUT2 EXP1 EXP2 +unset SKIP_VERIFY SKIP_CLEANUP SKIP_GUNZIP ONE_PASS_ONLY PREP_CMD +unset DESCRIPTION SKIP_UNLINK AFTER_CMD PASS_ZERO
Signature · 1 line
2.37.3
RFC 62/72 e2fsck: fix memory leaks with pfsck enabled
In reply to Ritesh Harjani (IBM)From: Wang Shilong <[email protected]>
valgrind detected two memory leaks:
1) quota context is not released after merging.
2) @refcount_orig should be released
--- e2fsck/e2fsck.c | 4 ++++ e2fsck/pass1.c | 1 + 2 files changed, 5 insertions(+)
e2fsck/e2fsck.c +4 -0
@@ -106,6 +106,10 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx)ea_refcount_free (ctx->refcount_extra); ctx->refcount_extra =0 ; } +if (ctx->refcount_orig) { +ea_refcount_free (ctx->refcount_orig); + ctx->refcount_orig =0 ; + }if (ctx->ea_block_quota_blocks) {ea_refcount_free (ctx->ea_block_quota_blocks); ctx->ea_block_quota_blocks =0 ;
e2fsck/pass1.c +1 -0
@@ -3039,6 +3039,7 @@ static int e2fsck_pass1_thread_join(e2fsck_t global_ctx, e2fsck_t thread_ctx) retval =e2fsck_pass1_merge_context (global_ctx, thread_ctx); +quota_release_context (&thread_ctx->qctx);/* * @block_metadata_map and @block_dup_map are * shared, so we don't free them.
Signature · 1 line
2.37.3
RFC 63/72 e2fsck: misc cleanups for pfsck
In reply to Ritesh Harjani (IBM)From: Andreas Dilger <[email protected]>
Add -m option description to e2fsck.8 man page.
Rename e2fsck_struct fs_num_threads to pfs_num_threads to avoid confusion with the ext2_filsys fs_num_threads field, and move thread_info to be together with the other HAVE_PTHREAD fields.
Move ext2_filsys fs_num_threads to fit into the __u16 "pad" field to avoid consuming one of the few remaining __u32 reserved fields.
Fix a few print format warnings.
--- e2fsck/e2fsck.8.in | 8 +++++++- e2fsck/e2fsck.h | 13 +++++-------- e2fsck/pass1.c | 20 +++++++++++--------- e2fsck/unix.c | 4 ++-- 4 files changed, 25 insertions(+), 20 deletions(-)
e2fsck/e2fsck.8.in +7 -1
@@ -8,7 +8,7 @@ e2fsck \- check a Linux ext2/ext3/ext4 file system .SH SYNOPSIS .B e2fsck [ -.B \-pacnyrdfkvtDFV +.B \-pacnyrdfkmvtDFV ] [ .B \-b
@@ -333,6 +333,12 @@ Set the bad blocks list to be the list of blocks specified by option, except the bad blocks list is cleared before the blocks listed in the file are added to the bad blocks list.) .TP +.B \-m " threads" +Run e2fsck with up to the specified number of +.IR threads . +The actual number of threads may be lower, if the filesystem does not +have enough block groups to effectively parallelize the workload. +.TP .B \-n Open the file system read-only, and assume an answer of `no' to all questions. Allows
e2fsck/e2fsck.h +5 -8
@@ -277,8 +277,8 @@ struct e2fsck_thread {dgrp_t et_group_next;/* Scanned inode number */ ext2_ino_t et_inode_number; -char et_log_buf[2048 ];char et_log_length; + char et_log_buf[2048]; };#endif
@@ -367,11 +367,6 @@ struct e2fsck_struct {ext2_ino_t stashed_ino;struct ext2_inode *stashed_inode; -/* 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 */
@@ -487,7 +482,9 @@ struct e2fsck_struct {char *undo_file;#ifdef HAVE_PTHREAD -__u32 fs_num_threads; +/* if @global_ctx is null, this field is unused */ +struct e2fsck_thread thread_info; +__u32 pfs_num_threads;__u32 mmp_update_thread;int fs_need_locking;/* serialize fix operation for multiple threads */
@@ -732,7 +729,7 @@ void check_resize_inode(e2fsck_t ctx);int check_init_orphan_file (e2fsck_t ctx);/* util.c */ -#define E2FSCK_MAX_THREADS (65536) +#define E2FSCK_MAX_THREADS (65535)extern void *e2fsck_allocate_memory (e2fsck_t ctx,unsigned long size,const char *description);extern int ask (e2fsck_t ctx,const char * string,int def);
e2fsck/pass1.c +11 -9
@@ -1265,7 +1265,7 @@ static void e2fsck_pass1_set_thread_num(e2fsck_t ctx) {unsigned flexbg_size =1 ;ext2_filsys fs = ctx->fs; -int num_threads = ctx->fs_num_threads; +int num_threads = ctx->pfs_num_threads;int max_threads;if (num_threads <1 ) {
@@ -1285,6 +1285,8 @@ static void e2fsck_pass1_set_thread_num(e2fsck_t ctx) max_threads = fs->group_desc_count / flexbg_size;if (max_threads ==0 ) max_threads =1 ; +if (max_threads >E2FSCK_MAX_THREADS ) + max_threads =E2FSCK_MAX_THREADS ;if (num_threads > max_threads) { fprintf(stderr, "Use max possible thread num: %d instead\n",
@@ -1292,7 +1294,7 @@ static void e2fsck_pass1_set_thread_num(e2fsck_t ctx) num_threads = max_threads; } out: - ctx->fs_num_threads = num_threads; + ctx->pfs_num_threads = num_threads; ctx->fs->fs_num_threads = num_threads; }#endif
@@ -1320,7 +1322,7 @@ static errcode_t e2fsck_pass1_prepare(e2fsck_t ctx)#ifdef HAVE_PTHREAD /* don't use more than 1/10 of memory for threads checking */ - readahead_kb =get_memory_size () / (10 * ctx->fs_num_threads); + readahead_kb =get_memory_size () / (10 * ctx->pfs_num_threads);/* maybe better disable RA if this is too small? */ if (ctx->readahead_kb > readahead_kb) ctx->readahead_kb = readahead_kb;
@@ -1378,7 +1380,7 @@ static errcode_t e2fsck_pass1_prepare(e2fsck_t ctx)#ifdef HAVE_PTHREAD pthread_rwlock_init (&ctx->fs_fix_rwlock,NULL );pthread_rwlock_init (&ctx->fs_block_map_rwlock,NULL ); -if (ctx->fs_num_threads >1 ) +if (ctx->pfs_num_threads >1 ) ctx->fs_need_locking =1 ;else ctx->fs_need_locking =0 ;
@@ -1659,7 +1661,7 @@ void e2fsck_pass1_run(e2fsck_t ctx)if (ctx->global_ctx) {if (ctx->options &E2F_OPT_DEBUG && ctx->options &E2F_OPT_MULTITHREAD ) -fprintf (stderr,"thread %d jumping to group %d\n" , +fprintf (stderr,"thread %d jumping to group %u\n" , ctx->thread_info.et_thread_index, ctx->thread_info.et_group_start); pctx.errcode = ext2fs_inode_scan_goto_blockgroup(scan,
@@ -3064,7 +3066,7 @@ static int e2fsck_pass1_threads_join(struct e2fsck_thread_info *infos,errcode_t ret =0 ;int i;struct e2fsck_thread_info *pinfo; -int num_threads = global_ctx->fs_num_threads; +int num_threads = global_ctx->pfs_num_threads;/* merge invalid bitmaps will recalculate it */ global_ctx->invalid_bitmaps =0 ;
@@ -3130,7 +3132,7 @@ static void *e2fsck_pass1_thread(void *arg) out:if (thread_ctx->options &E2F_OPT_MULTITHREAD )log_out (thread_ctx, -_ ("Scanned group range [%lu, %lu), inodes %lu\n" ), +_ ("Scanned group range [%u, %u), inodes %u\n" ), thread_ctx->thread_info.et_group_start, thread_ctx->thread_info.et_group_end, thread_ctx->thread_info.et_inode_number);
@@ -3156,7 +3158,7 @@ static int e2fsck_pass1_threads_start(struct e2fsck_thread_info **pinfo,int i;e2fsck_t thread_ctx;dgrp_t average_group; -int num_threads = global_ctx->fs_num_threads; +int num_threads = global_ctx->pfs_num_threads;#ifdef DEBUG_THREADS struct e2fsck_thread_debug thread_debug = {PTHREAD_MUTEX_INITIALIZER ,PTHREAD_COND_INITIALIZER ,0 };
@@ -3259,7 +3261,7 @@ void e2fsck_pass1(e2fsck_t ctx)if (retval)return ;#ifdef HAVE_PTHREAD -if (ctx->options &E2F_OPT_MULTITHREAD || ctx->fs_num_threads >1 ) +if (ctx->options &E2F_OPT_MULTITHREAD || ctx->pfs_num_threads >1 )e2fsck_pass1_multithread (ctx); else#endif
e2fsck/unix.c +2 -2
@@ -915,12 +915,12 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) _("Invalid multiple thread num.\n"));if (thread_num >E2FSCK_MAX_THREADS ) {fprintf (stderr, -_ ("threads %lu too large (max %lu)\n" ), +_ ("threads %lu too large (max %u)\n" ), thread_num,E2FSCK_MAX_THREADS );fatal_error (ctx,0 ); } ctx->options |=E2F_OPT_MULTITHREAD ; - ctx->fs_num_threads = thread_num; + ctx->pfs_num_threads = thread_num;break ;#endif case 'n' :
Signature · 1 line
2.37.3
RFC 64/72 e2fsck: propagate number of threads
In reply to Ritesh Harjani (IBM)From: Saranya Muruganandam <[email protected]>
Sometimes, such as in orphan_inode case, e2fsck_pass1 is called after reading the block bitmaps. This results in reading the block bitmap sequentially and multithreading only gets kicked in later. Fix the thread count earlier while setting up the file system.
--- e2fsck/unix.c | 3 +++ 1 file changed, 3 insertions(+)
e2fsck/unix.c +3 -0
@@ -1745,6 +1745,9 @@ failure: ctx->fs = fs; fs->now = ctx->now; +#ifdef HAVE_PTHREAD + fs->fs_num_threads = ctx->pfs_num_threads; +#endif sb = fs->super;if (sb->s_rev_level >E2FSCK_CURRENT_REV ) {
Signature · 1 line
2.37.3
RFC 65/72 e2fsck: Annotating fields in e2fsck_struct
In reply to Ritesh Harjani (IBM)From: Saranya Muruganandam <[email protected]>
Adding information on fields in e2fsck_struct
on how they are used when running parallel fsck.
--- e2fsck/e2fsck.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
e2fsck/e2fsck.h +14 -6
@@ -285,7 +285,7 @@ struct e2fsck_thread {struct e2fsck_struct {/* Global context to get the cancel flag */ e2fsck_t global_ctx; -ext2_filsys fs; +ext2_filsys fs;/* [fs_fix_rwlock] */ const char *program_name;char *filesystem_name;char *device_name;
@@ -294,7 +294,9 @@ struct e2fsck_struct {char *log_fn;FILE *problem_logf;char *problem_log_fn; -int flags;/* E2fsck internal flags */ +/* E2fsck internal flags. +* shared by different threads for pass1 [fs_fix_rwlock] */ +int flags;int options;unsigned blocksize;/* blocksize */ blk64_t use_superblock;/* sb requested by user */
@@ -314,6 +316,7 @@ struct e2fsck_struct {int (*progress)(e2fsck_t ctx,int pass,unsigned long cur,unsigned long max); +/* The following inode bitmaps are separately used in thread_ctx Pass1*/ ext2fs_inode_bitmap inode_used_map;/* Inodes which are in use */ ext2fs_inode_bitmap inode_bad_map;/* Inodes which are bad somehow */ ext2fs_inode_bitmap inode_dir_map;/* Inodes which are directories */
@@ -322,12 +325,14 @@ struct e2fsck_struct {ext2fs_inode_bitmap inode_reg_map;/* Inodes which are regular files*/ ext2fs_inode_bitmap inode_casefold_map;/* Inodes which are casefolded */ +/* Following 3 protected by [fs_block_map_rwlock] */ ext2fs_block_bitmap block_found_map;/* Blocks which are in use */ ext2fs_block_bitmap block_dup_map;/* Blks referenced more than once */ ext2fs_block_bitmap block_ea_map;/* Blocks which are used by EA's */ /* -* Inode count arrays +* Inode count arrays. +* Separately used in thread_ctx, pass1 */ ext2_icount_t inode_count;ext2_icount_t inode_link_info;
@@ -349,7 +354,8 @@ struct e2fsck_struct {/* * Array of flags indicating whether an inode bitmap, block -* bitmap, or inode table is invalid +* bitmap, or inode table is invalid. +* Separately used in thread_ctx, pass1 */ int *invalid_inode_bitmap_flag;int *invalid_block_bitmap_flag;
@@ -362,7 +368,8 @@ struct e2fsck_struct {char *block_buf;/* -* For pass1_check_directory and pass1_get_blocks +* For pass1_check_directory and pass1_get_blocks. +* Separately used in thread_ctx in pass1 */ ext2_ino_t stashed_ino;struct ext2_inode *stashed_inode;
@@ -421,6 +428,7 @@ struct e2fsck_struct {/* * How we display the progress update (for unix) +* shared by different threads for pass1 [fs_fix_rwlock] */ int progress_fd;int progress_pos;
@@ -429,7 +437,7 @@ struct e2fsck_struct {int interactive;/* Are we connected directly to a tty? */ char start_meta[2 ], stop_meta[2 ]; -/* File counts */ +/* File counts. Separately used in thread_ctx, pass1 */ __u32 fs_directory_count;__u32 fs_regular_count;__u32 fs_blockdev_count;
Signature · 1 line
2.37.3
RFC 66/72 e2fsck: merge casefolded dir lists after thread finish
In reply to Ritesh Harjani (IBM)From: Wang Shilong <[email protected]>
This is missed and should be done after threads finish.
Original commit:18538b27 ("LU-8465 e2fsck: merge encrypted dir lists after thread finish") Upstream is now using e2fsck_struct->casefolded_dirs instead of encrypted_dirs.
Only for the correctness of pfsck, we won't use casefolded feature on ldiskfs.
--- e2fsck/pass1.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
e2fsck/pass1.c +26 -0
@@ -2614,6 +2614,7 @@ static errcode_t e2fsck_pass1_thread_prepare(e2fsck_t global_ctx, e2fsck_t *thre }memcpy (thread_context, global_ctx,sizeof (struct e2fsck_struct )); thread_context->block_dup_map =NULL ; + thread_context->casefolded_dirs =NULL ; retval = e2fsck_allocate_block_bitmap(global_ctx->fs, _("in-use block map"), EXT2FS_BMAP64_RBTREE,
@@ -2905,6 +2906,24 @@ static errcode_t e2fsck_pass1_merge_ea_refcount(e2fsck_t global_ctx,return retval; } +static errcode_t e2fsck_pass1_merge_casefolded_dirs (e2fsck_t global_ctx, +e2fsck_t thread_ctx) +{ +errcode_t retval =0 ; + +if (!thread_ctx->casefolded_dirs) +return 0 ; + +if (!global_ctx->casefolded_dirs) + retval =ext2fs_badblocks_copy (thread_ctx->casefolded_dirs, + &global_ctx->casefolded_dirs); +else + retval =ext2fs_badblocks_merge (thread_ctx->casefolded_dirs, + global_ctx->casefolded_dirs); + +return retval; +} +static errcode_t e2fsck_pass1_merge_context (e2fsck_t global_ctx,e2fsck_t thread_ctx) {
@@ -2971,6 +2990,13 @@ static errcode_t e2fsck_pass1_merge_context(e2fsck_t global_ctx,if (retval)return retval; + retval =e2fsck_pass1_merge_casefolded_dirs (global_ctx, thread_ctx); +if (retval) { +com_err (global_ctx->program_name,0 , +_ ("while merging casefolded dirs\n" )); +return retval; + } +e2fsck_pass1_merge_invalid_bitmaps (global_ctx, thread_ctx); retval = e2fsck_pass1_merge_bitmap(global_fs,
Signature · 1 line
2.37.3
RFC 67/72 sec: support encrypted files handling in pfsck mode
In reply to Ritesh Harjani (IBM)From: Sebastien Buisson <[email protected]>
e2fsck needs to be improved in order to support encrypted files handling in parallel fsck mode. The e2fsck_merge_encrypted_info() function is added to merge encrypted inodes info collected from different threads in pass1, so that it can be used in pass2.
--- e2fsck/e2fsck.h | 2 + e2fsck/encrypted_files.c | 139 +++++++++++++++++++++++++++++++++++++++ e2fsck/pass1.c | 26 +++++++- 3 files changed, 164 insertions(+), 3 deletions(-)
e2fsck/e2fsck.h +2 -0
@@ -642,6 +642,8 @@ __u32 find_encryption_policy(e2fsck_t ctx, ext2_ino_t ino);void destroy_encryption_policy_map (e2fsck_t ctx);void destroy_encrypted_file_info (e2fsck_t ctx); +int e2fsck_merge_encrypted_info (e2fsck_t ctx,struct encrypted_file_info *src, +struct encrypted_file_info *dest);/* extents.c */ errcode_t e2fsck_rebuild_extents_later (e2fsck_t ctx,ext2_ino_t ino);
e2fsck/encrypted_files.c +139 -0
142 lines not on this page · raw message
e2fsck/pass1.c +23 -3
@@ -2411,9 +2411,6 @@ void e2fsck_pass1_run(e2fsck_t ctx) ctx->ea_block_quota_inodes =0 ; } -/* We don't need the encryption policy => ID map any more */ -destroy_encryption_policy_map (ctx); -if (ctx->flags &E2F_FLAG_RESTART ) {/* * Only the master copy of the superblock and block
@@ -2703,6 +2700,23 @@ static void e2fsck_pass1_merge_dx_dir(e2fsck_t global_ctx, e2fsck_t thread_ctx)e2fsck_merge_dx_dir (global_ctx, thread_ctx); } +static int e2fsck_pass1_merge_encrypted_info (e2fsck_t global_ctx, +e2fsck_t thread_ctx) +{ +if (thread_ctx->encrypted_files ==NULL ) +return 0 ; + +if (global_ctx->encrypted_files ==NULL ) { + global_ctx->encrypted_files = thread_ctx->encrypted_files; + thread_ctx->encrypted_files =NULL ; +return 0 ; + } + +return e2fsck_merge_encrypted_info (global_ctx, + thread_ctx->encrypted_files, + global_ctx->encrypted_files); +} +static inline errcode_t e2fsck_pass1_merge_icount (ext2_icount_t *dest_icount,ext2_icount_t *src_icount)
@@ -2963,6 +2977,12 @@ static errcode_t e2fsck_pass1_merge_context(e2fsck_t global_ctx,e2fsck_pass1_merge_dir_info (global_ctx, thread_ctx);e2fsck_pass1_merge_dx_dir (global_ctx, thread_ctx); + retval =e2fsck_pass1_merge_encrypted_info (global_ctx, thread_ctx); +if (retval) { +com_err (global_ctx->program_name,0 , +_ ("while merging encrypted info\n" )); +return retval; + } retval =ext2fs_merge_fs (&(thread_ctx->fs));if (retval) {
Signature · 1 line
2.37.3
Re: [RFCv1 67/72] sec: support encrypted files handling in pfsck mode
Quoted 2 lines · Ritesh Harjani (IBM)
sec: support encrypted files handling in pfsck mode
"sec:" => "e2fsck:".
Quoted 22 lines
e2fsck/encrypted_files.c +22
-0+/** +* Search policy matching @policy in @info->policies +* @ctx: e2fsck context +* @info: encrypted_file_info to look into +* @policy: the policy we are looking for +* @parent: (out) last known parent, useful to insert a new leaf +* in @info->policies +* +* Return: id of found policy on success, -1 if no matching policy found. +*/ +static inline int search_policy (e2fsck_t ctx,struct encrypted_file_info *info, +union fscrypt_policy policy, +struct rb_node **parent) +{ +struct rb_node *n = info->policies.rb_node; +struct policy_map_entry *entry; + +while (n) { +int res; + + *parent = n; + entry = ext2fs_rb_entry(n, struct policy_map_entry, node);
e2fsck/encrypted_files.c void destroy_encrypted_file_info(e2fsck_t ctx) · line 491
Quoted 10 lines
e2fsck/encrypted_files.c +10
-0+ res =cmp_fscrypt_policies (ctx, &policy, &entry->policy); +if (res <0 ) + n = n->rb_left; +else if (res >0 ) + n = n->rb_right; +else +return entry->policy_id; + } +return -1 ; +}
Can this rbtree search code be reused by get_encryption_policy_id()?
Also, please use the existing constant NO_ENCRYPTION_POLICY instead of -1.
e2fsck/encrypted_files.c void destroy_encrypted_file_info(e2fsck_t ctx) · line 504
Quoted 12 lines
e2fsck/encrypted_files.c +12
-0+/* +* Merge @src encrypted info into @dest +*/ +int e2fsck_merge_encrypted_info (e2fsck_t ctx,struct encrypted_file_info *src, +struct encrypted_file_info *dest) +{ +struct rb_root *src_policies = &src->policies; +__u32 *policy_trans; +int i, rc =0 ; + +if (dest->file_ranges[src->file_ranges_count -1 ].last_ino > + src->file_ranges[0 ].first_ino) {
There is an off-by-one error here. How about writing it like the following so that it looks like the check in append_ino_and_policy_id():
if (src->file_ranges[0].first_ino <=
dest->file_ranges[src->file_ranges_count - 1].last_ino) {e2fsck/encrypted_files.c void destroy_encrypted_file_info(e2fsck_t ctx) · line 514
Quoted 1 line
e2fsck/encrypted_files.c +1
-0+/* First, deal with the encryption policy => ID map.
My understanding is that e2fsprogs follows the kernel coding style, where block comments are formatted like the following:
/* * text */
e2fsck/encrypted_files.c void destroy_encrypted_file_info(e2fsck_t ctx) · line 516
Quoted 2 lines
e2fsck/encrypted_files.c +2
-0+* Compare encryption policies in src with policies already recorded +* in dest. It can be similar policies, but recorded with a different
"similar" => "the same"
e2fsck/encrypted_files.c void destroy_encrypted_file_info(e2fsck_t ctx) · line 531
Quoted 10 lines
e2fsck/encrypted_files.c +10
-0+while (!ext2fs_rb_empty_root (src_policies)) { +struct policy_map_entry *entry, *newentry; +struct rb_node *new, *parent =NULL ; +int existing_polid; + + entry =ext2fs_rb_entry (src_policies->rb_node, + struct policy_map_entry, node); + existing_polid =search_policy (ctx, dest, + entry->policy, &parent); +if (existing_polid >=0 ) {
existing_polid != NO_ENCRYPTION_POLICY
e2fsck/encrypted_files.c void destroy_encrypted_file_info(e2fsck_t ctx) · line 543
Quoted 12 lines
e2fsck/encrypted_files.c +12
-0+/* The policy in src is already recorded in dest, +* so just update its id. +*/ + policy_trans[entry->policy_id] = existing_polid; + }else { +/* The policy in src is new to dest, so insert it +* with the next available id (its original id could +* be already used in dest). +*/ + rc =ext2fs_get_mem (sizeof (*newentry), &newentry); +if (rc) + goto out_merge;
Use handle_nomem() for memory allocation failures?
e2fsck/encrypted_files.c void destroy_encrypted_file_info(e2fsck_t ctx) · line 549
Quoted 6 lines
e2fsck/encrypted_files.c +6
-0+ newentry->policy_id = dest->next_policy_id++; + newentry->policy = entry->policy; +ext2fs_rb_link_node (&newentry->node, parent, &new); +ext2fs_rb_insert_color (&newentry->node, + &dest->policies); + policy_trans[entry->policy_id] = newentry->policy_id;
This code also appears in get_encryption_policy_id(). Should it be refactored into a helper function?
Quoted 20 lines
e2fsck/encrypted_files.c +20
-0+/* Second, deal with the inode number => encryption policy ID map. */ +if (dest->file_ranges_capacity < + dest->file_ranges_count + src->file_ranges_count) { +/* dest->file_ranges is too short, increase its capacity. */ +size_t new_capacity = dest->file_ranges_count + + src->file_ranges_count; + +/* Make sure we at least double the capacity. */ +if (new_capacity < (dest->file_ranges_capacity *2 )) + new_capacity = dest->file_ranges_capacity *2 ; + +/* We won't need more than the filesystem's inode count. */ +if (new_capacity > ctx->fs->super->s_inodes_count) + new_capacity = ctx->fs->super->s_inodes_count; + + rc =ext2fs_resize_mem (dest->file_ranges_capacity * +sizeof (struct encrypted_file_range ), + new_capacity * +sizeof (struct encrypted_file_range ), + &dest->file_ranges);
e2fsck/encrypted_files.c void destroy_encrypted_file_info(e2fsck_t ctx) · line 584
Quoted 10 lines
e2fsck/encrypted_files.c +10
-0+if (rc) { +fix_problem (ctx,PR_1_ALLOCATE_ENCRYPTED_INODE_LIST , +NULL ); +/* Should never get here */ + ctx->flags |=E2F_FLAG_ABORT ; + goto out_merge; + } + + dest->file_ranges_capacity = new_capacity; + }
The exact allocation size that is needed is 'dest->file_ranges_count + src->file_ranges_count', so much of the above logic is unnecessary. Just reallocate that exact amount.
Also, handle_nomem() should be used.
e2fsck/encrypted_files.c void destroy_encrypted_file_info(e2fsck_t ctx) · line 592
Quoted 8 lines
e2fsck/encrypted_files.c +8
-0+/* Copy file ranges from src to dest. */ +for (i =0 ; i < src->file_ranges_count; i++) { +/* Make sure to convert policy ids in src. */ + src->file_ranges[i].policy_id = + policy_trans[src->file_ranges[i].policy_id]; + dest->file_ranges[dest->file_ranges_count++] = + src->file_ranges[i]; + }
This needs to handle UNRECOGNIZED_ENCRYPTION_POLICY as a special case.
Also, shouldn't src->file_ranges be freed after this?
Review
Quoted 2 lines
(quoted diff) +2
-0+ +out_merge:
I guess the "_merge" in "out_merge:" comes from the name of the containing function? It's a bit confusing. Maybe just use "out:".
e2fsck/pass1.c void e2fsck_pass1_run(e2fsck_t ctx) · line 2415
Quoted 10 lines
e2fsck/pass1.c +0
-2@@ -2411,9 +2411,6 @@ void e2fsck_pass1_run(e2fsck_t ctx) ctx->ea_block_quota_inodes =0 ; } -/* We don't need the encryption policy => ID map any more */ -destroy_encryption_policy_map (ctx);
With this change, there are no callers of destroy_encryption_policy_map() outside encrypted_files.c. So absent any other changes, destroy_encryption_policy_map() should be made into a static function and the 'if (info)' check inside it removed.
But, isn't there still some point where pass 1 is fully done and the encryption policy ID map can be destroyed? Maybe e2fsck_pass1_merge_encrypted_info() should be calling destroy_encryption_policy_map() on the global_ctx after doing the merge?
- Eric
RFC 68/72 e2fsck: Fix io->align assert check
In reply to Ritesh Harjani (IBM)dest->io->align might still get set later in case of non-aligned read done by any thread in raw_read_blk(). Hence remove this assert check.
--- e2fsck/pass1.c | 1 - 1 file changed, 1 deletion(-)
e2fsck/pass1.c +0 -1
@@ -2514,7 +2514,6 @@ static errcode_t e2fsck_open_channel_fs(ext2_filsys dest, e2fsck_t dest_context,assert (dest->io->flags == src->io->flags);assert (dest->io->app_data == dest);assert (src->io->app_data == src); -assert (dest->io->align == src->io->align); dest->priv_data = dest_context; dest_context->fs = dest;
Signature · 1 line
2.37.3
RFC 69/72 e2fsck: Fix double free of inodes_to_process
In reply to Ritesh Harjani (IBM)Found during code review, this fixes the double free of inodes_to_process in e2fsck_pass1_run.
--- e2fsck/pass1.c | 1 - 1 file changed, 1 deletion(-)
e2fsck/pass1.c +0 -1
@@ -2436,7 +2436,6 @@ void e2fsck_pass1_run(e2fsck_t ctx) } ctx->flags |=E2F_FLAG_ALLOC_OK ; -ext2fs_free_mem (&inodes_to_process); endit:e2fsck_use_inode_shortcuts (ctx,0 );ext2fs_free_mem (&inodes_to_process);
Signature · 1 line
2.37.3
RFC 70/72 e2fsck: Fix and simplify update_mmp in case of pfsck
In reply to Ritesh Harjani (IBM)This adds pass1_update_mmp_enter() & pass1_update_mmp_exit() routines to update mmp block. This also fixes a data race reported by threadsan because of reading and writing to mmp_update_thread variable.
--- e2fsck/pass1.c | 97 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 34 deletions(-)
e2fsck/pass1.c +63 -34
@@ -1097,6 +1097,66 @@ out:return 0 ; } +static void pass1_update_mmp_enter (e2fsck_t ctx,ext2_ino_t ino) +{ +ext2_filsys fs = ctx->fs; +e2fsck_t global_ctx = ctx->global_ctx ? ctx->global_ctx : ctx; +int check_mmp =0 ; +int set_mmp =0 ; + +#ifdef HAVE_PTHREAD +/* only one active thread could update mmp block. */ +e2fsck_pass1_block_map_r_lock (ctx); +if (!global_ctx->mmp_update_thread) + set_mmp =1 ; +if (global_ctx->mmp_update_thread == ctx->thread_info.et_thread_index +1 ) + check_mmp =1 ; +e2fsck_pass1_block_map_r_unlock (ctx); + +if (!check_mmp && !set_mmp) +return ; + +if (set_mmp) { +e2fsck_pass1_block_map_w_lock (ctx); +if (!global_ctx->mmp_update_thread) { + global_ctx->mmp_update_thread = + ctx->thread_info.et_thread_index +1 ; + check_mmp =1 ; + } +e2fsck_pass1_block_map_w_unlock (ctx); + } +#else + check_mmp =1 ; +#endif + +if (check_mmp && (ino % (fs->super->s_inodes_per_group *4 ) ==1 )) { +if (e2fsck_mmp_update (fs)) +fatal_error (ctx,0 ); + } +} + +static void pass1_update_mmp_exit (e2fsck_t ctx) +{ +ext2_filsys fs = ctx->fs; +e2fsck_t global_ctx = ctx->global_ctx ? ctx->global_ctx : ctx; +int set_mmp =0 ; + +#ifdef HAVE_PTHREAD +e2fsck_pass1_block_map_r_lock (ctx); +if (global_ctx->mmp_update_thread == ctx->thread_info.et_thread_index +1 ) + set_mmp =1 ; +e2fsck_pass1_block_map_r_unlock (ctx); + +if (!set_mmp) +return ; + +/* reset update_thread after this thread exit */ +e2fsck_pass1_block_map_w_lock (ctx); + global_ctx->mmp_update_thread =0 ; +e2fsck_pass1_block_map_w_unlock (ctx); +#endif +} +static void pass1_readahead (e2fsck_t ctx,dgrp_t *group,ext2_ino_t *next_ino) {ext2_ino_t inodes_in_group =0 , inodes_per_block, inodes_per_buffer;
@@ -1511,7 +1571,7 @@ void e2fsck_pass1_run(e2fsck_t ctx)dgrp_t ra_group =0 ;struct ea_quota ea_ibody_quota;struct process_inode_block *inodes_to_process; -int process_inode_count, check_mmp; +int process_inode_count;e2fsck_t global_ctx = ctx->global_ctx ? ctx->global_ctx : ctx;init_resource_track (&rtrack, ctx->fs->io);
@@ -1675,33 +1735,8 @@ void e2fsck_pass1_run(e2fsck_t ctx)#endif while (1 ) { - check_mmp =0 ;e2fsck_pass1_check_lock (ctx); -#ifdef HAVE_PTHREAD -if (!global_ctx->mmp_update_thread) { -e2fsck_pass1_block_map_w_lock (ctx); -if (!global_ctx->mmp_update_thread) { - global_ctx->mmp_update_thread = - ctx->thread_info.et_thread_index +1 ; - check_mmp =1 ; - } -e2fsck_pass1_block_map_w_unlock (ctx); - } - -/* only one active thread could update mmp block. */ -e2fsck_pass1_block_map_r_lock (ctx); -if (global_ctx->mmp_update_thread == - ctx->thread_info.et_thread_index +1 ) - check_mmp =1 ; -e2fsck_pass1_block_map_r_unlock (ctx); -#else - check_mmp =1 ; -#endif - -if (check_mmp && (ino % (fs->super->s_inodes_per_group *4 ) ==1 )) { -if (e2fsck_mmp_update (fs)) -fatal_error (ctx,0 ); - } +pass1_update_mmp_enter (ctx, ino); old_op =ehandler_operation (eop_next_inode); pctx.errcode =ext2fs_get_next_inode_full (scan, &ino, inode, inode_size);
@@ -2458,13 +2493,7 @@ endit:print_resource_track (ctx,_ ("Pass 1" ), &rtrack, ctx->fs->io); else ctx->invalid_bitmaps++; -#ifdef HAVE_PTHREAD -/* reset update_thread after this thread exit */ -e2fsck_pass1_block_map_w_lock (ctx); -if (check_mmp) - global_ctx->mmp_update_thread =0 ; -e2fsck_pass1_block_map_w_unlock (ctx); -#endif +pass1_update_mmp_exit (ctx); }#ifdef HAVE_PTHREAD
Signature · 1 line
2.37.3
RFC 71/72 e2fsck: Make threads call log_out after pthread_join
In reply to Ritesh Harjani (IBM)All fsck threads will call for log_out prints after the pass1 their respective pass1 scanning is completed. This patch moves the log_out print from to after the pthread_join operation.
This makes the threads always print the info in order.
--- e2fsck/pass1.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
e2fsck/pass1.c +6 -7
@@ -3112,6 +3112,12 @@ static int e2fsck_pass1_thread_join(e2fsck_t global_ctx, e2fsck_t thread_ctx) {errcode_t retval; +log_out (thread_ctx, +_ ("Scanned group range [%u, %u), inodes %u\n" ), + thread_ctx->thread_info.et_group_start, + thread_ctx->thread_info.et_group_end, + thread_ctx->thread_info.et_inode_number); + retval =e2fsck_pass1_merge_context (global_ctx, thread_ctx);quota_release_context (&thread_ctx->qctx);
@@ -3203,13 +3209,6 @@ static void *e2fsck_pass1_thread(void *arg)e2fsck_pass1_run (thread_ctx); out: -if (thread_ctx->options &E2F_OPT_MULTITHREAD ) -log_out (thread_ctx, -_ ("Scanned group range [%u, %u), inodes %u\n" ), - 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++;
Signature · 1 line
2.37.3
RFC 72/72 tests/f_multithread: Fix f_multithread related tests
In reply to Ritesh Harjani (IBM)With log_out() function now changed to print the message after the pthread join operation, it is safe to also add "Scan group range" related messages in expect files to compare against the pfsck output.
--- tests/f_multithread_ok/expect.1 | 8 ++++++++ tests/f_multithread_ok/script | 17 ----------------- 2 files changed, 8 insertions(+), 17 deletions(-)
tests/f_multithread_ok/expect.1 +8 -0
@@ -1,4 +1,12 @@ Pass 1: Checking inodes, blocks, and sizes +[Thread 0] Scan group range [0, 1) +[Thread 1] Scan group range [1, 2) +[Thread 2] Scan group range [2, 3) +[Thread 3] Scan group range [3, 4) +[Thread 0] Scanned group range [0, 1), inodes 8192 +[Thread 1] Scanned group range [1, 2), inodes 8192 +[Thread 2] Scanned group range [2, 3), inodes 8192 +[Thread 3] Scanned group range [3, 4), inodes 8192 Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts
tests/f_multithread_ok/script +0 -17
@@ -1,21 +1,4 @@ FSCK_OPT="-fym4" -SKIP_VERIFY="true" ONE_PASS_ONLY="true" -SKIP_CLEANUP="true" . $cmd_dir/run_e2fsck - -grep -v Thread $OUT1 > $OUT1.tmp -cmp -s $EXP1 $OUT1.tmp -status1=$? -if [ "$status1" -eq 0 ]; then - echo "$test_name: $test_description: ok" - touch $test_name.ok -else - echo "$test_name: $test_description: failed" - diff $DIFF_OPTS $EXP1 $OUT1.tmp > $test_name.failed -fi - -unset IMAGE FSCK_OPT SECOND_FSCK_OPT OUT1 OUT2 EXP1 EXP2 -unset SKIP_VERIFY SKIP_CLEANUP SKIP_GUNZIP ONE_PASS_ONLY PREP_CMD -unset DESCRIPTION SKIP_UNLINK AFTER_CMD PASS_ZERO
Signature · 1 line
2.37.3
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 39 lines · Andreas Dilger
On Nov 7, 2022, at 06:22, Ritesh Harjani (IBM) <[email protected]> wrote:
Hello,
This is a RFC patch series which has the list of all pfsck related changes which should also address the problem statements mentioned by Ted and Harshad here [1]
Below points will provide more details on how this patch series is laid out:-
1. This series is rebased on the latest e2fsprogs master branch.
2. Patch series is broken down into logical patches for easier review. The series contains libext2fs changes first, followed by e2fsck changes which utilizes libext2fs apis to add pfsck support to pass1.
3. Changes [0005] to [0012] addresses the problem statement laid out by Ted and Harshad [1] i.e. we now have a libext2fs API for clone and merge of
ext2_filsysstruct. (ext2fs_clone_fs()&ext2fs_merge_fs())4. These two changes [0016] & [0026] uses above clone/merge api for test and for use in e2fsck.
5. For a lot of libext2fs changes (for e.g. bitmap merging logic or clone/merge apis), there are some unit tests added for it's functionality verification.
Performance results:
=====================
1. On nvme with 22M 0-byte inodes: 7sec v/s 19sec
2. On nvme with 22M 4KB-32KB inodes: 17sec v/s 30sec
3. On nvme with 11M 32KB inodes: 9sec v/s 15sec
4. On RAID HDD setups: (will get back with perf results for this. Although, I had shared some numbers earlier, but I wanted to run pfsck with different FS layout and collect the numbers once again)
Quoted 2 lines
Ritesh,
Thanks for your work to update this patch series. I've been meaning to look at it, but
Thanks Andreas, I see you have already started reviewing. This is super helpful :)
Quoted 4 lines
have been traveling the past couple of weeks.
Have you done any performance comparisons against the original pfsck patch series?
Yes, I did, for the existing tests that I just mentioned above and found the perf numbers to be
similar. I am also planning to take a RAID device setup from an internal team and collect
some performance numbers there.
Quoted 5 lines
I did make a patch against our original series to improve the workload balance between threads, so that they are assigned a roughly equal number of inodes, instead of an equal number of block groups, since my testing showed the processing time of the threads
was proportional to the inode count. This avoids uneven thread completion and reduces overall processing time.
Yes, based on my testing so far. I too agree that to improve the workload balance one should assign an equal
number of inodes to different threads.
Quoted 5 lines
That patch is available in our Gerrit, and I can push it once this series lands, or it could be merged into the original patch that adds the
e2fsck_pass1_thread_prepare()code.
Sure, I will keep a note of this patch too in my performance runs.
So, now given the number of patches are quite large, I am hoping that we could review all libext2fs changes
for getting it in shape for merge. Then while we are at e2fsck change, we can definitely look at the above patch
too.
Thanks again!!
-ritesh
Quoted 224 lines
Cheers, Andreas.
For review: Since these are large number of changes. So if the overall series looks good, then we can start reviewing changes in batches. For e.g. if we could review initial changes in libext2fs (from [001] - [0020]), that would be a good start.
Patch-0073 adds support to all tests/* with "-m 2" mode to test pfsck as well. If pthread support is present, make check then test with "-m 2" fsck mode option as well (for tests which utilizes
run_e2fsckscript).
This was mainly done for verifying that all existing tests passes with pfsck. In this only few tests are kept disabled by passing SKIP_MT=true (Note: Last min. I have decided to drop this patch from sending. Although this can still be found in the github branch [2] for any testing)On Threadsan: I had tested this patch series against threadsan as well. It does lists few race conditions when running multi-threading (these doesn't looks to be any major problem). I have fixed a few [0070] and rest might either need some minor fixing or marking it false positive.
Here is the github link with all these commits (pfsck-RFCv1 branch) [2].
[1]: https://lore.kernel.org/linux-ext4/YMN10sXgoTR%[email protected]/
[2]: https://github.com/riteshharjani/e2fsprogs/commits/pfsck-RFCv1Andreas Dilger (2):
libext2fs: Misc fixes forstruct_ext2_filsys
e2fsck: misc cleanups for pfsckLi Xi (16):
dblist: add dblist merge logic
libext2fs: Add flush cleanup API
libext2fs: merge icounts after thread finishes
e2fsck: add -m option for multithread
e2fsck: copy context when using multi-thread fsck
e2fsck: create logs for multi-threads
e2fsck: configure one pfsck thread
e2fsck: Add asserts inopen_channel_fs
e2fsck: add start/end group for thread
e2fsck: split groups to different threads
e2fsck: print thread log properly
e2fsck: do not change global variables
e2fsck: optimize the inserting ofdir_info_db
e2fsck: mergedir_infoafter thread finishes
e2fsck: merge icounts after thread finishes
e2fsck: add debug codes for multiple threadsRitesh Harjani (IBM) (15):
e2fsck: Fix unbalanced mutex unlock forBOUNCE_MTX
gen_bitmaps: Fix ext2fs_compare_generic_bmap/bitmap logic
blkmap64_ba: Add common helper for bits size calculation
badblocks: Remove unusedbadblocks_flags
tst_badblocks: Add unit test to verify badblocks list merge api
tst_bitmaps_standalone: Add copy and merge bitmaps test
tst_bitmaps_pthread: Add merge bitmaps test using pthreads
tst_libext2fs_pthread: Add libext2fs merge/clone unit tests
e2fsck: Adde2fsck_pass1_thread_joinreturn value
e2fsck: Use merge/clone apis of libext2fs
e2fsck: Fixio->alignassert check
e2fsck: Fix double free ofinodes_to_process
e2fsck: Fix and simplifyupdate_mmpin case of pfsck
e2fsck: Make threads calllog_outafterpthread_jointests/f_multithread: Fixf_multithreadrelated testsSaranya Muruganandam (3):
libext2fs: dupfs: Add fs clone & merge api
e2fsck: propagate number of threads
e2fsck: Annotating fields ine2fsck_structSebastien Buisson (1):
sec: support encrypted files handling in pfsck modeWang Shilong (35):
badblocks: Add badblocks merge logic
libext2fs: Add rbtree bitmap merge logic
libext2fs: Add bitmaps merge ops
libext2fs: merge quota context after threads finish
libext2fs: Add support forext2fs_test_block_bitmap_range2_valid()
libext2fs: Add support to get average group count
libext2fs: avoid too much memory allocation in casefs_num_threads
e2fsck: Adde2fsck_pass1_merge_bitmap()api
e2fsck: rbtree bitmap for dir
e2fsck: merge counts after threads finish
e2fsck: mergedx_dir_infoafter threads finish
e2fsck: mergedirs_to_hashwhen threads finish
e2fsck: merge context flags properly
e2fsck: merge quota context after threads finish
e2fsck: serialize fix operations
e2fsck: move some fixes out of parallel pthreads
e2fsck: split and merge invalid bitmaps
e2fsck: merge EA blocks properly
e2fsck: kickoff mutex lock for block found map
e2fsck: allow admin specify number of threads
e2fsck: adjust number of threads
e2fsck: fix readahead for pfsck of pass1
e2fsck: merge options after threads finish
e2fsck: resetlost_and_foundafter threads finish
e2fsck: merge extent depth count after threads finish
e2fsck: simplify e2fsck context merging codes
e2fsck: setE2F_FLAG_ALLOC_OKafter threads
e2fsck: wait fix thread finish before checking
e2fsck: cleanupe2fsck_pass1_thread_join()
e2fsck: make default smallest RA size to 1M
e2fsck: update mmp block in one thread
e2fsck: reset @inodes_to_rebuild if restart
tests: add pfsck test
e2fsck: fix memory leaks with pfsck enabled
e2fsck: merge casefolded dir lists after thread finishe2fsck/dirinfo.c | 238 ++- e2fsck/dx_dirinfo.c | 64 + e2fsck/e2fsck.8.in | 8 +- e2fsck/e2fsck.c | 11 + e2fsck/e2fsck.h | 103 +- e2fsck/encrypted_files.c | 139 ++ e2fsck/logfile.c | 13 +- e2fsck/pass1.c | 1894 +++++++++++++++++++---- e2fsck/problem.c | 11 + e2fsck/problem.h | 3 + e2fsck/readahead.c | 4 + e2fsck/unix.c | 58 +- e2fsck/util.c | 193 ++- lib/ext2fs/Makefile.in | 53 +- lib/ext2fs/badblocks.c | 81 +- lib/ext2fs/bitmaps.c | 10 + lib/ext2fs/bitops.h | 2 + lib/ext2fs/blkmap64_ba.c | 20 +- lib/ext2fs/blkmap64_rb.c | 65 + lib/ext2fs/bmap64.h | 4 + lib/ext2fs/dblist.c | 38 + lib/ext2fs/dupfs.c | 183 +++ lib/ext2fs/ext2_err.et.in | 3 + lib/ext2fs/ext2_io.h | 2 + lib/ext2fs/ext2fs.h | 66 +- lib/ext2fs/ext2fsP.h | 1 - lib/ext2fs/gen_bitmap.c | 9 +- lib/ext2fs/gen_bitmap64.c | 72 +- lib/ext2fs/icount.c | 107 ++ lib/ext2fs/tst_badblocks.c | 61 +- lib/ext2fs/tst_bitmaps_pthread.c | 247 +++ lib/ext2fs/tst_bitmaps_standalone.c | 170 ++ lib/ext2fs/tst_libext2fs_pthread.c | 315 ++++ lib/ext2fs/undo_io.c | 19 + lib/ext2fs/unix_io.c | 25 +- lib/support/mkquota.c | 39 + lib/support/quotaio.h | 3 + tests/f_itable_collision/expect.1 | 3 - tests/f_multithread/expect.1 | 25 + tests/f_multithread/expect.2 | 7 + tests/f_multithread/image.gz | 1 + tests/f_multithread/name | 1 + tests/f_multithread/script | 4 + tests/f_multithread_completion/expect.1 | 2 + tests/f_multithread_completion/expect.2 | 23 + tests/f_multithread_completion/image.gz | 1 + tests/f_multithread_completion/name | 1 + tests/f_multithread_completion/script | 4 + tests/f_multithread_logfile/expect.1 | 25 + tests/f_multithread_logfile/image.gz | 1 + tests/f_multithread_logfile/name | 1 + tests/f_multithread_logfile/script | 32 + tests/f_multithread_no/expect.1 | 26 + tests/f_multithread_no/expect.2 | 23 + tests/f_multithread_no/image.gz | 1 + tests/f_multithread_no/name | 1 + tests/f_multithread_no/script | 4 + tests/f_multithread_ok/expect.1 | 15 + tests/f_multithread_ok/image.gz | Bin 0 -> 796311 bytes tests/f_multithread_ok/name | 1 + tests/f_multithread_ok/script | 4 + tests/f_multithread_preen/expect.1 | 11 + tests/f_multithread_preen/expect.2 | 23 + tests/f_multithread_preen/image.gz | 1 + tests/f_multithread_preen/name | 1 + tests/f_multithread_preen/script | 4 + tests/f_multithread_yes/expect.1 | 2 + tests/f_multithread_yes/expect.2 | 23 + tests/f_multithread_yes/image.gz | 1 + tests/f_multithread_yes/name | 1 + tests/f_multithread_yes/script | 4 + tests/test_one.in | 8 + 72 files changed, 4186 insertions(+), 433 deletions(-)create mode 100644
lib/ext2fs/tst_bitmaps_pthread.ccreate mode 100644lib/ext2fs/tst_bitmaps_standalone.ccreate mode 100644lib/ext2fs/tst_libext2fs_pthread.ccreate mode 100644 tests/f_multithread/expect.1 create mode 100644 tests/f_multithread/expect.2 create mode 120000 tests/f_multithread/image.gz create mode 100644 tests/f_multithread/name create mode 100644 tests/f_multithread/script create mode 100644 tests/f_multithread_completion/expect.1 create mode 100644 tests/f_multithread_completion/expect.2 create mode 120000 tests/f_multithread_completion/image.gz create mode 100644 tests/f_multithread_completion/name create mode 100644 tests/f_multithread_completion/script create mode 100644 tests/f_multithread_logfile/expect.1 create mode 120000 tests/f_multithread_logfile/image.gz create mode 100644 tests/f_multithread_logfile/name create mode 100644 tests/f_multithread_logfile/script create mode 100644 tests/f_multithread_no/expect.1 create mode 100644 tests/f_multithread_no/expect.2 create mode 120000 tests/f_multithread_no/image.gz create mode 100644 tests/f_multithread_no/name create mode 100644 tests/f_multithread_no/script create mode 100644 tests/f_multithread_ok/expect.1 create mode 100644 tests/f_multithread_ok/image.gz create mode 100644 tests/f_multithread_ok/name create mode 100644 tests/f_multithread_ok/script create mode 100644 tests/f_multithread_preen/expect.1 create mode 100644 tests/f_multithread_preen/expect.2 create mode 120000 tests/f_multithread_preen/image.gz create mode 100644 tests/f_multithread_preen/name create mode 100644 tests/f_multithread_preen/script create mode 100644 tests/f_multithread_yes/expect.1 create mode 100644 tests/f_multithread_yes/expect.2 create mode 120000 tests/f_multithread_yes/image.gz create mode 100644 tests/f_multithread_yes/name create mode 100644 tests/f_multithread_yes/script--
2.37.3