}
static int lfsck_namespace_prep(const struct lu_env *env,
- struct lfsck_component *com)
+ struct lfsck_component *com,
+ struct lfsck_start_param *lsp)
{
struct lfsck_instance *lfsck = com->lc_lfsck;
struct lfsck_namespace *ns = com->lc_file_ram;
cfs_list_del_init(&com->lc_link_dir);
cfs_list_add_tail(&com->lc_link, &lfsck->li_list_double_scan);
} else if (result == 0) {
- if (lfsck->li_paused) {
- ns->ln_status = LS_PAUSED;
- } else {
+ ns->ln_status = lfsck->li_status;
+ if (ns->ln_status == 0)
ns->ln_status = LS_STOPPED;
+ if (ns->ln_status != LS_PAUSED) {
cfs_list_del_init(&com->lc_link);
cfs_list_del_init(&com->lc_link_dir);
cfs_list_add_tail(&com->lc_link, &lfsck->li_list_idle);
return ret;
}
-static int lfsck_namespace_double_scan(const struct lu_env *env,
- struct lfsck_component *com)
+static int lfsck_namespace_double_scan_main(void *args)
{
+ struct lfsck_thread_args *lta = args;
+ const struct lu_env *env = <a->lta_env;
+ struct lfsck_component *com = lta->lta_com;
struct lfsck_instance *lfsck = com->lc_lfsck;
struct ptlrpc_thread *thread = &lfsck->li_thread;
struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram;
di = iops->init(env, obj, 0, BYPASS_CAPA);
if (IS_ERR(di))
- RETURN(PTR_ERR(di));
+ GOTO(out, rc = PTR_ERR(di));
fid_cpu_to_be(&fid, &ns->ln_fid_latest_scanned_phase2);
rc = iops->get(env, di, (const struct dt_key *)&fid);
fini:
iops->fini(env, di);
- down_write(&com->lc_sem);
+out:
+ down_write(&com->lc_sem);
ns->ln_run_time_phase2 += cfs_duration_sec(cfs_time_current() +
HALF_SEC - lfsck->li_time_last_checkpoint);
ns->ln_time_last_checkpoint = cfs_time_current_sec();
ns->ln_time_last_complete = ns->ln_time_last_checkpoint;
ns->ln_success_count++;
} else if (rc == 0) {
- if (lfsck->li_paused)
- ns->ln_status = LS_PAUSED;
- else
+ ns->ln_status = lfsck->li_status;
+ if (ns->ln_status == 0)
ns->ln_status = LS_STOPPED;
} else {
ns->ln_status = LS_FAILED;
}
- if (ns->ln_status != LS_PAUSED) {
- spin_lock(&lfsck->li_lock);
- cfs_list_del_init(&com->lc_link);
- cfs_list_add_tail(&com->lc_link, &lfsck->li_list_idle);
- spin_unlock(&lfsck->li_lock);
- }
-
rc = lfsck_namespace_store(env, com, false);
-
up_write(&com->lc_sem);
+ if (atomic_dec_and_test(&lfsck->li_double_scan_count))
+ wake_up_all(&thread->t_ctl_waitq);
+
+ lfsck_thread_args_fini(lta);
+
return rc;
}
+static int lfsck_namespace_double_scan(const struct lu_env *env,
+ struct lfsck_component *com)
+{
+ struct lfsck_instance *lfsck = com->lc_lfsck;
+ struct lfsck_namespace *ns = com->lc_file_ram;
+ struct lfsck_thread_args *lta;
+ long rc;
+ ENTRY;
+
+ if (unlikely(ns->ln_status != LS_SCANNING_PHASE2))
+ RETURN(0);
+
+ lta = lfsck_thread_args_init(lfsck, com, NULL);
+ if (IS_ERR(lta))
+ RETURN(PTR_ERR(lta));
+
+ atomic_inc(&lfsck->li_double_scan_count);
+ rc = PTR_ERR(kthread_run(lfsck_namespace_double_scan_main, lta,
+ "lfsck_namespace"));
+ if (IS_ERR_VALUE(rc)) {
+ CERROR("%s: cannot start LFSCK namespace thread: rc = %ld\n",
+ lfsck_lfsck2name(lfsck), rc);
+ atomic_dec(&lfsck->li_double_scan_count);
+ lfsck_thread_args_fini(lta);
+ } else {
+ rc = 0;
+ }
+
+ RETURN(rc);
+}
+
+static int lfsck_namespace_in_notify(const struct lu_env *env,
+ struct lfsck_component *com,
+ struct lfsck_request *lr)
+{
+ return 0;
+}
+
+static int lfsck_namespace_query(const struct lu_env *env,
+ struct lfsck_component *com)
+{
+ struct lfsck_namespace *ns = com->lc_file_ram;
+
+ return ns->ln_status;
+}
+
static struct lfsck_operations lfsck_namespace_ops = {
.lfsck_reset = lfsck_namespace_reset,
.lfsck_fail = lfsck_namespace_fail,
.lfsck_post = lfsck_namespace_post,
.lfsck_dump = lfsck_namespace_dump,
.lfsck_double_scan = lfsck_namespace_double_scan,
+ .lfsck_in_notify = lfsck_namespace_in_notify,
+ .lfsck_query = lfsck_namespace_query,
};
int lfsck_namespace_setup(const struct lu_env *env,