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); }
size_t pfl_odt_allocslot(struct pfl_odt *t) { struct pfl_odt_hdr *h; size_t item; h = t->odt_hdr; spinlock(&t->odt_lock); if (psc_vbitmap_next(t->odt_bitmap, &item) <= 0) { ODT_STAT_INCR(t, full); freelock(&t->odt_lock); return (-1); } if (item >= h->odth_nitems) { ODT_STAT_INCR(t, extend); OPSTAT_INCR("pfl.odtable-resize"); /* * psc_vbitmap_next() has enlarged the bitmap. Update * the number of items accordingly and write to the * disk. */ h->odth_nitems = psc_vbitmap_getsize(t->odt_bitmap); t->odt_ops.odtop_resize(t); /* slm_odt_resize() */ PFLOG_ODT(PLL_WARN, t, "odtable now has %u items (used to be %zd)", h->odth_nitems, item); } freelock(&t->odt_lock); return (item); }
/* * Return the next SLASH2 FID to use. Note that from ZFS point of view, * it is perfectly okay that we use the same SLASH2 FID to refer to * different files/directories. However, doing so can confuse our * clients (think identity theft). So we must make sure that we never * reuse a SLASH2 FID, even after a crash. * * The siteid has already been baked into the initial cursor file. */ int slm_get_next_slashfid(slfid_t *fidp) { uint64_t fid; spinlock(&slm_fid_lock); /* * This should never happen. If it does, we crash to let the * sysadmin know. He could fix this if there is still room in * the cycle bits. We have to let the sysadmin know otherwise * they will not know to bump the cycle bits. */ if (FID_GET_INUM(slm_next_fid) >= FID_MAX_INUM) { psclog_warnx("max FID "SLPRI_FID" reached, manual " "intervention needed (bump the cycle bits)", slm_next_fid); freelock(&slm_fid_lock); return (ENOSPC); } fid = slm_next_fid++; freelock(&slm_fid_lock); psclog_diag("most recently allocated FID: "SLPRI_FID, fid); *fidp = fid; return (0); }
void slmbmaptimeothr_begin(struct psc_thread *thr) { struct bmap_mds_lease *bml; int rc, nsecs = 0; while (pscthr_run(thr)) { spinlock(&mdsBmapTimeoTbl.btt_lock); bml = pll_peekhead(&mdsBmapTimeoTbl.btt_leases); if (!bml) { freelock(&mdsBmapTimeoTbl.btt_lock); nsecs = BMAP_TIMEO_MAX; goto sleep; } if (!BML_TRYLOCK(bml)) { freelock(&mdsBmapTimeoTbl.btt_lock); nsecs = 1; goto sleep; } if (bml->bml_refcnt) { BML_ULOCK(bml); freelock(&mdsBmapTimeoTbl.btt_lock); nsecs = 1; goto sleep; } if (!(bml->bml_flags & BML_FREEING)) { nsecs = bml->bml_expire - time(NULL); if (nsecs > 0) { BML_ULOCK(bml); freelock(&mdsBmapTimeoTbl.btt_lock); goto sleep; } bml->bml_flags |= BML_FREEING; } BML_ULOCK(bml); freelock(&mdsBmapTimeoTbl.btt_lock); rc = mds_bmap_bml_release(bml); if (rc) { DEBUG_BMAP(PLL_WARN, bml_2_bmap(bml), "rc=%d bml=%p fl=%d seq=%"PRId64, rc, bml, bml->bml_flags, bml->bml_seq); nsecs = 1; } else nsecs = 0; sleep: psclog_debug("nsecs=%d", nsecs); if (nsecs > 0) sleep((uint32_t)nsecs); } }
/* * Obtain a read lock on the PFL file system modules list. */ void pflfs_modules_rdpin(void) { spinlock(&pflfs_modules_lock); while (pflfs_modules_modifying) { freelock(&pflfs_modules_lock); usleep(1); spinlock(&pflfs_modules_lock); } pflfs_modules_pins++; freelock(&pflfs_modules_lock); }
/* * Release a write lock on the PFL file system modules list. */ void pflfs_modules_wrunpin(void) { spinlock(&pflfs_modules_lock); pflfs_modules_modifying = 0; freelock(&pflfs_modules_lock); }
// // send statusbyte to microHam device // static void writeFlags() { unsigned char seq[4]; int ret; DEBUG("%10d:Sending FlagByte: %02x\n", TIME, statusbyte); getlock(); seq[0] = 0x08; if (statusbyte & 0x80) { seq[0] = 0x09; } seq[1] = 0x80; seq[2] = 0x80; seq[3] = 0x80 | statusbyte; if ((ret = write(uh_device_fd, seq, 4)) < 4) { MYERROR("WriteFlags failed with %d\n", ret); if (ret < 0) { perror("WriteFlagsError:"); } } freelock(); }
void psc_compl_destroy(struct psc_compl *pc) { spinlock(&pc->pc_lock); pfl_waitq_destroy(&pc->pc_wq); freelock(&pc->pc_lock); }
int _aflinear(const Aflinear *rq) { Aflinst t; t.rq = rq; afprintv(rq->verbose, 2, "Linearizing"); afprintv(rq->verbose, 3, "Opening database"); if (linopen(&t) < 0) return -1; afprintv(rq->verbose, 4, "Checking if database is linearized"); /* exit if db is already linearized */ if (t.info.optimized) { if (afclosedbf(&t.f) < 0) return -1; if (freelock(t.rq->db) < 0) return -1; return aferr(AFELINEAR); } afprintv(rq->verbose, 3, "Performing linearize process"); if (linearize(&t) < 0) return -1; afprintv(rq->verbose, 3, "Closing database"); if (linclose(&t) < 0) return -1; return 0; }
struct psc_memnode * psc_memnode_get(void) { struct psc_memnode *pmn, **pmnv; int memnid, rc; pmn = pthread_getspecific(psc_memnodes_key); if (pmn) return (pmn); memnid = psc_memnode_getid(); spinlock(&psc_memnodes_lock); if (psc_dynarray_ensurelen(&psc_memnodes, memnid + 1) == -1) psc_fatalx("ensurelen"); pmnv = psc_dynarray_get_mutable(&psc_memnodes); pmn = pmnv[memnid]; if (pmn == NULL) { pmn = psc_alloc(sizeof(*pmn), PAF_NOLOG); INIT_SPINLOCK(&pmn->pmn_lock); psc_dynarray_init(&pmn->pmn_keys); rc = pthread_setspecific(psc_memnodes_key, pmn); if (rc) psc_fatalx("pthread_setspecific: %s", strerror(rc)); psc_dynarray_setpos(&psc_memnodes, memnid, pmn); } freelock(&psc_memnodes_lock); return (pmn); }
void slm_set_curr_slashfid(slfid_t slfid) { spinlock(&slm_fid_lock); slm_next_fid = slfid; freelock(&slm_fid_lock); }
/* * Release a read lock on the PFL file system modules list. */ void pflfs_modules_rdunpin(void) { spinlock(&pflfs_modules_lock); psc_assert(pflfs_modules_pins > 0); pflfs_modules_pins--; freelock(&pflfs_modules_lock); }
/* * A modification operation to the MDFS has begun. This means the * cursor thread must be woken to start a transaction group. */ void slm_zfs_cursor_start(void) { spinlock(&slm_cursor_lock); if (!slm_cursor_update_needed++ && !slm_cursor_update_inprog) psc_waitq_wakeall(&slm_cursor_waitq); freelock(&slm_cursor_lock); }
/* * Obtain a write lock on the PFL file system modules list. */ void pflfs_modules_wrpin(void) { spinlock(&pflfs_modules_lock); while (pflfs_modules_modifying) { freelock(&pflfs_modules_lock); usleep(1); spinlock(&pflfs_modules_lock); } pflfs_modules_modifying = 1; while (pflfs_modules_pins) { freelock(&pflfs_modules_lock); usleep(1); spinlock(&pflfs_modules_lock); } freelock(&pflfs_modules_lock); }
/* * A modification operation to the MDFS has ended. If other operations * are ongoing, we need to re-wake the cursor thread to ensure a * transaction group is active as it is not guaranteed to be awake. */ void slm_zfs_cursor_end(void) { spinlock(&slm_cursor_lock); psc_assert(slm_cursor_update_needed > 0); if (--slm_cursor_update_needed && !slm_cursor_update_inprog) psc_waitq_wakeall(&slm_cursor_waitq); freelock(&slm_cursor_lock); }
slfid_t slm_get_curr_slashfid(void) { slfid_t fid; spinlock(&slm_fid_lock); fid = slm_next_fid; freelock(&slm_fid_lock); return (fid); }
// // Write a control string to the microHam device // static void writeControl(unsigned char *data, int len) { int i, ret; unsigned char seq[8]; DEBUG("%10d:WriteControl:", TIME); for (i = 0; i < len; i++) { DEBUG(" %02x", data[i]); } DEBUG(".\n"); // Control data is in the second frame of a sequence, // So send a no-op first. Include statusbyte in first frame. // First and last byte of the control message is NOT marked "valid" getlock(); for (i = 0; i < len; i++) { // encode statusbyte in first frame seq[0] = 0x08; seq[1] = 0x80; seq[2] = 0x80; seq[3] = 0x80 | statusbyte; seq[4] = 0x48; // marked valid seq[5] = 0x80; seq[6] = 0x80; seq[7] = 0x80 | data[i]; if (statusbyte & 0x80) { seq[0] |= 1; } if (i == 0 || i == len - 1) { seq[4] = 0x40; // un-mark valid } if (data[i] & 0x80) { seq[4] |= 0x01; } if ((ret = write(uh_device_fd, seq, 8)) < 8) { MYERROR("WriteControl failed, ret=%d\n", ret); if (ret < 0) { perror("WriteControlError:"); } } } freelock(); }
void pscrpc_nbreapthr_main(struct psc_thread *thr) { struct pscrpc_request_set *set; struct pscrpc_nbreapthr *pnbt; int cntr; pnbt = thr->pscthr_private; set = pnbt->pnbt_set; while (pscthr_run(thr)) { spinlock(&set->set_lock); cntr = set->set_compl.pc_counter; if (pscrpc_set_checkone(set)) freelock(&set->set_lock); else if (cntr == set->set_compl.pc_counter) psc_compl_waitrel_s(&set->set_compl, &set->set_lock, 1); else freelock(&set->set_lock); } }
void * psc_memnode_getobj(int pos, void *(*initf)(void *), void *arg) { struct psc_memnode *pmn; void *p; pmn = psc_memnode_get(); p = psc_memnode_getkey(pmn, pos); if (p) return (p); spinlock(&pmn->pmn_lock); p = psc_memnode_getkey(pmn, pos); if (p) { freelock(&pmn->pmn_lock); return (p); } p = initf(arg); psc_memnode_setkey(pmn, pos, p); freelock(&pmn->pmn_lock); return (p); }
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); }
// // Send bytes to the WinKeyer within microHam device // static void writeWkey(unsigned char *bytes, int len) { unsigned char seq[12]; int i, ret; DEBUG("%10d:Send WinKey data: ", TIME); for (i = 0; i < len; i++) { DEBUG(" %02x", (int) bytes[i]); } DEBUG(".\n"); // Winkey data is in the third frame of a sequence, // So send two no-ops first. Include statusbyte in first frame getlock(); for (i = 0; i < len; i++) { seq[ 0] = 0x08; seq[ 1] = 0x80; seq[ 2] = 0x80; seq[ 3] = 0X80 | statusbyte; seq[ 4] = 0x40; seq[ 5] = 0x80; seq[ 6] = 0x80; seq[ 7] = 0x80; seq[ 8] = 0x48; seq[ 9] = 0x80; seq[10] = 0x80; seq[11] = 0x80 | bytes[i]; if (statusbyte & 0x80) { seq[ 0] |= 0x01; } if (bytes[i] & 0x80) { seq[ 8] |= 0x01; } if ((ret = write(uh_device_fd, seq, 12)) < 12) { MYERROR("WriteWINKEY failed with %d\n", ret); if (ret < 0) { perror("WriteWinkeyError:"); } } } freelock(); }
void _psc_compl_ready(struct psc_compl *pc, int rc, int one) { spinlock(&pc->pc_lock); if (one) pfl_waitq_wakeone(&pc->pc_wq); else { pc->pc_rc = rc; pc->pc_done = 1; pfl_waitq_wakeall(&pc->pc_wq); } pc->pc_counter++; freelock(&pc->pc_lock); }
/* * Free the odtable slot which corresponds to the provided receipt. * Note: r is freed here. */ void pfl_odt_freeitem(struct pfl_odt *t, int64_t item) { struct pfl_odt_slotftr f; _pfl_odt_doput(t, item, NULL, &f, 0); spinlock(&t->odt_lock); psc_vbitmap_unset(t->odt_bitmap, item); freelock(&t->odt_lock); PFLOG_ODT(PLL_DIAG, t, "slot=%"PRId64, item); ODT_STAT_INCR(t, free); }
static void pfl_odt_zerobuf_ensurelen(size_t len) { static psc_spinlock_t zerobuf_lock = SPINLOCK_INIT; static size_t zerobuf_len; if (len <= zerobuf_len) return; spinlock(&zerobuf_lock); if (len > zerobuf_len) { pfl_odt_zerobuf = psc_realloc(pfl_odt_zerobuf, len, 0); zerobuf_len = len; } freelock(&zerobuf_lock); }
/** * mds_bmap_timeotbl_mdsi - * Returns bmapseqno. */ uint64_t mds_bmap_timeotbl_mdsi(struct bmap_mds_lease *bml, int flags) { uint64_t seq = 0; if (flags & BTE_DEL) { bml->bml_flags &= ~BML_TIMEOQ; mds_bmap_timeotbl_remove(bml); return (BMAPSEQ_ANY); } if (flags & BTE_REATTACH) { /* BTE_REATTACH is only called from startup context. */ spinlock(&mdsBmapTimeoTbl.btt_lock); if (mdsBmapTimeoTbl.btt_maxseq < bml->bml_seq) /* * A lease has been found in odtable whose * issuance was after that of the last HWM * journal entry. (HWM's are journaled every * BMAP_SEQLOG_FACTOR times.) */ seq = mdsBmapTimeoTbl.btt_maxseq = bml->bml_seq; else if (mdsBmapTimeoTbl.btt_minseq > bml->bml_seq) /* This lease has already expired. */ seq = BMAPSEQ_ANY; else seq = bml->bml_seq; freelock(&mdsBmapTimeoTbl.btt_lock); } else { seq = mds_bmap_timeotbl_getnextseq(); } BML_LOCK(bml); if (bml->bml_flags & BML_TIMEOQ) { mds_bmap_timeotbl_remove(bml); pll_addtail(&mdsBmapTimeoTbl.btt_leases, bml); } else { bml->bml_flags |= BML_TIMEOQ; pll_addtail(&mdsBmapTimeoTbl.btt_leases, bml); } BML_ULOCK(bml); return (seq); }
//------------------------------------------------------------------------------ void IFile::load(const char *fileName) throw (std::ios_base::failure) { freelock(); fileName_ = std::string(fileName); fileIn_.open(fileName, std::ios::binary | std::ios::in); if (fileIn_.fail()) { fileIn_.close(); throw std::ios_base::failure("Cant read file: \"" + fileName_ + "\""); } else { readObject(fileIn_); loaded_ = true; } }
// // Send radio bytes to microHam device // static void writeRadio(unsigned char *bytes, int len) { unsigned char seq[4]; int i, ret; DEBUG("%10d:Send radio data: ", TIME); for (i = 0; i < len; i++) { DEBUG(" %02x", (int) bytes[i]); } DEBUG(".\n"); getlock(); for (i = 0; i < len; i++) { seq[0] = 0x28; seq[1] = 0x80 | bytes[i]; seq[2] = 0x80; seq[3] = 0X80 | statusbyte; if (statusbyte & 0x80) { seq[0] |= 0x01; } if (bytes[i] & 0x80) { seq[0] |= 0x04; } if ((ret = write(uh_device_fd, seq, 4)) < 4) { MYERROR("WriteRadio failed with %d\n", ret); if (ret < 0) { perror("WriteRadioError:"); } } } freelock(); }
int psc_compl_waitrel(struct psc_compl *pc, enum pfl_lockprim type, void *lockp, long sec, long nsec) { reqlock(&pc->pc_lock); PFL_LOCKPRIM_ULOCK(type, lockp); if (pc->pc_done) { freelock(&pc->pc_lock); } else { if (sec || nsec) { if (pfl_waitq_waitrel(&pc->pc_wq, &pc->pc_lock, sec, nsec)) return (0); } else pfl_waitq_wait(&pc->pc_wq, &pc->pc_lock); } return (pc->pc_rc); }
void mds_bmap_timeotbl_remove(struct bmap_mds_lease *bml) { struct bmap_mds_lease *tmp; int update = 0; spinlock(&mdsBmapTimeoTbl.btt_lock); if (pll_peekhead(&mdsBmapTimeoTbl.btt_leases) == bml) update = 1; pll_remove(&mdsBmapTimeoTbl.btt_leases, bml); if (update) { tmp = pll_peekhead(&mdsBmapTimeoTbl.btt_leases); if (tmp) mdsBmapTimeoTbl.btt_minseq = tmp->bml_seq; else mdsBmapTimeoTbl.btt_minseq = mdsBmapTimeoTbl.btt_maxseq; mds_bmap_timeotbl_journal_seqno(); } freelock(&mdsBmapTimeoTbl.btt_lock); }
static int linclose(Aflinst *t) { t->info.optimized = 1; afprintv(t->rq->verbose, 4, "Writing database information"); if (afwriteinfo(t->f.info, &(t->info)) < 0) return -1; afprintv(t->rq->verbose, 4, "Closing database files"); if (closefiles(&(t->f)) < 0) return -1; afprintv(t->rq->verbose, 4, "Truncating unlinearized files"); if (truncufiles(t->rq->db) < 0) return -1; afprintv(t->rq->verbose, 4, "Unlocking database"); if (freelock(t->rq->db) < 0) return -1; return 0; }