static int mdd_fill_fldb(const struct lu_env *env, struct mdd_device *mdd) { struct seq_server_site *ss = mdd_seq_site(mdd); struct lu_seq_range range; int rc; LASSERT(ss->ss_server_seq != NULL); LASSERT(ss->ss_server_fld != NULL); if (ss->ss_server_seq->lss_space.lsr_end == 0) return 0; memcpy(&range, &ss->ss_server_seq->lss_space, sizeof(range)); /* Pre-existing ZFS does not insert any entries to FLDB, we need * to insert it to FLDB during convertion */ range.lsr_start = FID_SEQ_NORMAL; fld_range_set_mdt(&range); mutex_lock(&ss->ss_server_fld->lsf_lock); rc = fld_insert_entry(env, ss->ss_server_fld, &range); mutex_unlock(&ss->ss_server_fld->lsf_lock); LCONSOLE_INFO("%s: insert missing range "DRANGE"\n", mdd2obd_dev(mdd)->obd_name, PRANGE(&range)); return rc; }
static int seq_client_rpc(struct lu_client_seq *seq, struct lu_seq_range *output, __u32 opc, const char *opcname) { struct obd_export *exp = seq->lcs_exp; struct ptlrpc_request *req; struct lu_seq_range *out, *in; __u32 *op; unsigned int debug_mask; int rc; ENTRY; LASSERT(exp != NULL && !IS_ERR(exp)); req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), &RQF_SEQ_QUERY, LUSTRE_MDS_VERSION, SEQ_QUERY); if (req == NULL) RETURN(-ENOMEM); /* Init operation code */ op = req_capsule_client_get(&req->rq_pill, &RMF_SEQ_OPC); *op = opc; /* Zero out input range, this is not recovery yet. */ in = req_capsule_client_get(&req->rq_pill, &RMF_SEQ_RANGE); lu_seq_range_init(in); ptlrpc_request_set_replen(req); in->lsr_index = seq->lcs_space.lsr_index; if (seq->lcs_type == LUSTRE_SEQ_METADATA) fld_range_set_mdt(in); else fld_range_set_ost(in); if (opc == SEQ_ALLOC_SUPER) { req->rq_request_portal = SEQ_CONTROLLER_PORTAL; req->rq_reply_portal = MDC_REPLY_PORTAL; /* During allocating super sequence for data object, * the current thread might hold the export of MDT0(MDT0 * precreating objects on this OST), and it will send the * request to MDT0 here, so we can not keep resending the * request here, otherwise if MDT0 is failed(umounted), * it can not release the export of MDT0 */ if (seq->lcs_type == LUSTRE_SEQ_DATA) req->rq_no_delay = req->rq_no_resend = 1; debug_mask = D_CONSOLE; } else { if (seq->lcs_type == LUSTRE_SEQ_METADATA) { req->rq_reply_portal = MDC_REPLY_PORTAL; req->rq_request_portal = SEQ_METADATA_PORTAL; } else { req->rq_reply_portal = OSC_REPLY_PORTAL; req->rq_request_portal = SEQ_DATA_PORTAL; } debug_mask = D_INFO; } /* Allow seq client RPC during recovery time. */ req->rq_allow_replay = 1; ptlrpc_at_set_req_timeout(req); rc = ptlrpc_queue_wait(req); if (rc) GOTO(out_req, rc); out = req_capsule_server_get(&req->rq_pill, &RMF_SEQ_RANGE); *output = *out; if (!lu_seq_range_is_sane(output)) { CERROR("%s: Invalid range received from server: " DRANGE"\n", seq->lcs_name, PRANGE(output)); GOTO(out_req, rc = -EINVAL); } if (lu_seq_range_is_exhausted(output)) { CERROR("%s: Range received from server is exhausted: " DRANGE"]\n", seq->lcs_name, PRANGE(output)); GOTO(out_req, rc = -EINVAL); } CDEBUG_LIMIT(debug_mask, "%s: Allocated %s-sequence "DRANGE"]\n", seq->lcs_name, opcname, PRANGE(output)); EXIT; out_req: ptlrpc_req_finished(req); return rc; }
/** * Retrieve fldb entry from MDT0 and add to local FLDB and cache. **/ int fld_update_from_controller(const struct lu_env *env, struct lu_server_fld *fld) { struct fld_thread_info *info; struct lu_seq_range *range; struct lu_seq_range_array *lsra; __u32 index; struct ptlrpc_request *req; int rc; int i; ENTRY; /* Update only happens during initalization, i.e. local FLDB * does not exist yet */ if (!fld->lsf_new) RETURN(0); rc = fld_name_to_index(fld->lsf_name, &index); if (rc < 0) RETURN(rc); /* No need update fldb for MDT0 */ if (index == 0) RETURN(0); info = lu_context_key_get(&env->le_ctx, &fld_thread_key); LASSERT(info != NULL); range = &info->fti_lrange; memset(range, 0, sizeof(*range)); range->lsr_index = index; fld_range_set_mdt(range); do { rc = fld_client_rpc(fld->lsf_control_exp, range, FLD_READ, &req); if (rc != 0 && rc != -EAGAIN) GOTO(out, rc); LASSERT(req != NULL); lsra = (struct lu_seq_range_array *)req_capsule_server_get( &req->rq_pill, &RMF_GENERIC_DATA); if (lsra == NULL) GOTO(out, rc = -EPROTO); range_array_le_to_cpu(lsra, lsra); for (i = 0; i < lsra->lsra_count; i++) { int rc1; if (lsra->lsra_lsr[i].lsr_flags != LU_SEQ_RANGE_MDT) GOTO(out, rc = -EINVAL); if (lsra->lsra_lsr[i].lsr_index != index) GOTO(out, rc = -EINVAL); mutex_lock(&fld->lsf_lock); rc1 = fld_insert_entry(env, fld, &lsra->lsra_lsr[i]); mutex_unlock(&fld->lsf_lock); if (rc1 != 0) GOTO(out, rc = rc1); } if (rc == -EAGAIN) *range = lsra->lsra_lsr[lsra->lsra_count - 1]; } while (rc == -EAGAIN); fld->lsf_new = 1; out: if (req != NULL) ptlrpc_req_finished(req); RETURN(rc); }