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); }
/* * 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); }
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); }
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); }
/* * 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); }
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); }
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); }
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); }
/* * 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); }
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); }
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); }
/* * 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); }