#define E2F_FLAG_TIME_INSANE 0x2000 /* Time is insane */
#define E2F_FLAG_PROBLEMS_FIXED 0x4000 /* At least one problem was fixed */
#define E2F_FLAG_ALLOC_OK 0x8000 /* Can we allocate blocks? */
+#define E2F_FLAG_DUP_BLOCK 0x20000 /* dup block found during pass1 */
#define E2F_RESET_FLAGS (E2F_FLAG_TIME_INSANE | E2F_FLAG_PROBLEMS_FIXED)
dgrp_t et_group_next;
/* Scanned inode number */
ext2_ino_t et_inode_number;
- char et_log_buf[2048];
int et_log_length;
+ char et_log_buf[2048];
};
#endif
ext2_refcount_t refcount;
ext2_refcount_t refcount_extra;
+ ext2_refcount_t refcount_orig;
/*
* Quota blocks and inodes to be charged for each ea block.
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
*/
/* Fast commit replay state */
struct e2fsck_fc_replay_state fc_replay_state;
+#ifdef HAVE_PTHREAD
+ /* 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 */
+ pthread_rwlock_t fs_fix_rwlock;
+ /* protect block_found_map, block_dup_map */
+ pthread_rwlock_t fs_block_map_rwlock;
+ struct e2fsck_thread_info *infos;
+#endif
};
#ifdef HAVE_PTHREAD
+#ifdef DEBUG_THREADS
+/*
+ * Enabling DEBUG_THREADS would cause the parallel
+ * fsck threads run sequentially.
+ */
+struct e2fsck_thread_debug {
+ pthread_mutex_t etd_mutex;
+ pthread_cond_t etd_cond;
+ int etd_finished_threads;
+};
+#endif
+
struct e2fsck_thread_info {
/* ID returned by pthread_create() */
pthread_t eti_thread_id;
int eti_started;
/* Context used for this thread */
e2fsck_t eti_thread_ctx;
+#ifdef DEBUG_THREADS
+ struct e2fsck_thread_debug *eti_debug;
+#endif
};
+
#endif
/* Data structures to evaluate whether an extent tree needs rebuilding. */
extern void e2fsck_pass1(e2fsck_t ctx);
extern void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
+extern void e2fsck_pass1_check_lock(e2fsck_t ctx);
+extern void e2fsck_pass1_check_unlock(e2fsck_t ctx);
extern void e2fsck_pass2(e2fsck_t ctx);
extern void e2fsck_pass3(e2fsck_t ctx);
extern void e2fsck_pass4(e2fsck_t ctx);
ext2_ino_t *parent);
extern int e2fsck_dir_info_get_dotdot(e2fsck_t ctx, ext2_ino_t ino,
ext2_ino_t *dotdot);
+extern void e2fsck_merge_dx_dir(e2fsck_t global_ctx, e2fsck_t thread_ctx);
/* dx_dirinfo.c */
extern void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino,
int check_init_orphan_file(e2fsck_t ctx);
/* util.c */
+#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);
const char *profile_name,
ext2fs_block_bitmap *ret);
unsigned long long get_memory_size(void);
+extern void e2fsck_pass1_fix_lock(e2fsck_t ctx);
+extern void e2fsck_pass1_fix_unlock(e2fsck_t ctx);
+extern void e2fsck_pass1_block_map_w_lock(e2fsck_t ctx);
+extern void e2fsck_pass1_block_map_w_unlock(e2fsck_t ctx);
+extern void e2fsck_pass1_block_map_r_lock(e2fsck_t ctx);
+extern void e2fsck_pass1_block_map_r_unlock(e2fsck_t ctx);
/* unix.c */
extern void e2fsck_clear_progbar(e2fsck_t ctx);