예제 #1
0
int
slc_fcmh_ctor(struct fidc_membh *f, __unusedx int flags)
{
	struct fcmh_cli_info *fci;
	struct sl_resource *res;
	struct sl_site *s;
	sl_siteid_t siteid;
	int i;

	fci = fcmh_get_pri(f);
	slc_fcmh_refresh_age(f);
	INIT_PSC_LISTENTRY(&fci->fci_lentry);
	siteid = FID_GET_SITEID(fcmh_2_fid(f));

	psc_assert(f->fcmh_flags & FCMH_INITING);

	if (fcmh_2_fid(f) != SLFID_ROOT &&
	    siteid != msl_rmc_resm->resm_siteid) {
		s = libsl_siteid2site(siteid);
		if (s == NULL) {
			psclog_errorx("fid "SLPRI_FID" has "
			    "invalid site ID %d",
			    fcmh_2_fid(f), siteid);
			return (ESTALE);
		}
		SITE_FOREACH_RES(s, res, i)
			if (res->res_type == SLREST_MDS) {
				fci->fci_resm = psc_dynarray_getpos(
				    &res->res_members, 0);
				return (0);
			}
		psclog_errorx("fid "SLPRI_FID" has invalid site ID %d",
		    fcmh_2_fid(f), siteid);
		return (ESTALE);
	}
예제 #2
0
파일: rmm.c 프로젝트: jasons-psc/slash2
/*
 * Handle a NAMESPACE_UPDATE request from another MDS.
 */
int
slm_rmm_handle_namespace_update(struct pscrpc_request *rq)
{
	struct srt_update_entry *entryp;
	struct srm_update_req *mq;
	struct srm_update_rep *mp;
	struct sl_mds_peerinfo *p;
	struct sl_resource *res;
	struct sl_site *site;
	struct iovec iov;
	int i, len, count;

	SL_RSX_ALLOCREP(rq, mq, mp);

	count = mq->count;
	if (count <= 0 || mq->size > LNET_MTU) {
		mp->rc = -EINVAL;
		return (mp->rc);
	}

	iov.iov_len = mq->size;
	iov.iov_base = PSCALLOC(mq->size);

	mp->rc = slrpc_bulkserver(rq, BULK_GET_SINK, SRMM_BULK_PORTAL,
	    &iov, 1);
	if (mp->rc)
		goto out;

	/* Search for the peer information by the given site ID. */
	site = libsl_siteid2site(mq->siteid);
	p = NULL;
	if (site)
		SITE_FOREACH_RES(site, res, i)
			if (res->res_type == SLREST_MDS) {
				p = res2rpmi(res)->rpmi_info;
				break;
			}
	if (p == NULL) {
		psclog_info("fail to find site ID %d", mq->siteid);
		PFL_GOTOERR(out, mp->rc = -EINVAL);
	}

	/*
	 * Iterate through the namespace update buffer and apply updates.
	 * If we fail to apply an update, we still report success to our
	 * peer because reporting an error does not help our cause.
	 */
	entryp = iov.iov_base;
	for (i = 0; i < count; i++) {
		slm_rmm_apply_update(entryp);
		len = UPDATE_ENTRY_LEN(entryp);
		entryp = PSC_AGP(entryp, len);
	}
	zfsslash2_wait_synced(0);

 out:
	PSCFREE(iov.iov_base);
	return (mp->rc);
}
예제 #3
0
파일: rmm.c 프로젝트: jasons-psc/slash2
/*
 * Forward a name space operation to a remote MDS first before
 * replicating the operation locally by our callers.
 */
int
slm_rmm_forward_namespace(int op, struct sl_fidgen *fg,
    struct sl_fidgen *nfg, char *name, char *newname, uint32_t mode,
    const struct slash_creds *crp, struct srt_stat *sstb,
    int32_t to_set)
{
	struct slashrpc_cservice *csvc = NULL;
	struct pscrpc_request *rq = NULL;
	struct sl_resm *resm = NULL;
	struct srm_forward_req *mq;
	struct srm_forward_rep *mp;
	struct sl_resource *res;
	struct sl_site *site;
	int rc, len, i, vfsid;
	sl_siteid_t siteid;

	if (op != SLM_FORWARD_MKDIR  && op != SLM_FORWARD_RMDIR &&
	    op != SLM_FORWARD_CREATE && op != SLM_FORWARD_UNLINK &&
	    op != SLM_FORWARD_RENAME && op != SLM_FORWARD_SETATTR &&
	    op != SLM_FORWARD_SYMLINK)
		return (-PFLERR_NOSYS);

	rc = slfid_to_vfsid(fg->fg_fid, &vfsid);
	if (rc)
		return (rc);

	siteid = FID_GET_SITEID(fg->fg_fid);
	site = libsl_siteid2site(siteid);
	if (site == NULL)
		return (-EBADF);

	SITE_FOREACH_RES(site, res, i) {
		if (res->res_type != SLREST_MDS)
			continue;
		resm = psc_dynarray_getpos(&res->res_members, 0);
		break;
	}
	csvc = slm_getmcsvc_wait(resm);
	if (csvc == NULL) {
		psclog_info("unable to connect to site %d", siteid);
		return (-EIO);
	}

	rc = SL_RSX_NEWREQ(csvc, SRMT_NAMESPACE_FORWARD, rq, mq, mp);
	if (rc)
		goto out;

	mq->op = op;
	mq->fg = *fg;

	if (op == SLM_FORWARD_SETATTR) {
		mq->to_set = to_set;
		mq->req.sstb = *sstb;
	} else
		strlcpy(mq->req.name, name, sizeof(mq->req.name));

	if (op == SLM_FORWARD_RENAME || op == SLM_FORWARD_SYMLINK) {
		if (op == SLM_FORWARD_RENAME)
			mq->nfg	= *nfg;
		len = strlen(name) + 1;
		strlcpy(mq->req.name + len, newname,
		    sizeof(mq->req.name) - len);
	}

	if (op == SLM_FORWARD_MKDIR ||
	    op == SLM_FORWARD_CREATE ||
	    op == SLM_FORWARD_SYMLINK) {
		mq->mode = mode;
		mq->creds.scr_uid = crp->scr_uid;
		mq->creds.scr_gid = crp->scr_gid;
	}

	rc = SL_RSX_WAITREP(csvc, rq, mp);
	if (!rc)
		rc = mp->rc;
	if (!rc && sstb)
		*sstb = mp->attr;

 out:
	if (rq)
		pscrpc_req_finished(rq);
	if (csvc)
		sl_csvc_decref(csvc);
	return (rc);
}