length -= tlen;
adc->validPos = abase;
if (adc->flags & DFWaiting) {
+ afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
+ ICL_TYPE_STRING, __FILE__,
+ ICL_TYPE_INT32, __LINE__,
+ ICL_TYPE_POINTER, adc,
+ ICL_TYPE_INT32, adc->flags);
adc->flags &= ~DFWaiting;
afs_osi_Wakeup(&adc->validPos);
}
#endif
}
MReleaseReadLock(&afs_xdcache);
+ if (!shortcut)
+ tdc = 0;
}
- if (!shortcut)
- {
-
- /*
- * Hash on the [fid, chunk] and get the corresponding dcache index
- * after write-locking the dcache.
- */
+ if (!tdc) {
+ /*
+ * Hash on the [fid, chunk] and get the corresponding dcache index
+ * after write-locking the dcache.
+ */
RetryLookup:
- i = DCHash(&avc->fid, chunk);
- afs_MaybeWakeupTruncateDaemon(); /* check to make sure our space is fine */
- MObtainWriteLock(&afs_xdcache,280);
- us = NULLIDX;
- for(index = afs_dchashTbl[i]; index != NULLIDX;) {
- if (afs_indexUnique[index] == avc->fid.Fid.Unique) {
- tdc = afs_GetDSlot(index, (struct dcache *)0);
- if (!FidCmp(&tdc->f.fid, &avc->fid) && chunk == tdc->f.chunk) {
- /* Move it up in the beginning of the list */
- if (afs_dchashTbl[i] != index) {
- afs_dcnextTbl[us] = afs_dcnextTbl[index];
- afs_dcnextTbl[index] = afs_dchashTbl[i];
- afs_dchashTbl[i] = index;
+ i = DCHash(&avc->fid, chunk);
+ afs_MaybeWakeupTruncateDaemon(); /* check to make sure our space is fine */
+ MObtainWriteLock(&afs_xdcache,280);
+ us = NULLIDX;
+ for(index = afs_dchashTbl[i]; index != NULLIDX;) {
+ if (afs_indexUnique[index] == avc->fid.Fid.Unique) {
+ tdc = afs_GetDSlot(index, (struct dcache *)0);
+ if (!FidCmp(&tdc->f.fid, &avc->fid) && chunk == tdc->f.chunk) {
+ /* Move it up in the beginning of the list */
+ if (afs_dchashTbl[i] != index) {
+ afs_dcnextTbl[us] = afs_dcnextTbl[index];
+ afs_dcnextTbl[index] = afs_dchashTbl[i];
+ afs_dchashTbl[i] = index;
+ }
+ MReleaseWriteLock(&afs_xdcache);
+ break; /* leaving refCount high for caller */
}
- MReleaseWriteLock(&afs_xdcache);
- break; /* leaving refCount high for caller */
- }
- lockedPutDCache(tdc);
- }
- us = index;
- index = afs_dcnextTbl[index];
- }
- /*
- * If we didn't find the entry, we'll create one.
- */
- if (index == NULLIDX) {
- afs_Trace2(afs_iclSetp, CM_TRACE_GETDCACHE1, ICL_TYPE_POINTER, avc,
- ICL_TYPE_INT32, chunk);
-
- if (afs_discardDCList == NULLIDX && afs_freeDCList == NULLIDX) {
- while (1) {
- if (!setLocks) avc->states |= CDCLock;
- afs_GetDownD(5, (int*)0); /* just need slots */
- if (!setLocks) avc->states &= (~CDCLock);
- if (afs_discardDCList != NULLIDX || afs_freeDCList != NULLIDX)
- break;
- /* If we can't get space for 5 mins we give up and panic */
- if (++downDCount > 300)
- osi_Panic("getdcache");
- MReleaseWriteLock(&afs_xdcache);
- afs_osi_Wait(1000, 0, 0);
- goto RetryLookup;
+ tdc->refCount--; /* was incremented by afs_GetDSlot */
+ tdc = 0;
+ }
+ us = index;
+ index = afs_dcnextTbl[index];
+ }
+ /*
+ * If we didn't find the entry, we'll create one.
+ */
+ if (index == NULLIDX) {
+ afs_Trace2(afs_iclSetp, CM_TRACE_GETDCACHE1, ICL_TYPE_POINTER, avc,
+ ICL_TYPE_INT32, chunk);
+
+ if (afs_discardDCList == NULLIDX && afs_freeDCList == NULLIDX) {
+ while (1) {
+ if (!setLocks) avc->states |= CDCLock;
+ afs_GetDownD(5, (int*)0); /* just need slots */
+ if (!setLocks) avc->states &= (~CDCLock);
+ if (afs_discardDCList != NULLIDX || afs_freeDCList != NULLIDX)
+ break;
+ /* If we can't get space for 5 mins we give up and panic */
+ if (++downDCount > 300)
+ osi_Panic("getdcache");
+ MReleaseWriteLock(&afs_xdcache);
+ afs_osi_Wait(1000, 0, 0);
+ goto RetryLookup;
+ }
}
- }
- if (afs_discardDCList == NULLIDX ||
- ((aflags & 2) && afs_freeDCList != NULLIDX)) {
- afs_indexFlags[afs_freeDCList] &= ~IFFree;
- tdc = afs_GetDSlot(afs_freeDCList, 0);
- afs_freeDCList = afs_dvnextTbl[tdc->index];
- afs_freeDCCount--;
- } else {
- afs_indexFlags[afs_discardDCList] &= ~IFDiscarded;
- tdc = afs_GetDSlot(afs_discardDCList, 0);
- afs_discardDCList = afs_dvnextTbl[tdc->index];
- afs_discardDCCount--;
- size = ((tdc->f.chunkBytes + afs_fsfragsize)^afs_fsfragsize)>>10;
- afs_blocksDiscarded -= size;
- afs_stats_cmperf.cacheBlocksDiscarded = afs_blocksDiscarded;
- if (aflags & 2) {
- /* Truncate the chunk so zeroes get filled properly */
- file = afs_CFileOpen(tdc->f.inode);
- afs_CFileTruncate(file, 0);
- afs_CFileClose(file);
- afs_AdjustSize(tdc, 0);
+ if (afs_discardDCList == NULLIDX ||
+ ((aflags & 2) && afs_freeDCList != NULLIDX)) {
+ afs_indexFlags[afs_freeDCList] &= ~IFFree;
+ tdc = afs_GetDSlot(afs_freeDCList, 0);
+ afs_freeDCList = afs_dvnextTbl[tdc->index];
+ afs_freeDCCount--;
+ } else {
+ afs_indexFlags[afs_discardDCList] &= ~IFDiscarded;
+ tdc = afs_GetDSlot(afs_discardDCList, 0);
+ afs_discardDCList = afs_dvnextTbl[tdc->index];
+ afs_discardDCCount--;
+ size = ((tdc->f.chunkBytes + afs_fsfragsize)^afs_fsfragsize)>>10;
+ afs_blocksDiscarded -= size;
+ afs_stats_cmperf.cacheBlocksDiscarded = afs_blocksDiscarded;
+ if (aflags & 2) {
+ /* Truncate the chunk so zeroes get filled properly */
+ file = afs_CFileOpen(tdc->f.inode);
+ afs_CFileTruncate(file, 0);
+ afs_CFileClose(file);
+ afs_AdjustSize(tdc, 0);
+ }
}
- }
-
- /*
- * Fill in the newly-allocated dcache record.
- */
- afs_indexFlags[tdc->index] &= ~(IFDirtyPages | IFAnyPages);
- tdc->f.fid = avc->fid;
- afs_indexUnique[tdc->index] = tdc->f.fid.Fid.Unique;
- hones(tdc->f.versionNo); /* invalid value */
- tdc->f.chunk = chunk;
- /* XXX */
- if (tdc->lruq.prev == &tdc->lruq) osi_Panic("lruq 1");
- /*
- * Now add to the two hash chains - note that i is still set
- * from the above DCHash call.
- */
- afs_dcnextTbl[tdc->index] = afs_dchashTbl[i];
- afs_dchashTbl[i] = tdc->index;
- i = DVHash(&avc->fid);
- afs_dvnextTbl[tdc->index] = afs_dvhashTbl[i];
- afs_dvhashTbl[i] = tdc->index;
- tdc->flags = DFEntryMod;
- tdc->f.states = 0;
- afs_MaybeWakeupTruncateDaemon();
- MReleaseWriteLock(&afs_xdcache);
- }
- } /* else hint failed... */
+
+ /*
+ * Fill in the newly-allocated dcache record.
+ */
+ afs_indexFlags[tdc->index] &= ~(IFDirtyPages | IFAnyPages);
+ tdc->f.fid = avc->fid;
+ afs_indexUnique[tdc->index] = tdc->f.fid.Fid.Unique;
+ hones(tdc->f.versionNo); /* invalid value */
+ tdc->f.chunk = chunk;
+ tdc->validPos = AFS_CHUNKTOBASE(chunk);
+ /* XXX */
+ if (tdc->lruq.prev == &tdc->lruq) osi_Panic("lruq 1");
+ /*
+ * Now add to the two hash chains - note that i is still set
+ * from the above DCHash call.
+ */
+ afs_dcnextTbl[tdc->index] = afs_dchashTbl[i];
+ afs_dchashTbl[i] = tdc->index;
+ i = DVHash(&avc->fid);
+ afs_dvnextTbl[tdc->index] = afs_dvhashTbl[i];
+ afs_dvhashTbl[i] = tdc->index;
+ tdc->flags = DFEntryMod;
+ tdc->f.states = 0;
+ afs_MaybeWakeupTruncateDaemon();
+ MReleaseWriteLock(&afs_xdcache);
+ }
+ } /* else hint failed... */
afs_Trace4(afs_iclSetp, CM_TRACE_GETDCACHE2, ICL_TYPE_POINTER, avc,
ICL_TYPE_POINTER, tdc,
* that this chunk's data hasn't been filled by another client.
*/
size = AFS_CHUNKSIZE(abyte);
- tlen = *alen;
+ if (aflags & 4) /* called from write */
+ tlen = *alen;
+ else /* called from read */
+ tlen = tdc->validPos - abyte;
Position = AFS_CHUNKTOBASE(chunk);
afs_Trace4(afs_iclSetp, CM_TRACE_GETDCACHE3,
ICL_TYPE_INT32, tlen,
hset(afs_indexTimes[tdc->index], afs_indexCounter);
hadd32(afs_indexCounter, 1);
updateV2DC(setLocks,avc,tdc,567);
+ if (vType(avc) == VDIR)
+ *aoffset = abyte;
+ else
+ *aoffset = AFS_CHUNKOFFSET(abyte);
+ if (tdc->validPos < abyte)
+ *alen = (afs_size_t) 0;
+ else
+ *alen = tdc->validPos - abyte;
return tdc; /* check if we're done */
}
osi_Assert(setLocks || WriteLocked(&avc->lock));
afs_RemoveVCB(&avc->fid);
tdc->f.states |= DWriting;
tdc->flags |= DFFetching;
- tdc->validPos = Position; /*Last valid position in this chunk*/
+ tdc->validPos = Position; /* which is AFS_CHUNKBASE(abyte) */
if (tdc->flags & DFFetchReq) {
tdc->flags &= ~DFFetchReq;
afs_osi_Wakeup(&tdc->validPos);
tdc->flags &= ~DFFetching;
if (tdc->flags & DFWaiting) {
+ afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT,
+ ICL_TYPE_STRING, __FILE__,
+ ICL_TYPE_INT32, __LINE__,
+ ICL_TYPE_POINTER, tdc,
+ ICL_TYPE_INT32, tdc->flags);
tdc->flags &= ~DFWaiting;
afs_osi_Wakeup(&tdc->validPos);
}
*aoffset = abyte;
else
*aoffset = AFS_CHUNKOFFSET(abyte);
- *alen = (tdc->f.chunkBytes - *aoffset);
+ *alen = *aoffset + tdc->f.chunkBytes - abyte;
}
return tdc;
# Copyright 2000, International Business Machines Corporation and others.
# All Rights Reserved.
-#
+#
# This software has been released under the terms of the IBM Public
# License. For details, see the LICENSE file in the top-level source
# directory or online at http://www.openafs.org/dl/license10.html
ec CM_TRACE_STOREALL, "StoreAll vp 0x%lx len (0x%x, 0x%x)"
ec CM_TRACE_INVALL, "InvalAll vp 0x%lx len 0x%x"
ec CM_TRACE_TRUNCALL, "TruncAll vp 0x%lx old len (0x%x, 0x%x) new len (0x%x, 0x%x)"
+
ec CM_TRACE_GNLINK, "Gn_link vp 0x%lx name %s (returns 0x%x)"
ec CM_TRACE_GMKDIR, "Gn_mkdir vp 0x%lx name %s mode 0x%x (returns 0x%x)"
ec CM_TRACE_GMKNOD, "Gn_mknod vp 0x%lx name %s mode 0x%x (returns 0x%x)"
ec CM_TRACE_STUFFVCACHE, "StuffVcache 0x%lx callback host 0x%lx expires %u (in %u secs)"
ec CM_TRACE_GETDCACHE1, "Getdcache vp 0x%lx failed to find chunk 0x%x"
ec CM_TRACE_GETDCACHE2, "GetdCache vp 0x%lx dcache 0x%lx dcache low-version 0x%x, vcache low-version 0x%x"
- ec CM_TRACE_GETDCACHE3, "GetdCache tlen 0x%x size 0x%x abyte (0x%x, 0x%x) Position (0x%x, 0x%x)"
+ ec CM_TRACE_GETDCACHE3, "GetdCache tlen 0x%x flags 0x%x abyte (0x%x, 0x%x) Position (0x%x, 0x%x)"
ec CM_TRACE_STOREMINI, "storemini vp 0x%lx length 0x%x"
ec CM_TRACE_STOREDCACHE, "StoreDCache vp 0x%lx chunk 0x%x length 0x%x at position 0x%x"
ec CM_TRACE_STOREDCACHEDONE, "StoreDCache Done for vp 0x%lx (returns 0x%x)"
ec CM_TRACE_STOREPROC2, "StoreProc got 0x%x"
ec CM_TRACE_ADJUSTSIZE, "AdjustSize index %d oldSize %d newSize %d blocksUsed %d"
ec CM_TRACE_SETLENGTH, "%s line %d: m.Length was (0x%x, 0x%x), now (0x%x, 0x%x)"
+ ec CM_TRACE_DCACHEWAIT, "%s line %d: sleeping or waiting for 0x%x flags 0x%x"
+ ec CM_TRACE_VNODEREAD, "UFSRead: tdc 0x%x, offset (0x%x, 0x%x) len (0x%x 0x%x)"
+ ec CM_TRACE_SLEEP, "Sleep: evp 0x%x, count %d seq 0x%x evp->seq 0x%x"
+ ec CM_TRACE_WAKE, "Wapeup: evp 0x%x, evp->seq 0x%x"
end