Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
/**
 * 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);
}