Changeset 28154 in vbox
- Timestamp:
- Apr 9, 2010 7:11:23 PM (15 years ago)
- Location:
- trunk/src/VBox/Devices/Storage
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/RawHDDCore.cpp
r27808 r28154 1200 1200 static bool rawIsAsyncIOSupported(void *pvBackendData) 1201 1201 { 1202 return false;1202 return true; 1203 1203 } 1204 1204 … … 1206 1206 PVDIOCTX pIoCtx, size_t *pcbActuallyRead) 1207 1207 { 1208 int rc = VERR_NOT_IMPLEMENTED; 1209 LogFlowFunc(("returns %Rrc\n", rc)); 1208 int rc = VINF_SUCCESS; 1209 PRAWIMAGE pImage = (PRAWIMAGE)pvBackendData; 1210 1211 rc = pImage->pInterfaceIOCallbacks->pfnReadUserAsync(pImage->pInterfaceIO->pvUser, 1212 pImage->pStorage, 1213 uOffset, pIoCtx, cbRead); 1214 if (RT_SUCCESS(rc)) 1215 *pcbActuallyRead = cbRead; 1216 1210 1217 return rc; 1211 1218 } … … 1216 1223 size_t *pcbPostRead, unsigned fWrite) 1217 1224 { 1218 int rc = VERR_NOT_IMPLEMENTED; 1219 LogFlowFunc(("returns %Rrc\n", rc)); 1225 int rc = VINF_SUCCESS; 1226 PRAWIMAGE pImage = (PRAWIMAGE)pvBackendData; 1227 1228 rc = pImage->pInterfaceIOCallbacks->pfnWriteUserAsync(pImage->pInterfaceIO->pvUser, 1229 pImage->pStorage, 1230 uOffset, pIoCtx, cbWrite); 1231 1232 if (RT_SUCCESS(rc)) 1233 { 1234 *pcbWriteProcess = cbWrite; 1235 *pcbPostRead = 0; 1236 *pcbPreRead = 0; 1237 } 1238 1220 1239 return rc; 1221 1240 } … … 1235 1254 sizeof(VBOXHDDBACKEND), 1236 1255 /* uBackendCaps */ 1237 VD_CAP_CREATE_FIXED | VD_CAP_FILE ,1256 VD_CAP_CREATE_FIXED | VD_CAP_FILE | VD_CAP_ASYNC, 1238 1257 /* papszFileExtensions */ 1239 1258 s_apszRawFileExtensions, -
trunk/src/VBox/Devices/Storage/VBoxHDD.cpp
r28108 r28154 208 208 /** Flag whether the request finished */ 209 209 volatile bool fComplete; 210 /** Temporary allocated memory which is freed 211 * when the context completes. */ 212 void *pvAllocation; 210 213 /** Parent I/O context if any. Sets the type of the context (root/child) */ 211 214 PVDIOCTX pIoCtxParent; … … 527 530 DECLINLINE(PVDIOCTX) vdIoCtxAlloc(PVBOXHDD pDisk, VDIOCTXTXDIR enmTxDir, 528 531 uint64_t uOffset, size_t cbTransfer, 529 PCRTSGSEG pcaSeg, unsigned cSeg) 532 PCRTSGSEG pcaSeg, unsigned cSeg, 533 void *pvAllocation) 530 534 { 531 535 PVDIOCTX pIoCtx = NULL; … … 540 544 pIoCtx->cMetaTransfersPending = 0; 541 545 pIoCtx->fComplete = false; 546 pIoCtx->pvAllocation = pvAllocation; 542 547 543 548 RTSgBufInit(&pIoCtx->SgBuf, pcaSeg, cSeg); … … 551 556 PCRTSGSEG paSeg, unsigned cSeg, 552 557 PFNVDASYNCTRANSFERCOMPLETE pfnComplete, 553 void *pvUser1, void *pvUser2) 558 void *pvUser1, void *pvUser2, 559 void *pvAllocation) 554 560 { 555 561 PVDIOCTX pIoCtx = vdIoCtxAlloc(pDisk, enmTxDir, uOffset, cbTransfer, 556 paSeg, cSeg );562 paSeg, cSeg, pvAllocation); 557 563 558 564 if (RT_LIKELY(pIoCtx)) … … 570 576 uint64_t uOffset, size_t cbTransfer, 571 577 PCRTSGSEG paSeg, unsigned cSeg, 572 PVDIOCTX pIoCtxParent, size_t cbTransferParent) 578 PVDIOCTX pIoCtxParent, size_t cbTransferParent, 579 void *pvAllocation) 573 580 { 574 581 PVDIOCTX pIoCtx = vdIoCtxAlloc(pDisk, enmTxDir, uOffset, cbTransfer, 575 paSeg, cSeg );582 paSeg, cSeg, pvAllocation); 576 583 577 584 if (RT_LIKELY(pIoCtx)) … … 621 628 static void vdIoCtxFree(PVBOXHDD pDisk, PVDIOCTX pIoCtx) 622 629 { 630 if (pIoCtx->pvAllocation) 631 RTMemFree(pIoCtx->pvAllocation); 623 632 RTMemCacheFree(pDisk->hMemCacheIoCtx, pIoCtx); 624 633 } … … 1138 1147 return rc; 1139 1148 1140 #if 0 1149 /** @todo Snapshots */ 1150 Assert(!pIoCtxDst->cbTransferLeft && !pIoCtxDst->cMetaTransfersPending); 1151 1152 vdIoCtxChildReset(pIoCtxDst); 1153 RTSgBufAdvance(&pIoCtxDst->SgBuf, cbPreRead); 1154 1141 1155 /* Check if the write would modify anything in this block. */ 1142 if ( !memcmp((char *)pvTmp + cbPreRead, pvBuf, cbThisWrite) 1143 && (!cbWriteCopy || !memcmp((char *)pvTmp + cbPreRead + cbThisWrite, 1144 (char *)pvBuf + cbThisWrite, cbWriteCopy))) 1145 { 1146 /* Block is completely unchanged, so no need to write anything. */ 1147 return VINF_SUCCESS; 1156 if (!RTSgBufCmp(&pIoCtxDst->SgBuf, &pIoCtxSrc->SgBuf, cbThisWrite)) 1157 { 1158 RTSGBUF SgBufSrcTmp; 1159 1160 RTSgBufClone(&SgBufSrcTmp, &pIoCtxSrc->SgBuf); 1161 RTSgBufAdvance(&SgBufSrcTmp, cbThisWrite); 1162 RTSgBufAdvance(&pIoCtxDst->SgBuf, cbThisWrite); 1163 1164 if (!cbWriteCopy || !RTSgBufCmp(&pIoCtxDst->SgBuf, &SgBufSrcTmp, cbWriteCopy)) 1165 { 1166 /* Block is completely unchanged, so no need to write anything. */ 1167 LogFlowFunc(("Block didn't changed\n")); 1168 ASMAtomicWriteU32(&pIoCtxDst->cbTransferLeft, 0); 1169 return VINF_SUCCESS; 1170 } 1148 1171 } 1149 1172 1150 1173 /* Copy the data to the right place in the buffer. */ 1151 memcpy((char *)pvTmp + cbPreRead, pvBuf, cbThisWrite); 1174 RTSgBufReset(&pIoCtxDst->SgBuf); 1175 RTSgBufAdvance(&pIoCtxDst->SgBuf, cbPreRead); 1176 vdIoCtxCopy(pIoCtxDst, pIoCtxSrc, cbThisWrite); 1152 1177 1153 1178 /* Handle the data that goes after the write to fill the block. */ … … 1156 1181 /* Now assemble the remaining data. */ 1157 1182 if (cbWriteCopy) 1158 memcpy((char *)pvTmp + cbPreRead + cbThisWrite, 1159 (char *)pvBuf + cbThisWrite, cbWriteCopy); 1183 vdIoCtxCopy(pIoCtxDst, pIoCtxSrc, cbWriteCopy); 1160 1184 /* Zero out the remainder of this block. Will never be visible, as this 1161 1185 * is beyond the limit of the image. */ 1162 1186 if (cbFill) 1163 memset((char *)pvTmp + cbPreRead + cbThisWrite + cbWriteCopy + cbReadImage, 1164 '\0', cbFill); 1187 { 1188 RTSgBufAdvance(&pIoCtxDst->SgBuf, cbReadImage); 1189 vdIoCtxSet(pIoCtxDst, '\0', cbFill); 1190 } 1165 1191 } 1166 1192 1167 1193 /* Write the full block to the virtual disk. */ 1168 rc = pImage->Backend->pfnWrite(pImage->pvBackendData, 1169 uOffset - cbPreRead, pvTmp, 1170 cbPreRead + cbThisWrite + cbPostRead, 1171 NULL, &cbPreRead, &cbPostRead, 0); 1194 RTSgBufReset(&pIoCtxDst->SgBuf); 1195 rc = pImage->Backend->pfnAsyncWrite(pImage->pvBackendData, 1196 uOffset - cbPreRead, 1197 cbPreRead + cbThisWrite + cbPostRead, 1198 pIoCtxDst, NULL, &cbPreRead, &cbPostRead, 0); 1172 1199 Assert(rc != VERR_VD_BLOCK_FREE); 1173 1200 Assert(cbPreRead == 0); 1174 1201 Assert(cbPostRead == 0); 1175 #endif 1202 1176 1203 return rc; 1177 1204 } … … 1211 1238 * A bit hackish but avoids the need to allocate memory twice. 1212 1239 */ 1213 PRTSGSEG pTmp = (PRTSGSEG)RTMem TmpAlloc(cbPreRead + cbThisWrite + cbPostRead + sizeof(RTSGSEG));1240 PRTSGSEG pTmp = (PRTSGSEG)RTMemAlloc(cbPreRead + cbThisWrite + cbPostRead + sizeof(RTSGSEG)); 1214 1241 AssertBreakStmt(VALID_PTR(pTmp), rc = VERR_NO_MEMORY); 1215 1242 … … 1218 1245 1219 1246 PVDIOCTX pIoCtxWrite = vdIoCtxChildAlloc(pDisk, VDIOCTXTXDIR_WRITE, 1220 uOffset , pTmp->cbSeg,1247 uOffset - cbPreRead, pTmp->cbSeg, 1221 1248 pTmp, 1, 1222 pIoCtx, cbThisWrite); 1249 pIoCtx, cbThisWrite, 1250 pTmp); 1223 1251 if (!VALID_PTR(pIoCtxWrite)) 1224 1252 { … … 1251 1279 if (RT_FAILURE(rc)) 1252 1280 { 1253 RTMemTmpFree(pTmp);1254 1281 vdIoCtxFree(pDisk, pIoCtxWrite); 1255 1282 break; … … 1259 1286 && ASMAtomicCmpXchgBool(&pIoCtxWrite->fComplete, true, false)) 1260 1287 { 1288 LogFlow(("Child write request completed\n")); 1261 1289 RTMemTmpFree(pTmp); 1262 1290 ASMAtomicSubU32(&pIoCtx->cbTransferLeft, cbThisWrite); 1263 1291 vdIoCtxFree(pDisk, pIoCtxWrite); 1264 1292 } 1293 else 1294 LogFlow(("Child write pending\n")); 1265 1295 } 1266 1296 … … 1551 1581 { 1552 1582 LogFlowFunc(("I/O context completed\n")); 1553 Assert(!pIoCtx->pIoCtxParent); 1554 pIoCtx->Type.Root.pfnComplete(pIoCtx->Type.Root.pvUser1, pIoCtx->Type.Root.pvUser2); 1583 if (pIoCtx->pIoCtxParent) 1584 { 1585 PVDIOCTX pIoCtxParent = pIoCtx->pIoCtxParent; 1586 1587 /* Update the parent state. */ 1588 Assert(!pIoCtxParent->pIoCtxParent); 1589 Assert(pIoCtx->enmTxDir == VDIOCTXTXDIR_WRITE); 1590 RTMemFree((void *)pIoCtx->SgBuf.pcaSeg); /* This will also free the attached buffer. */ 1591 ASMAtomicSubU32(&pIoCtxParent->cbTransferLeft, pIoCtx->Type.Child.cbTransferParent); 1592 1593 if ( !pIoCtxParent->cbTransferLeft 1594 && !pIoCtxParent->cMetaTransfersPending 1595 && ASMAtomicCmpXchgBool(&pIoCtxParent->fComplete, true, false)) 1596 { 1597 pIoCtxParent->Type.Root.pfnComplete(pIoCtxParent->Type.Root.pvUser1, pIoCtxParent->Type.Root.pvUser2); 1598 vdIoCtxFree(pDisk, pIoCtxParent); 1599 } 1600 } 1601 else 1602 pIoCtx->Type.Root.pfnComplete(pIoCtx->Type.Root.pvUser1, pIoCtx->Type.Root.pvUser2); 1603 1555 1604 vdIoCtxFree(pDisk, pIoCtx); 1556 1605 } … … 5534 5583 pIoCtx = vdIoCtxRootAlloc(pDisk, VDIOCTXTXDIR_READ, uOffset, 5535 5584 cbRead, paSeg, cSeg, 5536 pfnComplete, pvUser1, pvUser2); 5585 pfnComplete, pvUser1, pvUser2, 5586 NULL); 5537 5587 if (!pIoCtx) 5538 5588 { … … 5614 5664 rc = VERR_INVALID_PARAMETER); 5615 5665 5616 pIoCtx = vdIoCtxRootAlloc(pDisk, VDIOCTXTXDIR_ READ, uOffset,5666 pIoCtx = vdIoCtxRootAlloc(pDisk, VDIOCTXTXDIR_WRITE, uOffset, 5617 5667 cbWrite, paSeg, cSeg, 5618 pfnComplete, pvUser1, pvUser2); 5668 pfnComplete, pvUser1, pvUser2, 5669 NULL); 5619 5670 if (!pIoCtx) 5620 5671 { -
trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp
r28065 r28154 712 712 { 713 713 int rc; 714 715 if (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO)716 return VERR_NOT_SUPPORTED;717 714 718 715 pImage->uOpenFlags = uOpenFlags; … … 1632 1629 /* Image must be opened and the new flags must be valid. Just readonly and 1633 1630 * info flags are supported. */ 1634 if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO )))1631 if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO))) 1635 1632 { 1636 1633 rc = VERR_INVALID_PARAMETER; … … 2049 2046 static bool vdiIsAsyncIOSupported(void *pBackendData) 2050 2047 { 2051 #if 02052 2048 return true; 2053 #else2054 return false;2055 #endif2056 2049 } 2057 2050 … … 2484 2477 /* uBackendCaps */ 2485 2478 VD_CAP_UUID | VD_CAP_CREATE_FIXED | VD_CAP_CREATE_DYNAMIC 2486 | VD_CAP_DIFF | VD_CAP_FILE 2487 #if 0 2488 | VD_CAP_ASYNC 2489 #endif 2490 , 2479 | VD_CAP_DIFF | VD_CAP_FILE | VD_CAP_ASYNC, 2491 2480 /* papszFileExtensions */ 2492 2481 s_apszVdiFileExtensions,
Note:
See TracChangeset
for help on using the changeset viewer.