}
}
-/* call with cm_scacheLock write-locked and scp rw held */
-void cm_RemoveSCacheFromHashTable(cm_scache_t *scp)
+static int
+cm_RemoveSCacheFromHashChain(cm_scache_t *scp, int index)
{
cm_scache_t **lscpp;
cm_scache_t *tscp;
- int i;
+ int found = 0;
+
+ for (lscpp = &cm_data.scacheHashTablep[index], tscp = cm_data.scacheHashTablep[index];
+ tscp;
+ lscpp = &tscp->nextp, tscp = tscp->nextp) {
+ if (tscp == scp) {
+ *lscpp = scp->nextp;
+ scp->nextp = NULL;
+ found = 1;
+ break;
+ }
+ }
+
+ return found;
+}
+/* call with cm_scacheLock write-locked and scp rw held */
+void cm_RemoveSCacheFromHashTable(cm_scache_t *scp)
+{
lock_AssertWrite(&cm_scacheLock);
lock_AssertWrite(&scp->rw);
if (scp->flags & CM_SCACHEFLAG_INHASH) {
+ int h,i;
+ int found = 0;
+
/* hash it out first */
- i = CM_SCACHE_HASH(&scp->fid);
- for (lscpp = &cm_data.scacheHashTablep[i], tscp = cm_data.scacheHashTablep[i];
- tscp;
- lscpp = &tscp->nextp, tscp = tscp->nextp) {
- if (tscp == scp) {
- *lscpp = scp->nextp;
- scp->nextp = NULL;
- _InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_INHASH);
- break;
+ h = CM_SCACHE_HASH(&scp->fid);
+ found = cm_RemoveSCacheFromHashChain(scp, h);
+
+ if (!found) {
+ /*
+ * The CM_SCACHEFLAG_INHASH is set on the cm_scache_t but
+ * we didn't find the entry in the expected hash chain.
+ * Did the fid change?
+ * In any case, we will search the entire hashtable for
+ * the object. If we don't find it, then we know it is
+ * safe to remove the flag.
+ */
+ for (i=0; !found && i<cm_data.scacheHashTableSize; i++) {
+ if (i != h)
+ found = cm_RemoveSCacheFromHashChain(scp, i);
}
+
+ if (found)
+ osi_Log1(afsd_logp,"cm_RemoveSCacheFromHashTable scp 0x%p found in wrong hash chain", scp);
+ else
+ osi_Log1(afsd_logp,"cm_RemoveSCacheFromHashTable scp 0x%p not found in hash table", scp);
}
+
+ _InterlockedAnd(&scp->flags, ~CM_SCACHEFLAG_INHASH);
}
}
for ( scp = cm_data.scacheLRUFirstp, lscp = NULL, i = 0;
scp;
lscp = scp, scp = (cm_scache_t *) osi_QNext(&scp->q), i++ ) {
+
+ if ( scp < (cm_scache_t *)cm_data.scacheBaseAddress ||
+ scp >= (cm_scache_t *)cm_data.dnlcBaseAddress) {
+ afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers");
+ fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n");
+ return -18;
+ }
+
if (scp->magic != CM_SCACHE_MAGIC) {
afsi_log("cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC");
fprintf(stderr, "cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC\n");
return -1;
}
+
+ if ( scp->nextp < (cm_scache_t *)cm_data.scacheBaseAddress ||
+ scp->nextp >= (cm_scache_t *)cm_data.dnlcBaseAddress) {
+ afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers");
+ fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n");
+ return -21;
+ }
+
if (scp->nextp && scp->nextp->magic != CM_SCACHE_MAGIC) {
afsi_log("cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC");
fprintf(stderr, "cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC\n");
return -2;
}
+
+ if ( scp->randomACLp < (cm_aclent_t *)cm_data.aclBaseAddress ||
+ scp->randomACLp >= (cm_aclent_t *)cm_data.scacheBaseAddress) {
+ afsi_log("cm_ValidateSCache failure: out of range cm_aclent_t pointers");
+ fprintf(stderr, "cm_ValidateSCache failure: out of range cm_aclent_t pointers\n");
+ return -32;
+ }
+
if (scp->randomACLp && scp->randomACLp->magic != CM_ACLENT_MAGIC) {
afsi_log("cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC");
fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n");
for ( scp = cm_data.scacheLRULastp, lscp = NULL, i = 0; scp;
lscp = scp, scp = (cm_scache_t *) osi_QPrev(&scp->q), i++ ) {
+
+ if ( scp < (cm_scache_t *)cm_data.scacheBaseAddress ||
+ scp >= (cm_scache_t *)cm_data.dnlcBaseAddress) {
+ afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers");
+ fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n");
+ return -19;
+ }
+
if (scp->magic != CM_SCACHE_MAGIC) {
afsi_log("cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC");
fprintf(stderr, "cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC\n");
return -5;
}
+
+ if ( scp->nextp < (cm_scache_t *)cm_data.scacheBaseAddress ||
+ scp->nextp >= (cm_scache_t *)cm_data.dnlcBaseAddress) {
+ afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers");
+ fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n");
+ return -22;
+ }
+
if (scp->nextp && scp->nextp->magic != CM_SCACHE_MAGIC) {
afsi_log("cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC");
fprintf(stderr, "cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC\n");
return -6;
}
+
+ if ( scp->randomACLp < (cm_aclent_t *)cm_data.aclBaseAddress ||
+ scp->randomACLp >= (cm_aclent_t *)cm_data.scacheBaseAddress) {
+ afsi_log("cm_ValidateSCache failure: out of range cm_aclent_t pointers");
+ fprintf(stderr, "cm_ValidateSCache failure: out of range cm_aclent_t pointers\n");
+ return -31;
+ }
+
if (scp->randomACLp && scp->randomACLp->magic != CM_ACLENT_MAGIC) {
afsi_log("cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC");
fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n");
for ( i=0; i < cm_data.scacheHashTableSize; i++ ) {
for ( scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp ) {
afs_uint32 hash;
+
+ if ( scp < (cm_scache_t *)cm_data.scacheBaseAddress ||
+ scp >= (cm_scache_t *)cm_data.dnlcBaseAddress) {
+ afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers");
+ fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n");
+ return -20;
+ }
+
hash = CM_SCACHE_HASH(&scp->fid);
+
if (scp->magic != CM_SCACHE_MAGIC) {
afsi_log("cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC");
fprintf(stderr, "cm_ValidateSCache failure: scp->magic != CM_SCACHE_MAGIC\n");
return -9;
}
+
+ if ( scp->nextp < (cm_scache_t *)cm_data.scacheBaseAddress ||
+ scp->nextp >= (cm_scache_t *)cm_data.dnlcBaseAddress) {
+ afsi_log("cm_ValidateSCache failure: out of range cm_scache_t pointers");
+ fprintf(stderr, "cm_ValidateSCache failure: out of range cm_scache_t pointers\n");
+ return -23;
+ }
+
if (scp->nextp && scp->nextp->magic != CM_SCACHE_MAGIC) {
afsi_log("cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC");
fprintf(stderr, "cm_ValidateSCache failure: scp->nextp->magic != CM_SCACHE_MAGIC\n");
return -10;
}
+
+ if ( scp->randomACLp < (cm_aclent_t *)cm_data.aclBaseAddress ||
+ scp->randomACLp >= (cm_aclent_t *)cm_data.scacheBaseAddress) {
+ afsi_log("cm_ValidateSCache failure: out of range cm_aclent_t pointers");
+ fprintf(stderr, "cm_ValidateSCache failure: out of range cm_aclent_t pointers\n");
+ return -30;
+ }
+
if (scp->randomACLp && scp->randomACLp->magic != CM_ACLENT_MAGIC) {
afsi_log("cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC");
fprintf(stderr, "cm_ValidateSCache failure: scp->randomACLp->magic != CM_ACLENT_MAGIC\n");
* so leave it in place.
*/
if (cm_FidCmp(&scp->fid, &bp->fid) == 0 &&
- lock_TryMutex(&bp->mx)) {
+ bp->refCount == 0 &&
+ lock_TryMutex(&bp->mx)) {
if (bp->refCount == 0 &&
!(bp->flags & (CM_BUF_READING | CM_BUF_WRITING | CM_BUF_DIRTY)) &&
!(bp->qFlags & CM_BUF_QREDIR)) {
osi_Log2(afsd_logp,"cm_ReleaseSCacheNoLock scp 0x%p ref %d",scp, refCount);
afsi_log("%s:%d cm_ReleaseSCacheNoLock scp 0x%p ref %d", file, line, scp, refCount);
#endif
-
- if (refCount == 0 && (scp->flags & CM_SCACHEFLAG_DELETED)) {
- int deleted = 0;
- long lockstate;
-
- lockstate = lock_GetRWLockState(&cm_scacheLock);
- if (lockstate != OSI_RWLOCK_WRITEHELD)
- lock_ReleaseRead(&cm_scacheLock);
- else
- lock_ReleaseWrite(&cm_scacheLock);
-
- lock_ObtainWrite(&scp->rw);
- if (scp->flags & CM_SCACHEFLAG_DELETED)
- deleted = 1;
-
- if (refCount == 0 && deleted) {
- lock_ObtainWrite(&cm_scacheLock);
- cm_RecycleSCache(scp, 0);
- if (lockstate != OSI_RWLOCK_WRITEHELD)
- lock_ConvertWToR(&cm_scacheLock);
- } else {
- if (lockstate != OSI_RWLOCK_WRITEHELD)
- lock_ObtainRead(&cm_scacheLock);
- else
- lock_ObtainWrite(&cm_scacheLock);
- }
- lock_ReleaseWrite(&scp->rw);
- }
}
#ifdef DEBUG_REFCOUNT
afsi_log("%s:%d cm_ReleaseSCache scp 0x%p ref %d", file, line, scp, refCount);
#endif
lock_ReleaseRead(&cm_scacheLock);
-
- if (scp->flags & CM_SCACHEFLAG_DELETED) {
- int deleted = 0;
- lock_ObtainWrite(&scp->rw);
- if (scp->flags & CM_SCACHEFLAG_DELETED)
- deleted = 1;
- if (deleted) {
- lock_ObtainWrite(&cm_scacheLock);
- cm_RecycleSCache(scp, 0);
- lock_ReleaseWrite(&cm_scacheLock);
- }
- lock_ReleaseWrite(&scp->rw);
- }
}
/* just look for the scp entry to get filetype */