bp->redirLastAccess = 0;
bp->redirReleaseRequested = 0;
buf_ReleaseLocked(bp, TRUE);
+ InterlockedDecrement(&cm_data.buf_usedCount);
}
bp++;
}
bp->redirLastAccess = 0;
bp->redirReleaseRequested = 0;
buf_ReleaseLocked(bp, TRUE);
+ InterlockedDecrement(&cm_data.buf_usedCount);
}
lock_ReleaseWrite(&buf_globalLock);
}
reqp) == 0)
{
release_scp = 1;
+
+ lock_ObtainWrite(&scp->rw);
+ code = cm_SyncOp(scp, NULL, bp->userp ? bp->userp : cm_rootUserp, reqp, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ if (code == 0) {
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ }
+ lock_ReleaseWrite(&scp->rw);
+ }
+
+ if (scp && (scp->flags & CM_SCACHEFLAG_DELETED)) {
+ _InterlockedAnd(&bp->flags, ~CM_BUF_DIRTY);
+ _InterlockedOr(&bp->flags, CM_BUF_ERROR);
+ bp->dirty_length = 0;
+ bp->error = code;
+ bp->dataVersion = CM_BUF_VERSION_BAD;
+ bp->dirtyCounter++;
+ InterlockedDecrement(&cm_data.buf_usedCount);
}
while ((bp->flags & CM_BUF_DIRTY) == CM_BUF_DIRTY) {
* to determine if it is appropriate to fill a full chunk of data
* when storing to the file server.
*/
- code = (*cm_buf_opsp->Writep)(scp, &offset,
- bp->dirty_length,
- flags, bp->userp, reqp);
+ code = (*cm_buf_opsp->Writep)(scp, &offset, bp->dirty_length, flags,
+ bp->userp ? bp->userp : cm_rootUserp, reqp);
osi_Log3(buf_logp, "buf_CleanLocked I/O on scp 0x%p buf 0x%p, done=%d", scp, bp, code);
}
lock_ObtainMutex(&bp->mx);
*/
if (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BADFD || code == CM_ERROR_NOACCESS ||
code == CM_ERROR_QUOTA || code == CM_ERROR_SPACE || code == CM_ERROR_TOOBIG ||
- code == CM_ERROR_READONLY || code == CM_ERROR_NOSUCHPATH){
+ code == CM_ERROR_READONLY || code == CM_ERROR_NOSUCHPATH || code == EIO ||
+ code == CM_ERROR_INVAL || code == CM_ERROR_INVAL_NET_RESP || code == CM_ERROR_UNKNOWN){
_InterlockedAnd(&bp->flags, ~CM_BUF_DIRTY);
_InterlockedOr(&bp->flags, CM_BUF_ERROR);
- bp->dirty_offset = 0;
bp->dirty_length = 0;
bp->error = code;
bp->dataVersion = CM_BUF_VERSION_BAD;
bp->dirtyCounter++;
+ InterlockedDecrement(&cm_data.buf_usedCount);
break;
}
if (reqp->flags & CM_REQ_NORETRY)
break;
- /* Ditto if the hardDeadTimeout or idleTimeout was reached */
+ /*
+ * Ditto if the hardDeadTimeout or idleTimeout was reached
+ * Or a fatal error is received.
+ */
if (code == CM_ERROR_TIMEDOUT || code == CM_ERROR_ALLDOWN ||
code == CM_ERROR_ALLBUSY || code == CM_ERROR_ALLOFFLINE ||
- code == CM_ERROR_CLOCKSKEW) {
+ code == CM_ERROR_CLOCKSKEW || code == CM_ERROR_INVAL_NET_RESP ||
+ code == CM_ERROR_INVAL || code == CM_ERROR_UNKNOWN || code == EIO) {
break;
}
}
osi_panic("buf_GetNewLocked: TryMutex failed",__FILE__,__LINE__);
}
+ if ( cm_data.buf_usedCount < cm_data.buf_nbuffers)
+ InterlockedIncrement(&cm_data.buf_usedCount);
+
lock_ReleaseWrite(&buf_globalLock);
lock_ReleaseRead(&scp->bufCreateLock);
{
osi_assertx(bp->magic == CM_BUF_MAGIC, "invalid cm_buf_t magic");
osi_assertx(bp->refCount > 0, "cm_buf_t refcount 0");
+ osi_assertx(userp != NULL, "userp is NULL");
if (length == 0)
return;
}
_InterlockedAnd(&bufp->flags, ~CM_BUF_DIRTY);
bufp->error = 0;
- bufp->dirty_offset = 0;
bufp->dirty_length = 0;
bufp->dataVersion = CM_BUF_VERSION_BAD; /* known bad */
bufp->dirtyCounter++;
+ InterlockedDecrement(&cm_data.buf_usedCount);
}
else {
/* don't set dirty, since dirty implies
_InterlockedAnd(&bp->flags, ~CM_BUF_DIRTY);
_InterlockedOr(&bp->flags, CM_BUF_ERROR);
bp->error = CM_ERROR_BADFD;
- bp->dirty_offset = 0;
bp->dirty_length = 0;
bp->dataVersion = CM_BUF_VERSION_BAD; /* known bad */
bp->dirtyCounter++;
lock_ReleaseMutex(&bp->mx);
+ InterlockedDecrement(&cm_data.buf_usedCount);
} else if (!(scp->flags & CM_SCACHEFLAG_RO)) {
if (code) {
goto skip;
buf_HoldLocked(nbp);
buf_ReleaseLocked(bp, TRUE);
didRelease = 1;
+ if (bp->dataVersion != CM_BUF_VERSION_BAD)
+ InterlockedDecrement(&cm_data.buf_usedCount);
buf_Recycle(bp);
}
}
for (bp = cm_data.buf_fileHashTablepp[i]; bp; bp = bp->fileHashp) {
if (cm_FidCmp(&bp->fid, &scp->fid) == 0) {
bp->dataVersion = CM_BUF_VERSION_BAD;
+ InterlockedDecrement(&cm_data.buf_usedCount);
found = 1;
}
}
switch (code) {
case CM_ERROR_NOSUCHFILE:
+ case CM_ERROR_INVAL:
case CM_ERROR_BADFD:
case CM_ERROR_NOACCESS:
case CM_ERROR_QUOTA:
case CM_ERROR_TOOBIG:
case CM_ERROR_READONLY:
case CM_ERROR_NOSUCHPATH:
+ case EIO:
+ case CM_ERROR_INVAL_NET_RESP:
+ case CM_ERROR_UNKNOWN:
/*
* Apply the previous fatal error to this buffer.
* Do not waste the time attempting to store to
*/
_InterlockedAnd(&bp->flags, ~CM_BUF_DIRTY);
_InterlockedOr(&bp->flags, CM_BUF_ERROR);
- bp->dirty_offset = 0;
bp->dirty_length = 0;
bp->error = code;
bp->dataVersion = CM_BUF_VERSION_BAD;
bp->dirtyCounter++;
+ InterlockedDecrement(&cm_data.buf_usedCount);
break;
case CM_ERROR_TIMEDOUT:
case CM_ERROR_ALLDOWN:
}
}
lock_ReleaseRead(&buf_globalLock);
- return 0;
+ return found;
}
long buf_RDRBuffersExist(cm_fid_t *fidp)
lock_ObtainMutex(&bp->mx);
_InterlockedAnd(&bp->cmFlags, ~CM_BUF_CMSTORING);
_InterlockedAnd(&bp->flags, ~CM_BUF_DIRTY);
- bp->dirty_offset = 0;
bp->dirty_length = 0;
_InterlockedOr(&bp->flags, CM_BUF_ERROR);
bp->error = VNOVNODE;
}
lock_ReleaseMutex(&bp->mx);
buf_Release(bp);
+ InterlockedDecrement(&cm_data.buf_usedCount);
}
}
return 0;