int psc_dynarray_copy(const struct psc_dynarray *src, struct psc_dynarray *dst) { psc_dynarray_ensurelen(dst, psc_dynarray_len(src)); memcpy(dst->pda_items, src->pda_items, sizeof(void *) * psc_dynarray_len(src)); dst->pda_pos = psc_dynarray_len(src); return (0); }
/* * Remove the given position from the dynarray. This API assumes the * dynarray is unordered so it will reposition the final element in the * emptied slot. Use a different API if this is undesirable. */ void psc_dynarray_removepos(struct psc_dynarray *pda, int pos) { void **p; p = psc_dynarray_get_mutable(pda); psc_assert(pos >= 0 && pos < psc_dynarray_len(pda)); if (pos != psc_dynarray_len(pda) - 1) p[pos] = p[psc_dynarray_len(pda) - 1]; pda->pda_pos--; }
void psc_dynarray_swap(struct psc_dynarray *da, int a, int b) { void *tmp; psc_assert(a >= 0); psc_assert(b >= 0); psc_assert(a < psc_dynarray_len(da)); psc_assert(b < psc_dynarray_len(da)); if (a != b) SWAP(da->pda_items[a], da->pda_items[b], tmp); }
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); }
/* * 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); }
/* * Cut and replace a section of a dynarray. * @pda: dynamic array to splice. * @off: offset into array to begin splice. * @nrmv: number of items to remove. * @base: start array to splice from. * @nadd: number of new items to splice into the array. */ int psc_dynarray_splice(struct psc_dynarray *pda, int off, int nrmv, const void *base, int nadd) { int oldlen, rc, rem; void **p; oldlen = psc_dynarray_len(pda); psc_assert(nadd >= 0); psc_assert(nrmv >= 0); psc_assert(off + nrmv <= oldlen); rc = psc_dynarray_ensurelen(pda, oldlen + nadd - nrmv); if (rc) return (rc); p = pda->pda_items + off; if (nadd != nrmv) { rem = oldlen - off - nrmv; memmove(nadd > nrmv ? p + nadd - nrmv : p + nadd, p + nrmv, rem * sizeof(void *)); pda->pda_pos += nadd - nrmv; } memcpy(p, base, nadd * sizeof(void *)); return (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); }
void slm_fcmh_dtor(struct fidc_membh *f) { struct fcmh_mds_info *fmi; int rc, vfsid; fmi = fcmh_2_fmi(f); if (fcmh_isreg(f)) { psc_assert(psc_dynarray_len(&fmi->fmi_ptrunc_clients) == 0); psc_dynarray_free(&fmi->fmi_ptrunc_clients); } if (fcmh_isreg(f) || fcmh_isdir(f)) { /* XXX Need to worry about other modes here */ if (!fmi->fmi_ctor_rc) { slfid_to_vfsid(fcmh_2_fid(f), &vfsid); rc = mdsio_release(vfsid, &rootcreds, fcmh_2_mfh(f)); psc_assert(rc == 0); } } if (fcmh_isdir(f)) { slfid_to_vfsid(fcmh_2_fid(f), &vfsid); rc = mdsio_release(vfsid, &rootcreds, fcmh_2_dino_mfh(f)); psc_assert(rc == 0); } if (fmi->fmi_inodeh.inoh_extras) PSCFREE(fmi->fmi_inodeh.inoh_extras); }
/* * Initialize and push a new module into the file system processing * stack. */ void pflfs_module_add(int pos, struct pscfs *m) { if (pos == PFLFS_MOD_POS_LAST) pos = psc_dynarray_len(&pscfs_modules); psc_dynarray_splice(&pscfs_modules, pos, 0, &m, 1); }
/* * Access an item in a dynamic array. * @pda: dynamic array to access. * @pos: item index. */ void * psc_dynarray_getpos(const struct psc_dynarray *pda, int pos) { psc_assert(pos >= 0); if (pos >= psc_dynarray_len(pda)) psc_fatalx("out of bounds array access"); return (pda->pda_items[pos]); }
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 psc_subsys_register(int ssid, const char *name) { struct psc_subsys *ss; char *p, buf[BUFSIZ]; int nss; nss = psc_dynarray_len(&psc_subsystems); ss = psc_alloc(sizeof(*ss), PAF_NOLOG); ss->pss_name = name; snprintf(buf, sizeof(buf), "PSC_LOG_LEVEL_%s", name); p = getenv(buf); if (p) { ss->pss_loglevel = psc_loglevel_fromstr(p); if (ss->pss_loglevel == PNLOGLEVELS) psc_fatalx("invalid %s value", name); } else { ss->pss_loglevel = psc_log_getlevel_global(); if (ssid == PSS_TMP) ss->pss_loglevel = PLL_DEBUG; } snprintf(buf, sizeof(buf), "PSC_SYSLOG_%s", name); if (getenv(buf) || getenv("PSC_SYSLOG")) { static int init; if (!init) { extern const char *__progname; const char *ident = __progname; init = 1; p = getenv("PFL_SYSLOG_IDENT"); if (p) { static char idbuf[32]; ident = idbuf; (void)FMTSTR(idbuf, sizeof(idbuf), p, FMTSTRCASE('n', "s", __progname) ); } openlog(ident, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); } pfl_syslog = psc_realloc(pfl_syslog, sizeof(*pfl_syslog) * (nss + 1), PAF_NOLOG); pfl_syslog[nss] = 1; } if (ssid != nss) psc_fatalx("bad ID %d for subsys %s [want %d], " "check order", ssid, name, nss); psc_dynarray_add(&psc_subsystems, ss); }
/* * 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_subsys_id(const char *name) { const struct psc_subsys **ss; int n, len; ss = psc_dynarray_get(&psc_subsystems); len = psc_dynarray_len(&psc_subsystems); for (n = 0; n < len; n++) if (strcasecmp(name, ss[n]->pss_name) == 0) return (n); return (-1); }
void psc_log_setlevel_ss(int ssid, int newlevel) { struct psc_subsys **ss; int i, nss; if (newlevel >= PNLOGLEVELS || newlevel < 0) psc_fatalx("log level out of bounds (%d, max %d)", newlevel, PNLOGLEVELS); ss = psc_dynarray_get(&psc_subsystems); nss = psc_dynarray_len(&psc_subsystems); if (ssid == PSS_ALL) for (i = 0; i < nss; i++) ss[i]->pss_loglevel = newlevel; else if (ssid >= nss || ssid < 0) psc_fatalx("subsystem out of bounds (%d, max %d)", ssid, nss); else ss[ssid]->pss_loglevel = newlevel; }