From 7bea26dfbb11c746f70d75443d7a05910dcd704c Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 11 Sep 2007 06:04:10 +0000 Subject: [PATCH] DEVEL15-windows-prefetch-executables-20070911 avoid prefetch race condition in CreateX functions do not permit reference underflow when ending background prefetch ops (cherry picked from commit bf6c13352abf39e53e723e60aae11d6e246c0cfd) --- src/WINNT/afsd/cm_dcache.c | 11 +++++++++-- src/WINNT/afsd/smb3.c | 18 +++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index b67d780ef..0d9bbc65d 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -704,8 +704,10 @@ cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, af if (code || (bp->cmFlags & CM_BUF_CMFETCHING)) { code = 0; - if (bp) + if (bp) { buf_Release(bp); + bp = NULL; + } break; } @@ -721,8 +723,10 @@ cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, af cm_ClearPrefetchFlag(LargeIntegerGreaterThanZero(fetched) ? 0 : code, scp, &base, &fetched); lock_ReleaseMutex(&scp->mx); - if (bp) + if (bp) { buf_Release(bp); + bp = NULL; + } osi_Log4(afsd_logp, "Ending BKG prefetch scp 0x%p, code %d bytes 0x%x:%x", scp, code, fetched.HighPart, fetched.LowPart); @@ -832,6 +836,7 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, if (code) { lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); + bufp = NULL; buf_UnreserveBuffers(cm_chunkSize / cm_data.buf_blockSize); return code; } @@ -1095,6 +1100,7 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, } buf_Release(tbp); + tbp = NULL; pageBase = LargeIntegerAdd(tblocksize, pageBase); collected += cm_data.buf_blockSize; @@ -1216,6 +1222,7 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, &qdp->q); osi_QDFree(qdp); buf_Release(tbp); + tbp = NULL; } /* Caller expects this */ diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 6943380e6..4873559c1 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -2781,8 +2781,10 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t code = CM_ERROR_NOSUCHFILE; else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { cm_buf_t *bp = buf_Find(dscp, &hzero); - if (bp) + if (bp) { buf_Release(bp); + bp = NULL; + } else code = CM_ERROR_NOSUCHFILE; } @@ -3049,8 +3051,10 @@ long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet code = CM_ERROR_NOSUCHFILE; else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { cm_buf_t *bp = buf_Find(dscp, &hzero); - if (bp) + if (bp) { buf_Release(bp); + bp = NULL; + } else code = CM_ERROR_NOSUCHFILE; } @@ -7223,15 +7227,16 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) (scp->fileType == CM_SCACHETYPE_DIRECTORY || scp->fileType == CM_SCACHETYPE_MOUNTPOINT || scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); /* is a dir? */ - lock_ReleaseMutex(&scp->mx); smb_SetSMBDataLength(outp, 0); if ((fidp->flags & SMB_FID_EXECUTABLE) && - LargeIntegerGreaterThanZero(fidp->scp->length)) { + LargeIntegerGreaterThanZero(fidp->scp->length) && + !(scp->flags & CM_SCACHEFLAG_PREFETCHING)) { cm_QueueBKGRequest(fidp->scp, cm_BkgPrefetch, 0, 0, fidp->scp->length.LowPart, fidp->scp->length.HighPart, userp); } + lock_ReleaseMutex(&scp->mx); osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid, osi_LogSaveString(smb_logp, realPathp)); @@ -7959,12 +7964,15 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out lock_ReleaseMutex(&scp->mx); } + lock_ObtainMutex(&scp->mx); if ((fidp->flags & SMB_FID_EXECUTABLE) && - LargeIntegerGreaterThanZero(fidp->scp->length)) { + LargeIntegerGreaterThanZero(fidp->scp->length) && + !(scp->flags & CM_SCACHEFLAG_PREFETCHING)) { cm_QueueBKGRequest(fidp->scp, cm_BkgPrefetch, 0, 0, fidp->scp->length.LowPart, fidp->scp->length.HighPart, userp); } + lock_ReleaseMutex(&scp->mx); osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid); -- 2.39.5