case vl_unknown:
cm_InitReq(&req);
req.flags |= CM_REQ_NORETRY;
- buf_CleanAsyncLocked(NULL, bp, &req, 0, &dirty);
+ buf_CleanLocked(NULL, bp, &req, 0, &dirty);
wasDirty |= dirty;
}
cm_PutVolume(volp);
}
/* incremental sync daemon. Writes all dirty buffers every 5000 ms */
-void buf_IncrSyncer(long parm)
+static void *
+buf_IncrSyncer(void * parm)
{
long wasDirty = 0;
long i;
wasDirty = buf_Sync(1);
} /* whole daemon's while loop */
+
+ pthread_exit(NULL);
+ return NULL;
}
long
{
static osi_once_t once;
cm_buf_t *bp;
- thread_t phandle;
+ pthread_t phandle;
+ pthread_attr_t tattr;
+ int pstatus;
long i;
- unsigned long pid;
char *data;
if ( newFile ) {
cm_data.buf_nOrigBuffers = cm_data.buf_nbuffers;
/* lower hash size to a prime number */
- cm_data.buf_hashSize = osi_PrimeLessThan((afs_uint32)(cm_data.buf_nbuffers/7 + 1));
+ cm_data.buf_hashSize = cm_NextHighestPowerOf2((afs_uint32)(cm_data.buf_nbuffers/7));
/* create hash table */
memset((void *)cm_data.buf_scacheHashTablepp, 0, cm_data.buf_hashSize * sizeof(cm_buf_t *));
osi_EndOnce(&once);
/* and create the incr-syncer */
- phandle = thrd_Create(0, 0,
- (ThreadFunc) buf_IncrSyncer, 0, 0, &pid,
- "buf_IncrSyncer");
+ pthread_attr_init(&tattr);
+ pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
+
+ pstatus = pthread_create(&phandle, &tattr, buf_IncrSyncer, 0);
+ osi_assertx(pstatus == 0, "buf: can't create incremental sync proc");
- osi_assertx(phandle != NULL, "buf: can't create incremental sync proc");
- CloseHandle(phandle);
+ pthread_attr_destroy(&tattr);
}
#ifdef TESTING
* 'scp' may or may not be NULL. If it is not NULL, the FID for both cm_scache_t
* and cm_buf_t must match.
*/
-afs_uint32 buf_CleanAsyncLocked(cm_scache_t *scp, cm_buf_t *bp, cm_req_t *reqp,
+afs_uint32 buf_CleanLocked(cm_scache_t *scp, cm_buf_t *bp, cm_req_t *reqp,
afs_uint32 flags, afs_uint32 *pisdirty)
{
afs_uint32 code = 0;
* in fact be the case but we don't know that until we attempt
* a FetchStatus on the FID.
*/
- osi_Log1(buf_logp, "buf_CleanAsyncLocked unable to start I/O - scp not found buf 0x%p", bp);
+ osi_Log1(buf_logp, "buf_CleanLocked unable to start I/O - scp not found buf 0x%p", bp);
code = CM_ERROR_NOSUCHFILE;
} else {
- osi_Log2(buf_logp, "buf_CleanAsyncLocked starts I/O on scp 0x%p buf 0x%p", scp, bp);
+ osi_Log2(buf_logp, "buf_CleanLocked starts I/O on scp 0x%p buf 0x%p", scp, bp);
offset = bp->offset;
LargeIntegerAdd(offset, ConvertLongToLargeInteger(bp->dirty_offset));
+ /*
+ * Only specify the dirty length of the current buffer in the call
+ * to cm_BufWrite(). It is the responsibility of cm_BufWrite()
+ * 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,
-#if 1
- /* we might as well try to write all of the contiguous
- * dirty buffers in one RPC
- */
- cm_chunkSize,
-#else
bp->dirty_length,
-#endif
flags, bp->userp, reqp);
- osi_Log3(buf_logp, "buf_CleanAsyncLocked I/O on scp 0x%p buf 0x%p, done=%d", scp, bp, code);
+ 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 the Write routine returns No Such File, clear the dirty flag
lock_ReleaseWrite(&buf_globalLock);
lock_ReleaseRead(&scp->bufCreateLock);
- /* grab required lock and clean; this only
- * starts the I/O. By the time we're back,
- * it'll still be marked dirty, but it will also
- * have the WRITING flag set, so we won't get
- * back here.
+ /*
+ * grab required lock and clean.
+ * previously the claim was that the cleaning
+ * operation was async which it is not. It would
+ * be a good idea to use an async mechanism here
+ * but there is none at the moment other than
+ * the buf_IncrSyncer() thread.
*/
if (cm_FidCmp(&scp->fid, &bp->fid) == 0)
- buf_CleanAsync(scp, bp, reqp, 0, NULL);
+ buf_Clean(scp, bp, reqp, 0, NULL);
else
- buf_CleanAsync(NULL, bp, reqp, 0, NULL);
+ buf_Clean(NULL, bp, reqp, 0, NULL);
/* now put it back and go around again */
buf_Release(bp);
}
/* clean a buffer synchronously */
-afs_uint32 buf_CleanAsync(cm_scache_t *scp, cm_buf_t *bp, cm_req_t *reqp, afs_uint32 flags, afs_uint32 *pisdirty)
+afs_uint32 buf_Clean(cm_scache_t *scp, cm_buf_t *bp, cm_req_t *reqp, afs_uint32 flags, afs_uint32 *pisdirty)
{
long code;
osi_assertx(bp->magic == CM_BUF_MAGIC, "invalid cm_buf_t magic");
osi_assertx(!(flags & CM_BUF_WRITE_SCP_LOCKED), "scp->rw must not be held when calling buf_CleanAsync");
lock_ObtainMutex(&bp->mx);
- code = buf_CleanAsyncLocked(scp, bp, reqp, flags, pisdirty);
+ code = buf_CleanLocked(scp, bp, reqp, flags, pisdirty);
lock_ReleaseMutex(&bp->mx);
return code;
cm_InitReq(&req);
req.flags |= CM_REQ_NORETRY;
- buf_CleanAsync(NULL, bp, &req, 0, NULL);
+ buf_Clean(NULL, bp, &req, 0, NULL);
buf_CleanWait(NULL, bp, FALSE);
/* relock and release buffer */
long code;
long bufferPos;
afs_uint32 i;
+ afs_uint32 invalidate = 0;
/* assert that cm_bufCreateLock is held in write mode */
lock_AssertWrite(&scp->bufCreateLock);
lock_ReleaseWrite(&buf_globalLock);
}
} else {
- if (RDR_Initialized)
- RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode,
- scp->fid.unique, scp->fid.hash,
- scp->fileType, AFS_INVALIDATE_SMB);
+ invalidate = 1;
}
_InterlockedAnd(&bufp->flags, ~CM_BUF_DIRTY);
bufp->error = 0;
buf_ValidateBufQueues();
#endif /* TESTING */
+ if (invalidate && RDR_Initialized)
+ RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode,
+ scp->fid.unique, scp->fid.hash,
+ scp->fileType, AFS_INVALIDATE_SMB);
+
/* done */
return code;
}
lock_ObtainMutex(&bp->mx);
/* start cleaning the buffer, and wait for it to finish */
- buf_CleanAsyncLocked(scp, bp, reqp, 0, NULL);
+ buf_CleanLocked(scp, bp, reqp, 0, NULL);
buf_WaitIO(scp, bp);
lock_ReleaseMutex(&bp->mx);
*/
break;
default:
- code = buf_CleanAsyncLocked(scp, bp, reqp, 0, &wasDirty);
+ code = buf_CleanLocked(scp, bp, reqp, 0, &wasDirty);
if (bp->flags & CM_BUF_ERROR) {
code = bp->error;
if (code == 0)