Changeset 33234 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- Oct 19, 2010 3:12:48 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 66783
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/RawHDDCore.cpp
r33182 r33234 38 38 { 39 39 /** Image name. */ 40 const char *pszFilename;40 const char *pszFilename; 41 41 /** Storage handle. */ 42 PVDIOSTORAGE pStorage;42 PVDIOSTORAGE pStorage; 43 43 /** I/O interface. */ 44 PVDINTERFACE pInterfaceIO;44 PVDINTERFACE pInterfaceIO; 45 45 /** Async I/O interface callbacks. */ 46 PVDINTERFACEIOINT pInterfaceIOCallbacks;46 PVDINTERFACEIOINT pInterfaceIOCallbacks; 47 47 48 48 /** Pointer to the per-disk VD interface list. */ 49 PVDINTERFACE pVDIfsDisk;49 PVDINTERFACE pVDIfsDisk; 50 50 /** Pointer to the per-image VD interface list. */ 51 PVDINTERFACE pVDIfsImage;51 PVDINTERFACE pVDIfsImage; 52 52 53 53 /** Error callback. */ 54 PVDINTERFACE pInterfaceError;54 PVDINTERFACE pInterfaceError; 55 55 /** Opaque data for error callback. */ 56 PVDINTERFACEERROR pInterfaceErrorCallbacks;56 PVDINTERFACEERROR pInterfaceErrorCallbacks; 57 57 58 58 /** Open flags passed by VBoxHD layer. */ 59 unsigned uOpenFlags;59 unsigned uOpenFlags; 60 60 /** Image flags defined during creation or determined during open. */ 61 unsigned uImageFlags;61 unsigned uImageFlags; 62 62 /** Total size of the image. */ 63 uint64_t cbSize; 63 uint64_t cbSize; 64 /** Position in the image (only truly used for sequential access). */ 65 uint64_t offAccess; 66 /** Flag if this is a newly created image. */ 67 bool fCreate; 64 68 /** Physical geometry of this image. */ 65 VDGEOMETRY PCHSGeometry;69 VDGEOMETRY PCHSGeometry; 66 70 /** Logical geometry of this image. */ 67 VDGEOMETRY LCHSGeometry;71 VDGEOMETRY LCHSGeometry; 68 72 69 73 } RAWIMAGE, *PRAWIMAGE; 74 75 76 /** Size of write operations when filling an image with zeroes. */ 77 #define RAW_FILL_SIZE (128 * _1K) 70 78 71 79 /******************************************************************************* … … 249 257 /* No point updating the file that is deleted anyway. */ 250 258 if (!fDelete) 259 { 260 /* For newly created images in sequential mode fill it to 261 * the nominal size. */ 262 if ( pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL 263 && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 264 && pImage->fCreate) 265 { 266 /* Fill rest of image with zeroes, a must for sequential 267 * images to reach the nominal size. */ 268 uint64_t uOff; 269 void *pvBuf = RTMemTmpAllocZ(RAW_FILL_SIZE); 270 if (!pvBuf) 271 goto out; 272 273 uOff = pImage->offAccess; 274 /* Write data to all image blocks. */ 275 while (uOff < pImage->cbSize) 276 { 277 unsigned cbChunk = (unsigned)RT_MIN(pImage->cbSize, 278 RAW_FILL_SIZE); 279 280 rc = rawFileWriteSync(pImage, uOff, pvBuf, cbChunk, 281 NULL); 282 if (RT_FAILURE(rc)) 283 goto out; 284 285 uOff += cbChunk; 286 } 287 out: 288 if (pvBuf) 289 RTMemTmpFree(pvBuf); 290 } 251 291 rawFlushImage(pImage); 292 } 252 293 253 294 rawFileClose(pImage); … … 271 312 272 313 pImage->uOpenFlags = uOpenFlags; 314 pImage->fCreate = false; 273 315 274 316 pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ERROR); … … 324 366 RTFOFF cbFree = 0; 325 367 uint64_t uOff; 326 size_t cbBuf = 128 * _1K;327 368 void *pvBuf = NULL; 369 int32_t fOpen; 328 370 329 371 if (uImageFlags & VD_IMAGE_FLAGS_DIFF) … … 339 381 340 382 pImage->uImageFlags = uImageFlags; 383 pImage->fCreate = true; 341 384 pImage->PCHSGeometry = *pPCHSGeometry; 342 385 pImage->LCHSGeometry = *pLCHSGeometry; … … 353 396 354 397 /* Create image file. */ 355 rc = rawFileOpen(pImage, pImage->pszFilename, 356 VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, 357 true /* fCreate */)); 398 fOpen = VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, true /* fCreate */); 399 if (uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL) 400 fOpen &= ~RTFILE_O_READ; 401 rc = rawFileOpen(pImage, pImage->pszFilename, fOpen); 358 402 if (RT_FAILURE(rc)) 359 403 { … … 362 406 } 363 407 364 /* Check the free space on the disk and leave early if there is not 365 * sufficient space available. */ 366 rc = rawFileGetFreeSpace(pImage, pImage->pszFilename, &cbFree); 367 if (RT_SUCCESS(rc) /* ignore errors */ && ((uint64_t)cbFree < cbSize)) 368 { 369 rc = rawError(pImage, VERR_DISK_FULL, RT_SRC_POS, N_("Raw: disk would overflow creating image '%s'"), pImage->pszFilename); 370 goto out; 371 } 372 373 /* Allocate & commit whole file if fixed image, it must be more 374 * effective than expanding file by write operations. */ 375 rc = rawFileSetSize(pImage, cbSize); 376 if (RT_FAILURE(rc)) 377 { 378 rc = rawError(pImage, rc, RT_SRC_POS, N_("Raw: setting image size failed for '%s'"), pImage->pszFilename); 379 goto out; 380 } 381 382 /* Fill image with zeroes. We do this for every fixed-size image since on 383 * some systems (for example Windows Vista), it takes ages to write a block 384 * near the end of a sparse file and the guest could complain about an ATA 385 * timeout. */ 386 pvBuf = RTMemTmpAllocZ(cbBuf); 387 if (!pvBuf) 388 { 389 rc = VERR_NO_MEMORY; 390 goto out; 391 } 392 393 uOff = 0; 394 /* Write data to all image blocks. */ 395 while (uOff < cbSize) 396 { 397 unsigned cbChunk = (unsigned)RT_MIN(cbSize, cbBuf); 398 399 rc = rawFileWriteSync(pImage, uOff, pvBuf, cbChunk, NULL); 408 if (!(uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL)) 409 { 410 /* Check the free space on the disk and leave early if there is not 411 * sufficient space available. */ 412 rc = rawFileGetFreeSpace(pImage, pImage->pszFilename, &cbFree); 413 if (RT_SUCCESS(rc) /* ignore errors */ && ((uint64_t)cbFree < cbSize)) 414 { 415 rc = rawError(pImage, VERR_DISK_FULL, RT_SRC_POS, N_("Raw: disk would overflow creating image '%s'"), pImage->pszFilename); 416 goto out; 417 } 418 419 /* Allocate & commit whole file if fixed image, it must be more 420 * effective than expanding file by write operations. */ 421 rc = rawFileSetSize(pImage, cbSize); 400 422 if (RT_FAILURE(rc)) 401 423 { 402 rc = rawError(pImage, rc, RT_SRC_POS, N_("Raw: writing blockfailed for '%s'"), pImage->pszFilename);424 rc = rawError(pImage, rc, RT_SRC_POS, N_("Raw: setting image size failed for '%s'"), pImage->pszFilename); 403 425 goto out; 404 426 } 405 427 406 uOff += cbChunk; 407 408 if (pfnProgress) 428 /* Fill image with zeroes. We do this for every fixed-size image since 429 * on some systems (for example Windows Vista), it takes ages to write 430 * a block near the end of a sparse file and the guest could complain 431 * about an ATA timeout. */ 432 pvBuf = RTMemTmpAllocZ(RAW_FILL_SIZE); 433 if (!pvBuf) 409 434 { 410 rc = pfnProgress(pvUser, 411 uPercentStart + uOff * uPercentSpan * 98 / (cbSize * 100)); 435 rc = VERR_NO_MEMORY; 436 goto out; 437 } 438 439 uOff = 0; 440 /* Write data to all image blocks. */ 441 while (uOff < cbSize) 442 { 443 unsigned cbChunk = (unsigned)RT_MIN(cbSize, RAW_FILL_SIZE); 444 445 rc = rawFileWriteSync(pImage, uOff, pvBuf, cbChunk, NULL); 412 446 if (RT_FAILURE(rc)) 447 { 448 rc = rawError(pImage, rc, RT_SRC_POS, N_("Raw: writing block failed for '%s'"), pImage->pszFilename); 413 449 goto out; 450 } 451 452 uOff += cbChunk; 453 454 if (pfnProgress) 455 { 456 rc = pfnProgress(pvUser, 457 uPercentStart + uOff * uPercentSpan * 98 / (cbSize * 100)); 458 if (RT_FAILURE(rc)) 459 goto out; 460 } 414 461 } 415 462 } 416 RTMemTmpFree(pvBuf);417 463 418 464 if (RT_SUCCESS(rc) && pfnProgress) … … 424 470 425 471 out: 472 if (pvBuf) 473 RTMemTmpFree(pvBuf); 474 426 475 if (RT_SUCCESS(rc) && pfnProgress) 427 476 pfnProgress(pvUser, uPercentStart + uPercentSpan); … … 662 711 } 663 712 713 /* For sequential access do not allow to go back. */ 714 if ( pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL 715 && uOffset < pImage->offAccess) 716 { 717 rc = VERR_INVALID_PARAMETER; 718 goto out; 719 } 720 664 721 rc = rawFileReadSync(pImage, uOffset, pvBuf, cbToRead, NULL); 665 *pcbActuallyRead = cbToRead; 722 pImage->offAccess = uOffset + cbToRead; 723 if (pcbActuallyRead) 724 *pcbActuallyRead = cbToRead; 666 725 667 726 out: … … 696 755 } 697 756 757 /* For sequential access do not allow to go back. */ 758 if ( pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL 759 && uOffset < pImage->offAccess) 760 { 761 rc = VERR_INVALID_PARAMETER; 762 goto out; 763 } 764 698 765 rc = rawFileWriteSync(pImage, uOffset, pvBuf, cbToWrite, NULL); 766 pImage->offAccess = uOffset + cbToWrite; 699 767 if (pcbWriteProcess) 700 768 *pcbWriteProcess = cbToWrite;
Note:
See TracChangeset
for help on using the changeset viewer.