int (*close) (struct osi_file * fp);
int (*vreadUIO) (afs_dcache_id_t *, struct uio *);
int (*vwriteUIO) (struct vcache *, afs_dcache_id_t *, struct uio *);
- struct dcache *(*GetDSlot) (afs_int32 aslot, int needvalid);
+ struct dcache *(*GetDSlot) (afs_int32 aslot, int indexvalid, int datavalid);
struct volume *(*GetVolSlot) (void);
int (*HandleLink) (struct vcache * avc, struct vrequest * areq);
};
#define afs_CFileRead(file, offset, data, size) (*(afs_cacheType->fread))(file, offset, data, size)
#define afs_CFileWrite(file, offset, data, size) (*(afs_cacheType->fwrite))(file, offset, data, size)
#define afs_CFileClose(handle) (*(afs_cacheType->close))(handle)
-#define afs_GetValidDSlot(slot) (*(afs_cacheType->GetDSlot))(slot, 1)
-#define afs_GetNewDSlot(slot) (*(afs_cacheType->GetDSlot))(slot, 0)
#define afs_GetVolSlot() (*(afs_cacheType->GetVolSlot))()
#define afs_HandleLink(avc, areq) (*(afs_cacheType->HandleLink))(avc, areq)
+/* Use afs_GetValidDSlot to get a dcache from a dcache slot number when we
+ * know the dcache contains data we want (e.g. it's on the hash table) */
+#define afs_GetValidDSlot(slot) (*(afs_cacheType->GetDSlot))(slot, 1, 1)
+/* Use afs_GetUnusedDSlot when loading a dcache entry that is on the free or
+ * discard lists (the dcache does not contain valid data, but we know the
+ * dcache entry itself exists). */
+#define afs_GetUnusedDSlot(slot) (*(afs_cacheType->GetDSlot))(slot, 1, 0)
+/* Use afs_GetNewDSlot only when initializing dcache slots (the given slot
+ * number may not exist at all). */
+#define afs_GetNewDSlot(slot) (*(afs_cacheType->GetDSlot))(slot, 0, 0)
+
/* These memcpys should get optimised to simple assignments when afs_dcache_id_t
* is simple */
static_inline void afs_copy_inode(afs_dcache_id_t *dst, afs_dcache_id_t *src) {
/*
* Get an entry from the list of discarded cache elements
*/
- tdc = afs_GetNewDSlot(afs_discardDCList);
+ tdc = afs_GetUnusedDSlot(afs_discardDCList);
+ osi_Assert(tdc);
osi_Assert(tdc->refCount == 1);
ReleaseReadLock(&tdc->tlock);
|| ((lock & 2) && afs_freeDCList != NULLIDX)) {
afs_indexFlags[afs_freeDCList] &= ~IFFree;
- tdc = afs_GetNewDSlot(afs_freeDCList);
+ tdc = afs_GetUnusedDSlot(afs_freeDCList);
+ osi_Assert(tdc);
osi_Assert(tdc->refCount == 1);
ReleaseReadLock(&tdc->tlock);
ObtainWriteLock(&tdc->lock, 604);
afs_freeDCCount--;
} else {
afs_indexFlags[afs_discardDCList] &= ~IFDiscarded;
- tdc = afs_GetNewDSlot(afs_discardDCList);
+ tdc = afs_GetUnusedDSlot(afs_discardDCList);
+ osi_Assert(tdc);
osi_Assert(tdc->refCount == 1);
ReleaseReadLock(&tdc->tlock);
ObtainWriteLock(&tdc->lock, 605);
*/
struct dcache *
-afs_MemGetDSlot(afs_int32 aslot, int needvalid)
+afs_MemGetDSlot(afs_int32 aslot, int indexvalid, int datavalid)
{
struct dcache *tdc;
int existing = 0;
return tdc;
}
- /* if 'needvalid' is true, the slot must already exist and be populated
+ /* 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(!needvalid);
+ osi_Assert(!indexvalid);
if (!afs_freeDSList)
afs_GetDownDSlot(4);
*
* Parameters:
* aslot : Dcache slot to look at.
- * needvalid : Whether the specified slot should already exist
+ * 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.
*
* Environment:
* afs_xdcache lock write-locked.
*/
struct dcache *
-afs_UFSGetDSlot(afs_int32 aslot, int needvalid)
+afs_UFSGetDSlot(afs_int32 aslot, int indexvalid, int datavalid)
{
afs_int32 code;
struct dcache *tdc;
last_error = code;
#endif
lasterrtime = osi_Time();
- if (needvalid) {
+ if (indexvalid) {
struct osi_stat tstat;
if (afs_osi_Stat(afs_cacheInodep, &tstat)) {
tstat.size = -1;
}
if (!afs_CellNumValid(tdc->f.fid.Cell)) {
entryok = 0;
- if (needvalid) {
+ if (datavalid) {
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 (needvalid && tdc->f.fid.Fid.Volume == 0) {
+ if (datavalid && tdc->f.fid.Fid.Volume == 0) {
osi_Panic("afs: invalid zero-volume dcache entry at slot %d off %d",
(int)aslot, off);
}
- if (!entryok) {
+ if (!entryok || !datavalid) {
tdc->f.fid.Cell = 0;
tdc->f.fid.Fid.Volume = 0;
tdc->f.chunk = -1;
extern void shutdown_dcache(void);
extern void afs_CacheTruncateDaemon(void);
extern afs_int32 afs_fsfragsize;
-extern struct dcache *afs_MemGetDSlot(afs_int32 aslot, int needvalid);
+extern struct dcache *afs_MemGetDSlot(afs_int32 aslot, int indexvalid, int datavalid);
extern struct dcache *afs_GetDCache(struct vcache *avc,
afs_size_t abyte,
struct vrequest *areq,
extern void updateV2DC(int lockVc, struct vcache *v, struct dcache *d,
int src);
extern void afs_WriteThroughDSlots(void);
-extern struct dcache *afs_UFSGetDSlot(afs_int32 aslot, int needvalid);
+extern struct dcache *afs_UFSGetDSlot(afs_int32 aslot, int indexvalid, int datavalid);
extern int afs_WriteDCache(struct dcache *adc, int atime);
extern int afs_wakeup(struct vcache *avc);
extern int afs_InitCacheFile(char *afile, ino_t ainode);