/*
* 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
&& LargeIntegerLessThan(scp->truncPos, truncPos))
truncPos = scp->truncPos;
scp->mask &= ~CM_SCACHEMASK_TRUNCPOS;
-
+
/* compute how many bytes to write from this buffer */
thyper = LargeIntegerSubtract(scp->length, biod.offset);
if (LargeIntegerLessThanZero(thyper)) {
ConvertLongToLargeInteger(LONG_MAX))) {
require_64bit_ops = 1;
}
-
+
lock_ReleaseWrite(&scp->rw);
/* now we're ready to do the store operation */
save_nbytes = nbytes;
do {
code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp);
- if (code)
+ if (code)
continue;
retry:
break;
} else {
osi_Log2(afsd_logp, "rx_Write succeeded bp 0x%p, %d",bufp,temp);
- }
+ }
nbytes -= wbytes;
#endif /* USE_RX_IOVEC */
} /* while more bytes to write */
lock_ObtainWrite(&scp->rw);
cm_ReleaseBIOD(&biod, 1, code, 1);
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL);
if (code == 0) {
osi_hyper_t t;
else if (code == CM_ERROR_QUOTA)
scp->flags |= CM_SCACHEFLAG_OVERQUOTA;
}
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL);
+
if (!scp_locked)
lock_ReleaseWrite(&scp->rw);
/* now we're ready to do the store operation */
do {
code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp);
- if (code)
+ if (code)
continue;
- retry:
+ retry:
rxconnp = cm_GetRxConn(connp);
rxcallp = rx_NewCall(rxconnp);
rx_PutConnection(rxconnp);
code = code1;
} while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code));
code = cm_MapRPCError(code, reqp);
-
+
/* now, clean up our state */
lock_ObtainWrite(&scp->rw);
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL);
-
if (code == 0) {
osi_hyper_t t;
/*
scp->mask &= ~CM_SCACHEMASK_LENGTH;
cm_MergeStatus(NULL, scp, &outStatus, &volSync, userp, reqp, CM_MERGEFLAG_STOREDATA);
}
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STOREDATA_EXCL);
return code;
}
long code;
lock_ObtainWrite(&scp->rw);
- code = cm_SyncOp(scp, NULL, userp, reqp, 0,
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSIZE);
lock_ReleaseWrite(&scp->rw);
long cm_BufUnstabilize(void *vscp, cm_user_t *userp)
{
cm_scache_t *scp = vscp;
-
+
lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSIZE);
lock_ReleaseWrite(&scp->rw);
-
+
/* always succeeds */
return 0;
}
code = bufp->flags & CM_BUF_DIRTY;
/* release lock if we obtained it here */
- if (!isBufLocked)
+ if (!isBufLocked)
lock_ReleaseMutex(&bufp->mx);
/* if buffer was dirty, buffer is acceptable for use */
- if (code)
+ if (code)
return 1;
- else
+ else
return 0;
}
long code;
cm_buf_t *bp;
int stop;
-
+
/* now scan all buffers in the range, looking for any that look like
* they need work.
*/
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
return code;
-
+
if (LargeIntegerGreaterThanOrEqualTo(tbase, scp->length)) {
/* we're past the end of file */
break;
buf_Release(bp);
bp = NULL;
}
- else
+ else
stop = 1;
/* if this buffer is essentially guaranteed to require a fetch,
* break out here and return this position.
*/
- if (stop)
+ if (stop)
break;
-
+
tbase = LargeIntegerAdd(tbase, tblocksize);
tlength = LargeIntegerSubtract(tlength, tblocksize);
}
-
+
/* if we get here, either everything is fine or 'stop' stopped us at a
* particular buffer in the range that definitely needs to be fetched.
*/
if (stop == 0) {
/* return non-zero code since realBasep won't be valid */
code = -1;
- }
+ }
else {
/* successfully found a page that will need fetching */
*realBasep = tbase;
osi_Log4(afsd_logp, "Finished BKG store scp 0x%p, offset 0x%x:%08x, code 0x%x", scp, p2, p1, code);
}
- /*
+ /*
* Keep the following list synchronized with the
- * error code list in cm_BkgDaemon
+ * error code list in cm_BkgDaemon
*/
switch ( code ) {
case CM_ERROR_TIMEDOUT: /* or server restarting */
/* Retries will be performed by the BkgDaemon thread if appropriate */
req.flags |= CM_REQ_NORETRY;
-
+
fetched.LowPart = 0;
fetched.HighPart = 0;
tblocksize = ConvertLongToLargeInteger(cm_data.buf_blockSize);
length.HighPart = p4;
end = LargeIntegerAdd(base, length);
-
+
osi_Log5(afsd_logp, "Starting BKG prefetch scp 0x%p offset 0x%x:%x length 0x%x:%x",
scp, p2, p1, p4, p3);
for ( code = 0, offset = base;
- code == 0 && LargeIntegerLessThan(offset, end);
+ code == 0 && LargeIntegerLessThan(offset, end);
offset = LargeIntegerAdd(offset, tblocksize) )
{
if (rxheld) {
code = cm_GetBuffer(scp, bp, NULL, userp, &req);
if (code == 0)
- fetched = LargeIntegerAdd(fetched, tblocksize);
+ fetched = LargeIntegerAdd(fetched, tblocksize);
buf_Release(bp);
bp->cmFlags &= ~CM_BUF_CMBKGFETCH;
}
-
+
if (!rxheld) {
lock_ObtainWrite(&scp->rw);
rxheld = 1;
buf_Release(bp);
}
}
- cm_ClearPrefetchFlag(LargeIntegerGreaterThanZero(fetched) ? 0 : code,
+ cm_ClearPrefetchFlag(LargeIntegerGreaterThanZero(fetched) ? 0 : code,
scp, &base, &fetched);
/* wakeup anyone who is waiting */
cm_buf_t *bp;
tblocksize = ConvertLongToLargeInteger(cm_data.buf_blockSize);
-
+
readBase = *offsetp;
/* round up to chunk boundary */
readBase.LowPart += (cm_chunkSize-1);
osi_Log2(afsd_logp, "BKG Prefetch request scp 0x%p, base 0x%x",
scp, realBase.LowPart);
- cm_QueueBKGRequest(scp, cm_BkgPrefetch,
- realBase.LowPart, realBase.HighPart,
- readLength.LowPart, readLength.HighPart,
+ cm_QueueBKGRequest(scp, cm_BkgPrefetch,
+ realBase.LowPart, realBase.HighPart,
+ readLength.LowPart, readLength.HighPart,
userp);
}
long temp;
long code;
long flags; /* flags to cm_SyncOp */
-
+
/* clear things out */
biop->scp = scp; /* do not hold; held by caller */
biop->offset = *inOffsetp;
lock_ObtainWrite(&scp->rw);
flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_STOREDATA | CM_SCACHESYNC_BUFLOCKED;
- code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags);
+ code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags);
if (code) {
lock_ReleaseMutex(&bufp->mx);
buf_Release(bufp);
bufp = NULL;
buf_UnreserveBuffers(cm_chunkSize / cm_data.buf_blockSize);
return code;
- }
-
+ }
+
/* if the buffer is dirty, we're done */
if (bufp->flags & CM_BUF_DIRTY) {
osi_assertx(!(bufp->flags & CM_BUF_WRITING),
lock_ReleaseMutex(&bufp->mx);
buf_Release(bufp);
bufp = NULL;
- }
+ }
}
biop->reserved = 1;
-
+
/* if we get here, if bufp is null, we didn't find any dirty buffers
* that weren't already being stored back, so we just quit now.
*/
/* don't need buffer mutex any more */
lock_ReleaseMutex(&bufp->mx);
-
+
/* put this element in the list */
qdp = osi_QDAlloc();
osi_SetQData(qdp, bufp);
while(LargeIntegerGreaterThanOrEqualTo(tbase, scanStart)) {
/* see if we can find the buffer */
bufp = buf_Find(scp, &tbase);
- if (!bufp)
+ if (!bufp)
break;
/* try to lock it, and quit if we can't (simplifies locking) */
bufp = NULL;
break;
}
-
+
code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags);
if (code) {
lock_ReleaseMutex(&bufp->mx);
bufp = NULL;
break;
}
-
+
if (!(bufp->flags & CM_BUF_DIRTY)) {
/* buffer is clean, so we shouldn't add it */
cm_SyncOpDone(scp, bufp, flags);
while(LargeIntegerLessThan(tbase, scanEnd)) {
/* see if we can find the buffer */
bufp = buf_Find(scp, &tbase);
- if (!bufp)
+ if (!bufp)
break;
/* try to lock it, and quit if we can't (simplifies locking) */
bufp = NULL;
break;
}
-
+
if (!(bufp->flags & CM_BUF_DIRTY)) {
/* buffer is clean, so we shouldn't add it */
cm_SyncOpDone(scp, bufp, flags);
/* update biod info describing the transfer */
biop->length += cm_data.buf_blockSize;
-
+
/* update loop pointer */
tbase = LargeIntegerAdd(tbase, thyper);
} /* while loop looking for pages following the first page we found */
-
+
/* finally, we're done */
return 0;
}
biop->reserved = 0;
/* first lookup the file's length, so we know when to stop */
- code = cm_SyncOp(scp, NULL, userp, reqp, 0,
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- if (code)
+ if (code)
return code;
-
+
/* copy out size, since it may change */
fileSize = scp->serverLength;
-
+
lock_ReleaseWrite(&scp->rw);
pageBase = *offsetp;
/* first hold all buffers, since we can't hold any locks in buf_Get */
while (1) {
/* stop at chunk boundary */
- if (collected >= cm_chunkSize)
+ if (collected >= cm_chunkSize)
break;
-
+
/* see if the next page would be past EOF */
- if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize))
+ if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize))
break;
code = buf_Get(scp, &pageBase, reqp, &tbp);
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
return code;
}
-
+
buf_Release(tbp);
tbp = NULL;
/* now hold all buffers, if they are still there */
while (1) {
/* stop at chunk boundary */
- if (collected >= cm_chunkSize)
+ if (collected >= cm_chunkSize)
break;
-
+
/* see if the next page would be past EOF */
- if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize))
+ if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize))
break;
tbp = buf_Find(scp, &pageBase);
- if (!tbp)
+ if (!tbp)
break;
/* add the buffer to the list */
qdp = osi_QDAlloc();
osi_SetQData(qdp, tbp);
- osi_QAddH((osi_queue_t **)&heldBufListp,
- (osi_queue_t **)&heldBufListEndp,
+ osi_QAddH((osi_queue_t **)&heldBufListp,
+ (osi_queue_t **)&heldBufListEndp,
&qdp->q);
/* leave tbp held (from buf_Get) */
- if (!reserving)
+ if (!reserving)
break;
collected += cm_data.buf_blockSize;
}
flags = CM_SCACHESYNC_FETCHDATA | CM_SCACHESYNC_BUFLOCKED;
- if (!isFirst)
+ if (!isFirst)
flags |= CM_SCACHESYNC_NOWAIT;
/* wait for the buffer to serialize, if required. Doesn't
lock_ReleaseMutex(&tbp->mx);
break;
}
-
+
/* don't fetch over dirty buffers */
if (tbp->flags & CM_BUF_DIRTY) {
cm_SyncOpDone(scp, tbp, flags);
/* add the buffer to the list */
qdp = osi_QDAlloc();
osi_SetQData(qdp, tbp);
- osi_QAddH((osi_queue_t **)&biop->bufListp,
- (osi_queue_t **)&biop->bufListEndp,
+ osi_QAddH((osi_queue_t **)&biop->bufListp,
+ (osi_queue_t **)&biop->bufListEndp,
&qdp->q);
buf_Hold(tbp);
isFirst = 0;
collected += cm_data.buf_blockSize;
}
-
+
/* now, we've held in biop->bufListp all the buffer's we're really
* interested in. We also have holds left from heldBufListp, and we
* now release those holds on the buffers.
/* Caller expects this */
lock_ObtainWrite(&scp->rw);
-
+
/* if we got a failure setting up the first buffer, then we don't have
* any side effects yet, and we also have failed an operation that the
* caller requires to make any progress. Give up now.
buf_UnreserveBuffers(cm_chunkSize / cm_data.buf_blockSize);
return code;
}
-
+
/* otherwise, we're still OK, and should just return the I/O setup we've
* got.
*/
/* Give back reserved buffers */
if (biop->reserved)
buf_UnreserveBuffers(cm_chunkSize / cm_data.buf_blockSize);
-
+
if (isStore)
flags = CM_SCACHESYNC_STOREDATA;
else
for(qdp = biop->bufListp; qdp; qdp = nqdp) {
/* lookup next guy first, since we're going to free this one */
nqdp = (osi_queueData_t *) osi_QNext(&qdp->q);
-
+
/* extract buffer and free queue data */
bufp = osi_GetQData(qdp);
osi_QRemoveHT((osi_queue_t **) &biop->bufListp,
lock_ObtainMutex(&bufp->mx);
lock_ObtainWrite(&scp->rw);
cm_SyncOpDone(scp, bufp, flags);
-
+
/* turn off writing and wakeup users */
if (isStore) {
if (bufp->flags & CM_BUF_WAITING) {
/* clean things out */
biop->bufListp = NULL;
biop->bufListEndp = NULL;
-}
+}
static int
cm_CloneStatus(cm_scache_t *scp, cm_user_t *userp, int scp_locked,
* which case we just retry.
*/
if (bufp->dataVersion <= scp->dataVersion && bufp->dataVersion >= scp->bufDataVersionLow || biod.length == 0) {
- if ((bufp->dataVersion == CM_BUF_VERSION_BAD || bufp->dataVersion < scp->bufDataVersionLow) &&
- LargeIntegerGreaterThanOrEqualTo(bufp->offset, scp->serverLength))
+ if ((bufp->dataVersion == CM_BUF_VERSION_BAD || bufp->dataVersion < scp->bufDataVersionLow) &&
+ LargeIntegerGreaterThanOrEqualTo(bufp->offset, scp->serverLength))
{
osi_Log4(afsd_logp, "Bad DVs 0x%x != (0x%x -> 0x%x) or length 0x%x",
bufp->dataVersion, scp->bufDataVersionLow, scp->dataVersion, biod.length);
// yj code
// if getroot then we don't need to make any calls
// just return fake data
-
+
if (cm_freelanceEnabled && getroot) {
- // setup the fake status
+ // setup the fake status
afsStatus.InterfaceVersion = 0x1;
afsStatus.FileType = 0x2;
afsStatus.LinkCount = scp->linkCount;
// once we're done setting up the status info,
// we just fill the buffer pages with fakedata
// from cm_FakeRootDir. Extra pages are set to
- // 0.
-
+ // 0.
+
lock_ObtainMutex(&cm_Freelance_Lock);
t1 = bufp->offset.LowPart;
qdp = biod.bufListEndp;
bufferp=tbufp->datap;
memset(bufferp, 0, cm_data.buf_blockSize);
t2 = cm_fakeDirSize - t1;
- if (t2> (afs_int32)cm_data.buf_blockSize)
+ if (t2> (afs_int32)cm_data.buf_blockSize)
t2=cm_data.buf_blockSize;
if (t2 > 0) {
memcpy(bufferp, cm_FakeRootDir+t1, t2);
}
lock_ReleaseMutex(&cm_Freelance_Lock);
-
+
// once we're done, we skip over the part of the
// code that does the ACTUAL fetching of data for
// real files
/* now make the call */
do {
code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp);
- if (code)
+ if (code)
continue;
rxconnp = cm_GetRxConn(connp);
bufferp = tbufp->datap;
buffer_offset = 0;
}
- else
+ else
bufferp = NULL;
/* fill length_found of data from the pipe into the pages.
tbufp = osi_GetQData(qdp);
bufferp = tbufp->datap;
}
- else
+ else
bufferp = NULL;
- } else
+ } else
bufferp += temp;
#endif /* USE_RX_IOVEC */
}
if (rbytes != 0)
memset(bufferp, 0, rbytes);
qdp = (osi_queueData_t *) osi_QPrev(&qdp->q);
- if (qdp == NULL)
+ if (qdp == NULL)
break;
tbufp = osi_GetQData(qdp);
bufferp = tbufp->datap;
/* bytes to clear in this page */
rbytes = cm_data.buf_blockSize;
- }
+ }
}
if (code == 0) {
if (!scp_locked)
lock_ObtainWrite(&scp->rw);
-
+
/* we know that no one else has changed the buffer, since we still have
* the fetching flag on the buffers, and we have the scp locked again.
* Copy in the version # into the buffer if we got code 0 back from the
/* release scatter/gather I/O structure (buffers, locks) */
cm_ReleaseBIOD(&biod, 0, code, 1);
- if (code == 0)
+ if (code == 0)
cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, reqp, CM_MERGEFLAG_FETCHDATA);
-
+
return code;
}