#include "lfsck_internal.h"
+#define LFSCK_CHECKPOINT_SKIP 1
+
/* define lfsck thread key */
LU_KEY_INIT(lfsck, struct lfsck_thread_info);
struct lfsck_thread_info *info = data;
lu_buf_free(&info->lti_linkea_buf);
+ lu_buf_free(&info->lti_linkea_buf2);
lu_buf_free(&info->lti_big_buf);
OBD_FREE_PTR(info);
}
"broadcast",
"orphan",
"create_ostobj",
+ "create_mdtobj",
NULL
};
if (likely(ltd != NULL)) {
LASSERT(list_empty(<d->ltd_layout_list));
LASSERT(list_empty(<d->ltd_layout_phase_list));
+ LASSERT(list_empty(<d->ltd_namespace_list));
+ LASSERT(list_empty(<d->ltd_namespace_phase_list));
ltds->ltd_tgtnr--;
cfs_bitmap_clear(ltds->ltd_tgts_bitmap, idx);
memset(policy, 0, sizeof(*policy));
policy->l_inodebits.bits = bits;
fid_build_reg_res_name(lfsck_dto2fid(obj), resid);
- rc = ldlm_cli_enqueue_local(lfsck->li_namespace, resid, LDLM_IBITS,
- policy, mode, &flags, ldlm_blocking_ast,
- ldlm_completion_ast, NULL, NULL, 0,
- LVB_T_NONE, NULL, lh);
+ if (dt_object_remote(obj)) {
+ struct ldlm_enqueue_info *einfo = &info->lti_einfo;
+
+ memset(einfo, 0, sizeof(*einfo));
+ einfo->ei_type = LDLM_IBITS;
+ einfo->ei_mode = mode;
+ einfo->ei_cb_bl = ldlm_blocking_ast;
+ einfo->ei_cb_cp = ldlm_completion_ast;
+ einfo->ei_res_id = resid;
+
+ rc = dt_object_lock(env, obj, lh, einfo, policy);
+ } else {
+ rc = ldlm_cli_enqueue_local(lfsck->li_namespace, resid,
+ LDLM_IBITS, policy, mode,
+ &flags, ldlm_blocking_ast,
+ ldlm_completion_ast, NULL, NULL,
+ 0, LVB_T_NONE, NULL, lh);
+ }
+
if (rc == ELDLM_OK) {
rc = 0;
} else {
}
}
-static const char dot[] = ".";
-static const char dotdot[] = "..";
+int lfsck_find_mdt_idx_by_fid(const struct lu_env *env,
+ struct lfsck_instance *lfsck,
+ const struct lu_fid *fid)
+{
+ struct seq_server_site *ss =
+ lu_site2seq(lfsck->li_bottom->dd_lu_dev.ld_site);
+ struct lu_seq_range *range = &lfsck_env_info(env)->lti_range;
+ int rc;
+
+ fld_range_set_mdt(range);
+ rc = fld_server_lookup(env, ss->ss_server_fld, fid_seq(fid), range);
+ if (rc == 0)
+ rc = range->lsr_index;
+
+ return rc;
+}
+
+const char dot[] = ".";
+const char dotdot[] = "..";
static const char dotlustre[] = ".lustre";
static const char lostfound[] = "lost+found";
ENTRY;
rc = linkea_data_new(&ldata,
- &lfsck_env_info(env)->lti_linkea_buf);
+ &lfsck_env_info(env)->lti_linkea_buf2);
if (rc != 0)
RETURN(rc);
ENTRY;
rc = linkea_data_new(&ldata,
- &lfsck_env_info(env)->lti_linkea_buf);
+ &lfsck_env_info(env)->lti_linkea_buf2);
if (rc != 0)
RETURN(rc);
break;
ent->lde_namelen = le16_to_cpu(ent->lde_namelen);
- if (ent->lde_name[0] == '.') {
- if (ent->lde_namelen == 1)
- goto next;
-
- if (ent->lde_namelen == 2 && ent->lde_name[1] == '.')
- goto next;
- }
+ if (name_is_dot_or_dotdot(ent->lde_name, ent->lde_namelen))
+ goto next;
/* name length must be strlen("MDTxxxx") */
if (ent->lde_namelen != 7)
snprintf(name, 8, "MDT%04x", node);
rc = dt_lookup(env, parent, (struct dt_rec *)cfid,
(const struct dt_key *)name, BYPASS_CAPA);
- if (rc == -ENOENT)
- goto check_child1;
+ if (rc == -ENOENT) {
+ if (!fid_is_zero(&bk->lb_lpf_fid))
+ goto check_child1;
+
+ GOTO(put, rc = 0);
+ }
if (rc != 0)
GOTO(put, rc);
struct ptlrpc_thread *thread = &lfsck->li_thread;
struct lfsck_component *com;
struct lfsck_component *next;
+ struct lfsck_lmv_unit *llu;
+ struct lfsck_lmv_unit *llu_next;
+ struct lfsck_lmv *llmv;
ENTRY;
LASSERT(list_empty(&lfsck->li_link));
}
LASSERT(lfsck->li_obj_dir == NULL);
+ LASSERT(lfsck->li_lmv == NULL);
+
+ list_for_each_entry_safe(llu, llu_next, &lfsck->li_list_lmv, llu_link) {
+ llmv = &llu->llu_lmv;
+
+ LASSERTF(atomic_read(&llmv->ll_ref) == 1,
+ "still in using: %u\n",
+ atomic_read(&llmv->ll_ref));
+
+ lfsck_lmv_put(env, llmv);
+ }
list_for_each_entry_safe(com, next, &lfsck->li_list_scan, lc_link) {
lfsck_component_cleanup(env, com);
bool dirty = false;
if (limit != LFSCK_SPEED_NO_LIMIT) {
- if (limit > HZ) {
- lfsck->li_sleep_rate = limit / HZ;
+ if (limit > msecs_to_jiffies(MSEC_PER_SEC)) {
+ lfsck->li_sleep_rate = limit /
+ msecs_to_jiffies(MSEC_PER_SEC);
lfsck->li_sleep_jif = 1;
} else {
lfsck->li_sleep_rate = 1;
- lfsck->li_sleep_jif = HZ / limit;
+ lfsck->li_sleep_jif = msecs_to_jiffies(MSEC_PER_SEC) /
+ limit;
}
} else {
lfsck->li_sleep_jif = 0;
}
}
-struct lfsck_thread_args *lfsck_thread_args_init(struct lfsck_instance *lfsck,
- struct lfsck_component *com,
- struct lfsck_start_param *lsp)
+static struct lfsck_thread_args *
+lfsck_thread_args_init(struct lfsck_instance *lfsck,
+ struct lfsck_component *com,
+ struct lfsck_start_param *lsp)
{
struct lfsck_thread_args *lta;
int rc;
OBD_FREE_PTR(lta);
}
+struct lfsck_assistant_data *
+lfsck_assistant_data_init(struct lfsck_assistant_operations *lao,
+ const char *name)
+{
+ struct lfsck_assistant_data *lad;
+
+ OBD_ALLOC_PTR(lad);
+ if (lad != NULL) {
+ lad->lad_bitmap = CFS_ALLOCATE_BITMAP(BITS_PER_LONG);
+ if (lad->lad_bitmap == NULL) {
+ OBD_FREE_PTR(lad);
+ return NULL;
+ }
+
+ INIT_LIST_HEAD(&lad->lad_req_list);
+ spin_lock_init(&lad->lad_lock);
+ INIT_LIST_HEAD(&lad->lad_ost_list);
+ INIT_LIST_HEAD(&lad->lad_ost_phase1_list);
+ INIT_LIST_HEAD(&lad->lad_ost_phase2_list);
+ INIT_LIST_HEAD(&lad->lad_mdt_list);
+ INIT_LIST_HEAD(&lad->lad_mdt_phase1_list);
+ INIT_LIST_HEAD(&lad->lad_mdt_phase2_list);
+ init_waitqueue_head(&lad->lad_thread.t_ctl_waitq);
+ lad->lad_ops = lao;
+ lad->lad_name = name;
+ }
+
+ return lad;
+}
+
+/**
+ * Generic LFSCK asynchronous communication interpretor function.
+ * The LFSCK RPC reply for both the event notification and status
+ * querying will be handled here.
+ *
+ * \param[in] env pointer to the thread context
+ * \param[in] req pointer to the LFSCK request
+ * \param[in] args pointer to the lfsck_async_interpret_args
+ * \param[in] rc the result for handling the LFSCK request
+ *
+ * \retval 0 for success
+ * \retval negative error number on failure
+ */
+int lfsck_async_interpret_common(const struct lu_env *env,
+ struct ptlrpc_request *req,
+ void *args, int rc)
+{
+ struct lfsck_async_interpret_args *laia = args;
+ struct lfsck_component *com = laia->laia_com;
+ struct lfsck_assistant_data *lad = com->lc_data;
+ struct lfsck_tgt_descs *ltds = laia->laia_ltds;
+ struct lfsck_tgt_desc *ltd = laia->laia_ltd;
+ struct lfsck_request *lr = laia->laia_lr;
+
+ LASSERT(com->lc_lfsck->li_master);
+
+ switch (lr->lr_event) {
+ case LE_START:
+ if (rc != 0) {
+ CDEBUG(D_LFSCK, "%s: fail to notify %s %x for %s "
+ "start: rc = %d\n",
+ lfsck_lfsck2name(com->lc_lfsck),
+ (lr->lr_flags & LEF_TO_OST) ? "OST" : "MDT",
+ ltd->ltd_index, lad->lad_name, rc);
+
+ if (com->lc_type == LFSCK_TYPE_LAYOUT) {
+ struct lfsck_layout *lo = com->lc_file_ram;
+
+ if (lr->lr_flags & LEF_TO_OST)
+ lfsck_lad_set_bitmap(env, com,
+ ltd->ltd_index);
+ else
+ lo->ll_flags |= LF_INCOMPLETE;
+ } else {
+ struct lfsck_namespace *ns = com->lc_file_ram;
+
+ /* If some MDT does not join the namespace
+ * LFSCK, then we cannot know whether there
+ * is some name entry on such MDT that with
+ * the referenced MDT-object on this MDT or
+ * not. So the namespace LFSCK on this MDT
+ * cannot handle orphan MDT-objects properly.
+ * So we mark the LFSCK as LF_INCOMPLETE and
+ * skip orphan MDT-objects handling. */
+ ns->ln_flags |= LF_INCOMPLETE;
+ }
+ break;
+ }
+
+ spin_lock(<ds->ltd_lock);
+ if (ltd->ltd_dead) {
+ spin_unlock(<ds->ltd_lock);
+ break;
+ }
+
+ if (com->lc_type == LFSCK_TYPE_LAYOUT) {
+ struct list_head *list;
+ struct list_head *phase_list;
+
+ if (ltd->ltd_layout_done) {
+ spin_unlock(<ds->ltd_lock);
+ break;
+ }
+
+ if (lr->lr_flags & LEF_TO_OST) {
+ list = &lad->lad_ost_list;
+ phase_list = &lad->lad_ost_phase1_list;
+ } else {
+ list = &lad->lad_mdt_list;
+ phase_list = &lad->lad_mdt_phase1_list;
+ }
+
+ if (list_empty(<d->ltd_layout_list))
+ list_add_tail(<d->ltd_layout_list, list);
+ if (list_empty(<d->ltd_layout_phase_list))
+ list_add_tail(<d->ltd_layout_phase_list,
+ phase_list);
+ } else {
+ if (ltd->ltd_namespace_done) {
+ spin_unlock(<ds->ltd_lock);
+ break;
+ }
+
+ if (list_empty(<d->ltd_namespace_list))
+ list_add_tail(<d->ltd_namespace_list,
+ &lad->lad_mdt_list);
+ if (list_empty(<d->ltd_namespace_phase_list))
+ list_add_tail(<d->ltd_namespace_phase_list,
+ &lad->lad_mdt_phase1_list);
+ }
+ spin_unlock(<ds->ltd_lock);
+ break;
+ case LE_STOP:
+ case LE_PHASE1_DONE:
+ case LE_PHASE2_DONE:
+ case LE_PEER_EXIT:
+ if (rc != 0 && rc != -EALREADY)
+ CDEBUG(D_LFSCK, "%s: fail to notify %s %x for %s: "
+ "event = %d, rc = %d\n",
+ lfsck_lfsck2name(com->lc_lfsck),
+ (lr->lr_flags & LEF_TO_OST) ? "OST" : "MDT",
+ ltd->ltd_index, lad->lad_name, lr->lr_event, rc);
+ break;
+ case LE_QUERY: {
+ struct lfsck_reply *reply;
+ struct list_head *list;
+ struct list_head *phase_list;
+
+ if (com->lc_type == LFSCK_TYPE_LAYOUT) {
+ list = <d->ltd_layout_list;
+ phase_list = <d->ltd_layout_phase_list;
+ } else {
+ list = <d->ltd_namespace_list;
+ phase_list = <d->ltd_namespace_phase_list;
+ }
+
+ if (rc != 0) {
+ spin_lock(<ds->ltd_lock);
+ list_del_init(phase_list);
+ list_del_init(list);
+ spin_unlock(<ds->ltd_lock);
+ break;
+ }
+
+ reply = req_capsule_server_get(&req->rq_pill,
+ &RMF_LFSCK_REPLY);
+ if (reply == NULL) {
+ rc = -EPROTO;
+ CDEBUG(D_LFSCK, "%s: invalid query reply for %s: "
+ "rc = %d\n", lfsck_lfsck2name(com->lc_lfsck),
+ lad->lad_name, rc);
+ spin_lock(<ds->ltd_lock);
+ list_del_init(phase_list);
+ list_del_init(list);
+ spin_unlock(<ds->ltd_lock);
+ break;
+ }
+
+ switch (reply->lr_status) {
+ case LS_SCANNING_PHASE1:
+ break;
+ case LS_SCANNING_PHASE2:
+ spin_lock(<ds->ltd_lock);
+ list_del_init(phase_list);
+ if (ltd->ltd_dead) {
+ spin_unlock(<ds->ltd_lock);
+ break;
+ }
+
+ if (com->lc_type == LFSCK_TYPE_LAYOUT) {
+ if (ltd->ltd_layout_done) {
+ spin_unlock(<ds->ltd_lock);
+ break;
+ }
+
+ if (lr->lr_flags & LEF_TO_OST)
+ list_add_tail(phase_list,
+ &lad->lad_ost_phase2_list);
+ else
+ list_add_tail(phase_list,
+ &lad->lad_mdt_phase2_list);
+ } else {
+ if (ltd->ltd_namespace_done) {
+ spin_unlock(<ds->ltd_lock);
+ break;
+ }
+
+ list_add_tail(phase_list,
+ &lad->lad_mdt_phase2_list);
+ }
+ spin_unlock(<ds->ltd_lock);
+ break;
+ default:
+ spin_lock(<ds->ltd_lock);
+ list_del_init(phase_list);
+ list_del_init(list);
+ spin_unlock(<ds->ltd_lock);
+ break;
+ }
+ break;
+ }
+ default:
+ CDEBUG(D_LFSCK, "%s: unexpected event: rc = %d\n",
+ lfsck_lfsck2name(com->lc_lfsck), lr->lr_event);
+ break;
+ }
+
+ if (!laia->laia_shared) {
+ lfsck_tgt_put(ltd);
+ lfsck_component_put(env, com);
+ }
+
+ return 0;
+}
+
static void lfsck_interpret(const struct lu_env *env,
struct lfsck_instance *lfsck,
struct ptlrpc_request *req, void *args, int result)
spin_lock(&lfsck->li_lock);
list_for_each_entry(com, &lfsck->li_list_scan, lc_link) {
- if (com->lc_ops->lfsck_interpret != NULL) {
- laia->laia_com = com;
- com->lc_ops->lfsck_interpret(env, req, laia, result);
- }
+ laia->laia_com = com;
+ lfsck_async_interpret_common(env, req, laia, result);
}
list_for_each_entry(com, &lfsck->li_list_double_scan, lc_link) {
- if (com->lc_ops->lfsck_interpret != NULL) {
- laia->laia_com = com;
- com->lc_ops->lfsck_interpret(env, req, laia, result);
- }
+ laia->laia_com = com;
+ lfsck_async_interpret_common(env, req, laia, result);
}
spin_unlock(&lfsck->li_lock);
}
struct lfsck_tgt_descs *ltds,
struct lfsck_tgt_desc *ltd, __u16 type)
{
- struct ptlrpc_request_set *set;
- struct lfsck_component *com;
- int rc = 0;
+ struct lfsck_component *com;
+ int rc = 0;
ENTRY;
+ LASSERT(lfsck->li_master);
+
spin_lock(&lfsck->li_lock);
com = __lfsck_component_find(lfsck, type, &lfsck->li_list_scan);
if (com == NULL)
spin_unlock(&lfsck->li_lock);
if (com != NULL) {
- if (com->lc_ops->lfsck_stop_notify != NULL) {
- set = ptlrpc_prep_set();
- if (set == NULL) {
- lfsck_component_put(env, com);
+ struct lfsck_thread_info *info = lfsck_env_info(env);
+ struct lfsck_async_interpret_args *laia = &info->lti_laia;
+ struct lfsck_request *lr = &info->lti_lr;
+ struct lfsck_assistant_data *lad = com->lc_data;
+ struct list_head *list;
+ struct list_head *phase_list;
+ struct ptlrpc_request_set *set;
+
+ set = ptlrpc_prep_set();
+ if (set == NULL) {
+ lfsck_component_put(env, com);
- RETURN(-ENOMEM);
- }
+ RETURN(-ENOMEM);
+ }
- rc = com->lc_ops->lfsck_stop_notify(env, com, ltds,
- ltd, set);
- if (rc == 0)
- rc = ptlrpc_set_wait(set);
+ if (type == LFSCK_TYPE_LAYOUT) {
+ list = <d->ltd_layout_list;
+ phase_list = <d->ltd_layout_phase_list;
+ } else {
+ list = <d->ltd_namespace_list;
+ phase_list = <d->ltd_namespace_phase_list;
+ }
+ spin_lock(<ds->ltd_lock);
+ if (list_empty(list)) {
+ LASSERT(list_empty(phase_list));
+ spin_unlock(<ds->ltd_lock);
ptlrpc_set_destroy(set);
+
+ RETURN(0);
+ }
+
+ list_del_init(phase_list);
+ list_del_init(list);
+ spin_unlock(<ds->ltd_lock);
+
+ memset(lr, 0, sizeof(*lr));
+ lr->lr_index = lfsck_dev_idx(lfsck->li_bottom);
+ lr->lr_event = LE_PEER_EXIT;
+ lr->lr_active = type;
+ lr->lr_status = LS_CO_PAUSED;
+ if (ltds == &lfsck->li_ost_descs)
+ lr->lr_flags = LEF_TO_OST;
+
+ laia->laia_com = com;
+ laia->laia_ltds = ltds;
+ atomic_inc(<d->ltd_ref);
+ laia->laia_ltd = ltd;
+ laia->laia_lr = lr;
+ laia->laia_shared = 0;
+
+ rc = lfsck_async_request(env, ltd->ltd_exp, lr, set,
+ lfsck_async_interpret_common,
+ laia, LFSCK_NOTIFY);
+ if (rc != 0) {
+ CDEBUG(D_LFSCK, "%s: fail to notify %s %x for "
+ "co-stop for %s: rc = %d\n",
+ lfsck_lfsck2name(lfsck),
+ (lr->lr_flags & LEF_TO_OST) ? "OST" : "MDT",
+ ltd->ltd_index, lad->lad_name, rc);
+ lfsck_tgt_put(ltd);
+ } else {
+ rc = ptlrpc_set_wait(set);
}
+ ptlrpc_set_destroy(set);
lfsck_component_put(env, com);
}
return 0;
}
+int lfsck_start_assistant(const struct lu_env *env, struct lfsck_component *com,
+ struct lfsck_start_param *lsp)
+{
+ struct lfsck_instance *lfsck = com->lc_lfsck;
+ struct lfsck_assistant_data *lad = com->lc_data;
+ struct ptlrpc_thread *mthread = &lfsck->li_thread;
+ struct ptlrpc_thread *athread = &lad->lad_thread;
+ struct lfsck_thread_args *lta;
+ struct task_struct *task;
+ int rc;
+ ENTRY;
+
+ lad->lad_assistant_status = 0;
+ lad->lad_post_result = 0;
+ lad->lad_to_post = 0;
+ lad->lad_to_double_scan = 0;
+ lad->lad_in_double_scan = 0;
+ lad->lad_exit = 0;
+ thread_set_flags(athread, 0);
+
+ lta = lfsck_thread_args_init(lfsck, com, lsp);
+ if (IS_ERR(lta))
+ RETURN(PTR_ERR(lta));
+
+ task = kthread_run(lfsck_assistant_engine, lta, lad->lad_name);
+ if (IS_ERR(task)) {
+ rc = PTR_ERR(task);
+ CERROR("%s: cannot start LFSCK assistant thread for %s: "
+ "rc = %d\n", lfsck_lfsck2name(lfsck), lad->lad_name, rc);
+ lfsck_thread_args_fini(lta);
+ } else {
+ struct l_wait_info lwi = { 0 };
+
+ l_wait_event(mthread->t_ctl_waitq,
+ thread_is_running(athread) ||
+ thread_is_stopped(athread),
+ &lwi);
+ if (unlikely(!thread_is_running(athread)))
+ rc = lad->lad_assistant_status;
+ else
+ rc = 0;
+ }
+
+ RETURN(rc);
+}
+
+int lfsck_checkpoint_generic(const struct lu_env *env,
+ struct lfsck_component *com)
+{
+ struct lfsck_assistant_data *lad = com->lc_data;
+ struct ptlrpc_thread *mthread = &com->lc_lfsck->li_thread;
+ struct ptlrpc_thread *athread = &lad->lad_thread;
+ struct l_wait_info lwi = { 0 };
+
+ if (com->lc_new_checked == 0)
+ return LFSCK_CHECKPOINT_SKIP;
+
+ l_wait_event(mthread->t_ctl_waitq,
+ list_empty(&lad->lad_req_list) ||
+ !thread_is_running(mthread) ||
+ thread_is_stopped(athread),
+ &lwi);
+
+ if (!thread_is_running(mthread) || thread_is_stopped(athread))
+ return LFSCK_CHECKPOINT_SKIP;
+
+ return 0;
+}
+
+void lfsck_post_generic(const struct lu_env *env,
+ struct lfsck_component *com, int *result)
+{
+ struct lfsck_assistant_data *lad = com->lc_data;
+ struct ptlrpc_thread *athread = &lad->lad_thread;
+ struct ptlrpc_thread *mthread = &com->lc_lfsck->li_thread;
+ struct l_wait_info lwi = { 0 };
+
+ lad->lad_post_result = *result;
+ if (*result <= 0)
+ lad->lad_exit = 1;
+ lad->lad_to_post = 1;
+
+ wake_up_all(&athread->t_ctl_waitq);
+ l_wait_event(mthread->t_ctl_waitq,
+ (*result > 0 && list_empty(&lad->lad_req_list)) ||
+ thread_is_stopped(athread),
+ &lwi);
+
+ if (lad->lad_assistant_status < 0)
+ *result = lad->lad_assistant_status;
+}
+
+int lfsck_double_scan_generic(const struct lu_env *env,
+ struct lfsck_component *com, int status)
+{
+ struct lfsck_assistant_data *lad = com->lc_data;
+ struct ptlrpc_thread *mthread = &com->lc_lfsck->li_thread;
+ struct ptlrpc_thread *athread = &lad->lad_thread;
+ struct l_wait_info lwi = { 0 };
+
+ if (status != LS_SCANNING_PHASE2)
+ lad->lad_exit = 1;
+ else
+ lad->lad_to_double_scan = 1;
+
+ wake_up_all(&athread->t_ctl_waitq);
+ l_wait_event(mthread->t_ctl_waitq,
+ lad->lad_in_double_scan ||
+ thread_is_stopped(athread),
+ &lwi);
+
+ if (lad->lad_assistant_status < 0)
+ return lad->lad_assistant_status;
+
+ return 0;
+}
+
+void lfsck_quit_generic(const struct lu_env *env,
+ struct lfsck_component *com)
+{
+ struct lfsck_assistant_data *lad = com->lc_data;
+ struct ptlrpc_thread *mthread = &com->lc_lfsck->li_thread;
+ struct ptlrpc_thread *athread = &lad->lad_thread;
+ struct l_wait_info lwi = { 0 };
+
+ lad->lad_exit = 1;
+ wake_up_all(&athread->t_ctl_waitq);
+ l_wait_event(mthread->t_ctl_waitq,
+ thread_is_init(athread) ||
+ thread_is_stopped(athread),
+ &lwi);
+}
+
/* external interfaces */
int lfsck_get_speed(struct seq_file *m, struct dt_device *key)
lr->lr_param = start->ls_flags;
lr->lr_async_windows = bk->lb_async_windows;
lr->lr_valid = LSV_SPEED_LIMIT | LSV_ERROR_HANDLE | LSV_DRYRUN |
- LSV_ASYNC_WINDOWS;
+ LSV_ASYNC_WINDOWS | LSV_CREATE_OSTOBJ |
+ LSV_CREATE_MDTOBJ;
laia->laia_com = NULL;
laia->laia_ltds = ltds;
laia->laia_ltd = ltd;
ltd->ltd_layout_done = 0;
+ ltd->ltd_namespace_done = 0;
rc = lfsck_async_request(env, ltd->ltd_exp, lr, set,
lfsck_async_interpret, laia,
LFSCK_NOTIFY);
}
trigger:
- lfsck->li_args_dir = LUDA_64BITHASH | LUDA_VERIFY;
+ lfsck->li_args_dir = LUDA_64BITHASH | LUDA_VERIFY | LUDA_TYPE;
if (bk->lb_param & LPF_DRYRUN)
lfsck->li_args_dir |= LUDA_VERIFY_DRYRUN;
EXPORT_SYMBOL(lfsck_stop);
int lfsck_in_notify(const struct lu_env *env, struct dt_device *key,
- struct lfsck_request *lr)
+ struct lfsck_request *lr, struct thandle *th)
{
int rc = -EOPNOTSUPP;
ENTRY;
case LE_FID_ACCESSED:
case LE_PEER_EXIT:
case LE_CONDITIONAL_DESTROY:
+ case LE_CREATE_ORPHAN:
+ case LE_SKIP_NLINK_DECLARE:
+ case LE_SKIP_NLINK:
+ case LE_SET_LMV_MASTER:
+ case LE_SET_LMV_SLAVE:
case LE_PAIRS_VERIFY: {
struct lfsck_instance *lfsck;
struct lfsck_component *com;
com = lfsck_component_find(lfsck, lr->lr_active);
if (likely(com != NULL)) {
- rc = com->lc_ops->lfsck_in_notify(env, com, lr);
+ rc = com->lc_ops->lfsck_in_notify(env, com, lr, th);
lfsck_component_put(env, com);
}
INIT_LIST_HEAD(&lfsck->li_list_dir);
INIT_LIST_HEAD(&lfsck->li_list_double_scan);
INIT_LIST_HEAD(&lfsck->li_list_idle);
+ INIT_LIST_HEAD(&lfsck->li_list_lmv);
atomic_set(&lfsck->li_ref, 1);
atomic_set(&lfsck->li_double_scan_count, 0);
init_waitqueue_head(&lfsck->li_thread.t_ctl_waitq);
INIT_LIST_HEAD(<d->ltd_orphan_list);
INIT_LIST_HEAD(<d->ltd_layout_list);
INIT_LIST_HEAD(<d->ltd_layout_phase_list);
+ INIT_LIST_HEAD(<d->ltd_namespace_list);
+ INIT_LIST_HEAD(<d->ltd_namespace_phase_list);
atomic_set(<d->ltd_ref, 1);
ltd->ltd_index = index;
spin_lock(<ds->ltd_lock);
ltd->ltd_dead = 1;
spin_unlock(<ds->ltd_lock);
+ lfsck_stop_notify(env, lfsck, ltds, ltd, LFSCK_TYPE_NAMESPACE);
lfsck_stop_notify(env, lfsck, ltds, ltd, LFSCK_TYPE_LAYOUT);
lfsck_tgt_put(ltd);
}