- Timestamp:
- Sep 11, 2009 10:41:14 PM (15 years ago)
- Location:
- trunk/src/VBox/Devices/Storage
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvVD.cpp
r22277 r22966 209 209 PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK); 210 210 PDRVVDSTORAGEBACKEND pStorageBackend = (PDRVVDSTORAGEBACKEND)pvTemplateUser; 211 int rc = VINF_VD_ASYNC_IO_FINISHED;212 void *pvCallerUser = NULL;213 211 214 212 if (pStorageBackend->fSyncIoPending) 215 213 { 216 pStorageBackend->fSyncIoPending ;214 pStorageBackend->fSyncIoPending = false; 217 215 RTSemEventSignal(pStorageBackend->EventSem); 218 216 } 219 else if (pStorageBackend->pfnCompleted)220 rc = pStorageBackend->pfnCompleted(pvUser, &pvCallerUser);221 217 else 222 pvCallerUser = pvUser; 223 224 if (rc == VINF_VD_ASYNC_IO_FINISHED) 225 { 226 rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvCallerUser); 227 AssertRC(rc); 228 } 229 else 230 AssertMsg(rc == VERR_VD_ASYNC_IO_IN_PROGRESS, ("Invalid return code from disk backend rc=%Rrc\n", rc)); 231 } 232 233 static DECLCALLBACK(int) drvvdAsyncIOOpen(void *pvUser, const char *pszLocation, bool fReadonly, 218 { 219 int rc = VINF_VD_ASYNC_IO_FINISHED; 220 void *pvCallerUser = NULL; 221 222 if (pStorageBackend->pfnCompleted) 223 rc = pStorageBackend->pfnCompleted(pvUser, &pvCallerUser); 224 else 225 pvCallerUser = pvUser; 226 227 if (rc == VINF_VD_ASYNC_IO_FINISHED) 228 { 229 rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvCallerUser); 230 AssertRC(rc); 231 } 232 else 233 AssertMsg(rc == VERR_VD_ASYNC_IO_IN_PROGRESS, ("Invalid return code from disk backend rc=%Rrc\n", rc)); 234 } 235 } 236 237 static DECLCALLBACK(int) drvvdAsyncIOOpen(void *pvUser, const char *pszLocation, unsigned uOpenFlags, 234 238 PFNVDCOMPLETED pfnCompleted, void **ppStorage) 235 239 { … … 251 255 { 252 256 rc = PDMR3AsyncCompletionEpCreateForFile(&pStorageBackend->pEndpoint, pszLocation, 253 fReadonly257 uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY 254 258 ? PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_CACHING 255 259 : PDMACEP_FILE_FLAGS_CACHING, … … 292 296 293 297 return PDMR3AsyncCompletionEpGetSize(pStorageBackend->pEndpoint, pcbSize); 298 } 299 300 static DECLCALLBACK(int) drvvdAsyncIOSetSize(void *pvUser, void *pStorage, uint64_t cbSize) 301 { 302 PVBOXDISK pDrvVD = (PVBOXDISK)pvUser; 303 PDRVVDSTORAGEBACKEND pStorageBackend = (PDRVVDSTORAGEBACKEND)pStorage; 304 305 return VERR_NOT_SUPPORTED; 294 306 } 295 307 … … 846 858 pThis->VDIAsyncIOCallbacks.pfnClose = drvvdAsyncIOClose; 847 859 pThis->VDIAsyncIOCallbacks.pfnGetSize = drvvdAsyncIOGetSize; 860 pThis->VDIAsyncIOCallbacks.pfnSetSize = drvvdAsyncIOSetSize; 848 861 pThis->VDIAsyncIOCallbacks.pfnReadSync = drvvdAsyncIOReadSync; 849 862 pThis->VDIAsyncIOCallbacks.pfnWriteSync = drvvdAsyncIOWriteSync; … … 871 884 /* Try to attach async media port interface above.*/ 872 885 pThis->pDrvMediaAsyncPort = (PPDMIMEDIAASYNCPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_MEDIA_ASYNC_PORT); 873 874 /*875 * Attach the async transport driver below if the device above us implements the876 * async interface.877 */878 if (pThis->pDrvMediaAsyncPort)879 {880 /* Try to attach the driver. */881 PPDMIBASE pBase;882 883 rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBase);884 if (rc == VERR_PDM_NO_ATTACHED_DRIVER)885 {886 /*887 * Though the device supports async I/O there is no transport driver888 * which processes async requests.889 * Revert to non async I/O.890 */891 rc = VINF_SUCCESS;892 pThis->pDrvMediaAsyncPort = NULL;893 pThis->fAsyncIOSupported = false;894 }895 else if (RT_FAILURE(rc))896 {897 AssertMsgFailed(("Failed to attach async transport driver below rc=%Rrc\n", rc));898 }899 else900 {901 /*902 * The device supports async I/O and we successfully attached the transport driver.903 * Indicate that async I/O is supported for now as we check if the image backend supports904 * it later.905 */906 pThis->fAsyncIOSupported = true;907 908 /** @todo: Use PDM async completion manager */909 }910 }911 886 912 887 /* … … 1042 1017 } 1043 1018 1019 if (pThis->pDrvMediaAsyncPort) 1020 pThis->fAsyncIOSupported = true; 1021 1044 1022 while (pCurNode && RT_SUCCESS(rc)) 1045 1023 { … … 1086 1064 if (fHonorZeroWrites) 1087 1065 uOpenFlags |= VD_OPEN_FLAGS_HONOR_ZEROES; 1088 if (pThis-> pDrvMediaAsyncPort)1066 if (pThis->fAsyncIOSupported) 1089 1067 uOpenFlags |= VD_OPEN_FLAGS_ASYNC_IO; 1090 1068 … … 1094 1072 { 1095 1073 /* Seems async I/O is not supported by the backend, open in normal mode. */ 1074 pThis->fAsyncIOSupported = false; 1096 1075 uOpenFlags &= ~VD_OPEN_FLAGS_ASYNC_IO; 1097 1076 rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage); … … 1149 1128 else 1150 1129 { 1151 /*1152 * Check if every opened image supports async I/O.1153 * If not we revert to non async I/O.1154 */1155 if (pThis->fAsyncIOSupported)1156 {1157 for (unsigned i = 0; i < VDGetCount(pThis->pDisk); i++)1158 {1159 VDBACKENDINFO vdBackendInfo;1160 1161 rc = VDBackendInfoSingle(pThis->pDisk, i, &vdBackendInfo);1162 AssertRC(rc);1163 1164 if (vdBackendInfo.uBackendCaps & VD_CAP_ASYNC)1165 {1166 /*1167 * Backend indicates support for at least some files.1168 * Check if current file is supported with async I/O)1169 */1170 rc = VDImageIsAsyncIOSupported(pThis->pDisk, i, &pThis->fAsyncIOSupported);1171 AssertRC(rc);1172 1173 /*1174 * Check if current image is supported.1175 * If not we can stop checking because1176 * at least one does not support it.1177 */1178 if (!pThis->fAsyncIOSupported)1179 break;1180 }1181 else1182 {1183 pThis->fAsyncIOSupported = false;1184 break;1185 }1186 }1187 }1188 1189 1130 /* Switch to runtime error facility. */ 1190 1131 pThis->fErrorUseRuntime = true; -
trunk/src/VBox/Devices/Storage/ParallelsHDDCore.cpp
r21806 r22966 70 70 /** Error interface callbacks. */ 71 71 PVDINTERFACEERROR pInterfaceErrorCallbacks; 72 #ifdef VBOX_WITH_NEW_IO_CODE 73 /** Async I/O interface. */ 74 PVDINTERFACE pInterfaceAsyncIO; 75 /** Async I/O interface callbacks. */ 76 PVDINTERFACEASYNCIO pInterfaceAsyncIOCallbacks; 77 #endif 72 78 73 79 /** Image file name. */ 74 80 const char *pszFilename; 75 /** File handle. */ 81 #ifndef VBOX_WITH_NEW_IO_CODE 82 /** File descriptor. */ 76 83 RTFILE File; 84 #else 85 /** Opaque storage handle. */ 86 void *pvStorage; 87 #endif 77 88 /** Open flags passed by VBoxHD layer. */ 78 89 unsigned uOpenFlags; … … 125 136 } 126 137 138 static int parallelsFileOpen(PPARALLELSIMAGE pImage, bool fReadonly, bool fCreate) 139 { 140 int rc = VINF_SUCCESS; 141 142 AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly while being created\n")); 143 144 #ifndef VBOX_WITH_NEW_IO_CODE 145 unsigned uFileFlags = fReadonly ? RTFILE_O_READ | RTFILE_O_DENY_NONE 146 : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE; 147 148 if (fCreate) 149 uFileFlags |= RTFILE_O_CREATE; 150 else 151 uFileFlags |= RTFILE_O_OPEN; 152 153 rc = RTFileOpen(&pImage->File, pImage->pszFilename, uFileFlags); 154 #else 155 156 unsigned uOpenFlags = fReadonly ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY : 0; 157 158 if (fCreate) 159 uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE; 160 161 rc = pImage->pInterfaceAsyncIOCallbacks->pfnOpen(pImage->pInterfaceAsyncIO->pvUser, 162 pImage->pszFilename, 163 uOpenFlags, 164 NULL, &pImage->pvStorage); 165 #endif 166 167 return rc; 168 } 169 170 static int parallelsFileClose(PPARALLELSIMAGE pImage) 171 { 172 int rc = VINF_SUCCESS; 173 174 #ifndef VBOX_WITH_NEW_IO_CODE 175 if (pImage->File != NIL_RTFILE) 176 rc = RTFileClose(pImage->File); 177 178 pImage->File = NIL_RTFILE; 179 #else 180 if (pImage->pvStorage) 181 rc = pImage->pInterfaceAsyncIOCallbacks->pfnClose(pImage->pInterfaceAsyncIO->pvUser, 182 pImage->pvStorage); 183 184 pImage->pvStorage = NULL; 185 #endif 186 187 return rc; 188 } 189 190 static int parallelsFileFlushSync(PPARALLELSIMAGE pImage) 191 { 192 int rc = VINF_SUCCESS; 193 194 #ifndef VBOX_WITH_NEW_IO_CODE 195 rc = RTFileFlush(pImage->File); 196 #else 197 if (pImage->pvStorage) 198 rc = pImage->pInterfaceAsyncIOCallbacks->pfnFlushSync(pImage->pInterfaceAsyncIO->pvUser, 199 pImage->pvStorage); 200 #endif 201 202 return rc; 203 } 204 205 static int parallelsFileGetSize(PPARALLELSIMAGE pImage, uint64_t *pcbSize) 206 { 207 int rc = VINF_SUCCESS; 208 209 #ifndef VBOX_WITH_NEW_IO_CODE 210 rc = RTFileGetSize(pImage->File, pcbSize); 211 #else 212 if (pImage->pvStorage) 213 rc = pImage->pInterfaceAsyncIOCallbacks->pfnGetSize(pImage->pInterfaceAsyncIO->pvUser, 214 pImage->pvStorage, 215 pcbSize); 216 #endif 217 218 return rc; 219 220 } 221 222 static int parallelsFileSetSize(PPARALLELSIMAGE pImage, uint64_t cbSize) 223 { 224 int rc = VINF_SUCCESS; 225 226 #ifndef VBOX_WITH_NEW_IO_CODE 227 rc = RTFileSetSize(pImage->File, cbSize); 228 #else 229 if (pImage->pvStorage) 230 rc = pImage->pInterfaceAsyncIOCallbacks->pfnSetSize(pImage->pInterfaceAsyncIO->pvUser, 231 pImage->pvStorage, 232 cbSize); 233 #endif 234 235 return rc; 236 } 237 238 239 static int parallelsFileWriteSync(PPARALLELSIMAGE pImage, uint64_t off, const void *pcvBuf, size_t cbWrite, size_t *pcbWritten) 240 { 241 int rc = VINF_SUCCESS; 242 243 #ifndef VBOX_WITH_NEW_IO_CODE 244 rc = RTFileWriteAt(pImage->File, off, pcvBuf, cbWrite, pcbWritten); 245 #else 246 if (pImage->pvStorage) 247 rc = pImage->pInterfaceAsyncIOCallbacks->pfnWriteSync(pImage->pInterfaceAsyncIO->pvUser, 248 pImage->pvStorage, 249 off, cbWrite, pcvBuf, 250 pcbWritten); 251 #endif 252 253 return rc; 254 } 255 256 static int parallelsFileReadSync(PPARALLELSIMAGE pImage, uint64_t off, void *pvBuf, size_t cbRead, size_t *pcbRead) 257 { 258 int rc = VINF_SUCCESS; 259 260 #ifndef VBOX_WITH_NEW_IO_CODE 261 rc = RTFileReadAt(pImage->File, off, pvBuf, cbRead, pcbRead); 262 #else 263 if (pImage->pvStorage) 264 rc = pImage->pInterfaceAsyncIOCallbacks->pfnReadSync(pImage->pInterfaceAsyncIO->pvUser, 265 pImage->pvStorage, 266 off, cbRead, pvBuf, 267 pcbRead); 268 #endif 269 270 return rc; 271 } 272 273 static bool parallelsFileOpened(PPARALLELSIMAGE pImage) 274 { 275 #ifndef VBOX_WITH_NEW_IO_CODE 276 return pImage->File != NIL_RTFILE; 277 #else 278 return pImage->pvStorage != NULL; 279 #endif 280 } 281 127 282 static int parallelsOpenImage(PPARALLELSIMAGE pImage, unsigned uOpenFlags) 128 283 { 129 284 int rc = VINF_SUCCESS; 130 RTFILE File;131 285 ParallelsHeader parallelsHeader; 132 286 … … 136 290 pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError); 137 291 138 rc = RTFileOpen(&File, pImage->pszFilename, 139 uOpenFlags & VD_OPEN_FLAGS_READONLY 140 ? RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE 141 : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 292 #ifdef VBOX_WITH_NEW_IO_CODE 293 /* Try to get async I/O interface. */ 294 pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO); 295 AssertPtr(pImage->pInterfaceAsyncIO); 296 pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO); 297 AssertPtr(pImage->pInterfaceAsyncIOCallbacks); 298 #endif 299 300 rc = parallelsFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false); 142 301 if (RT_FAILURE(rc)) 143 302 goto out; 144 303 145 pImage->File = File; 146 147 rc = RTFileGetSize(pImage->File, &pImage->cbFileCurrent); 304 rc = parallelsFileGetSize(pImage, &pImage->cbFileCurrent); 148 305 if (RT_FAILURE(rc)) 149 306 goto out; 150 307 AssertMsg(pImage->cbFileCurrent % 512 == 0, ("File size is not a multiple of 512\n")); 151 308 152 rc = RTFileReadAt(File, 0, ¶llelsHeader, sizeof(ParallelsHeader), NULL);309 rc = parallelsFileReadSync(pImage, 0, ¶llelsHeader, sizeof(parallelsHeader), NULL); 153 310 if (RT_FAILURE(rc)) 154 311 goto out; … … 198 355 } 199 356 200 rc = RTFileReadAt(File, sizeof(ParallelsHeader), pImage->pAllocationBitmap, 201 pImage->cAllocationBitmapEntries * sizeof(uint32_t), NULL); 357 rc = parallelsFileReadSync(pImage, sizeof(ParallelsHeader), 358 pImage->pAllocationBitmap, 359 pImage->cAllocationBitmapEntries * sizeof(uint32_t), 360 NULL); 202 361 if (RT_FAILURE(rc)) 203 362 goto out; … … 223 382 pImage->fAllocationBitmapChanged = false; 224 383 /* Write the allocation bitmap to the file. */ 225 rc = RTFileWriteAt(pImage->File, sizeof(ParallelsHeader),226 pImage->pAllocationBitmap,227 pImage->cAllocationBitmapEntries * sizeof(uint32_t),228 NULL);384 rc = parallelsFileWriteSync(pImage, sizeof(ParallelsHeader), 385 pImage->pAllocationBitmap, 386 pImage->cAllocationBitmapEntries * sizeof(uint32_t), 387 NULL); 229 388 if (RT_FAILURE(rc)) 230 389 return rc; … … 232 391 233 392 /* Flush file. */ 234 rc = RTFileFlush(pImage->File);393 rc = parallelsFileFlushSync(pImage); 235 394 236 395 LogFlowFunc(("returns %Rrc\n", rc)); … … 245 404 RTMemFree(pImage->pAllocationBitmap); 246 405 247 if (p Image->File != NIL_RTFILE)248 RTFileClose(pImage->File);406 if (parallelsFileOpened(pImage)) 407 parallelsFileClose(pImage); 249 408 } 250 409 … … 340 499 } 341 500 501 #ifndef VBOX_WITH_NEW_IO_CODE 342 502 pImage->File = NIL_RTFILE; 503 #else 504 pImage->pvStorage = NULL; 505 #endif 343 506 pImage->fAllocationBitmapChanged = false; 344 507 pImage->pszFilename = pszFilename; … … 408 571 if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) 409 572 { 410 rc = RTFileReadAt(pImage->File, uOffset, pvBuf, cbToRead, NULL); 573 rc = parallelsFileReadSync(pImage, uOffset, 574 pvBuf, cbToRead, NULL); 411 575 } 412 576 else … … 427 591 { 428 592 uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512; 429 rc = RTFileReadAt(pImage->File, uOffsetInFile, pvBuf, cbToRead, NULL); 593 rc = parallelsFileReadSync(pImage, uOffsetInFile, 594 pvBuf, cbToRead, NULL); 430 595 } 431 596 } … … 455 620 if (pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED) 456 621 { 457 rc = RTFileWriteAt(pImage->File, uOffset, pvBuf, cbToWrite, NULL); 622 rc = parallelsFileWriteSync(pImage, uOffset, 623 pvBuf, cbToWrite, NULL); 458 624 } 459 625 else … … 474 640 pImage->cbFileCurrent += pImage->PCHSGeometry.cSectors * 512; 475 641 pImage->fAllocationBitmapChanged = true; 476 rc = RTFileSetSize(pImage->File, pImage->cbFileCurrent); 477 if (RT_FAILURE(rc)) 478 return rc; 479 } 480 481 uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512; 482 rc = RTFileWriteAt(pImage->File, uOffsetInFile, pvBuf, cbToWrite, NULL); 642 643 uint8_t *pNewBlock = (uint8_t *)RTMemAllocZ(pImage->PCHSGeometry.cSectors * 512); 644 645 if (!pNewBlock) 646 return VERR_NO_MEMORY; 647 648 uOffsetInFile = (uint64_t)pImage->pAllocationBitmap[iIndexInAllocationTable] * 512; 649 memcpy(pNewBlock + (uOffset - ((uint64_t)iIndexInAllocationTable * pImage->PCHSGeometry.cSectors * 512)), 650 pvBuf, cbToWrite); 651 652 /* 653 * Write the new block at the current end of the file. 654 */ 655 rc = parallelsFileWriteSync(pImage, uOffsetInFile, 656 pNewBlock, 657 pImage->PCHSGeometry.cSectors * 512, NULL); 658 659 RTMemFree(pNewBlock); 660 } 661 else 662 { 663 uOffsetInFile = (pImage->pAllocationBitmap[iIndexInAllocationTable] + uSector) * 512; 664 rc = parallelsFileWriteSync(pImage, uOffsetInFile, 665 pvBuf, cbToWrite, NULL); 666 } 483 667 } 484 668 … … 543 727 if (pImage) 544 728 { 545 if (pImage->File != NIL_RTFILE) 546 { 547 RTFileGetSize(pImage->File, &cb); 548 } 729 if (parallelsFileOpened(pImage)) 730 cb = pImage->cbFileCurrent; 549 731 } 550 732 -
trunk/src/VBox/Devices/Storage/RawHDDCore.cpp
r21806 r22966 44 44 /** Base image name. */ 45 45 const char *pszFilename; 46 #ifndef VBOX_WITH_NEW_IO_CODE 46 47 /** File descriptor. */ 47 48 RTFILE File; 49 #else 50 /** Opaque storage handle. */ 51 void *pvStorage; 52 #endif 48 53 49 54 /** Pointer to the per-disk VD interface list. */ … … 54 59 /** Opaque data for error callback. */ 55 60 PVDINTERFACEERROR pInterfaceErrorCallbacks; 61 #ifdef VBOX_WITH_NEW_IO_CODE 62 /** Async I/O interface. */ 63 PVDINTERFACE pInterfaceAsyncIO; 64 /** Async I/O interface callbacks. */ 65 PVDINTERFACEASYNCIO pInterfaceAsyncIOCallbacks; 66 #endif 56 67 57 68 /** Open flags passed by VBoxHD layer. */ … … 104 115 } 105 116 117 static int rawFileOpen(PRAWIMAGE pImage, bool fReadonly, bool fCreate) 118 { 119 int rc = VINF_SUCCESS; 120 121 AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly while being created\n")); 122 123 #ifndef VBOX_WITH_NEW_IO_CODE 124 unsigned uFileFlags = fReadonly ? RTFILE_O_READ | RTFILE_O_DENY_NONE 125 : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE; 126 127 if (fCreate) 128 uFileFlags |= RTFILE_O_CREATE; 129 else 130 uFileFlags |= RTFILE_O_OPEN; 131 132 rc = RTFileOpen(&pImage->File, pImage->pszFilename, uFileFlags); 133 #else 134 135 unsigned uOpenFlags = fReadonly ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY : 0; 136 137 if (fCreate) 138 uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE; 139 140 rc = pImage->pInterfaceAsyncIOCallbacks->pfnOpen(pImage->pInterfaceAsyncIO->pvUser, 141 pImage->pszFilename, 142 uOpenFlags, 143 NULL, &pImage->pvStorage); 144 #endif 145 146 return rc; 147 } 148 149 static int rawFileClose(PRAWIMAGE pImage) 150 { 151 int rc = VINF_SUCCESS; 152 153 #ifndef VBOX_WITH_NEW_IO_CODE 154 if (pImage->File != NIL_RTFILE) 155 rc = RTFileClose(pImage->File); 156 157 pImage->File = NIL_RTFILE; 158 #else 159 if (pImage->pvStorage) 160 rc = pImage->pInterfaceAsyncIOCallbacks->pfnClose(pImage->pInterfaceAsyncIO->pvUser, 161 pImage->pvStorage); 162 163 pImage->pvStorage = NULL; 164 #endif 165 166 return rc; 167 } 168 169 static int rawFileFlushSync(PRAWIMAGE pImage) 170 { 171 int rc = VINF_SUCCESS; 172 173 #ifndef VBOX_WITH_NEW_IO_CODE 174 rc = RTFileFlush(pImage->File); 175 #else 176 if (pImage->pvStorage) 177 rc = pImage->pInterfaceAsyncIOCallbacks->pfnFlushSync(pImage->pInterfaceAsyncIO->pvUser, 178 pImage->pvStorage); 179 #endif 180 181 return rc; 182 } 183 184 static int rawFileGetSize(PRAWIMAGE pImage, uint64_t *pcbSize) 185 { 186 int rc = VINF_SUCCESS; 187 188 #ifndef VBOX_WITH_NEW_IO_CODE 189 rc = RTFileGetSize(pImage->File, pcbSize); 190 #else 191 if (pImage->pvStorage) 192 rc = pImage->pInterfaceAsyncIOCallbacks->pfnGetSize(pImage->pInterfaceAsyncIO->pvUser, 193 pImage->pvStorage, 194 pcbSize); 195 #endif 196 197 return rc; 198 199 } 200 201 static int rawFileSetSize(PRAWIMAGE pImage, uint64_t cbSize) 202 { 203 int rc = VINF_SUCCESS; 204 205 #ifndef VBOX_WITH_NEW_IO_CODE 206 rc = RTFileSetSize(pImage->File, cbSize); 207 #else 208 if (pImage->pvStorage) 209 rc = pImage->pInterfaceAsyncIOCallbacks->pfnSetSize(pImage->pInterfaceAsyncIO->pvUser, 210 pImage->pvStorage, 211 cbSize); 212 #endif 213 214 return rc; 215 } 216 217 218 static int rawFileWriteSync(PRAWIMAGE pImage, uint64_t off, const void *pcvBuf, size_t cbWrite, size_t *pcbWritten) 219 { 220 int rc = VINF_SUCCESS; 221 222 #ifndef VBOX_WITH_NEW_IO_CODE 223 rc = RTFileWriteAt(pImage->File, off, pcvBuf, cbWrite, pcbWritten); 224 #else 225 if (pImage->pvStorage) 226 rc = pImage->pInterfaceAsyncIOCallbacks->pfnWriteSync(pImage->pInterfaceAsyncIO->pvUser, 227 pImage->pvStorage, 228 off, cbWrite, pcvBuf, 229 pcbWritten); 230 #endif 231 232 return rc; 233 } 234 235 static int rawFileReadSync(PRAWIMAGE pImage, uint64_t off, void *pvBuf, size_t cbRead, size_t *pcbRead) 236 { 237 int rc = VINF_SUCCESS; 238 239 #ifndef VBOX_WITH_NEW_IO_CODE 240 rc = RTFileReadAt(pImage->File, off, pvBuf, cbRead, pcbRead); 241 #else 242 if (pImage->pvStorage) 243 rc = pImage->pInterfaceAsyncIOCallbacks->pfnReadSync(pImage->pInterfaceAsyncIO->pvUser, 244 pImage->pvStorage, 245 off, cbRead, pvBuf, 246 pcbRead); 247 #endif 248 249 return rc; 250 } 251 252 static bool rawFileOpened(PRAWIMAGE pImage) 253 { 254 #ifndef VBOX_WITH_NEW_IO_CODE 255 return pImage->File != NIL_RTFILE; 256 #else 257 return pImage->pvStorage != NULL; 258 #endif 259 } 260 106 261 /** 107 262 * Internal: Open an image, constructing all necessary data structures. … … 110 265 { 111 266 int rc; 112 RTFILE File;113 267 114 268 if (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO) … … 121 275 pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError); 122 276 277 #ifdef VBOX_WITH_NEW_IO_CODE 278 /* Try to get async I/O interface. */ 279 pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO); 280 AssertPtr(pImage->pInterfaceAsyncIO); 281 pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO); 282 AssertPtr(pImage->pInterfaceAsyncIOCallbacks); 283 #endif 284 123 285 /* 124 286 * Open the image. 125 287 */ 126 rc = RTFileOpen(&File, pImage->pszFilename, 127 uOpenFlags & VD_OPEN_FLAGS_READONLY 128 ? RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE 129 : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 288 rc = rawFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false); 130 289 if (RT_FAILURE(rc)) 131 290 { … … 134 293 goto out; 135 294 } 136 pImage->File = File; 137 138 rc = RTFileGetSize(pImage->File, &pImage->cbSize); 295 296 rc = rawFileGetSize(pImage, &pImage->cbSize); 139 297 if (RT_FAILURE(rc)) 140 298 goto out; … … 163 321 { 164 322 int rc; 165 RTFILE File;166 323 RTFOFF cbFree = 0; 167 324 uint64_t uOff; … … 184 341 pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError); 185 342 343 #ifdef VBOX_WITH_NEW_IO_CODE 344 /* Try to get async I/O interface. */ 345 pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO); 346 AssertPtr(pImage->pInterfaceAsyncIO); 347 pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO); 348 AssertPtr(pImage->pInterfaceAsyncIOCallbacks); 349 #endif 350 186 351 /* Create image file. */ 187 rc = RTFileOpen(&File, pImage->pszFilename, 188 RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_ALL); 352 rc = rawFileOpen(pImage, false, true); 189 353 if (RT_FAILURE(rc)) 190 354 { … … 192 356 goto out; 193 357 } 194 pImage->File = File;195 358 196 359 /* Check the free space on the disk and leave early if there is not … … 205 368 /* Allocate & commit whole file if fixed image, it must be more 206 369 * effective than expanding file by write operations. */ 207 rc = RTFileSetSize(File, cbSize);370 rc = rawFileSetSize(pImage, cbSize); 208 371 if (RT_FAILURE(rc)) 209 372 { … … 229 392 unsigned cbChunk = (unsigned)RT_MIN(cbSize, cbBuf); 230 393 231 rc = RTFileWriteAt(File, uOff, pvBuf, cbChunk, NULL);394 rc = rawFileWriteSync(pImage, uOff, pvBuf, cbChunk, NULL); 232 395 if (RT_FAILURE(rc)) 233 396 { … … 275 438 Assert(pImage); 276 439 277 if ( pImage->File != NIL_RTFILE)440 if (rawFileOpened(pImage)) 278 441 { 279 442 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 280 443 rawFlushImage(pImage); 281 RTFileClose(pImage->File); 282 pImage->File = NIL_RTFILE; 444 rawFileClose(pImage); 283 445 } 284 446 if (fDelete && pImage->pszFilename) … … 293 455 int rc = VINF_SUCCESS; 294 456 295 if ( pImage->File != NIL_RTFILE457 if ( rawFileOpened(pImage) 296 458 && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 297 rc = RTFileFlush(pImage->File);459 rc = rawFileFlushSync(pImage); 298 460 299 461 return rc; … … 354 516 } 355 517 pImage->pszFilename = pszFilename; 518 #ifndef VBOX_WITH_NEW_IO_CODE 356 519 pImage->File = NIL_RTFILE; 520 #else 521 pImage->pvStorage = NULL; 522 #endif 357 523 pImage->pVDIfsDisk = pVDIfsDisk; 358 524 … … 417 583 } 418 584 pImage->pszFilename = pszFilename; 585 #ifndef VBOX_WITH_NEW_IO_CODE 419 586 pImage->File = NIL_RTFILE; 587 #else 588 pImage->pvStorage = NULL; 589 #endif 420 590 pImage->pVDIfsDisk = pVDIfsDisk; 421 591 … … 487 657 } 488 658 489 rc = RTFileReadAt(pImage->File, uOffset, pvBuf, cbToRead, NULL);659 rc = rawFileReadSync(pImage, uOffset, pvBuf, cbToRead, NULL); 490 660 *pcbActuallyRead = cbToRead; 491 661 … … 521 691 } 522 692 523 rc = RTFileWriteAt(pImage->File, uOffset, pvBuf, cbToWrite, NULL);693 rc = rawFileWriteSync(pImage, uOffset, pvBuf, cbToWrite, NULL); 524 694 if (pcbWriteProcess) 525 695 *pcbWriteProcess = cbToWrite; … … 582 752 { 583 753 uint64_t cbFile; 584 if ( pImage->File != NIL_RTFILE)754 if (rawFileOpened(pImage)) 585 755 { 586 int rc = RTFileGetSize(pImage->File, &cbFile);756 int rc = rawFileGetSize(pImage, &cbFile); 587 757 if (RT_SUCCESS(rc)) 588 758 cb += cbFile; -
trunk/src/VBox/Devices/Storage/VBoxHDD.cpp
r21806 r22966 47 47 /** Buffer size used for merging images. */ 48 48 #define VD_MERGE_BUFFER_SIZE (16 * _1M) 49 50 /** 51 * VD async I/O interface storage descriptor. 52 */ 53 typedef struct VDIASYNCIOSTORAGE 54 { 55 /** File handle. */ 56 RTFILE File; 57 /** Completion callback. */ 58 PFNVDCOMPLETED pfnCompleted; 59 /** Thread for async access. */ 60 RTTHREAD ThreadAsync; 61 } VDIASYNCIOSTORAGE, *PVDIASYNCIOSTORAGE; 49 62 50 63 /** … … 116 129 /** Pointer to the error interface we use if available. */ 117 130 PVDINTERFACEERROR pInterfaceErrorCallbacks; 131 132 /** Fallback async interface. */ 133 VDINTERFACE VDIAsyncIO; 134 /** Fallback async I/O interface callback table. */ 135 VDINTERFACEASYNCIO VDIAsyncIOCallbacks; 118 136 }; 119 137 … … 708 726 709 727 /** 728 * VD async I/O interface open callback. 729 */ 730 static int vdAsyncIOOpen(void *pvUser, const char *pszLocation, unsigned uOpenFlags, 731 PFNVDCOMPLETED pfnCompleted, void **ppStorage) 732 { 733 PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)RTMemAllocZ(sizeof(VDIASYNCIOSTORAGE)); 734 735 if (!pStorage) 736 return VERR_NO_MEMORY; 737 738 pStorage->pfnCompleted = pfnCompleted; 739 740 unsigned uFlags = 0; 741 742 if (uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY) 743 uFlags |= RTFILE_O_READ | RTFILE_O_DENY_NONE; 744 else 745 uFlags |= RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE; 746 747 if (uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE) 748 uFlags |= RTFILE_O_CREATE; 749 else 750 uFlags |= RTFILE_O_OPEN; 751 752 /* Open the file. */ 753 int rc = RTFileOpen(&pStorage->File, pszLocation, uFlags); 754 if (RT_SUCCESS(rc)) 755 { 756 *ppStorage = pStorage; 757 return VINF_SUCCESS; 758 } 759 760 RTMemFree(pStorage); 761 return rc; 762 } 763 764 /** 765 * VD async I/O interface close callback. 766 */ 767 static int vdAsyncIOClose(void *pvUser, void *pvStorage) 768 { 769 PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage; 770 771 RTFileClose(pStorage->File); 772 RTMemFree(pStorage); 773 return VINF_SUCCESS; 774 } 775 776 /** 777 * VD async I/O interface callback for retrieving the file size. 778 */ 779 static int vdAsyncIOGetSize(void *pvUser, void *pvStorage, uint64_t *pcbSize) 780 { 781 PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage; 782 783 return RTFileGetSize(pStorage->File, pcbSize); 784 } 785 786 /** 787 * VD async I/O interface callback for setting the file size. 788 */ 789 static int vdAsyncIOSetSize(void *pvUser, void *pvStorage, uint64_t cbSize) 790 { 791 PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage; 792 793 return RTFileSetSize(pStorage->File, cbSize); 794 } 795 796 /** 797 * VD async I/O interface callback for a synchronous write to the file. 798 */ 799 static int vdAsyncIOWriteSync(void *pvUser, void *pvStorage, uint64_t uOffset, 800 size_t cbWrite, const void *pvBuf, size_t *pcbWritten) 801 { 802 PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage; 803 804 return RTFileWriteAt(pStorage->File, uOffset, pvBuf, cbWrite, pcbWritten); 805 } 806 807 /** 808 * VD async I/O interface callback for a synchronous read from the file. 809 */ 810 static int vdAsyncIOReadSync(void *pvUser, void *pvStorage, uint64_t uOffset, 811 size_t cbRead, void *pvBuf, size_t *pcbRead) 812 { 813 PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage; 814 815 return RTFileReadAt(pStorage->File, uOffset, pvBuf, cbRead, pcbRead); 816 } 817 818 /** 819 * VD async I/O interface callback for a synchronous flush of the file data. 820 */ 821 static int vdAsyncIOFlushSync(void *pvUser, void *pvStorage) 822 { 823 PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)pvStorage; 824 825 return RTFileFlush(pStorage->File); 826 } 827 828 /** 829 * VD async I/O interface callback for a asynchronous read from the file. 830 */ 831 static int vdAsyncIOReadAsync(void *pvUser, void *pStorage, uint64_t uOffset, 832 PCPDMDATASEG paSegments, size_t cSegments, 833 size_t cbRead, void *pvCompletion, 834 void **ppTask) 835 { 836 return VERR_NOT_IMPLEMENTED; 837 } 838 839 /** 840 * VD async I/O interface callback for a asynchronous write to the file. 841 */ 842 static int vdAsyncIOWriteAsync(void *pvUser, void *pStorage, uint64_t uOffset, 843 PCPDMDATASEG paSegments, size_t cSegments, 844 size_t cbWrite, void *pvCompletion, 845 void **ppTask) 846 { 847 return VERR_NOT_IMPLEMENTED; 848 } 849 850 /** 851 * VD async I/O interface callback for a asynchronous flush of the file data. 852 */ 853 static int vdAsyncIOFlushAsync(void *pvUser, void *pStorage, 854 void *pvCompletion, void **ppTask) 855 { 856 return VERR_NOT_IMPLEMENTED; 857 } 858 859 /** 710 860 * internal: send output to the log (unconditionally). 711 861 */ … … 894 1044 if (pDisk->pInterfaceError) 895 1045 pDisk->pInterfaceErrorCallbacks = VDGetInterfaceError(pDisk->pInterfaceError); 1046 1047 /* Use the fallback async I/O interface if the caller doesn't provide one. */ 1048 PVDINTERFACE pVDIfAsyncIO = VDInterfaceGet(pVDIfsDisk, VDINTERFACETYPE_ASYNCIO); 1049 if (!pVDIfAsyncIO) 1050 { 1051 pDisk->VDIAsyncIOCallbacks.cbSize = sizeof(VDINTERFACEASYNCIO); 1052 pDisk->VDIAsyncIOCallbacks.enmInterface = VDINTERFACETYPE_ASYNCIO; 1053 pDisk->VDIAsyncIOCallbacks.pfnOpen = vdAsyncIOOpen; 1054 pDisk->VDIAsyncIOCallbacks.pfnClose = vdAsyncIOClose; 1055 pDisk->VDIAsyncIOCallbacks.pfnGetSize = vdAsyncIOGetSize; 1056 pDisk->VDIAsyncIOCallbacks.pfnSetSize = vdAsyncIOSetSize; 1057 pDisk->VDIAsyncIOCallbacks.pfnReadSync = vdAsyncIOReadSync; 1058 pDisk->VDIAsyncIOCallbacks.pfnWriteSync = vdAsyncIOWriteSync; 1059 pDisk->VDIAsyncIOCallbacks.pfnFlushSync = vdAsyncIOFlushSync; 1060 pDisk->VDIAsyncIOCallbacks.pfnReadAsync = vdAsyncIOReadAsync; 1061 pDisk->VDIAsyncIOCallbacks.pfnWriteAsync = vdAsyncIOWriteAsync; 1062 pDisk->VDIAsyncIOCallbacks.pfnFlushAsync = vdAsyncIOFlushAsync; 1063 rc = VDInterfaceAdd(&pDisk->VDIAsyncIO, "VD_AsyncIO", VDINTERFACETYPE_ASYNCIO, 1064 &pDisk->VDIAsyncIOCallbacks, pDisk, &pDisk->pVDIfsDisk); 1065 AssertRC(rc); 1066 } 1067 896 1068 *ppDisk = pDisk; 897 1069 } -
trunk/src/VBox/Devices/Storage/VDICore.h
r20374 r22966 528 528 struct VDIIMAGEDESC *pNext; 529 529 #endif /* !VBOX_VDICORE_VD */ 530 #ifndef VBOX_WITH_NEW_IO_CODE 530 531 /** File handle. */ 531 532 RTFILE File; 533 #else 534 /** Opaque storage handle. */ 535 void *pvStorage; 536 #endif 532 537 #ifndef VBOX_VDICORE_VD 533 538 /** True if the image is operating in readonly mode. */ … … 585 590 /** Error interface callback table. */ 586 591 PVDINTERFACEERROR pInterfaceErrorCallbacks; 592 # ifdef VBOX_WITH_NEW_IO_CODE 593 /** Async I/O interface. */ 594 PVDINTERFACE pInterfaceAsyncIO; 595 /** Async I/O interface callbacks. */ 596 PVDINTERFACEASYNCIO pInterfaceAsyncIOCallbacks; 597 # endif 587 598 #endif /* VBOX_VDICORE_VD */ 588 599 } VDIIMAGEDESC, *PVDIIMAGEDESC; -
trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp
r21806 r22966 82 82 83 83 84 static int vdiFileOpen(PVDIIMAGEDESC pImage, bool fReadonly, bool fCreate) 85 { 86 int rc = VINF_SUCCESS; 87 88 AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly whilebeing created\n")); 89 90 #ifndef VBOX_WITH_NEW_IO_CODE 91 unsigned uFileFlags = fReadonly ? RTFILE_O_READ | RTFILE_O_DENY_NONE 92 : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE; 93 94 if (fCreate) 95 uFileFlags |= RTFILE_O_CREATE; 96 else 97 uFileFlags |= RTFILE_O_OPEN; 98 99 rc = RTFileOpen(&pImage->File, pImage->pszFilename, uFileFlags); 100 #else 101 102 unsigned uOpenFlags = fReadonly ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY : 0; 103 104 if (fCreate) 105 uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE; 106 107 rc = pImage->pInterfaceAsyncIOCallbacks->pfnOpen(pImage->pInterfaceAsyncIO->pvUser, 108 pImage->pszFilename, 109 uOpenFlags, 110 NULL, &pImage->pvStorage); 111 #endif 112 113 return rc; 114 } 115 116 static int vdiFileClose(PVDIIMAGEDESC pImage) 117 { 118 int rc = VINF_SUCCESS; 119 120 #ifndef VBOX_WITH_NEW_IO_CODE 121 if (pImage->File != NIL_RTFILE) 122 rc = RTFileClose(pImage->File); 123 124 pImage->File = NIL_RTFILE; 125 #else 126 if (pImage->pvStorage) 127 rc = pImage->pInterfaceAsyncIOCallbacks->pfnClose(pImage->pInterfaceAsyncIO->pvUser, 128 pImage->pvStorage); 129 130 pImage->pvStorage = NULL; 131 #endif 132 133 return rc; 134 } 135 136 static int vdiFileFlushSync(PVDIIMAGEDESC pImage) 137 { 138 int rc = VINF_SUCCESS; 139 140 #ifndef VBOX_WITH_NEW_IO_CODE 141 rc = RTFileFlush(pImage->File); 142 #else 143 if (pImage->pvStorage) 144 rc = pImage->pInterfaceAsyncIOCallbacks->pfnFlushSync(pImage->pInterfaceAsyncIO->pvUser, 145 pImage->pvStorage); 146 #endif 147 148 return rc; 149 } 150 151 static int vdiFileGetSize(PVDIIMAGEDESC pImage, uint64_t *pcbSize) 152 { 153 int rc = VINF_SUCCESS; 154 155 #ifndef VBOX_WITH_NEW_IO_CODE 156 rc = RTFileGetSize(pImage->File, pcbSize); 157 #else 158 if (pImage->pvStorage) 159 rc = pImage->pInterfaceAsyncIOCallbacks->pfnGetSize(pImage->pInterfaceAsyncIO->pvUser, 160 pImage->pvStorage, 161 pcbSize); 162 #endif 163 164 return rc; 165 } 166 167 static int vdiFileSetSize(PVDIIMAGEDESC pImage, uint64_t cbSize) 168 { 169 int rc = VINF_SUCCESS; 170 171 #ifndef VBOX_WITH_NEW_IO_CODE 172 rc = RTFileSetSize(pImage->File, cbSize); 173 #else 174 if (pImage->pvStorage) 175 rc = pImage->pInterfaceAsyncIOCallbacks->pfnSetSize(pImage->pInterfaceAsyncIO->pvUser, 176 pImage->pvStorage, 177 cbSize); 178 #endif 179 180 return rc; 181 } 182 183 static int vdiFileWriteSync(PVDIIMAGEDESC pImage, uint64_t off, const void *pcvBuf, size_t cbWrite, size_t *pcbWritten) 184 { 185 int rc = VINF_SUCCESS; 186 187 #ifndef VBOX_WITH_NEW_IO_CODE 188 rc = RTFileWriteAt(pImage->File, off, pcvBuf, cbWrite, pcbWritten); 189 #else 190 if (pImage->pvStorage) 191 rc = pImage->pInterfaceAsyncIOCallbacks->pfnWriteSync(pImage->pInterfaceAsyncIO->pvUser, 192 pImage->pvStorage, 193 off, cbWrite, pcvBuf, 194 pcbWritten); 195 #endif 196 197 return rc; 198 } 199 200 static int vdiFileReadSync(PVDIIMAGEDESC pImage, uint64_t off, void *pvBuf, size_t cbRead, size_t *pcbRead) 201 { 202 int rc = VINF_SUCCESS; 203 204 #ifndef VBOX_WITH_NEW_IO_CODE 205 rc = RTFileReadAt(pImage->File, off, pvBuf, cbRead, pcbRead); 206 #else 207 if (pImage->pvStorage) 208 rc = pImage->pInterfaceAsyncIOCallbacks->pfnReadSync(pImage->pInterfaceAsyncIO->pvUser, 209 pImage->pvStorage, 210 off, cbRead, pvBuf, 211 pcbRead); 212 #endif 213 214 return rc; 215 } 216 217 static bool vdiFileOpened(PVDIIMAGEDESC pImage) 218 { 219 #ifndef VBOX_WITH_NEW_IO_CODE 220 return pImage->File != NIL_RTFILE; 221 #else 222 return pImage->pvStorage != NULL; 223 #endif 224 } 225 226 84 227 /** 85 228 * internal: return power of 2 or 0 if num error. … … 415 558 416 559 /* Create image file. */ 417 rc = RTFileOpen(&File, pImage->pszFilename, 418 RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_ALL); 560 rc = vdiFileOpen(pImage, false /* fReadonly */, true /* fCreate */); 419 561 if (RT_FAILURE(rc)) 420 562 { … … 422 564 goto out; 423 565 } 424 pImage->File = File;425 566 426 567 cbTotal = pImage->offStartData … … 446 587 * effective than expanding file by write operations. 447 588 */ 448 rc = RTFileSetSize(File, cbTotal);589 rc = vdiFileSetSize(pImage, cbTotal); 449 590 } 450 591 else 451 592 { 452 593 /* Set file size to hold header and blocks array. */ 453 rc = RTFileSetSize(pImage->File, pImage->offStartData);594 rc = vdiFileSetSize(pImage, pImage->offStartData); 454 595 } 455 596 if (RT_FAILURE(rc)) … … 466 607 467 608 /* Write pre-header. */ 468 rc = RTFileWriteAt(File, 0, &pImage->PreHeader, sizeof(pImage->PreHeader), NULL);609 rc = vdiFileWriteSync(pImage, 0, &pImage->PreHeader, sizeof(pImage->PreHeader), NULL); 469 610 if (RT_FAILURE(rc)) 470 611 { … … 474 615 475 616 /* Write header. */ 476 rc = RTFileWriteAt(File, sizeof(pImage->PreHeader), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);617 rc = vdiFileWriteSync(pImage, sizeof(pImage->PreHeader), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL); 477 618 if (RT_FAILURE(rc)) 478 619 { … … 481 622 } 482 623 483 rc = RTFileWriteAt(File, pImage->offStartBlocks,484 pImage->paBlocks,485 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER),486 NULL);624 rc = vdiFileWriteSync(pImage, pImage->offStartBlocks, 625 pImage->paBlocks, 626 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER), 627 NULL); 487 628 if (RT_FAILURE(rc)) 488 629 { … … 516 657 unsigned cbChunk = (unsigned)RT_MIN(cbFill, cbBuf); 517 658 518 rc = RTFileWriteAt(File, pImage->offStartData + uOff,519 pvBuf, cbChunk, NULL);659 rc = vdiFileWriteSync(pImage, pImage->offStartData + uOff, 660 pvBuf, cbChunk, NULL); 520 661 if (RT_FAILURE(rc)) 521 662 { … … 554 695 { 555 696 int rc; 556 RTFILE File;557 697 558 698 if (uOpenFlags & VD_OPEN_FLAGS_ASYNC_IO) … … 565 705 pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError); 566 706 707 #ifdef VBOX_WITH_NEW_IO_CODE 708 /* Try to get async I/O interface. */ 709 pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO); 710 AssertPtr(pImage->pInterfaceAsyncIO); 711 pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO); 712 AssertPtr(pImage->pInterfaceAsyncIOCallbacks); 713 #endif 714 567 715 /* 568 716 * Open the image. 569 717 */ 570 rc = RTFileOpen(&File, pImage->pszFilename, 571 uOpenFlags & VD_OPEN_FLAGS_READONLY 572 ? RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE 573 : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); 718 rc = vdiFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false /* fCreate */); 574 719 if (RT_FAILURE(rc)) 575 720 { … … 578 723 goto out; 579 724 } 580 pImage->File = File;581 725 582 726 /* Read pre-header. */ 583 rc = RTFileReadAt(File, 0, &pImage->PreHeader, sizeof(pImage->PreHeader),584 NULL);727 rc = vdiFileReadSync(pImage, 0, &pImage->PreHeader, sizeof(pImage->PreHeader), 728 NULL); 585 729 if (RT_FAILURE(rc)) 586 730 { … … 600 744 { 601 745 case 0: 602 rc = RTFileReadAt(File, sizeof(pImage->PreHeader),603 &pImage->Header.u.v0, sizeof(pImage->Header.u.v0),604 NULL);746 rc = vdiFileReadSync(pImage, sizeof(pImage->PreHeader), 747 &pImage->Header.u.v0, sizeof(pImage->Header.u.v0), 748 NULL); 605 749 if (RT_FAILURE(rc)) 606 750 { … … 610 754 break; 611 755 case 1: 612 rc = RTFileReadAt(File, sizeof(pImage->PreHeader),613 &pImage->Header.u.v1, sizeof(pImage->Header.u.v1),614 NULL);756 rc = vdiFileReadSync(pImage, sizeof(pImage->PreHeader), 757 &pImage->Header.u.v1, sizeof(pImage->Header.u.v1), 758 NULL); 615 759 if (RT_FAILURE(rc)) 616 760 { … … 635 779 { 636 780 /* Read the actual VDI 1.1+ header completely. */ 637 rc = RTFileReadAt(File, sizeof(pImage->PreHeader), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);781 rc = vdiFileReadSync(pImage, sizeof(pImage->PreHeader), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL); 638 782 if (RT_FAILURE(rc)) 639 783 { … … 667 811 668 812 /* Read blocks array. */ 669 rc = RTFileReadAt(pImage->File, pImage->offStartBlocks, pImage->paBlocks,670 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER),671 NULL);813 rc = vdiFileReadSync(pImage, pImage->offStartBlocks, pImage->paBlocks, 814 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER), 815 NULL); 672 816 673 817 out: … … 686 830 { 687 831 case 0: 688 rc = RTFileWriteAt(pImage->File, sizeof(VDIPREHEADER), &pImage->Header.u.v0, sizeof(pImage->Header.u.v0), NULL);832 rc = vdiFileWriteSync(pImage, sizeof(VDIPREHEADER), &pImage->Header.u.v0, sizeof(pImage->Header.u.v0), NULL); 689 833 break; 690 834 case 1: 691 835 if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus)) 692 rc = RTFileWriteAt(pImage->File, sizeof(VDIPREHEADER), &pImage->Header.u.v1, sizeof(pImage->Header.u.v1), NULL);836 rc = vdiFileWriteSync(pImage, sizeof(VDIPREHEADER), &pImage->Header.u.v1, sizeof(pImage->Header.u.v1), NULL); 693 837 else 694 rc = RTFileWriteAt(pImage->File, sizeof(VDIPREHEADER), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);838 rc = vdiFileWriteSync(pImage, sizeof(VDIPREHEADER), &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL); 695 839 break; 696 840 default: … … 712 856 { 713 857 /* write only one block pointer. */ 714 rc = RTFileWriteAt(pImage->File,715 pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER),716 &pImage->paBlocks[uBlock],717 sizeof(VDIIMAGEBLOCKPOINTER),718 NULL);858 rc = vdiFileWriteSync(pImage, 859 pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER), 860 &pImage->paBlocks[uBlock], 861 sizeof(VDIIMAGEBLOCKPOINTER), 862 NULL); 719 863 AssertMsgRC(rc, ("vdiUpdateBlockInfo failed to update block=%u, filename=\"%s\", rc=%Rrc\n", 720 864 uBlock, pImage->pszFilename, rc)); … … 734 878 AssertMsgRC(rc, ("vdiUpdateHeader() failed, filename=\"%s\", rc=%Rrc\n", 735 879 pImage->pszFilename, rc)); 736 RTFileFlush(pImage->File);880 vdiFileFlushSync(pImage); 737 881 } 738 882 } … … 746 890 AssertPtr(pImage); 747 891 748 if ( pImage->File != NIL_RTFILE)892 if (vdiFileOpened(pImage)) 749 893 { 750 894 vdiFlushImage(pImage); 751 RTFileClose(pImage->File); 752 pImage->File = NIL_RTFILE; 895 vdiFileClose(pImage); 753 896 } 754 897 if (pImage->paBlocks) … … 783 926 } 784 927 pImage->pszFilename = pszFilename; 928 #ifndef VBOX_WITH_NEW_IO_CODE 785 929 pImage->File = NIL_RTFILE; 930 #else 931 pImage->pvStorage = NULL; 932 #endif 786 933 pImage->paBlocks = NULL; 787 934 pImage->pVDIfsDisk = NULL; … … 827 974 } 828 975 pImage->pszFilename = pszFilename; 976 #ifndef VBOX_WITH_NEW_IO_CODE 829 977 pImage->File = NIL_RTFILE; 978 #else 979 pImage->pvStorage = NULL; 980 #endif 830 981 pImage->paBlocks = NULL; 831 982 pImage->pVDIfsDisk = pVDIfsDisk; … … 901 1052 } 902 1053 pImage->pszFilename = pszFilename; 1054 #ifndef VBOX_WITH_NEW_IO_CODE 903 1055 pImage->File = NIL_RTFILE; 1056 #else 1057 pImage->pvStorage = NULL; 1058 #endif 904 1059 pImage->paBlocks = NULL; 905 1060 pImage->pVDIfsDisk = pVDIfsDisk; … … 1035 1190 uint64_t u64Offset = (uint64_t)pImage->paBlocks[uBlock] * pImage->cbTotalBlockData 1036 1191 + (pImage->offStartData + pImage->offStartBlockData + offRead); 1037 rc = RTFileReadAt(pImage->File, u64Offset, pvBuf, cbToRead, NULL);1192 rc = vdiFileReadSync(pImage, u64Offset, pvBuf, cbToRead, NULL); 1038 1193 } 1039 1194 … … 1115 1270 uint64_t u64Offset = (uint64_t)cBlocksAllocated * pImage->cbTotalBlockData 1116 1271 + (pImage->offStartData + pImage->offStartBlockData); 1117 rc = RTFileWriteAt(pImage->File, u64Offset, pvBuf, cbToWrite, NULL);1272 rc = vdiFileWriteSync(pImage, u64Offset, pvBuf, cbToWrite, NULL); 1118 1273 if (RT_FAILURE(rc)) 1119 1274 goto out; … … 1142 1297 uint64_t u64Offset = (uint64_t)pImage->paBlocks[uBlock] * pImage->cbTotalBlockData 1143 1298 + (pImage->offStartData + pImage->offStartBlockData + offWrite); 1144 rc = RTFileWriteAt(pImage->File, u64Offset, pvBuf, cbToWrite, NULL);1299 rc = vdiFileWriteSync(pImage, u64Offset, pvBuf, cbToWrite, NULL); 1145 1300 } 1146 1301 } while (0); … … 1216 1371 { 1217 1372 uint64_t cbFile; 1218 if ( pImage->File != NIL_RTFILE)1219 { 1220 int rc = RTFileGetSize(pImage->File, &cbFile);1373 if (vdiFileOpened(pImage)) 1374 { 1375 int rc = vdiFileGetSize(pImage, &cbFile); 1221 1376 if (RT_SUCCESS(rc)) 1222 1377 cb += cbFile; … … 1721 1876 PVDIIMAGEDESC pImage = (PVDIIMAGEDESC)pBackendData; 1722 1877 1878 #ifndef VBOX_WITH_NEW_IO_CODE 1723 1879 pImage->pInterfaceErrorCallbacks->pfnMessage(pImage->pInterfaceError->pvUser, "Dumping VDI image \"%s\" mode=%s uOpenFlags=%X File=%08X\n", 1724 1880 pImage->pszFilename, … … 1726 1882 pImage->uOpenFlags, 1727 1883 pImage->File); 1884 #else 1885 pImage->pInterfaceErrorCallbacks->pfnMessage(pImage->pInterfaceError->pvUser, "Dumping VDI image \"%s\" mode=%s uOpenFlags=%X File=%#p\n", 1886 pImage->pszFilename, 1887 (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) ? "r/o" : "r/w", 1888 pImage->uOpenFlags, 1889 pImage->pvStorage); 1890 #endif 1728 1891 pImage->pInterfaceErrorCallbacks->pfnMessage(pImage->pInterfaceError->pvUser, "Header: Version=%08X Type=%X Flags=%X Size=%llu\n", 1729 1892 pImage->PreHeader.u32Version, … … 1889 2052 1890 2053 uint64_t cbFile; 1891 rc = RTFileGetSize(pImage->File, &cbFile);2054 rc = vdiFileGetSize(pImage, &cbFile); 1892 2055 AssertRCBreak(rc); 1893 2056 unsigned cBlocksAllocated = (unsigned)((cbFile - pImage->offStartData - pImage->offStartBlockData) >> pImage->uShiftOffset2Index); … … 1952 2115 uint64_t u64Offset = (uint64_t)ptrBlock * pImage->cbTotalBlockData 1953 2116 + (pImage->offStartData + pImage->offStartBlockData); 1954 rc = RTFileReadAt(pImage->File, u64Offset, pvTmp, cbBlock, NULL);2117 rc = vdiFileReadSync(pImage, u64Offset, pvTmp, cbBlock, NULL); 1955 2118 if (RT_FAILURE(rc)) 1956 2119 break; … … 2015 2178 uint64_t u64Offset = (uint64_t)uBlockUsedPos * pImage->cbTotalBlockData 2016 2179 + (pImage->offStartData + pImage->offStartBlockData); 2017 rc = RTFileReadAt(pImage->File, u64Offset, pvTmp, cbBlock, NULL);2180 rc = vdiFileReadSync(pImage, u64Offset, pvTmp, cbBlock, NULL); 2018 2181 u64Offset = (uint64_t)i * pImage->cbTotalBlockData 2019 2182 + (pImage->offStartData + pImage->offStartBlockData); 2020 rc = RTFileWriteAt(pImage->File, u64Offset, pvTmp, cbBlock, NULL);2183 rc = vdiFileWriteSync(pImage, u64Offset, pvTmp, cbBlock, NULL); 2021 2184 pImage->paBlocks[uBlockData] = i; 2022 2185 setImageBlocksAllocated(&pImage->Header, cBlocksAllocated - cBlocksMoved); … … 2046 2209 2047 2210 /* Truncate the image to the proper size to finish compacting. */ 2048 rc = RTFileSetSize(pImage->File,2211 rc = vdiFileSetSize(pImage, 2049 2212 (uint64_t)uBlockUsedPos * pImage->cbTotalBlockData 2050 2213 + (pImage->offStartData + pImage->offStartBlockData)); -
trunk/src/VBox/Devices/Storage/VHDHDDCore.cpp
r21008 r22966 130 130 /** Base image name. */ 131 131 const char *pszFilename; 132 #ifndef VBOX_WITH_NEW_IO_CODE 132 133 /** Descriptor file if applicable. */ 133 134 RTFILE File; 135 #else 136 /** Opaque storage handle. */ 137 void *pvStorage; 138 #endif 134 139 135 140 /** Pointer to the per-disk VD interface list. */ … … 139 144 /** Error interface callback table. */ 140 145 PVDINTERFACEERROR pInterfaceErrorCallbacks; 146 #ifdef VBOX_WITH_NEW_IO_CODE 147 /** Async I/O interface. */ 148 PVDINTERFACE pInterfaceAsyncIO; 149 /** Async I/O interface callbacks. */ 150 PVDINTERFACEASYNCIO pInterfaceAsyncIOCallbacks; 151 #endif 141 152 142 153 /** Open flags passed by VBoxHD layer. */ … … 208 219 static int vhdLoadDynamicDisk(PVHDIMAGE pImage, uint64_t uDynamicDiskHeaderOffset); 209 220 221 static int vhdFileOpen(PVHDIMAGE pImage, bool fReadonly, bool fCreate) 222 { 223 int rc = VINF_SUCCESS; 224 225 AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly while being created\n")); 226 227 #ifndef VBOX_WITH_NEW_IO_CODE 228 unsigned uFileFlags = fReadonly ? RTFILE_O_READ | RTFILE_O_DENY_NONE 229 : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE; 230 231 if (fCreate) 232 uFileFlags |= RTFILE_O_CREATE; 233 else 234 uFileFlags |= RTFILE_O_OPEN; 235 236 rc = RTFileOpen(&pImage->File, pImage->pszFilename, uFileFlags); 237 #else 238 239 unsigned uOpenFlags = fReadonly ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY : 0; 240 241 if (fCreate) 242 uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE; 243 244 rc = pImage->pInterfaceAsyncIOCallbacks->pfnOpen(pImage->pInterfaceAsyncIO->pvUser, 245 pImage->pszFilename, 246 uOpenFlags, 247 NULL, &pImage->pvStorage); 248 #endif 249 250 return rc; 251 } 252 253 static int vhdFileClose(PVHDIMAGE pImage) 254 { 255 int rc = VINF_SUCCESS; 256 257 #ifndef VBOX_WITH_NEW_IO_CODE 258 if (pImage->File != NIL_RTFILE) 259 rc = RTFileClose(pImage->File); 260 261 pImage->File = NIL_RTFILE; 262 #else 263 if (pImage->pvStorage) 264 rc = pImage->pInterfaceAsyncIOCallbacks->pfnClose(pImage->pInterfaceAsyncIO->pvUser, 265 pImage->pvStorage); 266 267 pImage->pvStorage = NULL; 268 #endif 269 270 return rc; 271 } 272 273 static int vhdFileFlushSync(PVHDIMAGE pImage) 274 { 275 int rc = VINF_SUCCESS; 276 277 #ifndef VBOX_WITH_NEW_IO_CODE 278 rc = RTFileFlush(pImage->File); 279 #else 280 if (pImage->pvStorage) 281 rc = pImage->pInterfaceAsyncIOCallbacks->pfnFlushSync(pImage->pInterfaceAsyncIO->pvUser, 282 pImage->pvStorage); 283 #endif 284 285 return rc; 286 } 287 288 static int vhdFileGetSize(PVHDIMAGE pImage, uint64_t *pcbSize) 289 { 290 int rc = VINF_SUCCESS; 291 292 #ifndef VBOX_WITH_NEW_IO_CODE 293 rc = RTFileGetSize(pImage->File, pcbSize); 294 #else 295 if (pImage->pvStorage) 296 rc = pImage->pInterfaceAsyncIOCallbacks->pfnGetSize(pImage->pInterfaceAsyncIO->pvUser, 297 pImage->pvStorage, 298 pcbSize); 299 #endif 300 301 return rc; 302 303 } 304 305 static int vhdFileSetSize(PVHDIMAGE pImage, uint64_t cbSize) 306 { 307 int rc = VINF_SUCCESS; 308 309 #ifndef VBOX_WITH_NEW_IO_CODE 310 rc = RTFileSetSize(pImage->File, cbSize); 311 #else 312 if (pImage->pvStorage) 313 rc = pImage->pInterfaceAsyncIOCallbacks->pfnSetSize(pImage->pInterfaceAsyncIO->pvUser, 314 pImage->pvStorage, 315 cbSize); 316 #endif 317 318 return rc; 319 } 320 321 322 static int vhdFileWriteSync(PVHDIMAGE pImage, uint64_t off, const void *pcvBuf, size_t cbWrite, size_t *pcbWritten) 323 { 324 int rc = VINF_SUCCESS; 325 326 #ifndef VBOX_WITH_NEW_IO_CODE 327 rc = RTFileWriteAt(pImage->File, off, pcvBuf, cbWrite, pcbWritten); 328 #else 329 if (pImage->pvStorage) 330 rc = pImage->pInterfaceAsyncIOCallbacks->pfnWriteSync(pImage->pInterfaceAsyncIO->pvUser, 331 pImage->pvStorage, 332 off, cbWrite, pcvBuf, 333 pcbWritten); 334 #endif 335 336 return rc; 337 } 338 339 static int vhdFileReadSync(PVHDIMAGE pImage, uint64_t off, void *pvBuf, size_t cbRead, size_t *pcbRead) 340 { 341 int rc = VINF_SUCCESS; 342 343 #ifndef VBOX_WITH_NEW_IO_CODE 344 rc = RTFileReadAt(pImage->File, off, pvBuf, cbRead, pcbRead); 345 #else 346 if (pImage->pvStorage) 347 rc = pImage->pInterfaceAsyncIOCallbacks->pfnReadSync(pImage->pInterfaceAsyncIO->pvUser, 348 pImage->pvStorage, 349 off, cbRead, pvBuf, 350 pcbRead); 351 #endif 352 353 return rc; 354 } 355 356 static bool vhdFileOpened(PVHDIMAGE pImage) 357 { 358 #ifndef VBOX_WITH_NEW_IO_CODE 359 return pImage->File != NIL_RTFILE; 360 #else 361 return pImage->pvStorage != NULL; 362 #endif 363 } 364 210 365 /* 946684800 is a number of seconds between 1/1/1970 and 1/1/2000 */ 211 366 #define VHD_TO_UNIX_EPOCH_SECONDS UINT64_C(946684800) … … 338 493 goto out; 339 494 } 340 rc = RTFileWriteAt(pImage->File, RT_BE2H_U64(pLocator->u64DataOffset), pvBuf,341 RT_BE2H_U32(pLocator->u32DataSpace) * VHD_SECTOR_SIZE, NULL);495 rc = vhdFileWriteSync(pImage, RT_BE2H_U64(pLocator->u64DataOffset), pvBuf, 496 RT_BE2H_U32(pLocator->u32DataSpace) * VHD_SECTOR_SIZE, NULL); 342 497 343 498 out: … … 358 513 return VERR_VD_NOT_OPENED; 359 514 360 rc = RTFileReadAt(pImage->File, pImage->u64DataOffset, &ddh, sizeof(ddh), NULL);515 rc = vhdFileReadSync(pImage, pImage->u64DataOffset, &ddh, sizeof(ddh), NULL); 361 516 if (RT_FAILURE(rc)) 362 517 return rc; … … 403 558 ddh.Checksum = 0; 404 559 ddh.Checksum = RT_H2BE_U32(vhdChecksum(&ddh, sizeof(ddh))); 405 rc = RTFileWriteAt(pImage->File, pImage->u64DataOffset, &ddh, sizeof(ddh), NULL);560 rc = vhdFileWriteSync(pImage, pImage->u64DataOffset, &ddh, sizeof(ddh), NULL); 406 561 if (RT_FAILURE(rc)) 407 562 return rc; 408 563 409 564 /* Update the VHD footer copy. */ 410 rc = RTFileWriteAt(pImage->File, 0, &pImage->vhdFooterCopy, sizeof(VHDFooter), NULL);565 rc = vhdFileWriteSync(pImage, 0, &pImage->vhdFooterCopy, sizeof(VHDFooter), NULL); 411 566 412 567 out: … … 417 572 static int vhdOpenImage(PVHDIMAGE pImage, unsigned uOpenFlags) 418 573 { 419 RTFILE File;420 574 uint64_t FileSize; 421 575 VHDFooter vhdFooter; … … 430 584 pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError); 431 585 586 #ifdef VBOX_WITH_NEW_IO_CODE 587 /* Try to get async I/O interface. */ 588 pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO); 589 AssertPtr(pImage->pInterfaceAsyncIO); 590 pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO); 591 AssertPtr(pImage->pInterfaceAsyncIOCallbacks); 592 #endif 593 432 594 /* 433 595 * Open the image. 434 596 */ 435 int rc = RTFileOpen(&File, pImage->pszFilename, uOpenFlags & VD_OPEN_FLAGS_READONLY 436 ? RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE 437 : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 597 int rc = vhdFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false); 438 598 if (RT_FAILURE(rc)) 439 599 { … … 442 602 return rc; 443 603 } 444 pImage->File = File; 445 446 rc = RTFileGetSize(File, &FileSize); 604 605 rc = vhdFileGetSize(pImage, &FileSize); 447 606 pImage->FileSize = FileSize; 448 607 pImage->uCurrentEndOfFile = FileSize - sizeof(VHDFooter); 449 608 450 rc = RTFileReadAt(File, pImage->uCurrentEndOfFile, &vhdFooter, sizeof(VHDFooter), NULL);609 rc = vhdFileReadSync(pImage, pImage->uCurrentEndOfFile, &vhdFooter, sizeof(VHDFooter), NULL); 451 610 if (memcmp(vhdFooter.Cookie, VHD_FOOTER_COOKIE, VHD_FOOTER_COOKIE_SIZE) != 0) 452 611 return VERR_VD_VHD_INVALID_HEADER; … … 524 683 } 525 684 pImage->pszFilename = pszFilename; 685 #ifndef VBOX_WITH_NEW_IO_CODE 526 686 pImage->File = NIL_RTFILE; 687 #else 688 pImage->pvStorage != NULL; 689 #endif 527 690 pImage->pVDIfsDisk = pVDIfsDisk; 528 691 … … 546 709 * Read the dynamic disk header. 547 710 */ 548 rc = RTFileReadAt(pImage->File, uDynamicDiskHeaderOffset, &vhdDynamicDiskHeader, sizeof(VHDDynamicDiskHeader), NULL);711 rc = vhdFileReadSync(pImage, uDynamicDiskHeaderOffset, &vhdDynamicDiskHeader, sizeof(VHDDynamicDiskHeader), NULL); 549 712 if (memcmp(vhdDynamicDiskHeader.Cookie, VHD_DYNAMIC_DISK_HEADER_COOKIE, VHD_DYNAMIC_DISK_HEADER_COOKIE_SIZE) != 0) 550 713 return VERR_INVALID_PARAMETER; … … 581 744 LogFlowFunc(("uBlockAllocationTableOffset=%llu\n", uBlockAllocationTableOffset)); 582 745 pImage->uBlockAllocationTableOffset = uBlockAllocationTableOffset; 583 rc = RTFileReadAt(pImage->File, uBlockAllocationTableOffset, pBlockAllocationTable, pImage->cBlockAllocationTableEntries * sizeof(uint32_t), NULL);746 rc = vhdFileReadSync(pImage, uBlockAllocationTableOffset, pBlockAllocationTable, pImage->cBlockAllocationTableEntries * sizeof(uint32_t), NULL); 584 747 pImage->uDataBlockStart = uBlockAllocationTableOffset + pImage->cBlockAllocationTableEntries * sizeof(uint32_t); 585 748 LogFlowFunc(("uDataBlockStart=%llu\n", pImage->uDataBlockStart)); … … 793 956 if (RT_FAILURE(rc)) 794 957 goto out; 795 RTFileClose(pImage->File);958 vhdFileClose(pImage); 796 959 pImage->uOpenFlags = uOpenFlags; 797 rc = RTFileOpen(&pImage->File, pImage->pszFilename, uOpenFlags & VD_OPEN_FLAGS_READONLY 798 ? RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE 799 : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 960 rc = vhdFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false); 800 961 801 962 out: … … 822 983 /* Close the file. vhdFreeImage would additionally free pImage. */ 823 984 vhdFlush(pImage); 824 RTFileClose(pImage->File);985 vhdFileClose(pImage); 825 986 826 987 /* Rename the file. */ … … 878 1039 { 879 1040 vhdFlush(pImage); 880 RTFileClose(pImage->File);1041 vhdFileClose(pImage); 881 1042 vhdFreeImageMemory(pImage); 882 1043 } … … 898 1059 { 899 1060 /* No point in updating the file that is deleted anyway. */ 900 RTFileClose(pImage->File);1061 vhdFileClose(pImage); 901 1062 RTFileDelete(pImage->pszFilename); 902 1063 vhdFreeImageMemory(pImage); … … 994 1155 995 1156 /* Read in the block's bitmap. */ 996 rc = RTFileReadAt(pImage->File,997 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE,998 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, NULL);1157 rc = vhdFileReadSync(pImage, 1158 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE, 1159 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, NULL); 999 1160 if (RT_SUCCESS(rc)) 1000 1161 { … … 1021 1182 1022 1183 LogFlowFunc(("uVhdOffset=%llu cbRead=%u\n", uVhdOffset, cbRead)); 1023 rc = RTFileReadAt(pImage->File, uVhdOffset, pvBuf, cbRead, NULL);1184 rc = vhdFileReadSync(pImage, uVhdOffset, pvBuf, cbRead, NULL); 1024 1185 } 1025 1186 else … … 1053 1214 else 1054 1215 { 1055 rc = RTFileReadAt(pImage->File, uOffset, pvBuf, cbRead, NULL);1216 rc = vhdFileReadSync(pImage, uOffset, pvBuf, cbRead, NULL); 1056 1217 } 1057 1218 … … 1124 1285 * Write the new block at the current end of the file. 1125 1286 */ 1126 rc = RTFileWriteAt(pImage->File, pImage->uCurrentEndOfFile, pNewBlock, cbNewBlock, NULL);1287 rc = vhdFileWriteSync(pImage, pImage->uCurrentEndOfFile, pNewBlock, cbNewBlock, NULL); 1127 1288 1128 1289 /* … … 1140 1301 1141 1302 /* Write data. */ 1142 RTFileWriteAt(pImage->File, uVhdOffset, pvBuf, cbToWrite, NULL);1303 vhdFileWriteSync(pImage, uVhdOffset, pvBuf, cbToWrite, NULL); 1143 1304 1144 1305 /* Read in the block's bitmap. */ 1145 rc = RTFileReadAt(pImage->File,1306 rc = vhdFileReadSync(pImage, 1146 1307 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE, 1147 1308 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, NULL); … … 1156 1317 1157 1318 /* Write the bitmap back. */ 1158 rc = RTFileWriteAt(pImage->File,1319 rc = vhdFileWriteSync(pImage, 1159 1320 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE, 1160 1321 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, NULL); … … 1163 1324 else 1164 1325 { 1165 rc = RTFileWriteAt(pImage->File, uOffset, pvBuf, cbToWrite, NULL);1326 rc = vhdFileWriteSync(pImage, uOffset, pvBuf, cbToWrite, NULL); 1166 1327 } 1167 1328 … … 1204 1365 * Write the block allocation table after the copy of the disk footer and the dynamic disk header. 1205 1366 */ 1206 RTFileWriteAt(pImage->File, pImage->uBlockAllocationTableOffset, pBlockAllocationTableToWrite, cbBlockAllocationTableToWrite, NULL);1207 RTFileWriteAt(pImage->File, pImage->uCurrentEndOfFile, &pImage->vhdFooterCopy, sizeof(VHDFooter), NULL);1367 vhdFileWriteSync(pImage, pImage->uBlockAllocationTableOffset, pBlockAllocationTableToWrite, cbBlockAllocationTableToWrite, NULL); 1368 vhdFileWriteSync(pImage, pImage->uCurrentEndOfFile, &pImage->vhdFooterCopy, sizeof(VHDFooter), NULL); 1208 1369 if (pImage->fDynHdrNeedsUpdate) 1209 1370 vhdDynamicHeaderUpdate(pImage); … … 1211 1372 } 1212 1373 1213 int rc = RTFileFlush(pImage->File);1374 int rc = vhdFileFlushSync(pImage); 1214 1375 1215 1376 return rc; … … 1240 1401 { 1241 1402 uint64_t cb; 1242 int rc = RTFileGetSize(pImage->File, &cb);1403 int rc = vhdFileGetSize(pImage, &cb); 1243 1404 if (RT_SUCCESS(rc)) 1244 1405 return cb; … … 1391 1552 AssertPtr(pImage); 1392 1553 1393 if (pImage && pImage->File != NIL_RTFILE)1554 if (pImage && vhdFileOpened(pImage)) 1394 1555 { 1395 1556 if (!(pImage->uImageFlags & VD_IMAGE_FLAGS_FIXED)) … … 1546 1707 VHDDynamicDiskHeader DynamicDiskHeader; 1547 1708 uint32_t u32BlockAllocationTableSectors; 1709 void *pvTmp = NULL; 1548 1710 1549 1711 memset(&DynamicDiskHeader, 0, sizeof(DynamicDiskHeader)); … … 1574 1736 pImage->uBlockAllocationTableOffset + u32BlockAllocationTableSectors * VHD_SECTOR_SIZE); 1575 1737 1576 rc = RTFileSetSize(pImage->File, pImage->uCurrentEndOfFile + sizeof(VHDFooter)); 1738 /* Set dynamic image size. */ 1739 pvTmp = RTMemTmpAllocZ(pImage->uCurrentEndOfFile + sizeof(VHDFooter)); 1740 if (!pvTmp) 1741 return vhdError(pImage, VERR_NO_MEMORY, RT_SRC_POS, N_("VHD: cannot set the file size for '%s'"), pImage->pszFilename); 1742 1743 rc = vhdFileWriteSync(pImage, 0, pvTmp, pImage->uCurrentEndOfFile + sizeof(VHDFooter), NULL); 1577 1744 if (RT_FAILURE(rc)) 1745 { 1746 RTMemTmpFree(pvTmp); 1578 1747 return vhdError(pImage, rc, RT_SRC_POS, N_("VHD: cannot set the file size for '%s'"), pImage->pszFilename); 1748 } 1749 1750 RTMemTmpFree(pvTmp); 1579 1751 1580 1752 /* Initialize and write the dynamic disk header. */ … … 1589 1761 DynamicDiskHeader.Checksum = RT_H2BE_U32(vhdChecksum(&DynamicDiskHeader, sizeof(DynamicDiskHeader))); 1590 1762 1591 rc = RTFileWriteAt(pImage->File, sizeof(VHDFooter), &DynamicDiskHeader, sizeof(DynamicDiskHeader), NULL);1763 rc = vhdFileWriteSync(pImage, sizeof(VHDFooter), &DynamicDiskHeader, sizeof(DynamicDiskHeader), NULL); 1592 1764 if (RT_FAILURE(rc)) 1593 1765 return vhdError(pImage, rc, RT_SRC_POS, N_("VHD: cannot write dynamic disk header to image '%s'"), pImage->pszFilename); 1594 1766 1595 1767 /* Write BAT. */ 1596 rc = RTFileWriteAt(pImage->File, pImage->uBlockAllocationTableOffset, pImage->pBlockAllocationTable,1597 pImage->cBlockAllocationTableEntries * sizeof(uint32_t), NULL);1768 rc = vhdFileWriteSync(pImage, pImage->uBlockAllocationTableOffset, pImage->pBlockAllocationTable, 1769 pImage->cBlockAllocationTableEntries * sizeof(uint32_t), NULL); 1598 1770 if (RT_FAILURE(rc)) 1599 1771 return vhdError(pImage, rc, RT_SRC_POS, N_("VHD: cannot write BAT to image '%s'"), pImage->pszFilename); … … 1625 1797 pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError); 1626 1798 1627 /* Create image file. */ 1628 rc = RTFileOpen(&File, pImage->pszFilename, 1629 RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_ALL); 1799 rc = vhdFileOpen(pImage, false /* fReadonly */, true /* fCreate */); 1630 1800 if (RT_FAILURE(rc)) 1631 1801 return vhdError(pImage, rc, RT_SRC_POS, N_("VHD: cannot create image '%s'"), pImage->pszFilename); 1632 pImage->File = File; 1802 1633 1803 1634 1804 pImage->cbSize = cbSize; … … 1670 1840 /** @todo r=klaus replace this with actual data writes, see the experience 1671 1841 * with VDI files on Windows, can cause long freezes when writing. */ 1672 rc = RTFileSetSize(File, pImage->uCurrentEndOfFile + sizeof(VHDFooter));1842 rc = vhdFileSetSize(pImage, pImage->uCurrentEndOfFile + sizeof(VHDFooter)); 1673 1843 if (RT_FAILURE(rc)) 1674 1844 { … … 1714 1884 1715 1885 /* Store the footer */ 1716 rc = RTFileWriteAt(File, pImage->uCurrentEndOfFile, &Footer, sizeof(Footer), NULL);1886 rc = vhdFileWriteSync(pImage, pImage->uCurrentEndOfFile, &Footer, sizeof(Footer), NULL); 1717 1887 if (RT_FAILURE(rc)) 1718 1888 { … … 1725 1895 { 1726 1896 /* Write the copy of the footer. */ 1727 rc = RTFileWriteAt(File, 0, &Footer, sizeof(Footer), NULL);1897 rc = vhdFileWriteSync(pImage, 0, &Footer, sizeof(Footer), NULL); 1728 1898 if (RT_FAILURE(rc)) 1729 1899 { … … 1781 1951 } 1782 1952 pImage->pszFilename = pszFilename; 1953 #ifndef VBOX_WITH_NEW_IO_CODE 1783 1954 pImage->File = NIL_RTFILE; 1784 pImage->pVDIfsDisk = NULL; 1955 #else 1956 pImage->pvStorage = NULL; 1957 #endif 1958 pImage->pVDIfsDisk = pVDIfsDisk; 1959 1960 #ifdef VBOX_WITH_NEW_IO_CODE 1961 /* Try to get async I/O interface. */ 1962 pImage->pInterfaceAsyncIO = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ASYNCIO); 1963 AssertPtr(pImage->pInterfaceAsyncIO); 1964 pImage->pInterfaceAsyncIOCallbacks = VDGetInterfaceAsyncIO(pImage->pInterfaceAsyncIO); 1965 AssertPtr(pImage->pInterfaceAsyncIOCallbacks); 1966 #endif 1785 1967 1786 1968 rc = vhdCreateImage(pImage, cbSize, uImageFlags, pszComment, … … 1828 2010 RTFSOBJINFO info; 1829 2011 2012 #ifndef VBOX_WITH_NEW_IO_CODE 1830 2013 rc = RTFileQueryInfo(pImage->File, &info, RTFSOBJATTRADD_NOTHING); 2014 #else 2015 /* Interface doesn't provide such a feature. */ 2016 RTFILE File; 2017 rc = RTFileOpen(&File, pImage->pszFilename, RTFILE_O_OPEN | RTFILE_O_READ); 2018 if (RT_SUCCESS(rc)) 2019 { 2020 rc = RTFileQueryInfo(File, &info, RTFSOBJATTRADD_NOTHING); 2021 RTFileClose(File); 2022 } 2023 #endif 2024 1831 2025 *pTimeStamp = info.ModificationTime; 1832 2026 } -
trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp
r21806 r22966 582 582 pszFilename, 583 583 pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY 584 ? true585 : false,584 ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY 585 : 0, 586 586 NULL, 587 587 &pVmdkFile->pStorage); … … 700 700 DECLINLINE(int) vmdkFileGetSize(PVMDKFILE pVmdkFile, uint64_t *pcbSize) 701 701 { 702 PVMDKIMAGE pImage = pVmdkFile->pImage; 703 702 704 if (pVmdkFile->fAsyncIO) 703 705 { 704 AssertMsgFailed(("TODO\n")); 705 return 0; 706 return pImage->pInterfaceAsyncIOCallbacks->pfnGetSize(pImage->pInterfaceAsyncIO->pvUser, 707 pVmdkFile->pStorage, 708 pcbSize); 706 709 } 707 710 else … … 714 717 DECLINLINE(int) vmdkFileSetSize(PVMDKFILE pVmdkFile, uint64_t cbSize) 715 718 { 719 PVMDKIMAGE pImage = pVmdkFile->pImage; 720 716 721 if (pVmdkFile->fAsyncIO) 717 722 { 718 AssertMsgFailed(("TODO\n")); 719 return VERR_NOT_SUPPORTED; 723 return pImage->pInterfaceAsyncIOCallbacks->pfnSetSize(pImage->pInterfaceAsyncIO->pvUser, 724 pVmdkFile->pStorage, 725 cbSize); 720 726 } 721 727 else … … 5814 5820 { 5815 5821 /* Check for enough room first. */ 5816 if (RT_ LIKELY(cSegments >= pImage->cSegments))5822 if (RT_UNLIKELY(cSegments >= pImage->cSegments)) 5817 5823 { 5818 5824 /* We reached maximum, resize array. Try to realloc memory first. */ … … 5942 5948 { 5943 5949 /* Check for enough room first. */ 5944 if (RT_ LIKELY(cSegments >= pImage->cSegments))5950 if (RT_UNLIKELY(cSegments >= pImage->cSegments)) 5945 5951 { 5946 5952 /* We reached maximum, resize array. Try to realloc memory first. */
Note:
See TracChangeset
for help on using the changeset viewer.