void afs_GetDynrootMount(char **dynrootDir, int *dynrootLen, struct AFSFetchStatus *status) { ObtainReadLock(&afs_dynrootDirLock); if (!afs_dynrootMountDir) { ReleaseReadLock(&afs_dynrootDirLock); afs_RebuildDynrootMount(); ObtainReadLock(&afs_dynrootDirLock); } if (dynrootDir) *dynrootDir = afs_dynrootMountDir; if (dynrootLen) *dynrootLen = afs_dynrootMountDirLen; if (status) { memset(status, 0, sizeof(struct AFSFetchStatus)); status->FileType = Directory; status->LinkCount = 1; status->Length = afs_dynrootMountDirLen; status->DataVersion = 1; status->CallerAccess = PRSFS_LOOKUP | PRSFS_READ; status->AnonymousAccess = PRSFS_LOOKUP | PRSFS_READ; status->UnixModeBits = 0755; status->ParentVnode = 1; status->ParentUnique = 1; status->dataVersionHigh = 0; } }
int DFlush(void) { /* Flush all the modified buffers. */ int i; struct buffer **tbp; afs_int32 code, rcode; rcode = 0; tbp = Buffers; ObtainReadLock(&afs_bufferLock); for (i = 0; i < nbuffers; i++, tbp++) { if ((*tbp)->dirty) { ObtainWriteLock(&(*tbp)->lock); (*tbp)->lockers++; ReleaseReadLock(&afs_bufferLock); if ((*tbp)->dirty) { code = ReallyWrite((*tbp)->fid, (*tbp)->page, (*tbp)->data); if (!code) (*tbp)->dirty = 0; /* Clear the dirty flag */ if (code && !rcode) { rcode = code; } } (*tbp)->lockers--; ReleaseWriteLock(&(*tbp)->lock); ObtainReadLock(&afs_bufferLock); } } ReleaseReadLock(&afs_bufferLock); return rcode; }
int DFlushEntry(afs_int32 *fid) { /* Flush pages modified by one entry. */ struct buffer *tb; int code; ObtainReadLock(&afs_bufferLock); for (tb = phTable[pHash(fid)]; tb; tb = tb->hashNext) if (FidEq(tb->fid, fid) && tb->dirty) { ObtainWriteLock(&tb->lock); if (tb->dirty) { code = ReallyWrite(tb->fid, tb->page, tb->data); if (code) { ReleaseWriteLock(&tb->lock); ReleaseReadLock(&afs_bufferLock); return code; } tb->dirty = 0; } ReleaseWriteLock(&tb->lock); } ReleaseReadLock(&afs_bufferLock); return 0; }
/* * this routine simulates a read in the Memory Cache */ int afs_MemReadBlk(struct osi_file *fP, int offset, void *dest, int size) { struct memCacheEntry *mceP = (struct memCacheEntry *)fP; int bytesRead; ObtainReadLock(&mceP->afs_memLock); AFS_STATCNT(afs_MemReadBlk); if (offset < 0) { ReleaseReadLock(&mceP->afs_memLock); return 0; } /* use min of bytes in buffer or requested size */ bytesRead = (size < mceP->size - offset) ? size : mceP->size - offset; if (bytesRead > 0) { AFS_GUNLOCK(); memcpy(dest, mceP->data + offset, bytesRead); AFS_GLOCK(); } else bytesRead = 0; ReleaseReadLock(&mceP->afs_memLock); return bytesRead; }
/*! * \brief Query the AFSDB handler and wait for response. * \param acellName * \return 0 for success. < 0 is error. */ static int afs_GetCellHostsAFSDB(char *acellName) { AFS_ASSERT_GLOCK(); if (!afsdb_handler_running) return ENOENT; ObtainWriteLock(&afsdb_client_lock, 685); ObtainWriteLock(&afsdb_req_lock, 686); afsdb_req.cellname = acellName; afsdb_req.complete = 0; afsdb_req.pending = 1; afs_osi_Wakeup(&afsdb_req); ConvertWToRLock(&afsdb_req_lock); while (afsdb_handler_running && !afsdb_req.complete) { ReleaseReadLock(&afsdb_req_lock); afs_osi_Sleep(&afsdb_req); ObtainReadLock(&afsdb_req_lock); }; ReleaseReadLock(&afsdb_req_lock); ReleaseWriteLock(&afsdb_client_lock); if (afsdb_req.cellname) { return 0; } else return ENOENT; }
//---------------------------------------------------------------------------------------- unsigned int GenericAccessGroupCollectionEntry::GetEntryCount() const { ObtainReadLock(); unsigned int entryCount = (unsigned int)entries.size(); ReleaseReadLock(); return entryCount; }
/* * Invalidate the /afs vnode for dynroot; called when the underlying * directory has changed and needs to be re-read. */ void afs_DynrootInvalidate(void) { afs_int32 retry; struct vcache *tvc; struct VenusFid tfid; if (!afs_dynrootEnable) return; ObtainWriteLock(&afs_dynrootDirLock, 687); afs_dynrootVersion++; afs_dynrootVersionHigh = osi_Time(); ReleaseWriteLock(&afs_dynrootDirLock); afs_GetDynrootFid(&tfid); do { retry = 0; ObtainReadLock(&afs_xvcache); tvc = afs_FindVCache(&tfid, &retry, 0); ReleaseReadLock(&afs_xvcache); } while (retry); if (tvc) { tvc->f.states &= ~(CStatd | CUnique); osi_dnlc_purgedp(tvc); afs_PutVCache(tvc); } }
/*! * Print list of disconnected files. * * \note Call with afs_DDirtyVCListLock read locked. */ void afs_DbgDisconFiles(void) { struct vcache *tvc; struct afs_q *q; int i = 0; afs_warn("List of dirty files: \n"); ObtainReadLock(&afs_disconDirtyLock); for (q = QPrev(&afs_disconDirty); q != &afs_disconDirty; q = QPrev(q)) { tvc = QEntry(q, struct vcache, dirtyq); afs_warn("Cell=%u Volume=%u VNode=%u Unique=%u\n", tvc->f.fid.Cell, tvc->f.fid.Fid.Volume, tvc->f.fid.Fid.Vnode, tvc->f.fid.Fid.Unique); i++; if (i >= 30) osi_Panic("afs_DbgDisconFiles: loop in dirty list\n"); } ReleaseReadLock(&afs_disconDirtyLock); }
/* * this routine simulates a readv in the Memory Cache */ int afs_MemReadvBlk(struct memCacheEntry *mceP, int offset, struct iovec *iov, int nio, int size) { int i; int bytesRead; int bytesToRead; ObtainReadLock(&mceP->afs_memLock); AFS_STATCNT(afs_MemReadBlk); if (offset < 0) { ReleaseReadLock(&mceP->afs_memLock); return 0; } /* use min of bytes in buffer or requested size */ bytesRead = (size < mceP->size - offset) ? size : mceP->size - offset; if (bytesRead > 0) { for (i = 0, size = bytesRead; i < nio && size > 0; i++) { bytesToRead = (size < iov[i].iov_len) ? size : iov[i].iov_len; AFS_GUNLOCK(); memcpy(iov[i].iov_base, mceP->data + offset, bytesToRead); AFS_GLOCK(); offset += bytesToRead; size -= bytesToRead; } bytesRead -= size; } else bytesRead = 0; ReleaseReadLock(&mceP->afs_memLock); return bytesRead; }
int SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index, afs_int32 * a_srvr_addr, afs_int32 * a_srvr_rank) { int i, j; struct srvAddr *sa; RX_AFS_GLOCK(); AFS_STATCNT(SRXAFSCB_GetServerPrefs); ObtainReadLock(&afs_xserver); /* Search the hash table for the server with this index */ *a_srvr_addr = 0xffffffff; *a_srvr_rank = 0xffffffff; for (i = 0, j = 0; j < NSERVERS && i <= a_index; j++) { for (sa = afs_srvAddrs[j]; sa && i <= a_index; sa = sa->next_bkt, i++) { if (i == a_index) { *a_srvr_addr = ntohl(sa->sa_ip); *a_srvr_rank = sa->sa_iprank; } } } ReleaseReadLock(&afs_xserver); RX_AFS_GUNLOCK(); return 0; }
int SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr) { int i; int code = 0; RX_AFS_GLOCK(); AFS_STATCNT(SRXAFSCB_WhoAreYou); memset(addr, 0, sizeof(*addr)); ObtainReadLock(&afs_xinterface); /* return all network interface addresses */ addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces; addr->uuid = afs_cb_interface.uuid; for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) { addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]); addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]); addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]); } ReleaseReadLock(&afs_xinterface); RX_AFS_GUNLOCK(); return code; }
int afs_UFSHandleLink(register struct vcache *avc, struct vrequest *areq) { register struct dcache *tdc; register char *tp, *rbuf; void *tfile; afs_size_t offset, len; afs_int32 tlen, alen; register afs_int32 code; /* two different formats, one for links protected 644, have a "." at the * end of the file name, which we turn into a null. Others, protected * 755, we add a null to the end of */ AFS_STATCNT(afs_UFSHandleLink); if (!avc->linkData) { tdc = afs_GetDCache(avc, (afs_size_t) 0, areq, &offset, &len, 0); afs_Trace3(afs_iclSetp, CM_TRACE_UFSLINK, ICL_TYPE_POINTER, avc, ICL_TYPE_POINTER, tdc, ICL_TYPE_OFFSET, ICL_HANDLE_OFFSET(avc->f.m.Length)); if (!tdc) { if (AFS_IS_DISCONNECTED) return ENETDOWN; else return EIO; } /* otherwise we have the data loaded, go for it */ if (len > 1024) { afs_PutDCache(tdc); return EFAULT; } if (avc->f.m.Mode & 0111) alen = len + 1; /* regular link */ else alen = len; /* mt point */ rbuf = (char *)osi_AllocLargeSpace(AFS_LRALLOCSIZ); tlen = len; ObtainReadLock(&tdc->lock); #if defined(LINUX_USE_FH) tfile = osi_UFSOpen_fh(&tdc->f.fh, tdc->f.fh_type); #else tfile = osi_UFSOpen(tdc->f.inode); #endif code = afs_osi_Read(tfile, -1, rbuf, tlen); osi_UFSClose(tfile); ReleaseReadLock(&tdc->lock); afs_PutDCache(tdc); rbuf[alen - 1] = '\0'; alen = strlen(rbuf) + 1; tp = afs_osi_Alloc(alen); /* make room for terminating null */ memcpy(tp, rbuf, alen); osi_FreeLargeSpace(rbuf); if (code != tlen) { afs_osi_Free(tp, alen); return EIO; } avc->linkData = tp; } return 0; }
/*! * \brief Set a transaction lock. * \param atype is #LOCKREAD or #LOCKWRITE. * \param await is TRUE if you want to wait for the lock instead of returning * #EWOULDBLOCK. * * \note The #DBHOLD lock must be held. */ extern int ulock_getLock(struct ubik_trans *atrans, int atype, int await) { struct ubik_dbase *dbase = atrans->dbase; if ((atype != LOCKREAD) && (atype != LOCKWRITE)) return EINVAL; if (atrans->flags & TRDONE) return UDONE; if (atype != LOCKREAD && (atrans->flags & TRREADWRITE)) { return EINVAL; } if (atrans->locktype != 0) { ubik_print("Ubik: Internal Error: attempted to take lock twice\n"); abort(); } /* *ubik_print("Ubik: DEBUG: Thread 0x%x request %s lock\n", lwp_cpptr, * ((atype == LOCKREAD) ? "READ" : "WRITE")); */ /* Check if the lock would would block */ if (!await && !(atrans->flags & TRREADWRITE)) { if (atype == LOCKREAD) { if (WouldReadBlock(&rwlock)) return EAGAIN; } else { if (WouldWriteBlock(&rwlock)) return EAGAIN; } } /* Create new lock record and add to spec'd transaction: * locktype. This field also tells us if the thread is * waiting for a lock: It will be equal to LOCKWAIT. */ atrans->locktype = LOCKWAIT; DBRELE(dbase); if (atrans->flags & TRREADWRITE) { /* noop; don't actually lock anything for TRREADWRITE */ } else if (atype == LOCKREAD) { ObtainReadLock(&rwlock); } else { ObtainWriteLock(&rwlock); } DBHOLD(dbase); atrans->locktype = atype; /* *ubik_print("Ubik: DEBUG: Thread 0x%x took %s lock\n", lwp_cpptr, * ((atype == LOCKREAD) ? "READ" : "WRITE")); */ return 0; }
static void deadlock_read2 (void) { struct Lock lock; Lock_Init (&lock); ObtainReadLock(&lock); ObtainWriteLock(&lock); }
/*! * Check if the given name exists as a cell or alias. Locks afs_xcell. * \param aname * \return */ int afs_CellOrAliasExists(char *aname) { int ret; ObtainReadLock(&afs_xcell); ret = afs_CellOrAliasExists_nl(aname); ReleaseReadLock(&afs_xcell); return ret; }
/*! * Execute a callback for each existing cell, with a lock on afs_xcell. * \see afs_TraverseCells_nl * \param cb Traversal callback for each cell. * \param arg * \return Found data or NULL. */ void * afs_TraverseCells(void *(*cb) (struct cell *, void *), void *arg) { void *ret; ObtainReadLock(&afs_xcell); ret = afs_TraverseCells_nl(cb, arg); ReleaseReadLock(&afs_xcell); return ret; }
bool bbuf::full(void) { ObtainReadLock(&lock); if (count == bnd) { ReleaseReadLock(&lock); return mtrue; } else { ReleaseReadLock(&lock); return mfalse; } }
bool bbuf::empty(void) { ObtainReadLock(&lock); if (count == 0) { ReleaseReadLock(&lock); return mtrue; } else { ReleaseReadLock(&lock); return mfalse; } }
/*! * Get cell alias by index (starting at 0). * \param index Cell index. * \return Found struct or null. */ struct cell_alias * afs_GetCellAlias(int index) { struct cell_alias *tc; ObtainReadLock(&afs_xcell); for (tc = afs_cellalias_head; tc != NULL; tc = tc->next) if (tc->index == index) break; ReleaseReadLock(&afs_xcell); return tc; }
int DFlush(void) { /* Flush all the modified buffers. */ int i; struct buffer *tb; AFS_STATCNT(DFlush); tb = Buffers; ObtainReadLock(&afs_bufferLock); for (i = 0; i < nbuffers; i++, tb++) { if (tb->dirty) { ObtainWriteLock(&tb->lock, 263); tb->lockers++; ReleaseReadLock(&afs_bufferLock); if (tb->dirty) { /* it seems safe to do this I/O without having the dcache * locked, since the only things that will update the data in * a directory are the buffer package, which holds the relevant * tb->lock while doing the write, or afs_GetDCache, which * DZap's the directory while holding the dcache lock. * It is not possible to lock the dcache or even call * afs_GetDSlot to map the index to the dcache since the dir * package's caller has some dcache object locked already (so * we cannot lock afs_xdcache). In addition, we cannot obtain * a dcache lock while holding the tb->lock of the same file * since that can deadlock with DRead/DNew */ DFlushBuffer(tb); } tb->lockers--; ReleaseWriteLock(&tb->lock); ObtainReadLock(&afs_bufferLock); } } ReleaseReadLock(&afs_bufferLock); return 0; }
int afs_MemHandleLink(struct vcache *avc, struct vrequest *areq) { struct dcache *tdc; char *tp, *rbuf; afs_size_t offset, len; afs_int32 tlen, alen; afs_int32 code; AFS_STATCNT(afs_MemHandleLink); /* two different formats, one for links protected 644, have a "." at * the end of the file name, which we turn into a null. Others, * protected 755, we add a null to the end of */ if (!avc->linkData) { void *addr; tdc = afs_GetDCache(avc, (afs_size_t) 0, areq, &offset, &len, 0); if (!tdc) { return EIO; } /* otherwise we have the data loaded, go for it */ if (len > 1024) { afs_PutDCache(tdc); return EFAULT; } if (avc->f.m.Mode & 0111) alen = len + 1; /* regular link */ else alen = len; /* mt point */ rbuf = osi_AllocLargeSpace(AFS_LRALLOCSIZ); ObtainReadLock(&tdc->lock); addr = afs_MemCacheOpen(&tdc->f.inode); tlen = len; code = afs_MemReadBlk(addr, 0, rbuf, tlen); afs_MemCacheClose(addr); ReleaseReadLock(&tdc->lock); afs_PutDCache(tdc); rbuf[alen - 1] = 0; alen = strlen(rbuf) + 1; tp = afs_osi_Alloc(alen); /* make room for terminating null */ osi_Assert(tp != NULL); memcpy(tp, rbuf, alen); osi_FreeLargeSpace(rbuf); if (code != len) { afs_osi_Free(tp, alen); return EIO; } avc->linkData = tp; } return 0; }
void DZap(dir_file_t dir) { /* Destroy all buffers pertaining to a particular fid. */ struct buffer *tb; ObtainReadLock(&afs_bufferLock); for (tb = phTable[pHash(dir)]; tb; tb = tb->hashNext) if (FidEq(bufferDir(tb), dir)) { ObtainWriteLock(&tb->lock); FidZap(bufferDir(tb)); tb->dirty = 0; ReleaseWriteLock(&tb->lock); } ReleaseReadLock(&afs_bufferLock); }
void DZap(afs_int32 *fid) { /* Destroy all buffers pertaining to a particular fid. */ struct buffer *tb; ObtainReadLock(&afs_bufferLock); for (tb = phTable[pHash(fid)]; tb; tb = tb->hashNext) if (FidEq(tb->fid, fid)) { ObtainWriteLock(&tb->lock); FidZap(tb->fid); tb->dirty = 0; ReleaseWriteLock(&tb->lock); } ReleaseReadLock(&afs_bufferLock); }
int afs_MemReadUIO(afs_dcache_id_t *ainode, struct uio *uioP) { struct memCacheEntry *mceP = (struct memCacheEntry *)afs_MemCacheOpen(ainode); int length = mceP->size - AFS_UIO_OFFSET(uioP); afs_int32 code; AFS_STATCNT(afs_MemReadUIO); ObtainReadLock(&mceP->afs_memLock); length = (length < AFS_UIO_RESID(uioP)) ? length : AFS_UIO_RESID(uioP); AFS_UIOMOVE(mceP->data + AFS_UIO_OFFSET(uioP), length, UIO_READ, uioP, code); ReleaseReadLock(&mceP->afs_memLock); return code; }
void DFlushDCache(struct dcache *adc) { int i; struct buffer *tb; ObtainReadLock(&afs_bufferLock); for (i = 0; i <= PHPAGEMASK; i++) for (tb = phTable[pHash(adc->index, i)]; tb; tb = tb->hashNext) if (tb->fid == adc->index) { ObtainWriteLock(&tb->lock, 701); tb->lockers++; ReleaseReadLock(&afs_bufferLock); if (tb->dirty) { DFlushBuffer(tb); } tb->lockers--; ReleaseWriteLock(&tb->lock); ObtainReadLock(&afs_bufferLock); } ReleaseReadLock(&afs_bufferLock); }
/*! * Check if a cell number is valid (also set the used flag). * \param cellnum * \return 1 - true, 0 - false */ int afs_CellNumValid(afs_int32 cellnum) { struct cell_name *cn; ObtainReadLock(&afs_xcell); cn = afs_cellname_lookup_id(cellnum); ReleaseReadLock(&afs_xcell); if (cn) { cn->used = 1; return 1; } else { return 0; } }
int osi_dnlc_remove(struct vcache *adp, char *aname, struct vcache *avc) { unsigned int key, skey; char *ts = aname; struct nc *tnc; if (!afs_usednlc) return 0; TRACE(osi_dnlc_removeT, skey); dnlcHash(ts, key); /* leaves ts pointing at the NULL */ if (ts - aname >= AFSNCNAMESIZE) { return 0; } skey = key & (NHSIZE - 1); TRACE(osi_dnlc_removeT, skey); dnlcstats.removes++; ObtainReadLock(&afs_xdnlc); for (tnc = nameHash[skey]; tnc; tnc = tnc->next) { if ((tnc->dirp == adp) && (tnc->key == key) && (!strcmp((char *)tnc->name, aname))) { tnc->dirp = NULL; /* now it won't match anything */ break; } else if (tnc->next == nameHash[skey]) { /* end of list */ tnc = NULL; break; } } ReleaseReadLock(&afs_xdnlc); if (!tnc) return 0; /* there is a little race condition here, but it's relatively * harmless. At worst, I wind up removing a mapping that I just * created. */ if (EWOULDBLOCK == NBObtainWriteLock(&afs_xdnlc, 1)) { return 0; /* no big deal, tnc will get recycled eventually */ } RemoveEntry(tnc, skey); tnc->next = ncfreelist; ncfreelist = tnc; ReleaseWriteLock(&afs_xdnlc); return 0; }
/* Returns the "afs exporter" structure of type, "type". NULL is returned if not found */ struct afs_exporter * exporter_find(int type) { struct afs_exporter *op; AFS_STATCNT(exporter_add); ObtainReadLock(&afs_xexp); for (op = root_exported; op; op = op->exp_next) { if (op->exp_type == type) { ReleaseReadLock(&afs_xexp); return op; } } ReleaseReadLock(&afs_xexp); return (struct afs_exporter *)0; }
afs_int32 ka_LookupKey(struct ubik_trans *tt, char *name, char *inst, afs_int32 *kvno, /* returned */ struct ktc_encryptionKey *key) /* copied out */ { int i; afs_int32 to; struct kaentry tentry; afs_int32 code = 0; ObtainReadLock(&keycache_lock); if (keyCacheVersion != ntohl(cheader.specialKeysVersion)) code = KAKEYCACHEINVALID; else { for (i = 0; i < maxCachedKeys; i++) { if (keyCache[i].used) { /* zero used date means invalid */ if ((keyCache[i].superseded == NEVERDATE) && (strcmp(keyCache[i].name, name) == 0) && (strcmp(keyCache[i].inst, inst) == 0)) { memcpy(key, &keyCache[i].key, sizeof(*key)); *kvno = keyCache[i].kvno; keyCache[i].used = time(0); ReleaseReadLock(&keycache_lock); return 0; } } } code = KAUNKNOWNKEY; } ReleaseReadLock(&keycache_lock); if (!tt) return code; /* we missed in the cache so need to look in the Ubik database */ code = FindBlock(tt, name, inst, &to, &tentry); if (code) return code; if (to == 0) return KANOENT; memcpy(key, &tentry.key, sizeof(*key)); *kvno = ntohl(tentry.key_version); ka_Encache(name, inst, *kvno, key, NEVERDATE); return 0; }
/*! * Return a cell with a given cell number. * \param cellnum Cell number. * \param locktype Lock to be used. * \return */ struct cell * afs_GetCell(afs_int32 cellnum, afs_int32 locktype) { struct cell *tc; struct cell_name *cn; tc = afs_GetCellStale(cellnum, locktype); if (tc) { afs_RefreshCell(tc); } else { ObtainReadLock(&afs_xcell); cn = afs_cellname_lookup_id(cellnum); ReleaseReadLock(&afs_xcell); if (cn) tc = afs_GetCellByName(cn->cellname, locktype); } return tc; }