+#ifdef HAVE_PTHREAD
+#define e2fsck_get_lock_context(ctx) \
+ e2fsck_t global_ctx = ctx->global_ctx; \
+ if (!global_ctx) \
+ global_ctx = ctx; \
+
+/**
+ * before we hold write lock, read lock should
+ * has been held.
+ */
+void e2fsck_pass1_fix_lock(e2fsck_t ctx)
+{
+ int err;
+
+ if (!ctx->fs_need_locking)
+ return;
+
+ e2fsck_get_lock_context(ctx);
+ err = pthread_rwlock_trywrlock(&global_ctx->fs_fix_rwlock);
+ assert(err != 0);
+ pthread_rwlock_unlock(&global_ctx->fs_fix_rwlock);
+ pthread_rwlock_wrlock(&global_ctx->fs_fix_rwlock);
+}
+
+void e2fsck_pass1_fix_unlock(e2fsck_t ctx)
+{
+ if (!ctx->fs_need_locking)
+ return;
+ e2fsck_get_lock_context(ctx);
+ /* unlock write lock */
+ pthread_rwlock_unlock(&global_ctx->fs_fix_rwlock);
+ /* get read lock again */
+ pthread_rwlock_rdlock(&global_ctx->fs_fix_rwlock);
+}
+
+void e2fsck_pass1_check_lock(e2fsck_t ctx)
+{
+ if (!ctx->fs_need_locking)
+ return;
+ e2fsck_get_lock_context(ctx);
+ pthread_rwlock_rdlock(&global_ctx->fs_fix_rwlock);
+}
+
+void e2fsck_pass1_check_unlock(e2fsck_t ctx)
+{
+ if (!ctx->fs_need_locking)
+ return;
+ e2fsck_get_lock_context(ctx);
+ pthread_rwlock_unlock(&global_ctx->fs_fix_rwlock);
+}
+
+void e2fsck_pass1_block_map_w_lock(e2fsck_t ctx)
+{
+ if (!ctx->fs_need_locking)
+ return;
+ e2fsck_get_lock_context(ctx);
+ pthread_rwlock_wrlock(&global_ctx->fs_block_map_rwlock);
+}
+
+void e2fsck_pass1_block_map_w_unlock(e2fsck_t ctx)
+{
+ if (!ctx->fs_need_locking)
+ return;
+ e2fsck_get_lock_context(ctx);
+ pthread_rwlock_unlock(&global_ctx->fs_block_map_rwlock);
+}
+
+void e2fsck_pass1_block_map_r_lock(e2fsck_t ctx)
+{
+ if (!ctx->fs_need_locking)
+ return;
+ e2fsck_get_lock_context(ctx);
+ pthread_rwlock_rdlock(&global_ctx->fs_block_map_rwlock);
+}
+
+void e2fsck_pass1_block_map_r_unlock(e2fsck_t ctx)
+{
+ if (!ctx->fs_need_locking)
+ return;
+ e2fsck_get_lock_context(ctx);
+ pthread_rwlock_unlock(&global_ctx->fs_block_map_rwlock);
+ }
+#else
+void e2fsck_pass1_fix_lock(e2fsck_t ctx)
+{
+
+}
+
+void e2fsck_pass1_fix_unlock(e2fsck_t ctx)
+{
+
+}
+void e2fsck_pass1_check_lock(e2fsck_t ctx)
+{
+
+}
+void e2fsck_pass1_check_unlock(e2fsck_t ctx)
+{
+
+}
+void e2fsck_pass1_block_map_w_lock(e2fsck_t ctx)
+{
+
+}
+
+void e2fsck_pass1_block_map_w_unlock(e2fsck_t ctx)
+{
+
+}
+
+void e2fsck_pass1_block_map_r_lock(e2fsck_t ctx)
+{
+
+}
+
+void e2fsck_pass1_block_map_r_unlock(e2fsck_t ctx)
+{
+
+}
+#endif
+