* exist, check to see if an I/O operation is in progress
* by using the writing and reading flags as an indicator.
*/
- osi_hyper_t base;
cm_buf_t *bufp = NULL;
+ rock_BkgFetch_t *rockp = (rock_BkgFetch_t *)rp->rockp;
- base.LowPart = rp->p1;
- base.HighPart = rp->p2;
-
- bufp = buf_Find(&rp->scp->fid, &base);
+ bufp = buf_Find(&rp->scp->fid, &rockp->base);
if (bufp) {
willBlock = (bufp->flags & (CM_BUF_WRITING|CM_BUF_READING));
buf_Release(bufp);
#ifdef DEBUG_REFCOUNT
osi_Log3(afsd_logp,"cm_BkgDaemon[%u] (before) scp 0x%x ref %d", daemonID, rp->scp, rp->scp->refCount);
#endif
- code = (*rp->procp)(rp->scp, rp->p1, rp->p2, rp->p3, rp->p4, rp->userp, &rp->req);
+ code = (*rp->procp)(rp->scp, rp->rockp, rp->userp, &rp->req);
#ifdef DEBUG_REFCOUNT
osi_Log3(afsd_logp,"cm_BkgDaemon[%u] (after) scp 0x%x ref %d", daemonID, rp->scp, rp->scp->refCount);
#endif
}
cm_ReleaseUser(rp->userp);
cm_ReleaseSCache(rp->scp);
+ free(rp->rockp);
free(rp);
lock_ObtainWrite(&cm_daemonLockp[daemonID]);
}
return NULL;
}
-void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
- cm_user_t *userp, cm_req_t *reqp)
+void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, void *rockp,
+ cm_user_t *userp, cm_req_t *reqp)
{
cm_bkgRequest_t *rp, *rpq;
afs_uint32 daemonID;
cm_HoldUser(userp);
rp->userp = userp;
rp->procp = procp;
- rp->p1 = p1;
- rp->p2 = p2;
- rp->p3 = p3;
- rp->p4 = p4;
+ rp->rockp = rockp;
rp->req = *reqp;
/* Use separate queues for fetch and store operations */
/* Check to see if this is a duplicate request */
for (rpq = cm_bkgListpp[daemonID]; rpq; rpq = (cm_bkgRequest_t *) osi_QNext(&rpq->q))
{
- if ( rpq->p1 == p1 &&
- rpq->p3 == p3 &&
- rpq->procp == procp &&
- rpq->p2 == p2 &&
- rpq->p4 == p4 &&
+ if ( rpq->procp == procp &&
rpq->scp == scp &&
rpq->userp == userp)
{
- /* found a duplicate; update request with latest info */
- duplicate = 1;
- break;
+ if (rp->procp == cm_BkgStore) {
+ rock_BkgStore_t *rock1p = (rock_BkgStore_t *)rp->rockp;
+ rock_BkgStore_t *rock2p = (rock_BkgStore_t *)rpq->rockp;
+
+ duplicate = (memcmp(rock1p, rock2p, sizeof(*rock1p)) == 0);
+ }
+ else if (rp->procp == RDR_BkgFetch || rp->procp == cm_BkgPrefetch) {
+ rock_BkgFetch_t *rock1p = (rock_BkgFetch_t *)rp->rockp;
+ rock_BkgFetch_t *rock2p = (rock_BkgFetch_t *)rpq->rockp;
+
+ duplicate = (memcmp(rock1p, rock2p, sizeof(*rock1p)) == 0);
+ }
+
+ if (duplicate) {
+ /* found a duplicate; update request with latest info */
+ break;
+ }
}
}
if (duplicate) {
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
+ free(rp->rockp);
free(rp);
} else {
osi_Wakeup((LONG_PTR) &cm_bkgListpp[daemonID]);
void cm_InitDaemon(int nDaemons);
-typedef afs_int32 (cm_bkgProc_t)(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3,
- afs_uint32 p4, struct cm_user *up, cm_req_t *reqp);
+/* cm_bkgProc_t must free the rock */
+typedef afs_int32 (cm_bkgProc_t)(cm_scache_t *scp, void *rockp, struct cm_user *userp, cm_req_t *reqp);
typedef struct cm_bkgRequest {
- osi_queue_t q;
- cm_bkgProc_t *procp;
- cm_scache_t *scp;
- afs_uint32 p1;
- afs_uint32 p2;
- afs_uint32 p3;
- afs_uint32 p4;
- cm_user_t *userp;
- cm_req_t req;
+ osi_queue_t q;
+ cm_bkgProc_t *procp;
+ void * rockp;
+ cm_scache_t *scp;
+ cm_user_t *userp;
+ cm_req_t req;
} cm_bkgRequest_t;
-extern void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, afs_uint32 p1,
- afs_uint32 p2, afs_uint32 p3, afs_uint32 p4, cm_user_t *userp, cm_req_t *reqp);
+extern void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, void *rockp, cm_user_t *userp, cm_req_t *reqp);
#define CM_MAX_DAEMONS 64
}
afs_int32
-cm_BkgStore(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
- cm_user_t *userp, cm_req_t *reqp)
+cm_BkgStore(cm_scache_t *scp, void *rockp, cm_user_t *userp, cm_req_t *reqp)
{
osi_hyper_t toffset;
- long length;
+ afs_uint32 length;
long code = 0;
afs_uint32 req_flags = reqp->flags;
+ toffset = ((rock_BkgStore_t *)rockp)->offset;
+ length = ((rock_BkgStore_t *)rockp)->length;
+
if (scp->flags & CM_SCACHEFLAG_DELETED) {
- osi_Log4(afsd_logp, "Skipping BKG store - Deleted scp 0x%p, offset 0x%x:%08x, length 0x%x", scp, p2, p1, p3);
+ osi_Log4(afsd_logp, "Skipping BKG store - Deleted scp 0x%p, offset 0x%x:%08x, length 0x%x",
+ scp, toffset.HighPart, toffset.LowPart, length);
} else {
/* Retries will be performed by the BkgDaemon thread if appropriate */
reqp->flags |= CM_REQ_NORETRY;
- toffset.LowPart = p1;
- toffset.HighPart = p2;
- length = p3;
-
- osi_Log4(afsd_logp, "Starting BKG store scp 0x%p, offset 0x%x:%08x, length 0x%x", scp, p2, p1, p3);
+ osi_Log4(afsd_logp, "Starting BKG store scp 0x%p, offset 0x%x:%08x, length 0x%x",
+ scp, toffset.HighPart, toffset.LowPart, length);
code = cm_BufWrite(scp, &toffset, length, /* flags */ 0, userp, reqp);
- osi_Log4(afsd_logp, "Finished BKG store scp 0x%p, offset 0x%x:%08x, code 0x%x", scp, p2, p1, code);
+ osi_Log5(afsd_logp, "Finished BKG store scp 0x%p, offset 0x%x:%08x, length 0x%x, code 0x%x",
+ scp, toffset.HighPart, toffset.LowPart, length, code);
reqp->flags = req_flags;
}
/* do the prefetch. if the prefetch fails, return 0 (success)
* because there is no harm done. */
afs_int32
-cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
- cm_user_t *userp, cm_req_t *reqp)
+cm_BkgPrefetch(cm_scache_t *scp, void *rockp, cm_user_t *userp, cm_req_t *reqp)
{
osi_hyper_t length;
osi_hyper_t base;
fetched.LowPart = 0;
fetched.HighPart = 0;
tblocksize = ConvertLongToLargeInteger(cm_data.buf_blockSize);
- base.LowPart = p1;
- base.HighPart = p2;
- length.LowPart = p3;
- length.HighPart = p4;
+ base = ((rock_BkgFetch_t *)rockp)->base;
+ length = ((rock_BkgFetch_t *)rockp)->length;
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);
+ scp, base.HighPart, base.LowPart, length.HighPart, length.LowPart);
for ( code = 0, offset = base;
code == 0 && LargeIntegerLessThan(offset, end);
osi_hyper_t readLength;
osi_hyper_t readEnd;
osi_hyper_t tblocksize; /* a long long temp variable */
+ rock_BkgFetch_t *rockp;
tblocksize = ConvertLongToLargeInteger(cm_data.buf_blockSize);
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,
- userp, reqp);
+ rockp = malloc(sizeof(*rockp));
+ if (rockp == NULL) {
+ return; /* can't proceed without a rock */
+ }
+
+ rockp->base = realBase;
+ rockp->length = readLength;
+
+ /* cm_BkgDaemon frees the rock */
+ cm_QueueBKGRequest(scp, cm_BkgPrefetch, rockp, userp, reqp);
}
/* scp must be locked; temporarily unlocked during processing.
extern long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp,
long inSize, cm_bulkIO_t *biop, cm_user_t *userp, cm_req_t *reqp);
-extern afs_int32 cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
- struct cm_user *userp, cm_req_t *reqp);
+typedef struct rock_BkgFetch {
+ osi_hyper_t base;
+ osi_hyper_t length;
+} rock_BkgFetch_t;
-extern afs_int32 cm_BkgStore(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
- struct cm_user *userp, cm_req_t *reqp);
+extern afs_int32 cm_BkgPrefetch(cm_scache_t *scp, void *rockp, struct cm_user *userp, cm_req_t *reqp);
+
+typedef struct rock_BkgStore {
+ osi_hyper_t offset;
+ afs_uint32 length;
+} rock_BkgStore_t;
+
+extern afs_int32 cm_BkgStore(cm_scache_t *scp, void *rockp, struct cm_user *userp, cm_req_t *reqp);
extern void cm_ConsiderPrefetch(cm_scache_t *scp, osi_hyper_t *offsetp,
afs_uint32 count,
}
if (code == 0 && doWriteBack) {
- code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_ASYNCSTORE);
- if (code == 0)
- cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
- writeBackOffset.HighPart, writeBackLength, 0, userp, reqp);
+ rock_BkgStore_t *rockp = malloc(sizeof(*rockp));
+
+ if (rockp) {
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_ASYNCSTORE);
+ if (code == 0) {
+ rockp->length = writeBackLength;
+ rockp->offset = writeBackOffset;
+
+ cm_QueueBKGRequest(scp, cm_BkgStore, rockp, userp, reqp);
+
+ /* rock is freed by cm_BkgDaemon */
+ } else {
+ free(rockp);
+ }
+ }
}
/* cm_SyncOpDone is called when cm_BkgStore completes */
if (smb_AsyncStore > 0) {
if (doWriteBack) {
long code2;
-
- lock_ObtainWrite(&scp->rw);
- osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE",
- fidp->fid);
- code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE);
- osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns 0x%x",
- fidp->fid, code2);
- lock_ReleaseWrite(&scp->rw);
- cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
- writeBackOffset.HighPart,
- smb_AsyncStoreSize, 0, userp, &req);
- /* cm_SyncOpDone is called at the completion of cm_BkgStore */
+ rock_BkgStore_t *rockp = malloc(sizeof(*rockp));
+
+ if (rockp) {
+ lock_ObtainWrite(&scp->rw);
+ osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE",
+ fidp->fid);
+ code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE);
+ osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns 0x%x",
+ fidp->fid, code2);
+ lock_ReleaseWrite(&scp->rw);
+ if (code2 == 0) {
+ rockp->length = smb_AsyncStoreSize;
+ rockp->offset = writeBackOffset;
+
+ cm_QueueBKGRequest(scp, cm_BkgStore, rockp, userp, &req);
+ /* cm_SyncOpDone is called at the completion of cm_BkgStore */
+ /* rock is freed by cm_BkgDaemon */
+ } else {
+ free(rockp);
+ }
+ }
}
} else {
cm_BufWrite(scp, offsetp, *writtenp, 0, userp, &req);
}
lock_ReleaseRead(&scp->rw);
- if (prefetch)
- cm_QueueBKGRequest(scp, cm_BkgPrefetch, 0, 0,
- scp->length.LowPart, scp->length.HighPart,
- userp, &req);
+ if (prefetch) {
+ rock_BkgFetch_t *rockp = malloc(sizeof(*rockp));
+ if (rockp) {
+ rockp->base.LowPart = 0;
+ rockp->base.HighPart = 0;
+ rockp->length = scp->length;
+
+ cm_QueueBKGRequest(scp, cm_BkgPrefetch, rockp, userp, &req);
+
+ /* rock is freed by cm_BkgDaemon */
+ }
+ }
osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %S", fidp->fid,
osi_LogSaveClientString(smb_logp, realPathp));
}
lock_ReleaseRead(&scp->rw);
- if (prefetch)
- cm_QueueBKGRequest(scp, cm_BkgPrefetch, 0, 0,
- scp->length.LowPart, scp->length.HighPart,
- userp, &req);
+ if (prefetch) {
+ rock_BkgFetch_t *rockp = malloc(sizeof(*rockp));
+
+ if (rockp) {
+ rockp->base.LowPart = 0;
+ rockp->base.HighPart = 0;
+ rockp->length = scp->length;
+
+ cm_QueueBKGRequest(scp, cm_BkgPrefetch, rockp, userp, &req);
+
+ /* rock is freed by cm_BkgDaemon */
+ }
+ }
osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid);
RDR_SysName(ULONG Architecture, ULONG Count, WCHAR **NameList);
extern afs_int32
-RDR_BkgFetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
- cm_user_t *userp, cm_req_t *reqp);
+RDR_BkgFetch(cm_scache_t *scp, void *rockp, cm_user_t *userp, cm_req_t *reqp);
extern VOID RDR_Suspend( void);
/* do the background fetch. */
afs_int32
-RDR_BkgFetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
- cm_user_t *userp, cm_req_t *reqp)
+RDR_BkgFetch(cm_scache_t *scp, void *rockp, cm_user_t *userp, cm_req_t *reqp)
{
osi_hyper_t length;
osi_hyper_t base;
fetched.LowPart = 0;
fetched.HighPart = 0;
tblocksize = ConvertLongToLargeInteger(cm_data.buf_blockSize);
- base.LowPart = p1;
- base.HighPart = p2;
- length.LowPart = p3;
- length.HighPart = p4;
-
+ base = ((rock_BkgFetch_t *)rockp)->base;
+ length = ((rock_BkgFetch_t *)rockp)->length;
end = LargeIntegerAdd(base, length);
osi_Log5(afsd_logp, "Starting BKG Fetch scp 0x%p offset 0x%x:%x length 0x%x:%x",
- scp, p2, p1, p4, p3);
+ scp, base.HighPart, base.LowPart, length.HighPart, length.LowPart);
/*
* Make sure we have a callback.
buf_Release(bufp);
if (QueueLength) {
- req.flags &= ~CM_REQ_NORETRY;
- cm_QueueBKGRequest(scp, RDR_BkgFetch, QueueOffset.LowPart, QueueOffset.HighPart,
- QueueLength, 0, userp, &req);
- osi_Log3(afsd_logp, "RDR_RequestFileExtentsAsync Queued a Background Fetch offset 0x%x:%x length 0x%x",
- QueueOffset.HighPart, QueueOffset.LowPart, QueueLength);
- req.flags |= CM_REQ_NORETRY;
+ rock_BkgFetch_t * rockp = malloc(sizeof(*rockp));
+
+ if (rockp) {
+ req.flags &= ~CM_REQ_NORETRY;
+ rockp->base = QueueOffset;
+ rockp->length.LowPart = QueueLength;
+ rockp->length.HighPart = 0;
+
+ cm_QueueBKGRequest(scp, RDR_BkgFetch, rockp, userp, &req);
+ osi_Log3(afsd_logp, "RDR_RequestFileExtentsAsync Queued a Background Fetch offset 0x%x:%x length 0x%x",
+ QueueOffset.HighPart, QueueOffset.LowPart, QueueLength);
+ req.flags |= CM_REQ_NORETRY;
+ } else {
+ code = ENOMEM;
+ }
}
} else {
/* No error from buf_Get() can be fatal */
if (BeginOffset.QuadPart != EndOffset.QuadPart) {
afs_uint32 length = (afs_uint32)(EndOffset.QuadPart - BeginOffset.QuadPart);
+ rock_BkgFetch_t * rockp = malloc(sizeof(*rockp));
- req.flags &= ~CM_REQ_NORETRY;
- cm_QueueBKGRequest(scp, RDR_BkgFetch, BeginOffset.LowPart, BeginOffset.HighPart,
- length, 0, userp, &req);
- osi_Log3(afsd_logp, "RDR_RequestFileExtentsAsync Queued a Background Fetch offset 0x%x:%x length 0x%x",
- BeginOffset.HighPart, BeginOffset.LowPart, length);
+ if (rockp) {
+ req.flags &= ~CM_REQ_NORETRY;
+ rockp->base = QueueOffset;
+ rockp->length.LowPart = QueueLength;
+ rockp->length.HighPart = 0;
+
+ cm_QueueBKGRequest(scp, RDR_BkgFetch, rockp, userp, &req);
+ osi_Log3(afsd_logp, "RDR_RequestFileExtentsAsync Queued a Background Fetch offset 0x%x:%x length 0x%x",
+ BeginOffset.HighPart, BeginOffset.LowPart, length);
+ } else {
+ code = ENOMEM;
+ }
}
cm_ReleaseSCache(scp);
int released = 0;
int deleted = 0;
DWORD status;
+ rock_BkgStore_t *rockp;
#ifdef ODS_DEBUG
#ifdef VALIDATE_CHECK_SUM
char md5dbg[33], md5dbg2[33], md5dbg3[33];
{
length += cm_data.buf_blockSize;
} else {
- if (!(offset.QuadPart == 0 && length == 0))
- cm_QueueBKGRequest(scp, cm_BkgStore, offset.LowPart, offset.HighPart,
- length, 0, userp, &req);
+ if (!(offset.QuadPart == 0 && length == 0)) {
+ rockp = malloc(sizeof(*rockp));
+ if (rockp) {
+ rockp->length = length;
+ rockp->offset = offset;
+
+ cm_QueueBKGRequest(scp, cm_BkgStore, rockp, userp, &req);
+
+ /* rock is freed by cm_BkgStore */
+ }
+ }
offset.QuadPart = ReleaseExtentsCB->FileExtents[count].FileOffset.QuadPart;
length = cm_data.buf_blockSize;
}
}
- cm_QueueBKGRequest(scp, cm_BkgStore, offset.LowPart, offset.HighPart,
- length, 0, userp, &req);
+
+ /* Store whatever is left */
+ rockp = malloc(sizeof(*rockp));
+ if (rockp) {
+ rockp->length = length;
+ rockp->offset = offset;
+
+ cm_QueueBKGRequest(scp, cm_BkgStore, rockp, userp, &req);
+
+ /* rock is freed by cm_BkgStore */
+ }
}
}
cm_ReleaseSCache(scp);
cm_buf_t *bufp;
unsigned int fileno, extentno, total_extents = 0;
AFSReleaseFileExtentsResultFileCB *pNextFileCB;
+ rock_BkgStore_t *rockp;
#ifdef ODS_DEBUG
#ifdef VALIDATE_CHECK_SUM
char md5dbg[33], md5dbg2[33], md5dbg3[33];
length < cm_chunkSize) {
length += cm_data.buf_blockSize;
} else {
- if (!(offset.QuadPart == 0 && length == 0))
- cm_QueueBKGRequest(scp, cm_BkgStore, offset.LowPart, offset.HighPart,
- length, 0, userp, &req);
+ if (!(offset.QuadPart == 0 && length == 0)) {
+ rockp = malloc(sizeof(*rockp));
+ if (rockp) {
+ rockp->offset = offset;
+ rockp->length = length;
+
+ cm_QueueBKGRequest(scp, cm_BkgStore, rockp, userp, &req);
+ } else {
+ code = ENOMEM;
+ }
+ }
offset.QuadPart = pExtent->FileOffset.QuadPart;
length = cm_data.buf_blockSize;
}
}
- cm_QueueBKGRequest(scp, cm_BkgStore, offset.LowPart, offset.HighPart,
- length, 0, userp, &req);
+
+ /* Background store the rest */
+ rockp = malloc(sizeof(*rockp));
+ if (rockp) {
+ rockp->offset = offset;
+ rockp->length = length;
+
+ cm_QueueBKGRequest(scp, cm_BkgStore, rockp, userp, &req);
+ } else {
+ code = ENOMEM;
+ }
}
osi_Log5(afsd_logp, "RDR_ProcessReleaseFileExtentsResult File FID cell=0x%x vol=0x%x vn=0x%x uniq=0x%x Released %d",