* GPL HEADER END
*/
/*
- * Copyright (c) 2013, 2015, Intel Corporation.
+ * Copyright (c) 2013, 2016, Intel Corporation.
*/
/*
* lustre/lfsck/lfsck_engine.c
struct lfsck_thread_info *info = lfsck_env_info(env);
struct lu_fid *fid = &info->lti_fid;
struct lu_seq_range *range = &info->lti_range;
+ struct lu_attr *la = &info->lti_la;
struct seq_server_site *ss = lfsck_dev_site(lfsck);
__u32 idx = lfsck_dev_idx(lfsck);
int depth = 0;
if (list_empty(&lfsck->li_list_dir) || !S_ISDIR(lfsck_object_type(obj)))
return 0;
+ *fid = *lfsck_dto2fid(obj);
+ rc = dt_attr_get(env, obj, la);
+ if (unlikely(rc || (la->la_valid & LA_FLAGS &&
+ la->la_flags & LUSTRE_ORPHAN_FL))) {
+ /* Orphan directory is empty, does not need scan. */
+ CDEBUG(D_INFO,
+ "%s: skip orphan dir "DFID", %llx/%x: rc = %d\n",
+ lfsck_lfsck2name(lfsck), PFID(fid),
+ la->la_valid, la->la_flags, rc);
+
+ return rc;
+ }
+
LASSERT(ss != NULL);
- *fid = *lfsck_dto2fid(obj);
while (1) {
/* Global /ROOT is visible. */
if (unlikely(lu_fid_eq(fid, &lfsck->li_global_root_fid)))
if (fid_is_norm(fid))
return 1;
+ /* Only true after "obj = NULL" set below */
if (obj == NULL) {
obj = lfsck_object_find_bottom(env, lfsck, fid);
if (IS_ERR(obj))
GOTO(out, rc = 0);
}
- dt_read_lock(env, obj, MOR_TGT_CHILD);
+ dt_read_lock(env, obj, DT_TGT_CHILD);
if (unlikely(lfsck_is_dead_obj(obj))) {
dt_read_unlock(env, obj);
LASSERT(lfsck->li_obj_dir == NULL);
LASSERT(lfsck->li_lmv == NULL);
- rc = lfsck_read_stripe_lmv(env, obj, lmv);
+ rc = lfsck_read_stripe_lmv(env, lfsck, obj, lmv);
if (rc == -ENODATA) {
lfsck->li_obj_dir = lfsck_object_get(obj);
GOTO(out, rc = PTR_ERR(di));
rc = iops->load(env, di, cookie);
- if (rc == 0 || (rc > 0 && cookie > 0))
+ if (rc == -ENODATA)
+ rc = 1;
+ else if (rc == 0 || (rc > 0 && cookie > 0))
rc = iops->next(env, di);
else if (rc > 0)
rc = 0;
int rc = 0;
int rc1 = 0;
- if (likely(cfs_time_beforeq(cfs_time_current(),
- lfsck->li_time_next_checkpoint)))
+ if (likely(ktime_get_seconds() <= lfsck->li_time_next_checkpoint))
return 0;
lfsck_pos_fill(env, lfsck, &lfsck->li_pos_checkpoint, false);
rc1 = rc;
}
- lfsck->li_time_last_checkpoint = cfs_time_current();
+ lfsck->li_time_last_checkpoint = ktime_get_seconds();
lfsck->li_time_next_checkpoint = lfsck->li_time_last_checkpoint +
- cfs_time_seconds(LFSCK_CHECKPOINT_INTERVAL);
+ LFSCK_CHECKPOINT_INTERVAL;
return rc1 != 0 ? rc1 : rc;
}
/* Init otable-based iterator. */
if (pos == NULL) {
rc = iops->load(env, lfsck->li_di_oit, 0);
- if (rc > 0) {
+ if (rc > 0 || unlikely(rc == -ENODATA)) {
lfsck->li_oit_over = 1;
rc = 0;
}
}
rc = iops->load(env, lfsck->li_di_oit, pos->lp_oit_cookie);
- if (rc < 0)
- GOTO(out, rc);
- else if (rc > 0)
+ if (rc > 0 || unlikely(rc == -ENODATA))
lfsck->li_oit_over = 1;
+ else if (rc < 0)
+ GOTO(out, rc);
if (!lfsck->li_master || fid_is_zero(&pos->lp_dir_parent))
GOTO(out, rc = 0);
break;
}
- lfsck->li_time_last_checkpoint = cfs_time_current();
+ lfsck->li_time_last_checkpoint = ktime_get_seconds();
lfsck->li_time_next_checkpoint = lfsck->li_time_last_checkpoint +
- cfs_time_seconds(LFSCK_CHECKPOINT_INTERVAL);
+ LFSCK_CHECKPOINT_INTERVAL;
return rc;
}
(__u32)com->lc_type, rc);
}
- lfsck->li_time_last_checkpoint = cfs_time_current();
+ lfsck->li_time_last_checkpoint = ktime_get_seconds();
lfsck->li_time_next_checkpoint = lfsck->li_time_last_checkpoint +
- cfs_time_seconds(LFSCK_CHECKPOINT_INTERVAL);
+ LFSCK_CHECKPOINT_INTERVAL;
/* Ignore some component post failure to make other can go ahead. */
return result;
{
struct lfsck_component *com;
struct lfsck_component *next;
- struct l_wait_info lwi = { 0 };
int rc = 0;
int rc1 = 0;
rc1 = rc;
}
- l_wait_event(lfsck->li_thread.t_ctl_waitq,
- atomic_read(&lfsck->li_double_scan_count) == 0,
- &lwi);
+ wait_event_idle(lfsck->li_thread.t_ctl_waitq,
+ atomic_read(&lfsck->li_double_scan_count) == 0);
if (lfsck->li_status != LS_PAUSED &&
lfsck->li_status != LS_CO_PAUSED) {
if (CFS_FAIL_TIMEOUT(OBD_FAIL_LFSCK_DELAY2, cfs_fail_val) &&
unlikely(!thread_is_running(thread))) {
CDEBUG(D_LFSCK, "%s: scan dir exit for engine stop, "
- "parent "DFID", cookie "LPX64"\n",
+ "parent "DFID", cookie %#llx\n",
lfsck_lfsck2name(lfsck),
PFID(lfsck_dto2fid(dir)), lfsck->li_cookie_dir);
if (rc != 0) {
CDEBUG(D_LFSCK, "%s: scan dir failed at rec(), "
- "parent "DFID", cookie "LPX64": rc = %d\n",
+ "parent "DFID", cookie %#llx: rc = %d\n",
lfsck_lfsck2name(lfsck),
PFID(lfsck_dto2fid(dir)),
lfsck->li_cookie_dir, rc);
lfsck_control_speed(lfsck);
if (unlikely(!thread_is_running(thread))) {
CDEBUG(D_LFSCK, "%s: scan dir exit for engine stop, "
- "parent "DFID", cookie "LPX64"\n",
+ "parent "DFID", cookie %#llx\n",
lfsck_lfsck2name(lfsck),
PFID(lfsck_dto2fid(dir)),
lfsck->li_cookie_dir);
}
rc = iops->next(env, di);
+ if (rc < 0)
+ CDEBUG(D_LFSCK, "%s dir engine fail to locate next "
+ "for the directory "DFID": rc = %d\n",
+ lfsck_lfsck2name(lfsck),
+ PFID(&lfsck->li_pos_current.lp_dir_parent), rc);
} while (rc == 0);
if (rc > 0 && !lfsck->li_oit_over)
if (CFS_FAIL_TIMEOUT(OBD_FAIL_LFSCK_DELAY1, cfs_fail_val) &&
unlikely(!thread_is_running(thread))) {
CDEBUG(D_LFSCK, "%s: OIT scan exit for engine stop, "
- "cookie "LPU64"\n",
+ "cookie %llu\n",
lfsck_lfsck2name(lfsck), iops->store(env, di));
RETURN(0);
target = lfsck_object_find_bottom(env, lfsck, fid);
if (IS_ERR(target)) {
CDEBUG(D_LFSCK, "%s: OIT scan failed at find target "
- DFID", cookie "LPU64": rc = %d\n",
+ DFID", cookie %llu: rc = %d\n",
lfsck_lfsck2name(lfsck), PFID(fid),
iops->store(env, di), rc);
lfsck_fail(env, lfsck, true);
lfsck->li_oit_over = 1;
else if (likely(rc == 0))
lfsck->li_current_oit_processed = 0;
+ else
+ CDEBUG(D_LFSCK, "%s oit engine fail to locate next at "
+ "%llu: rc = %d\n", lfsck_lfsck2name(lfsck),
+ iops->store(env, di), rc);
if (unlikely(!thread_is_running(thread))) {
CDEBUG(D_LFSCK, "%s: OIT scan exit for engine stop, "
- "cookie "LPU64"\n", lfsck_lfsck2name(lfsck),
+ "cookie %llu\n", lfsck_lfsck2name(lfsck),
iops->store(env, di));
RETURN(0);
}
struct dt_object *oit_obj = lfsck->li_obj_oit;
const struct dt_it_ops *oit_iops = &oit_obj->do_index_ops->dio_it;
struct dt_it *oit_di;
- struct l_wait_info lwi = { 0 };
int rc;
ENTRY;
+ spin_lock(&lfsck->li_lock);
+ lfsck->li_task = current;
+ spin_unlock(&lfsck->li_lock);
+
/* There will be some objects verification during the LFSCK start,
* such as the subsequent lfsck_verify_lpf(). Trigger low layer OI
* OI scrub before that to handle the potential inconsistence. */
GOTO(fini_oit, rc);
CDEBUG(D_LFSCK, "LFSCK entry: oit_flags = %#x, dir_flags = %#x, "
- "oit_cookie = "LPU64", dir_cookie = "LPX64", parent = "DFID
+ "oit_cookie = %llu, dir_cookie = %#llx, parent = "DFID
", pid = %d\n", lfsck->li_args_oit, lfsck->li_args_dir,
lfsck->li_pos_checkpoint.lp_oit_cookie,
lfsck->li_pos_checkpoint.lp_dir_cookie,
current_pid());
spin_lock(&lfsck->li_lock);
+ if (unlikely(!thread_is_starting(thread))) {
+ spin_unlock(&lfsck->li_lock);
+ GOTO(fini_oit, rc = 0);
+ }
+
thread_set_flags(thread, SVC_RUNNING);
spin_unlock(&lfsck->li_lock);
wake_up_all(&thread->t_ctl_waitq);
- l_wait_event(thread->t_ctl_waitq,
- lfsck->li_start_unplug ||
- !thread_is_running(thread),
- &lwi);
+ wait_event_idle(thread->t_ctl_waitq,
+ lfsck->li_start_unplug ||
+ !thread_is_running(thread));
if (!thread_is_running(thread))
GOTO(fini_oit, rc = 0);
lfsck_pos_fill(env, lfsck, &lfsck->li_pos_checkpoint, false);
CDEBUG(D_LFSCK, "LFSCK exit: oit_flags = %#x, dir_flags = %#x, "
- "oit_cookie = "LPU64", dir_cookie = "LPX64", parent = "DFID
+ "oit_cookie = %llu, dir_cookie = %#llx, parent = "DFID
", pid = %d, rc = %d\n", lfsck->li_args_oit, lfsck->li_args_dir,
lfsck->li_pos_checkpoint.lp_oit_cookie,
lfsck->li_pos_checkpoint.lp_dir_cookie,
fini_args:
spin_lock(&lfsck->li_lock);
thread_set_flags(thread, SVC_STOPPED);
+ lfsck->li_task = NULL;
spin_unlock(&lfsck->li_lock);
wake_up_all(&thread->t_ctl_waitq);
lfsck_thread_args_fini(lta);
memset(lr, 0, sizeof(*lr));
lr->lr_event = LE_QUERY;
lr->lr_active = com->lc_type;
+
+ memset(laia, 0, sizeof(*laia));
laia->laia_com = com;
laia->laia_lr = lr;
- laia->laia_shared = 0;
if (!list_empty(&lad->lad_mdt_phase1_list)) {
ltds = &lfsck->li_mdt_descs;
}
spin_unlock(<ds->ltd_lock);
- rc = ptlrpc_set_wait(set);
+ rc = ptlrpc_set_wait(env, set);
if (rc < 0) {
ptlrpc_set_destroy(set);
RETURN(rc);
lr->lr_index = lfsck_dev_idx(lfsck);
lr->lr_active = com->lc_type;
+
+ memset(laia, 0, sizeof(*laia));
laia->laia_com = com;
laia->laia_lr = lr;
- laia->laia_shared = 0;
switch (lr->lr_event) {
case LE_START:
LASSERT(ltd != NULL);
laia->laia_ltd = ltd;
- ltd->ltd_layout_done = 0;
- ltd->ltd_synced_failures = 0;
rc = lfsck_async_request(env, ltd->ltd_exp, lr, set,
lfsck_async_interpret_common,
laia, LFSCK_NOTIFY);
up_read(<ds->ltd_rw_sem);
/* Sync up */
- rc = ptlrpc_set_wait(set);
+ rc = ptlrpc_set_wait(env, set);
if (rc < 0) {
ptlrpc_set_destroy(set);
RETURN(rc);
}
spin_unlock(<ds->ltd_lock);
- rc = ptlrpc_set_wait(set);
+ rc = ptlrpc_set_wait(env, set);
if (rc < 0) {
ptlrpc_set_destroy(set);
RETURN(rc);
break;
}
- rc1 = ptlrpc_set_wait(set);
+ rc1 = ptlrpc_set_wait(env, set);
ptlrpc_set_destroy(set);
RETURN(rc != 0 ? rc : rc1);
}
spin_lock(&lad->lad_lock);
+ lad->lad_task = current;
thread_set_flags(athread, SVC_RUNNING);
spin_unlock(&lad->lad_lock);
wake_up_all(&mthread->t_ctl_waitq);
while (!list_empty(&lad->lad_req_list)) {
bool wakeup = false;
- if (unlikely(lad->lad_exit ||
+ if (unlikely(test_bit(LAD_EXIT, &lad->lad_flags) ||
!thread_is_running(mthread)))
- GOTO(cleanup1, rc = lad->lad_post_result);
+ GOTO(cleanup, rc = lad->lad_post_result);
lar = list_entry(lad->lad_req_list.next,
struct lfsck_assistant_req,
lao->la_req_fini(env, lar);
if (rc < 0 && bk->lb_param & LPF_FAILOUT)
- GOTO(cleanup1, rc);
+ GOTO(cleanup, rc);
}
l_wait_event(athread->t_ctl_waitq,
!lfsck_assistant_req_empty(lad) ||
- lad->lad_exit ||
- lad->lad_to_post ||
- lad->lad_to_double_scan,
+ test_bit(LAD_EXIT, &lad->lad_flags) ||
+ test_bit(LAD_TO_POST, &lad->lad_flags) ||
+ test_bit(LAD_TO_DOUBLE_SCAN, &lad->lad_flags),
&lwi);
- if (unlikely(lad->lad_exit))
- GOTO(cleanup1, rc = lad->lad_post_result);
+ if (unlikely(test_bit(LAD_EXIT, &lad->lad_flags)))
+ GOTO(cleanup, rc = lad->lad_post_result);
if (!list_empty(&lad->lad_req_list))
continue;
- if (lad->lad_to_post) {
+ if (test_bit(LAD_TO_POST, &lad->lad_flags)) {
CDEBUG(D_LFSCK, "%s: %s LFSCK assistant thread post\n",
lfsck_lfsck2name(lfsck), lad->lad_name);
- if (unlikely(lad->lad_exit))
- GOTO(cleanup1, rc = lad->lad_post_result);
+ if (unlikely(test_bit(LAD_EXIT, &lad->lad_flags)))
+ GOTO(cleanup, rc = lad->lad_post_result);
- lad->lad_to_post = 0;
+ clear_bit(LAD_TO_POST, &lad->lad_flags);
LASSERT(lad->lad_post_result > 0);
/* Wakeup the master engine to go ahead. */
lad->lad_name, rc);
}
- if (lad->lad_to_double_scan) {
- lad->lad_to_double_scan = 0;
+ if (test_bit(LAD_TO_DOUBLE_SCAN, &lad->lad_flags)) {
+ clear_bit(LAD_TO_DOUBLE_SCAN, &lad->lad_flags);
atomic_inc(&lfsck->li_double_scan_count);
- lad->lad_in_double_scan = 1;
+ set_bit(LAD_IN_DOUBLE_SCAN, &lad->lad_flags);
wake_up_all(&mthread->t_ctl_waitq);
com->lc_new_checked = 0;
com->lc_new_scanned = 0;
- com->lc_time_last_checkpoint = cfs_time_current();
+ com->lc_time_last_checkpoint = ktime_get_seconds();
com->lc_time_next_checkpoint =
com->lc_time_last_checkpoint +
- cfs_time_seconds(LFSCK_CHECKPOINT_INTERVAL);
+ LFSCK_CHECKPOINT_INTERVAL;
CDEBUG(D_LFSCK, "%s: LFSCK assistant sync before "
"the second-stage scaning\n",
lfsck_lfsck2name(lfsck), rc2);
if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_NO_DOUBLESCAN))
- GOTO(cleanup2, rc = 0);
+ GOTO(cleanup, rc = 0);
+
+ while (test_bit(LAD_IN_DOUBLE_SCAN, &lad->lad_flags)) {
+ int seconds = 30;
- while (lad->lad_in_double_scan) {
rc = lfsck_assistant_query_others(env, com);
if (lfsck_phase2_next_ready(lad))
goto p2_next;
if (rc < 0)
- GOTO(cleanup2, rc);
+ GOTO(cleanup, rc);
/* Pull LFSCK status on related targets once
* per 30 seconds if we are not notified. */
- lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(30),
- cfs_time_seconds(1),
- NULL, NULL);
- rc = l_wait_event(athread->t_ctl_waitq,
- lfsck_phase2_next_ready(lad) ||
- lad->lad_exit ||
- !thread_is_running(mthread),
- &lwi);
-
- if (unlikely(lad->lad_exit ||
- !thread_is_running(mthread)))
- GOTO(cleanup2, rc = 0);
-
- if (rc == -ETIMEDOUT)
+ while (seconds > 0 &&
+ wait_event_idle_timeout(
+ athread->t_ctl_waitq,
+ lfsck_phase2_next_ready(lad) ||
+ test_bit(LAD_EXIT,
+ &lad->lad_flags) ||
+ !thread_is_running(mthread),
+ cfs_time_seconds(1)) == 0)
+ seconds -= 1;
+
+ if (unlikely(
+ test_bit(LAD_EXIT, &lad->lad_flags) ||
+ !thread_is_running(mthread)))
+ GOTO(cleanup, rc = 0);
+
+ if (seconds == 0)
continue;
- if (rc < 0)
- GOTO(cleanup2, rc);
-
p2_next:
rc = lao->la_handler_p2(env, com);
if (rc != 0)
- GOTO(cleanup2, rc);
+ GOTO(cleanup, rc);
- if (unlikely(lad->lad_exit ||
- !thread_is_running(mthread)))
- GOTO(cleanup2, rc = 0);
+ if (unlikely(
+ test_bit(LAD_EXIT, &lad->lad_flags) ||
+ !thread_is_running(mthread)))
+ GOTO(cleanup, rc = 0);
}
}
}
-cleanup1:
+cleanup:
/* Cleanup the unfinished requests. */
spin_lock(&lad->lad_lock);
if (rc < 0)
lad->lad_assistant_status = rc;
- if (lad->lad_exit && lad->lad_post_result <= 0)
+ if (test_bit(LAD_EXIT, &lad->lad_flags) && lad->lad_post_result <= 0)
lao->la_fill_pos(env, com, &lfsck->li_pos_checkpoint);
+ thread_set_flags(athread, SVC_STOPPING);
while (!list_empty(&lad->lad_req_list)) {
lar = list_entry(lad->lad_req_list.next,
struct lfsck_assistant_req,
}
spin_unlock(&lad->lad_lock);
- LASSERTF(lad->lad_prefetched == 0, "unmatched prefeteched objs %d\n",
- lad->lad_prefetched);
-
-cleanup2:
memset(lr, 0, sizeof(*lr));
if (rc > 0) {
lr->lr_event = LE_PHASE2_DONE;
/* Under force exit case, some requests may be just freed without
* verification, those objects should be re-handled when next run.
* So not update the on-disk trace file under such case. */
- if (lad->lad_in_double_scan) {
- if (!lad->lad_exit)
+ if (test_bit(LAD_IN_DOUBLE_SCAN, &lad->lad_flags)) {
+ if (!test_bit(LAD_EXIT, &lad->lad_flags))
rc1 = lao->la_double_scan_result(env, com, rc);
CDEBUG(D_LFSCK, "%s: LFSCK assistant phase2 scan "
}
fini:
- if (lad->lad_in_double_scan)
+ if (test_bit(LAD_IN_DOUBLE_SCAN, &lad->lad_flags))
atomic_dec(&lfsck->li_double_scan_count);
spin_lock(&lad->lad_lock);
lad->lad_assistant_status = (rc1 != 0 ? rc1 : rc);
thread_set_flags(athread, SVC_STOPPED);
- wake_up_all(&mthread->t_ctl_waitq);
+ lad->lad_task = NULL;
spin_unlock(&lad->lad_lock);
CDEBUG(D_LFSCK, "%s: %s LFSCK assistant thread exit: rc = %d\n",
lad->lad_assistant_status);
lfsck_thread_args_fini(lta);
+ wake_up_all(&mthread->t_ctl_waitq);
return rc;
}