Windows: Convert BkgDaemon Procedures to use rock
authorJeffrey Altman <jaltman@your-file-system.com>
Thu, 17 Jan 2013 06:44:27 +0000 (01:44 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Sat, 2 Feb 2013 17:12:24 +0000 (09:12 -0800)
The BkgDaemon functions accepted four 32-bit parameters into
which 64-bit offsets and lengths were fit.  Convert the routines
to use a procedure specific rock type which is allocated by the
caller to cm_QueueBkgRequest and freed by cm_BkgDaemon.

The use of a rock will permit greater flexibility for future
background procedures to be implemented that require more complex
data to be passed around.

Change-Id: I4fc06e1d4a3a3ee25c699c95a90a9c9993199ddd
Reviewed-on: http://gerrit.openafs.org/8966
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsd/cm_daemon.c
src/WINNT/afsd/cm_daemon.h
src/WINNT/afsd/cm_dcache.c
src/WINNT/afsd/cm_dcache.h
src/WINNT/afsd/rawops.c
src/WINNT/afsd/smb.c
src/WINNT/afsd/smb3.c
src/WINNT/afsrdr/common/AFSUserPrototypes.h
src/WINNT/afsrdr/user/RDRFunction.c

index d55d34f..6acfd9a 100644 (file)
@@ -117,13 +117,10 @@ afs_int32 cm_RequestWillBlock(cm_bkgRequest_t *rp)
          * 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);
@@ -214,7 +211,7 @@ void * cm_BkgDaemon(void * vparm)
 #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
@@ -254,6 +251,7 @@ void * cm_BkgDaemon(void * vparm)
             }
             cm_ReleaseUser(rp->userp);
             cm_ReleaseSCache(rp->scp);
+            free(rp->rockp);
             free(rp);
             lock_ObtainWrite(&cm_daemonLockp[daemonID]);
         }
@@ -264,8 +262,8 @@ void * cm_BkgDaemon(void * vparm)
     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;
@@ -279,10 +277,7 @@ void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, afs_uint32 p1, af
     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 */
@@ -294,17 +289,27 @@ void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, afs_uint32 p1, af
     /* 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;
+            }
         }
     }
 
@@ -317,6 +322,7 @@ void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, afs_uint32 p1, af
     if (duplicate) {
         cm_ReleaseSCache(scp);
         cm_ReleaseUser(userp);
+        free(rp->rockp);
         free(rp);
     } else {
         osi_Wakeup((LONG_PTR) &cm_bkgListpp[daemonID]);
index b70f380..17d8108 100644 (file)
@@ -25,23 +25,19 @@ void cm_DaemonShutdown(void);
 
 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
 
index 670ed19..1c94b05 100644 (file)
@@ -773,29 +773,30 @@ cm_CheckFetchRange(cm_scache_t *scp, osi_hyper_t *startBasep, osi_hyper_t *lengt
 }
 
 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;
     }
@@ -841,8 +842,7 @@ void cm_ClearPrefetchFlag(long code, cm_scache_t *scp, osi_hyper_t *base, osi_hy
 /* 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;
@@ -862,15 +862,13 @@ cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, af
     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);
@@ -942,6 +940,7 @@ void cm_ConsiderPrefetch(cm_scache_t *scp, osi_hyper_t *offsetp, afs_uint32 coun
     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);
 
@@ -983,10 +982,16 @@ void cm_ConsiderPrefetch(cm_scache_t *scp, osi_hyper_t *offsetp, afs_uint32 coun
     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.
index 8cf0ec4..00f122b 100644 (file)
@@ -51,11 +51,19 @@ extern void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore, long failed, int scp_
 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,
index 85751ce..8cba65f 100644 (file)
@@ -311,10 +311,21 @@ raw_WriteData( cm_scache_t *scp, osi_hyper_t *offsetp, afs_uint32 length, char *
     }
 
     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 */
index 3b3ad0c..99c3bc6 100644 (file)
@@ -7546,18 +7546,27 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char
         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);
index 4eed701..2811419 100644 (file)
@@ -8401,11 +8401,19 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     }
     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));
@@ -9169,10 +9177,19 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
     }
     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);
 
index 3d44e9b..44df633 100644 (file)
@@ -60,8 +60,7 @@ extern DWORD
 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);
 
index 56d534c..0ecc032 100644 (file)
@@ -3292,8 +3292,7 @@ HexCheckSum(unsigned char * buf, int buflen, unsigned char * md5cksum)
 
 /* 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;
@@ -3321,15 +3320,12 @@ RDR_BkgFetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_
     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.
@@ -3741,12 +3737,21 @@ RDR_RequestFileExtentsAsync( IN cm_user_t *userp,
                 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 */
@@ -3757,12 +3762,20 @@ RDR_RequestFileExtentsAsync( IN cm_user_t *userp,
 
     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);
 
@@ -3797,6 +3810,7 @@ RDR_ReleaseFileExtents( IN cm_user_t *userp,
     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];
@@ -4250,15 +4264,32 @@ RDR_ReleaseFileExtents( IN cm_user_t *userp,
                     {
                         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);
@@ -4291,6 +4322,7 @@ RDR_ProcessReleaseFileExtentsResult( IN AFSReleaseFileExtentsResultCB *ReleaseFi
     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];
@@ -4697,15 +4729,32 @@ RDR_ProcessReleaseFileExtentsResult( IN AFSReleaseFileExtentsResultCB *ReleaseFi
                      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",