Changeset 49387 in vbox
- Timestamp:
- Nov 4, 2013 10:35:04 PM (11 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Storage/VD.cpp (modified) (22 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/VD.cpp
r49314 r49387 261 261 /** Pointer to the discard state if any. */ 262 262 PVDDISCARDSTATE pDiscard; 263 264 /** Event semaphore for synchronous I/O. */265 RTSEMEVENT hEventSemSyncIo;266 /** Status code of the last synchronous I/O request. */267 int rcSync;268 263 }; 269 264 … … 1161 1156 } 1162 1157 1158 DECLINLINE(void) vdIoCtxDiscardInit(PVDIOCTX pIoCtx, PVBOXHDD pDisk, PCRTRANGE paRanges, 1159 unsigned cRanges, PFNVDASYNCTRANSFERCOMPLETE pfnComplete, 1160 void *pvUser1, void *pvUser2, void *pvAllocation, 1161 PFNVDIOCTXTRANSFER pfnIoCtxTransfer, uint32_t fFlags) 1162 { 1163 pIoCtx->pIoCtxNext = NULL; 1164 pIoCtx->pDisk = pDisk; 1165 pIoCtx->enmTxDir = VDIOCTXTXDIR_DISCARD; 1166 pIoCtx->cDataTransfersPending = 0; 1167 pIoCtx->cMetaTransfersPending = 0; 1168 pIoCtx->fComplete = false; 1169 pIoCtx->fFlags = fFlags; 1170 pIoCtx->pvAllocation = pvAllocation; 1171 pIoCtx->pfnIoCtxTransfer = pfnIoCtxTransfer; 1172 pIoCtx->pfnIoCtxTransferNext = NULL; 1173 pIoCtx->rcReq = VINF_SUCCESS; 1174 pIoCtx->Req.Discard.paRanges = paRanges; 1175 pIoCtx->Req.Discard.cRanges = cRanges; 1176 pIoCtx->Req.Discard.idxRange = 0; 1177 pIoCtx->Req.Discard.cbDiscardLeft = 0; 1178 pIoCtx->Req.Discard.offCur = 0; 1179 pIoCtx->Req.Discard.cbThisDiscard = 0; 1180 1181 pIoCtx->pIoCtxParent = NULL; 1182 pIoCtx->Type.Root.pfnComplete = pfnComplete; 1183 pIoCtx->Type.Root.pvUser1 = pvUser1; 1184 pIoCtx->Type.Root.pvUser2 = pvUser2; 1185 } 1186 1163 1187 DECLINLINE(PVDIOCTX) vdIoCtxDiscardAlloc(PVBOXHDD pDisk, PCRTRANGE paRanges, 1164 1188 unsigned cRanges, … … 1174 1198 if (RT_LIKELY(pIoCtx)) 1175 1199 { 1176 pIoCtx->pIoCtxNext = NULL; 1177 pIoCtx->pDisk = pDisk; 1178 pIoCtx->enmTxDir = VDIOCTXTXDIR_DISCARD; 1179 pIoCtx->cDataTransfersPending = 0; 1180 pIoCtx->cMetaTransfersPending = 0; 1181 pIoCtx->fComplete = false; 1182 pIoCtx->fFlags = fFlags; 1183 pIoCtx->pvAllocation = pvAllocation; 1184 pIoCtx->pfnIoCtxTransfer = pfnIoCtxTransfer; 1185 pIoCtx->pfnIoCtxTransferNext = NULL; 1186 pIoCtx->rcReq = VINF_SUCCESS; 1187 pIoCtx->Req.Discard.paRanges = paRanges; 1188 pIoCtx->Req.Discard.cRanges = cRanges; 1189 pIoCtx->Req.Discard.idxRange = 0; 1190 pIoCtx->Req.Discard.cbDiscardLeft = 0; 1191 pIoCtx->Req.Discard.offCur = 0; 1192 pIoCtx->Req.Discard.cbThisDiscard = 0; 1193 1194 pIoCtx->pIoCtxParent = NULL; 1195 pIoCtx->Type.Root.pfnComplete = pfnComplete; 1196 pIoCtx->Type.Root.pvUser1 = pvUser1; 1197 pIoCtx->Type.Root.pvUser2 = pvUser2; 1200 vdIoCtxDiscardInit(pIoCtx, pDisk, paRanges, cRanges, pfnComplete, pvUser1, 1201 pvUser2, pvAllocation, pfnIoCtxTransfer, fFlags); 1198 1202 } 1199 1203 … … 1437 1441 ASMAtomicCmpXchgS32(&pIoCtx->rcReq, rc, VINF_SUCCESS); 1438 1442 1439 if (rc != VERR_DISK_FULL) 1440 { 1441 /* 1442 * The I/O context completed if we have an error and there is no data 1443 * or meta data transfer pending. 1444 */ 1445 if ( !pIoCtx->cMetaTransfersPending 1446 && !pIoCtx->cDataTransfersPending) 1447 rc = VINF_VD_ASYNC_IO_FINISHED; 1448 else 1449 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 1450 } 1443 /* 1444 * The I/O context completed if we have an error and there is no data 1445 * or meta data transfer pending. 1446 */ 1447 if ( !pIoCtx->cMetaTransfersPending 1448 && !pIoCtx->cDataTransfersPending) 1449 rc = VINF_VD_ASYNC_IO_FINISHED; 1450 else 1451 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 1451 1452 } 1452 1453 … … 1462 1463 * Processes the list of waiting I/O contexts. 1463 1464 * 1464 * @returns VBox status code. 1465 * @returns VBox status code, only valid if pIoCtxRc is not NULL, treat as void 1466 * function otherwise. 1465 1467 * @param pDisk The disk structure. 1466 1468 * @param pIoCtxRc An I/O context handle which waits on the list. When processed … … 1470 1472 static int vdDiskProcessWaitingIoCtx(PVBOXHDD pDisk, PVDIOCTX pIoCtxRc) 1471 1473 { 1472 int rc = V INF_SUCCESS;1474 int rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 1473 1475 1474 1476 LogFlowFunc(("pDisk=%#p pIoCtxRc=%#p\n", pDisk, pIoCtxRc)); … … 1517 1519 { 1518 1520 /* The given I/O context was processed, pass the return code to the caller. */ 1519 rc = rcTmp; 1521 if (rcTmp == VINF_VD_ASYNC_IO_FINISHED) 1522 rc = pTmp->rcReq; 1523 else 1524 rc = rcTmp; 1520 1525 } 1521 1526 else if ( rcTmp == VINF_VD_ASYNC_IO_FINISHED … … 1531 1536 } 1532 1537 1533 /*1534 * vdIoCtxProcessLocked() never returns VINF_SUCCESS.1535 * If the status code is still set and a valid I/O context was given1536 * it was not found on the list (another thread cleared it already).1537 * Return I/O in progress status code in that case.1538 */1539 if (rc == VINF_SUCCESS && pIoCtxRc)1540 rc = VERR_VD_ASYNC_IO_IN_PROGRESS;1541 1542 1538 LogFlowFunc(("returns rc=%Rrc\n", rc)); 1543 1539 return rc; … … 1637 1633 * 1638 1634 * @returns VBox status code of the completed request. 1639 * @param pIoCtx The sync I/O context. 1640 */ 1641 static int vdIoCtxProcessSync(PVDIOCTX pIoCtx) 1635 * @param pIoCtx The sync I/O context. 1636 * @param hEventComplete Event sempahore to wait on for completion. 1637 */ 1638 static int vdIoCtxProcessSync(PVDIOCTX pIoCtx, RTSEMEVENT hEventComplete) 1642 1639 { 1643 1640 int rc = VINF_SUCCESS; … … 1646 1643 LogFlowFunc(("pIoCtx=%p\n", pIoCtx)); 1647 1644 1648 AssertMsg(pIoCtx->fFlags & VDIOCTX_FLAGS_SYNC,1645 AssertMsg(pIoCtx->fFlags & (VDIOCTX_FLAGS_SYNC | VDIOCTX_FLAGS_DONT_FREE), 1649 1646 ("I/O context is not marked as synchronous\n")); 1650 1647 … … 1655 1652 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1656 1653 { 1657 rc = RTSemEventWait( pDisk->hEventSemSyncIo, RT_INDEFINITE_WAIT);1654 rc = RTSemEventWait(hEventComplete, RT_INDEFINITE_WAIT); 1658 1655 AssertRC(rc); 1659 1660 rc = pDisk->rcSync; 1661 } 1662 else /* Success or error. */ 1663 { 1664 rc = pIoCtx->rcReq; 1665 vdIoCtxFree(pDisk, pIoCtx); 1666 } 1656 } 1657 1658 rc = pIoCtx->rcReq; 1659 vdIoCtxFree(pDisk, pIoCtx); 1667 1660 1668 1661 return rc; … … 1953 1946 bool fZeroFreeBlocks, bool fUpdateCache, unsigned cImagesRead) 1954 1947 { 1948 int rc = VINF_SUCCESS; 1955 1949 uint32_t fFlags = VDIOCTX_FLAGS_SYNC | VDIOCTX_FLAGS_DONT_FREE; 1956 1950 RTSGSEG Segment; 1957 1951 RTSGBUF SgBuf; 1958 1952 VDIOCTX IoCtx; 1953 RTSEMEVENT hEventComplete = NIL_RTSEMEVENT; 1954 1955 rc = RTSemEventCreate(&hEventComplete); 1956 if (RT_FAILURE(rc)) 1957 return rc; 1959 1958 1960 1959 if (fZeroFreeBlocks) … … 1973 1972 IoCtx.Type.Root.pfnComplete = vdIoCtxSyncComplete; 1974 1973 IoCtx.Type.Root.pvUser1 = pDisk; 1975 IoCtx.Type.Root.pvUser2 = NULL; 1976 return vdIoCtxProcessSync(&IoCtx); 1974 IoCtx.Type.Root.pvUser2 = hEventComplete; 1975 rc = vdIoCtxProcessSync(&IoCtx, hEventComplete); 1976 1977 RTSemEventDestroy(hEventComplete); 1978 return rc; 1977 1979 } 1978 1980 … … 2045 2047 uint32_t fFlags, unsigned cImagesRead) 2046 2048 { 2049 int rc = VINF_SUCCESS; 2047 2050 RTSGSEG Segment; 2048 2051 RTSGBUF SgBuf; 2049 2052 VDIOCTX IoCtx; 2053 RTSEMEVENT hEventComplete = NIL_RTSEMEVENT; 2054 2055 rc = RTSemEventCreate(&hEventComplete); 2056 if (RT_FAILURE(rc)) 2057 return rc; 2050 2058 2051 2059 fFlags |= VDIOCTX_FLAGS_SYNC | VDIOCTX_FLAGS_DONT_FREE; … … 2062 2070 IoCtx.Type.Root.pfnComplete = vdIoCtxSyncComplete; 2063 2071 IoCtx.Type.Root.pvUser1 = pDisk; 2064 IoCtx.Type.Root.pvUser2 = NULL; 2065 return vdIoCtxProcessSync(&IoCtx); 2072 IoCtx.Type.Root.pvUser2 = hEventComplete; 2073 rc = vdIoCtxProcessSync(&IoCtx, hEventComplete); 2074 2075 RTSemEventDestroy(hEventComplete); 2076 return rc; 2066 2077 } 2067 2078 … … 2710 2721 Assert(pIoCtx->Req.Io.cbTransferLeft >= cbThisWrite); 2711 2722 Assert(cbThisWrite == (uint32_t)cbThisWrite); 2723 rc = pIoCtxWrite->rcReq; 2712 2724 ASMAtomicSubU32(&pIoCtx->Req.Io.cbTransferLeft, (uint32_t)cbThisWrite); 2713 2725 vdIoCtxUnlockDisk(pDisk, pIoCtx, false /* fProcessDeferredReqs*/ ); 2714 2726 vdIoCtxFree(pDisk, pIoCtxWrite); 2715 2716 rc = VINF_SUCCESS;2717 2727 } 2718 2728 else … … 4984 4994 { 4985 4995 PVBOXHDD pDisk = (PVBOXHDD)pvUser1; 4986 4987 pDisk->rcSync = rcReq; 4988 RTSemEventSignal( pDisk->hEventSemSyncIo);4996 RTSEMEVENT hEvent = (RTSEMEVENT)pvUser2; 4997 4998 RTSemEventSignal(hEvent); 4989 4999 } 4990 5000 … … 5182 5192 pDisk->pIoCtxHead = NULL; 5183 5193 pDisk->fLocked = false; 5184 pDisk->hEventSemSyncIo = NIL_RTSEMEVENT;5185 5194 pDisk->hMemCacheIoCtx = NIL_RTMEMCACHE; 5186 5195 pDisk->hMemCacheIoTask = NIL_RTMEMCACHE; 5187 5188 rc = RTSemEventCreate(&pDisk->hEventSemSyncIo);5189 if (RT_FAILURE(rc))5190 break;5191 5196 5192 5197 /* Create the I/O ctx cache */ … … 5217 5222 && pDisk) 5218 5223 { 5219 if (pDisk->hEventSemSyncIo != NIL_RTSEMEVENT)5220 RTSemEventDestroy(pDisk->hEventSemSyncIo);5221 5224 if (pDisk->hMemCacheIoCtx != NIL_RTMEMCACHE) 5222 5225 RTMemCacheDestroy(pDisk->hMemCacheIoCtx); … … 5250 5253 RTMemCacheDestroy(pDisk->hMemCacheIoCtx); 5251 5254 RTMemCacheDestroy(pDisk->hMemCacheIoTask); 5252 RTSemEventDestroy(pDisk->hEventSemSyncIo);5253 5255 RTMemFree(pDisk); 5254 5256 } while (0); … … 8135 8137 AssertPtrBreakStmt(pImage, rc = VERR_VD_NOT_OPENED); 8136 8138 8137 PVDIOCTX pIoCtx = vdIoCtxRootAlloc(pDisk, VDIOCTXTXDIR_FLUSH, 0, 8138 0, pDisk->pLast, NULL, 8139 vdIoCtxSyncComplete, pDisk, NULL, 8140 NULL, vdFlushHelperAsync, 8141 VDIOCTX_FLAGS_SYNC); 8142 8143 if (!pIoCtx) 8144 { 8145 rc = VERR_NO_MEMORY; 8139 VDIOCTX IoCtx; 8140 RTSEMEVENT hEventComplete = NIL_RTSEMEVENT; 8141 8142 rc = RTSemEventCreate(&hEventComplete); 8143 if (RT_FAILURE(rc)) 8146 8144 break; 8147 } 8148 8149 rc = vdIoCtxProcessSync(pIoCtx); 8145 8146 vdIoCtxInit(&IoCtx, pDisk, VDIOCTXTXDIR_FLUSH, 0, 0, pImage, NULL, 8147 NULL, vdFlushHelperAsync, VDIOCTX_FLAGS_SYNC | VDIOCTX_FLAGS_DONT_FREE); 8148 8149 IoCtx.Type.Root.pfnComplete = vdIoCtxSyncComplete; 8150 IoCtx.Type.Root.pvUser1 = pDisk; 8151 IoCtx.Type.Root.pvUser2 = hEventComplete; 8152 rc = vdIoCtxProcessSync(&IoCtx, hEventComplete); 8153 8154 RTSemEventDestroy(hEventComplete); 8150 8155 } while (0); 8151 8156 … … 9501 9506 rc = VERR_NOT_SUPPORTED); 9502 9507 9503 PVDIOCTX pIoCtx = vdIoCtxDiscardAlloc(pDisk, paRanges, cRanges, 9504 vdIoCtxSyncComplete, pDisk, NULL, NULL, 9505 vdDiscardHelperAsync, 9506 VDIOCTX_FLAGS_SYNC); 9507 if (!pIoCtx) 9508 { 9509 rc = VERR_NO_MEMORY; 9508 VDIOCTX IoCtx; 9509 RTSEMEVENT hEventComplete = NIL_RTSEMEVENT; 9510 9511 rc = RTSemEventCreate(&hEventComplete); 9512 if (RT_FAILURE(rc)) 9510 9513 break; 9511 } 9512 9513 rc = vdIoCtxProcessSync(pIoCtx); 9514 9515 vdIoCtxDiscardInit(&IoCtx, pDisk, paRanges, cRanges, 9516 vdIoCtxSyncComplete, pDisk, hEventComplete, NULL, 9517 vdDiscardHelperAsync, VDIOCTX_FLAGS_SYNC | VDIOCTX_FLAGS_DONT_FREE); 9518 rc = vdIoCtxProcessSync(&IoCtx, hEventComplete); 9519 9520 RTSemEventDestroy(hEventComplete); 9514 9521 } while (0); 9515 9522
Note:
See TracChangeset
for help on using the changeset viewer.

