Пример #1
0
struct pfl_opstat *
pfl_opstat_initf(int flags, const char *namefmt, ...)
{
	struct pfl_opstat *opst;
	int sz, pos;
	va_list ap;
	char *name = pfl_opstat_name;

	spinlock(&pfl_opstats_lock);

	va_start(ap, namefmt);
	sz = vsnprintf(name, 128, namefmt, ap) + 1;
	va_end(ap);

	/* (gdb) p ((struct pfl_opstat *)pfl_opstats.pda_items[74]).opst_name */
	pos = psc_dynarray_bsearch(&pfl_opstats, name, _pfl_opstat_cmp);
	if (pos < psc_dynarray_len(&pfl_opstats)) {
		opst = psc_dynarray_getpos(&pfl_opstats, pos);
		if (strcmp(name, opst->opst_name) == 0) {
			pfl_assert((flags & OPSTF_EXCL) == 0);
			freelock(&pfl_opstats_lock);
			return (opst);
		}
	}
	pfl_opstats_sum++;
	opst = PSCALLOC(sizeof(*opst) + sz);
	strlcpy(opst->opst_name, name, 128);
	opst->opst_flags = flags;
	psc_dynarray_splice(&pfl_opstats, pos, 0, &opst, 1);
	freelock(&pfl_opstats_lock);
	return (opst);
}
Пример #2
0
/*
 * Find the position of an item in a sorted dynarray.
 * @pda: sorted dynamic array to search.
 * @item: item contained within whose array index is desired.
 * @cmpf: comparison routine.
 * Returns the item's index into the array.  If the item is not in the
 * dynarray, the index value returned is the position the element should
 * take on to maintain sort order.
 *
 * XXX this should be changed to use bsearch_ceil().
 */
int
psc_dynarray_bsearch(const struct psc_dynarray *pda, const void *item,
    int (*cmpf)(const void *, const void *))
{
	int rc, min, max, mid;
	void *p;

	min = mid = 0;
	max = psc_dynarray_len(pda) - 1;
	while (min <= max) {
		mid = (max + min) / 2;
		p = psc_dynarray_getpos(pda, mid);
		rc = cmpf(item, p);
		if (rc < 0)
			max = mid - 1;
		else if (rc > 0) {
			min = mid + 1;

			/*
			 * If the item doesn't exist, inform caller that
			 * the position the item should take on is after
			 * this mid index.
			 */
			mid++;
		} else
			break;
	}
	return (mid);
}
Пример #3
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);
	}
Пример #4
0
int
sli_rmi_setmds(const char *name)
{
	struct slashrpc_cservice *csvc;
	struct sl_resource *res;
//	struct sl_resm *old;
	lnet_nid_t nid;

	/* XXX kill any old MDS and purge any bmap updates being held */
//	slconnthr_unwatch(rmi_resm->resm_csvc);
//	old = rmi_resm;
//	sl_csvc_disable(old->resm_csvc);

	nid = libcfs_str2nid(name);
	if (nid == LNET_NID_ANY) {
		res = libsl_str2res(name);
		if (res == NULL)
			return (SLERR_RES_UNKNOWN);
		rmi_resm = psc_dynarray_getpos(&res->res_members, 0);
	} else
		rmi_resm = libsl_nid2resm(nid);

	if (sli_rmi_getcsvc(&csvc))
		psclog_errorx("error connecting to MDS");
	else {
		slconnthr_watch(sliconnthr, csvc, CSVCF_PING, NULL,
		    NULL);
		sl_csvc_decref(csvc);
	}
	return (0);
}
Пример #5
0
/*
 * Remove a module from the file system processing stack.
 */
struct pscfs *
pflfs_module_remove(int pos)
{
	struct pscfs *m;

	m = psc_dynarray_getpos(&pscfs_modules, pos);
	psc_dynarray_splice(&pscfs_modules, pos, 1, NULL, 0);
	return (m);
}
Пример #6
0
const char *
psc_subsys_name(int ssid)
{
	const struct psc_subsys *ss;

	if (ssid < 0 || ssid >= psc_dynarray_len(&psc_subsystems))
		return ("<unknown>");
	ss = psc_dynarray_getpos(&psc_subsystems, ssid);
	return (ss->pss_name);
}
Пример #7
0
void
pfl_opstat_destroy_pos(int pos)
{
	struct pfl_opstat *opst;

	LOCK_ENSURE(&pfl_opstats_lock);
	opst = psc_dynarray_getpos(&pfl_opstats, pos);
	psc_dynarray_splice(&pfl_opstats, pos, 1, NULL, 0);
	PSCFREE(opst);
}
Пример #8
0
void
pfl_opstat_destroy(struct pfl_opstat *opst)
{
	int pos;

	spinlock(&pfl_opstats_lock);
	pos = psc_dynarray_bsearch(&pfl_opstats, opst->opst_name,
	    _pfl_opstat_cmp);
	pfl_assert(psc_dynarray_getpos(&pfl_opstats, pos) == opst);
	pfl_opstat_destroy_pos(pos);
	freelock(&pfl_opstats_lock);
}
Пример #9
0
/*
 * Duplicate items in one dynarray to another.
 * @pda: dynamic array to copy to.
 * @src: dynamic array to copy from.
 */
int
psc_dynarray_concat(struct psc_dynarray *pda,
    const struct psc_dynarray *src)
{
	int rc, i;

	for (i = 0; i < psc_dynarray_len(src); i++) {
		rc = psc_dynarray_add(pda, psc_dynarray_getpos(src, i));
		if (rc)
			return (rc);
	}
	return (0);
}
Пример #10
0
void *
psc_memnode_getkey(struct psc_memnode *pmn, int key)
{
	int locked;
	void *val;

	val = NULL;
	locked = reqlock(&pmn->pmn_lock);
	if (psc_dynarray_len(&pmn->pmn_keys) > key)
		val = psc_dynarray_getpos(&pmn->pmn_keys, key);
	ureqlock(&pmn->pmn_lock, locked);
	return (val);
}
Пример #11
0
int
psc_log_getlevel_ss(int ssid)
{
	const struct psc_subsys *ss;

	if (ssid >= psc_dynarray_len(&psc_subsystems) || ssid < 0) {
		/* don't use psclog to avoid loops */
		warnx("subsystem out of bounds (%d, max %d)", ssid,
		    psc_dynarray_len(&psc_subsystems));
		abort();
	}
	ss = psc_dynarray_getpos(&psc_subsystems, ssid);
	return (ss->pss_loglevel);
}
Пример #12
0
/*
 * 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);
}