- switch (lr->lr_event) {
- case LE_START:
- if (rc != 0) {
- struct lfsck_layout *lo = com->lc_file_ram;
-
- CERROR("%s: fail to notify %s %x for layout start: "
- "rc = %d\n", lfsck_lfsck2name(com->lc_lfsck),
- (lr->lr_flags & LEF_TO_OST) ? "OST" : "MDT",
- ltd->ltd_index, rc);
- lo->ll_flags |= LF_INCOMPLETE;
- break;
- }
-
- spin_lock(<ds->ltd_lock);
- if (ltd->ltd_dead || ltd->ltd_layout_done) {
- spin_unlock(<ds->ltd_lock);
- break;
- }
-
- if (lr->lr_flags & LEF_TO_OST) {
- if (list_empty(<d->ltd_layout_list))
- list_add_tail(<d->ltd_layout_list,
- &llmd->llmd_ost_list);
- if (list_empty(<d->ltd_layout_phase_list))
- list_add_tail(<d->ltd_layout_phase_list,
- &llmd->llmd_ost_phase1_list);
- } else {
- if (list_empty(<d->ltd_layout_list))
- list_add_tail(<d->ltd_layout_list,
- &llmd->llmd_mdt_list);
- if (list_empty(<d->ltd_layout_phase_list))
- list_add_tail(<d->ltd_layout_phase_list,
- &llmd->llmd_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)
- CWARN("%s: fail to notify %s %x for layout: "
- "event = %d, rc = %d\n",
- lfsck_lfsck2name(com->lc_lfsck),
- (lr->lr_flags & LEF_TO_OST) ? "OST" : "MDT",
- ltd->ltd_index, lr->lr_event, rc);
- break;
- case LE_QUERY: {
- struct lfsck_reply *reply;
-
- if (rc != 0) {
- 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);
- break;
- }
-
- reply = req_capsule_server_get(&req->rq_pill,
- &RMF_LFSCK_REPLY);
- if (reply == NULL) {
- rc = -EPROTO;
- CERROR("%s: invalid return value: rc = %d\n",
- lfsck_lfsck2name(com->lc_lfsck), rc);
- 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);
- break;
- }
-
- switch (reply->lr_status) {
- case LS_SCANNING_PHASE1:
- break;
- case LS_SCANNING_PHASE2:
- spin_lock(<ds->ltd_lock);
- list_del_init(<d->ltd_layout_phase_list);
- if (ltd->ltd_dead || ltd->ltd_layout_done) {
- spin_unlock(<ds->ltd_lock);
- break;
- }
-
- if (lr->lr_flags & LEF_TO_OST)
- list_add_tail(<d->ltd_layout_phase_list,
- &llmd->llmd_ost_phase2_list);
- else
- list_add_tail(<d->ltd_layout_phase_list,
- &llmd->llmd_mdt_phase2_list);
- spin_unlock(<ds->ltd_lock);
- break;
- default:
- 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);
- break;
- }
- break;
- }
- default:
- CERROR("%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 int lfsck_layout_master_query_others(const struct lu_env *env,
- struct lfsck_component *com)
-{
- struct lfsck_thread_info *info = lfsck_env_info(env);
- struct lfsck_request *lr = &info->lti_lr;
- struct lfsck_async_interpret_args *laia = &info->lti_laia;
- struct lfsck_instance *lfsck = com->lc_lfsck;
- struct lfsck_layout_master_data *llmd = com->lc_data;
- struct ptlrpc_request_set *set;
- struct lfsck_tgt_descs *ltds;
- struct lfsck_tgt_desc *ltd;
- struct list_head *head;
- int rc = 0;
- int rc1 = 0;
- ENTRY;
-
- set = ptlrpc_prep_set();
- if (set == NULL)
- RETURN(-ENOMEM);
-
- llmd->llmd_touch_gen++;
- memset(lr, 0, sizeof(*lr));
- lr->lr_index = lfsck_dev_idx(lfsck->li_bottom);
- lr->lr_event = LE_QUERY;
- lr->lr_active = LT_LAYOUT;
- laia->laia_com = com;
- laia->laia_lr = lr;
- laia->laia_shared = 0;
-
- if (!list_empty(&llmd->llmd_mdt_phase1_list)) {
- ltds = &lfsck->li_mdt_descs;
- lr->lr_flags = 0;
- head = &llmd->llmd_mdt_phase1_list;
- } else {
-
-again:
- ltds = &lfsck->li_ost_descs;
- lr->lr_flags = LEF_TO_OST;
- head = &llmd->llmd_ost_phase1_list;
- }
-
- laia->laia_ltds = ltds;
- spin_lock(<ds->ltd_lock);
- while (!list_empty(head)) {
- ltd = list_entry(head->next,
- struct lfsck_tgt_desc,
- ltd_layout_phase_list);
- if (ltd->ltd_layout_gen == llmd->llmd_touch_gen)
- break;
-
- ltd->ltd_layout_gen = llmd->llmd_touch_gen;
- list_del(<d->ltd_layout_phase_list);
- list_add_tail(<d->ltd_layout_phase_list, head);
- atomic_inc(<d->ltd_ref);
- laia->laia_ltd = ltd;
- spin_unlock(<ds->ltd_lock);
- rc = lfsck_async_request(env, ltd->ltd_exp, lr, set,
- lfsck_layout_master_async_interpret,
- laia, LFSCK_QUERY);
- if (rc != 0) {
- CERROR("%s: fail to query %s %x for layout: rc = %d\n",
- lfsck_lfsck2name(lfsck),
- (lr->lr_flags & LEF_TO_OST) ? "OST" : "MDT",
- ltd->ltd_index, rc);
- lfsck_tgt_put(ltd);
- rc1 = rc;
- }
- spin_lock(<ds->ltd_lock);
- }
- spin_unlock(<ds->ltd_lock);
-
- rc = ptlrpc_set_wait(set);
- if (rc < 0) {
- ptlrpc_set_destroy(set);
- RETURN(rc);
- }
-
- if (!(lr->lr_flags & LEF_TO_OST) &&
- list_empty(&llmd->llmd_mdt_phase1_list))
- goto again;
-
- ptlrpc_set_destroy(set);
-
- RETURN(rc1 != 0 ? rc1 : rc);
-}
-
-static inline bool
-lfsck_layout_master_to_orphan(struct lfsck_layout_master_data *llmd)
-{
- return list_empty(&llmd->llmd_mdt_phase1_list) &&
- (!list_empty(&llmd->llmd_ost_phase2_list) ||
- list_empty(&llmd->llmd_ost_phase1_list));
-}
-
-static int lfsck_layout_master_notify_others(const struct lu_env *env,
- struct lfsck_component *com,
- struct lfsck_request *lr)
-{
- struct lfsck_thread_info *info = lfsck_env_info(env);
- struct lfsck_async_interpret_args *laia = &info->lti_laia;
- struct lfsck_instance *lfsck = com->lc_lfsck;
- struct lfsck_layout_master_data *llmd = com->lc_data;
- struct lfsck_layout *lo = com->lc_file_ram;
- struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram;
- struct ptlrpc_request_set *set;
- struct lfsck_tgt_descs *ltds;
- struct lfsck_tgt_desc *ltd;
- struct lfsck_tgt_desc *next;
- struct list_head *head;
- __u32 idx;
- int rc = 0;
- ENTRY;
-
- set = ptlrpc_prep_set();
- if (set == NULL)
- RETURN(-ENOMEM);
-
- lr->lr_index = lfsck_dev_idx(lfsck->li_bottom);
- lr->lr_active = LT_LAYOUT;
- laia->laia_com = com;
- laia->laia_lr = lr;
- laia->laia_shared = 0;
- switch (lr->lr_event) {
- case LE_START:
- /* Notify OSTs firstly, then handle other MDTs if needed. */
- ltds = &lfsck->li_ost_descs;
- laia->laia_ltds = ltds;
- down_read(<ds->ltd_rw_sem);
- cfs_foreach_bit(ltds->ltd_tgts_bitmap, idx) {
- ltd = lfsck_tgt_get(ltds, idx);
- LASSERT(ltd != NULL);
-
- laia->laia_ltd = ltd;
- ltd->ltd_layout_done = 0;
- rc = lfsck_async_request(env, ltd->ltd_exp, lr, set,
- lfsck_layout_master_async_interpret,
- laia, LFSCK_NOTIFY);
- if (rc != 0) {
- CERROR("%s: fail to notify %s %x for layout "
- "start: rc = %d\n",
- lfsck_lfsck2name(lfsck),
- (lr->lr_flags & LEF_TO_OST) ? "OST" :
- "MDT", idx, rc);
- lfsck_tgt_put(ltd);
- lo->ll_flags |= LF_INCOMPLETE;
- }
- }
- up_read(<ds->ltd_rw_sem);
-
- /* Sync up */
- rc = ptlrpc_set_wait(set);
- if (rc < 0) {
- ptlrpc_set_destroy(set);
- RETURN(rc);
- }
-
- if (!(bk->lb_param & LPF_ALL_TGT))
- break;
-
- /* link other MDT targets locallly. */
- spin_lock(<ds->ltd_lock);
- cfs_foreach_bit(ltds->ltd_tgts_bitmap, idx) {
- ltd = LTD_TGT(ltds, idx);
- LASSERT(ltd != NULL);
-
- if (!list_empty(<d->ltd_layout_list))
- continue;
-
- list_add_tail(<d->ltd_layout_list,
- &llmd->llmd_mdt_list);
- list_add_tail(<d->ltd_layout_phase_list,
- &llmd->llmd_mdt_phase1_list);
- }
- spin_unlock(<ds->ltd_lock);
- break;
- case LE_STOP:
- case LE_PHASE2_DONE:
- case LE_PEER_EXIT: {
- /* Handle other MDTs firstly if needed, then notify the OSTs. */
- if (bk->lb_param & LPF_ALL_TGT) {
- head = &llmd->llmd_mdt_list;
- ltds = &lfsck->li_mdt_descs;
- if (lr->lr_event == LE_STOP) {
- /* unlink other MDT targets locallly. */
- spin_lock(<ds->ltd_lock);
- list_for_each_entry_safe(ltd, next, head,
- ltd_layout_list) {
- list_del_init(<d->ltd_layout_phase_list);
- list_del_init(<d->ltd_layout_list);
- }
- spin_unlock(<ds->ltd_lock);
-
- lr->lr_flags |= LEF_TO_OST;
- head = &llmd->llmd_ost_list;
- ltds = &lfsck->li_ost_descs;
- } else {
- lr->lr_flags &= ~LEF_TO_OST;
- }
- } else {
- lr->lr_flags |= LEF_TO_OST;
- head = &llmd->llmd_ost_list;
- ltds = &lfsck->li_ost_descs;
- }
-
-again:
- laia->laia_ltds = ltds;
- spin_lock(<ds->ltd_lock);
- while (!list_empty(head)) {
- ltd = list_entry(head->next, struct lfsck_tgt_desc,
- ltd_layout_list);
- if (!list_empty(<d->ltd_layout_phase_list))
- list_del_init(<d->ltd_layout_phase_list);
- list_del_init(<d->ltd_layout_list);
- atomic_inc(<d->ltd_ref);
- laia->laia_ltd = ltd;
- spin_unlock(<ds->ltd_lock);
- rc = lfsck_async_request(env, ltd->ltd_exp, lr, set,
- lfsck_layout_master_async_interpret,
- laia, LFSCK_NOTIFY);
- if (rc != 0) {
- CERROR("%s: fail to notify %s %x for layout "
- "stop/phase2: rc = %d\n",
- lfsck_lfsck2name(lfsck),
- (lr->lr_flags & LEF_TO_OST) ? "OST" :
- "MDT", ltd->ltd_index, rc);
- lfsck_tgt_put(ltd);
- }
- spin_lock(<ds->ltd_lock);
- }
- spin_unlock(<ds->ltd_lock);
-
- rc = ptlrpc_set_wait(set);
- if (rc < 0) {
- ptlrpc_set_destroy(set);
- RETURN(rc);
- }
-
- if (!(lr->lr_flags & LEF_TO_OST)) {
- lr->lr_flags |= LEF_TO_OST;
- head = &llmd->llmd_ost_list;
- ltds = &lfsck->li_ost_descs;
- goto again;
- }
- break;
- }
- case LE_PHASE1_DONE:
- llmd->llmd_touch_gen++;
- ltds = &lfsck->li_mdt_descs;
- laia->laia_ltds = ltds;
- spin_lock(<ds->ltd_lock);
- while (!list_empty(&llmd->llmd_mdt_phase1_list)) {
- ltd = list_entry(llmd->llmd_mdt_phase1_list.next,
- struct lfsck_tgt_desc,
- ltd_layout_phase_list);
- if (ltd->ltd_layout_gen == llmd->llmd_touch_gen)
- break;
-
- ltd->ltd_layout_gen = llmd->llmd_touch_gen;
- list_del_init(<d->ltd_layout_phase_list);
- list_add_tail(<d->ltd_layout_phase_list,
- &llmd->llmd_mdt_phase1_list);
- atomic_inc(<d->ltd_ref);
- laia->laia_ltd = ltd;
- spin_unlock(<ds->ltd_lock);
- rc = lfsck_async_request(env, ltd->ltd_exp, lr, set,
- lfsck_layout_master_async_interpret,
- laia, LFSCK_NOTIFY);
- if (rc != 0) {
- CERROR("%s: fail to notify MDT %x for layout "
- "phase1 done: rc = %d\n",
- lfsck_lfsck2name(lfsck),
- ltd->ltd_index, rc);
- lfsck_tgt_put(ltd);
- }
- spin_lock(<ds->ltd_lock);
- }
- spin_unlock(<ds->ltd_lock);
- break;
- default:
- CERROR("%s: unexpected LFSCK event: rc = %d\n",
- lfsck_lfsck2name(lfsck), lr->lr_event);
- rc = -EINVAL;
- break;