Whamcloud - gitweb
LU-3963 libcfs: convert llite/lmv/lod/lov cfs_atomic primitive
[fs/lustre-release.git] / lustre / lfsck / lfsck_namespace.c
index d1ba149..c80fb48 100644 (file)
@@ -752,7 +752,8 @@ static int lfsck_namespace_checkpoint(const struct lu_env *env,
 }
 
 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;
@@ -1055,10 +1056,10 @@ static int lfsck_namespace_post(const struct lu_env *env,
                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);
@@ -1347,9 +1348,11 @@ out:
        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    = &lta->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;
@@ -1372,7 +1375,7 @@ static int lfsck_namespace_double_scan(const struct lu_env *env,
 
        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);
@@ -1477,8 +1480,9 @@ put:
 
 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();
@@ -1493,27 +1497,69 @@ fini:
                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,
@@ -1524,6 +1570,8 @@ static struct lfsck_operations lfsck_namespace_ops = {
        .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,