int cacheDiskType; /*Type of backing disk for cache */
struct afs_cacheOps *afs_cacheType;
+
+/*
+ * The PFlush algorithm makes use of the fact that Fid.Unique is not used in
+ * below hash algorithms. Change it if need be so that flushing algorithm
+ * doesn't move things from one hash chain to another.
+ */
+/*Vnode, Chunk -> Hash table index */
+int DCHash(struct VenusFid *fid, afs_int32 chunk)
+{
+ afs_uint32 buf[3];
+
+ buf[0] = fid->Fid.Volume;
+ buf[1] = fid->Fid.Vnode;
+ buf[2] = chunk;
+ return opr_jhash(buf, 3, 0) & (afs_dhashsize - 1);
+}
+/*Vnode -> Other hash table index */
+int DVHash(struct VenusFid *fid)
+{
+ return opr_jhash_int2(fid->Fid.Volume, fid->Fid.Vnode, 0) &
+ (afs_dhashsize - 1);
+}
+
/*!
* Where is this vcache's entry associated dcache located/
* \param avc The vcache entry.
afs_PutDCache(tdc);
tdc = 0;
ReleaseReadLock(&avc->lock);
+
+ if (tc) {
+ /* If we have a connection, we must put it back,
+ * since afs_Analyze will not be called here. */
+ afs_PutConn(tc, rxconn, SHARED_LOCK);
+ }
+
slowPass = 1;
goto RetryGetDCache;
}
*/
struct afs_fheader theader;
- theader.magic = AFS_FHMAGIC;
- theader.firstCSize = AFS_FIRSTCSIZE;
- theader.otherCSize = AFS_OTHERCSIZE;
- theader.version = AFS_CI_VERSION;
- theader.dataSize = sizeof(struct fcache);
+ afs_InitFHeader(&theader);
afs_osi_Write(afs_cacheInodep, 0, &theader, sizeof(theader));
}
ReleaseWriteLock(&afs_xdcache);
*
* Parameters:
* aslot : Dcache slot to look at.
- * needvalid : Whether the specified slot should already exist
+ * type : What 'type' of dslot to get; see the dslot_state enum
*
* Environment:
* Must be called with afs_xdcache write-locked.
*/
struct dcache *
-afs_MemGetDSlot(afs_int32 aslot, int indexvalid, int datavalid)
+afs_MemGetDSlot(afs_int32 aslot, dslot_state type)
{
struct dcache *tdc;
int existing = 0;
return tdc;
}
- /* if 'indexvalid' is true, the slot must already exist and be populated
- * somewhere. for memcache, the only place that dcache entries exist is
- * in memory, so if we did not find it above, something is very wrong. */
- osi_Assert(!indexvalid);
+ /* if we got here, the given slot is not in memory in our list of known
+ * slots. for memcache, the only place a dslot can exist is in memory, so
+ * if the caller is expecting to get back a known dslot, and we've reached
+ * here, something is very wrong. DSLOT_NEW is the only type of dslot that
+ * may not exist; for all others, the caller assumes the given dslot
+ * already exists. so, 'type' had better be DSLOT_NEW here, or something is
+ * very wrong. */
+ osi_Assert(type == DSLOT_NEW);
if (!afs_freeDSList)
afs_GetDownDSlot(4);
*
* Parameters:
* aslot : Dcache slot to look at.
- * indexvalid : 1 if we know the slot we're giving is valid, and thus
- * reading the dcache from the disk index should succeed. 0
- * if we are initializing a new dcache, and so reading from
- * the disk index may fail.
- * datavalid : 0 if we are loading a dcache entry from the free or
- * discard list, so we know the data in the given dcache is
- * not valid. 1 if we are loading a known used dcache, so the
- * data in the dcache must be valid.
+ * type : What 'type' of dslot to get; see the dslot_state enum
*
* Environment:
* afs_xdcache lock write-locked.
*/
struct dcache *
-afs_UFSGetDSlot(afs_int32 aslot, int indexvalid, int datavalid)
+afs_UFSGetDSlot(afs_int32 aslot, dslot_state type)
{
afs_int32 code;
struct dcache *tdc;
last_error = code;
#endif
lasterrtime = osi_Time();
- if (indexvalid) {
+ if (type != DSLOT_NEW) {
+ /* If we are requesting a non-DSLOT_NEW slot, this is an error.
+ * non-DSLOT_NEW slots are supposed to already exist, so if we
+ * failed to read in the slot, something is wrong. */
struct osi_stat tstat;
if (afs_osi_Stat(afs_cacheInodep, &tstat)) {
tstat.size = -1;
}
if (!afs_CellNumValid(tdc->f.fid.Cell)) {
entryok = 0;
- if (datavalid) {
+ if (type == DSLOT_VALID) {
osi_Panic("afs: needed valid dcache but index %d off %d has "
"invalid cell num %d\n",
(int)aslot, off, (int)tdc->f.fid.Cell);
}
}
- if (datavalid && tdc->f.fid.Fid.Volume == 0) {
+ if (type == DSLOT_VALID && tdc->f.fid.Fid.Volume == 0) {
osi_Panic("afs: invalid zero-volume dcache entry at slot %d off %d",
(int)aslot, off);
}
- if (indexvalid && !datavalid) {
- /* we know that the given dslot does exist, but the data in it is not
- * valid. this only occurs when we pull a dslot from the free or
- * discard list, so be sure not to re-use the data; force invalidation.
+ if (type == DSLOT_UNUSED) {
+ /* the requested dslot is known to exist, but contain invalid data
+ * (this happens when we're using a dslot from the free or discard
+ * list). be sure not to re-use the data in it, so force invalidation.
*/
entryok = 0;
}
tdc->f.states &= ~(DRO|DBackup|DRW);
afs_DCMoveBucket(tdc, 0, 0);
} else {
- if (&tdc->f != 0) {
- if (tdc->f.states & DRO) {
- afs_DCMoveBucket(tdc, 0, 2);
- } else if (tdc->f.states & DBackup) {
- afs_DCMoveBucket(tdc, 0, 1);
- } else {
- afs_DCMoveBucket(tdc, 0, 1);
- }
+ if (tdc->f.states & DRO) {
+ afs_DCMoveBucket(tdc, 0, 2);
+ } else if (tdc->f.states & DBackup) {
+ afs_DCMoveBucket(tdc, 0, 1);
+ } else {
+ afs_DCMoveBucket(tdc, 0, 1);
}
}
tdc->refCount = 1;