Index: /trunk/src/VBox/VMM/PDMAsyncCompletionFileCache.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDMAsyncCompletionFileCache.cpp	(revision 23743)
+++ /trunk/src/VBox/VMM/PDMAsyncCompletionFileCache.cpp	(revision 23744)
@@ -1311,24 +1311,81 @@
                 else
                 {
-                    AssertMsg(!(pEntry->fFlags & PDMACFILECACHE_ENTRY_IO_IN_PROGRESS),
-                              ("Entry is not dirty but in progress\n"));
-
-                    /* Write as much as we can into the entry and update the file. */
-                    while (cbToWrite)
+                    /*
+                     * Check if a read is in progress for this entry.
+                     * We have to defer processing in that case.
+                     */
+                    if (pEntry->fFlags & PDMACFILECACHE_ENTRY_IO_IN_PROGRESS)
                     {
-                        size_t cbCopy = RT_MIN(cbSegLeft, cbToWrite);
-
-                        memcpy(pEntry->pbData + OffDiff, pbSegBuf, cbCopy);
-
-                        ADVANCE_SEGMENT_BUFFER(cbCopy);
-
-                        cbToWrite-= cbCopy;
-                        off      += cbCopy;
-                        OffDiff  += cbCopy;
-                        ASMAtomicSubS32(&pTask->cbTransferLeft, cbCopy);
+                        RTSemRWRequestWrite(pEndpointCache->SemRWEntries, RT_INDEFINITE_WAIT);
+
+                        /* Check again. The completion callback might have raced us. */
+                        if (pEntry->fFlags & PDMACFILECACHE_ENTRY_IO_IN_PROGRESS)
+                        {
+
+                            while (cbToWrite)
+                            {
+                                PPDMACFILETASKSEG pSeg = (PPDMACFILETASKSEG)RTMemAllocZ(sizeof(PDMACFILETASKSEG));
+
+                                pSeg->pTask      = pTask;
+                                pSeg->uBufOffset = OffDiff;
+                                pSeg->cbTransfer = RT_MIN(cbToWrite, cbSegLeft);
+                                pSeg->pvBuf      = pbSegBuf;
+                                pSeg->fWrite     = true;
+
+                                ADVANCE_SEGMENT_BUFFER(pSeg->cbTransfer);
+
+                                pSeg->pNext = pEntry->pHead;
+                                pEntry->pHead = pSeg;
+
+                                off       += pSeg->cbTransfer;
+                                OffDiff   += pSeg->cbTransfer;
+                                cbToWrite -= pSeg->cbTransfer;
+                            }
+
+                            RTSemRWReleaseWrite(pEndpointCache->SemRWEntries);
+                        }
+                        else
+                        {
+                            RTSemRWReleaseWrite(pEndpointCache->SemRWEntries);
+
+                            /* Write as much as we can into the entry and update the file. */
+                            while (cbToWrite)
+                            {
+                                size_t cbCopy = RT_MIN(cbSegLeft, cbToWrite);
+
+                                memcpy(pEntry->pbData + OffDiff, pbSegBuf, cbCopy);
+
+                                ADVANCE_SEGMENT_BUFFER(cbCopy);
+
+                                cbToWrite-= cbCopy;
+                                off      += cbCopy;
+                                OffDiff  += cbCopy;
+                                ASMAtomicSubS32(&pTask->cbTransferLeft, cbCopy);
+                            }
+
+                            pEntry->fFlags |= PDMACFILECACHE_ENTRY_IS_DIRTY;
+                            pdmacFileCacheWriteToEndpoint(pEntry);
+                        }
                     }
-
-                    pEntry->fFlags |= PDMACFILECACHE_ENTRY_IS_DIRTY;
-                    pdmacFileCacheWriteToEndpoint(pEntry);
+                    else
+                    {
+                        /* Write as much as we can into the entry and update the file. */
+                        while (cbToWrite)
+                        {
+                            size_t cbCopy = RT_MIN(cbSegLeft, cbToWrite);
+
+                            memcpy(pEntry->pbData + OffDiff, pbSegBuf, cbCopy);
+
+                            ADVANCE_SEGMENT_BUFFER(cbCopy);
+
+                            cbToWrite-= cbCopy;
+                            off      += cbCopy;
+                            OffDiff  += cbCopy;
+                            ASMAtomicSubS32(&pTask->cbTransferLeft, cbCopy);
+                        }
+
+                        pEntry->fFlags |= PDMACFILECACHE_ENTRY_IS_DIRTY;
+                        pdmacFileCacheWriteToEndpoint(pEntry);
+                    }
                 }
 
