Index: /trunk/src/VBox/Devices/Storage/VBoxHDD.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/VBoxHDD.cpp	(revision 30043)
+++ /trunk/src/VBox/Devices/Storage/VBoxHDD.cpp	(revision 30044)
@@ -269,4 +269,6 @@
             /** Number of bytes to post read. */
             size_t                       cbPostRead;
+            /** Number of bytes to write left in the parent. */
+            size_t                       cbWriteParent;
             /** Write type dependent data. */
             union
@@ -281,6 +283,4 @@
                     /** Bytes to read from the image. */
                     size_t               cbReadImage;
-                    /** Number of bytes to wite left. */
-                    size_t               cbWrite;
                 } Optimized;
             } Write;
@@ -643,5 +643,5 @@
                                        PCRTSGSEG paSeg, unsigned cSeg,
                                        PVDIOCTX pIoCtxParent, size_t cbTransferParent,
-                                       void *pvAllocation,
+                                       size_t cbWriteParent, void *pvAllocation,
                                        PFNVDIOCTXTRANSFER pfnIoCtxTransfer)
 {
@@ -655,4 +655,5 @@
         pIoCtx->Type.Child.cbTransferLeftSaved = cbTransfer;
         pIoCtx->Type.Child.cbTransferParent    = cbTransferParent;
+        pIoCtx->Type.Child.cbWriteParent       = cbWriteParent;
     }
 
@@ -1299,5 +1300,15 @@
         /* Now assemble the remaining data. */
         if (cbWriteCopy)
-            vdIoCtxCopy(pIoCtx, pIoCtxParent, cbWriteCopy);
+        {
+            /*
+             * The S/G buffer of the parent needs to be cloned because
+             * it is not allowed to modify the state.
+             */
+            RTSGBUF SgBufParentTmp;
+
+            RTSgBufClone(&SgBufParentTmp, &pIoCtxParent->SgBuf);
+            RTSgBufCopy(&pIoCtx->SgBuf, &SgBufParentTmp, cbWriteCopy);
+        }
+
         /* Zero out the remainder of this block. Will never be visible, as this
          * is beyond the limit of the image. */
@@ -1313,5 +1324,5 @@
     rc = pImage->Backend->pfnAsyncWrite(pImage->pvBackendData,
                                         pIoCtx->uOffset - cbPreRead,
-                                        cbPreRead + pIoCtx->cbTransferLeft + cbPostRead,
+                                        cbPreRead + cbThisWrite + cbPostRead,
                                         pIoCtx, NULL, &cbPreRead, &cbPostRead, 0);
     Assert(rc != VERR_VD_BLOCK_FREE);
@@ -1354,5 +1365,5 @@
     size_t cbPreRead   = pIoCtx->Type.Child.cbPreRead;
     size_t cbPostRead  = pIoCtx->Type.Child.cbPostRead;
-    size_t cbWrite     = pIoCtx->Type.Child.Write.Optimized.cbWrite;
+    size_t cbWrite     = pIoCtx->Type.Child.cbWriteParent;
     size_t cbFill = 0;
     size_t cbWriteCopy = 0;
@@ -1389,5 +1400,5 @@
     pIoCtx->cbTransferLeft = cbPreRead + cbThisWrite + cbPostRead - cbFill;
     pIoCtx->cbTransfer     = pIoCtx->cbTransferLeft;
-    pIoCtx->uOffset -= cbPreRead;
+    pIoCtx->uOffset       -= cbPreRead;
 
     /* Next step */
@@ -1439,5 +1450,5 @@
                 pIoCtx->fBlocked = true;
                 Assert(pIoCtx->NodeWriteGrowing.pNext == &pDisk->ListWriteGrowing);
-                Assert(pDisk->ListWriteGrowing.pPrev == & pIoCtx->NodeWriteGrowing);
+                Assert(pDisk->ListWriteGrowing.pPrev == &pIoCtx->NodeWriteGrowing);
                 rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
                 break;
@@ -1459,4 +1470,5 @@
                                                          pTmp, 1,
                                                          pIoCtx, cbThisWrite,
+                                                         cbWrite,
                                                          pTmp,
                                                            (pImage->uOpenFlags & VD_OPEN_FLAGS_HONOR_SAME)
