X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Flfsck%2Flfsck_lib.c;h=3eb3a02aa24ae6c68f8da0690064d114e5c12336;hb=refs%2Fchanges%2F65%2F7665%2F28;hp=d59a07a64bfcf4673c779a016ce167a3f9137bae;hpb=7f66fe7572a2a8ab6711146bdea67d04e6381b4b;p=fs%2Flustre-release.git diff --git a/lustre/lfsck/lfsck_lib.c b/lustre/lfsck/lfsck_lib.c index d59a07a..3eb3a02 100644 --- a/lustre/lfsck/lfsck_lib.c +++ b/lustre/lfsck/lfsck_lib.c @@ -90,6 +90,7 @@ const char *lfsck_param_names[] = { NULL, "failout", "dryrun", + "all_targets", NULL }; @@ -137,6 +138,7 @@ static void lfsck_tgt_descs_fini(struct lfsck_tgt_descs *ltds) ltd = LTD_TGT(ltds, idx); if (likely(ltd != NULL)) { LASSERT(list_empty(<d->ltd_layout_list)); + LASSERT(list_empty(<d->ltd_layout_phase_list)); ltds->ltd_tgtnr--; cfs_bitmap_clear(ltds->ltd_tgts_bitmap, idx); @@ -329,9 +331,6 @@ void lfsck_instance_cleanup(const struct lu_env *env, LASSERT(list_empty(&lfsck->li_link)); LASSERT(thread_is_init(thread) || thread_is_stopped(thread)); - lfsck_tgt_descs_fini(&lfsck->li_ost_descs); - lfsck_tgt_descs_fini(&lfsck->li_mdt_descs); - if (lfsck->li_obj_oit != NULL) { lu_object_put_nocache(env, &lfsck->li_obj_oit->do_lu); lfsck->li_obj_oit = NULL; @@ -362,6 +361,9 @@ void lfsck_instance_cleanup(const struct lu_env *env, lfsck_component_cleanup(env, com); } + lfsck_tgt_descs_fini(&lfsck->li_ost_descs); + lfsck_tgt_descs_fini(&lfsck->li_mdt_descs); + if (lfsck->li_bookmark_obj != NULL) { lu_object_put_nocache(env, &lfsck->li_bookmark_obj->do_lu); lfsck->li_bookmark_obj = NULL; @@ -680,7 +682,8 @@ static int lfsck_needs_scan_dir(const struct lu_env *env, } struct lfsck_thread_args *lfsck_thread_args_init(struct lfsck_instance *lfsck, - struct lfsck_component *com) + struct lfsck_component *com, + struct lfsck_start_param *lsp) { struct lfsck_thread_args *lta; int rc; @@ -699,6 +702,8 @@ struct lfsck_thread_args *lfsck_thread_args_init(struct lfsck_instance *lfsck, if (com != NULL) lta->lta_com = lfsck_component_get(com); + lta->lta_lsp = lsp; + return lta; } @@ -746,7 +751,8 @@ int lfsck_checkpoint(const struct lu_env *env, struct lfsck_instance *lfsck) return rc1 != 0 ? rc1 : rc; } -int lfsck_prep(const struct lu_env *env, struct lfsck_instance *lfsck) +int lfsck_prep(const struct lu_env *env, struct lfsck_instance *lfsck, + struct lfsck_start_param *lsp) { struct dt_object *obj = NULL; struct lfsck_component *com; @@ -767,7 +773,7 @@ int lfsck_prep(const struct lu_env *env, struct lfsck_instance *lfsck) if (lfsck->li_bookmark_ram.lb_param & LPF_DRYRUN) com->lc_journal = 0; - rc = com->lc_ops->lfsck_prep(env, com); + rc = com->lc_ops->lfsck_prep(env, com, lsp); if (rc != 0) GOTO(out, rc); @@ -981,7 +987,49 @@ int lfsck_double_scan(const struct lu_env *env, struct lfsck_instance *lfsck) atomic_read(&lfsck->li_double_scan_count) == 0, &lwi); - return (rc1 != 0 ? rc1 : rc); + return rc1 != 0 ? rc1 : rc; +} + +int lfsck_stop_notify(const struct lu_env *env, struct lfsck_instance *lfsck, + struct lfsck_tgt_descs *ltds, struct lfsck_tgt_desc *ltd) +{ + struct ptlrpc_request_set *set; + struct lfsck_component *com; + int cnt = 0; + int rc = 0; + int rc1 = 0; + + set = ptlrpc_prep_set(); + if (set == NULL) + return -ENOMEM; + + list_for_each_entry(com, &lfsck->li_list_scan, lc_link) { + if (com->lc_ops->lfsck_stop_notify != NULL) { + rc = com->lc_ops->lfsck_stop_notify(env, com, ltds, + ltd, set); + if (rc != 0) + rc1 = rc; + else + cnt++; + } + } + + list_for_each_entry(com, &lfsck->li_list_double_scan, lc_link) { + if (com->lc_ops->lfsck_stop_notify != NULL) { + rc = com->lc_ops->lfsck_stop_notify(env, com, ltds, + ltd, set); + if (rc != 0) + rc1 = rc; + else + cnt++; + } + } + + if (cnt > 0) + rc = ptlrpc_set_wait(set); + ptlrpc_set_destroy(set); + + return rc1 != 0 ? rc1 : rc; } void lfsck_quit(const struct lu_env *env, struct lfsck_instance *lfsck) @@ -1002,6 +1050,58 @@ void lfsck_quit(const struct lu_env *env, struct lfsck_instance *lfsck) } } +int lfsck_async_request(const struct lu_env *env, struct obd_export *exp, + struct lfsck_request *lr, + struct ptlrpc_request_set *set, + ptlrpc_interpterer_t interpreter, + void *args, int request) +{ + struct lfsck_async_interpret_args *laia; + struct ptlrpc_request *req; + struct lfsck_request *tmp; + struct req_format *format; + int rc; + + if (!(exp_connect_flags(exp) & OBD_CONNECT_LFSCK)) + return -EOPNOTSUPP; + + switch (request) { + case LFSCK_NOTIFY: + format = &RQF_LFSCK_NOTIFY; + break; + case LFSCK_QUERY: + format = &RQF_LFSCK_QUERY; + break; + default: + CERROR("%s: unknown async request: opc = %d\n", + exp->exp_obd->obd_name, request); + return -EINVAL; + } + + req = ptlrpc_request_alloc(class_exp2cliimp(exp), format); + if (req == NULL) + return -ENOMEM; + + rc = ptlrpc_request_pack(req, LUSTRE_OBD_VERSION, request); + if (rc != 0) { + ptlrpc_request_free(req); + + return rc; + } + + tmp = req_capsule_client_get(&req->rq_pill, &RMF_LFSCK_REQUEST); + *tmp = *lr; + ptlrpc_request_set_replen(req); + + laia = ptlrpc_req_async_args(req); + *laia = *(struct lfsck_async_interpret_args *)args; + lfsck_component_get(laia->laia_com); + req->rq_interpret_reply = interpreter; + ptlrpc_set_add_req(set, req); + + return 0; +} + /* external interfaces */ int lfsck_get_speed(struct dt_device *key, void *buf, int len) @@ -1189,20 +1289,27 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key, if (!thread_is_init(thread) && !thread_is_stopped(thread)) { rc = -EALREADY; while (start->ls_active != 0) { - if (type & start->ls_active) { + if (!(type & start->ls_active)) { + type <<= 1; + continue; + } + + com = __lfsck_component_find(lfsck, type, + &lfsck->li_list_scan); + if (com == NULL) com = __lfsck_component_find(lfsck, type, - &lfsck->li_list_scan); - if (com == NULL) - com = __lfsck_component_find(lfsck, - type, &lfsck->li_list_double_scan); - if (com == NULL) { - rc = -EBUSY; + if (com == NULL) { + rc = -EOPNOTSUPP; + break; + } + + if (com->lc_ops->lfsck_join != NULL) { + rc = com->lc_ops->lfsck_join( env, com, lsp); + if (rc != 0 && rc != -EALREADY) break; - } else { - start->ls_active &= ~type; - } } + start->ls_active &= ~type; type <<= 1; } spin_unlock(&lfsck->li_lock); @@ -1265,6 +1372,16 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key, } } + if (bk->lb_param & LPF_ALL_MDT && + !(start->ls_flags & LPF_ALL_MDT)) { + bk->lb_param &= ~LPF_ALL_MDT; + dirty = true; + } else if (!(bk->lb_param & LPF_ALL_MDT) && + start->ls_flags & LPF_ALL_MDT) { + bk->lb_param |= LPF_ALL_MDT; + dirty = true; + } + if (dirty) { rc = lfsck_bookmark_store(env, lfsck); if (rc != 0) @@ -1340,7 +1457,7 @@ trigger: lfsck->li_args_oit = (flags << DT_OTABLE_IT_FLAGS_SHIFT) | valid; thread_set_flags(thread, 0); - lta = lfsck_thread_args_init(lfsck, NULL); + lta = lfsck_thread_args_init(lfsck, NULL, lsp); if (IS_ERR(lta)) GOTO(out, rc = PTR_ERR(lta)); @@ -1388,10 +1505,13 @@ int lfsck_stop(const struct lu_env *env, struct dt_device *key, GOTO(out, rc = -EALREADY); } - if (stop != NULL) + if (stop != NULL) { lfsck->li_status = stop->ls_status; - else + lfsck->li_flags = stop->ls_flags; + } else { lfsck->li_status = LS_STOPPED; + lfsck->li_flags = 0; + } thread_set_flags(thread, SVC_STOPPING); spin_unlock(&lfsck->li_lock); @@ -1473,8 +1593,8 @@ int lfsck_query(const struct lu_env *env, struct dt_device *key, EXPORT_SYMBOL(lfsck_query); int lfsck_register(const struct lu_env *env, struct dt_device *key, - struct dt_device *next, lfsck_out_notify notify, - void *notify_data, bool master) + struct dt_device *next, struct obd_device *obd, + lfsck_out_notify notify, void *notify_data, bool master) { struct lfsck_instance *lfsck; struct dt_object *root = NULL; @@ -1505,6 +1625,7 @@ int lfsck_register(const struct lu_env *env, struct dt_device *key, lfsck->li_out_notify_data = notify_data; lfsck->li_next = next; lfsck->li_bottom = key; + lfsck->li_obd = obd; rc = lfsck_tgt_descs_init(&lfsck->li_ost_descs); if (rc != 0) @@ -1617,6 +1738,7 @@ int lfsck_add_target(const struct lu_env *env, struct dt_device *key, ltd->ltd_exp = exp; INIT_LIST_HEAD(<d->ltd_orphan_list); INIT_LIST_HEAD(<d->ltd_layout_list); + INIT_LIST_HEAD(<d->ltd_layout_phase_list); atomic_set(<d->ltd_ref, 1); ltd->ltd_index = index; @@ -1653,6 +1775,7 @@ void lfsck_del_target(const struct lu_env *env, struct dt_device *key, struct lfsck_tgt_desc *ltd; struct list_head *head; bool found = false; + bool stop = false; if (for_ost) head = &lfsck_ost_orphan_list; @@ -1692,11 +1815,19 @@ void lfsck_del_target(const struct lu_env *env, struct dt_device *key, goto unlock; found = true; + spin_lock(<ds->ltd_lock); + ltd->ltd_dead = 1; if (!list_empty(<d->ltd_layout_list)) { - spin_lock(<ds->ltd_lock); + list_del_init(<d->ltd_layout_phase_list); list_del_init(<d->ltd_layout_list); - spin_unlock(<ds->ltd_lock); + stop = true; + } else { + LASSERT(list_empty(<d->ltd_layout_phase_list)); } + spin_unlock(<ds->ltd_lock); + + if (stop && lfsck->li_master) + lfsck_stop_notify(env, lfsck, ltds, ltd); LASSERT(ltds->ltd_tgtnr > 0);