- Timestamp:
- Oct 27, 2010 7:46:48 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp
r33478 r33480 2469 2469 2470 2470 /** 2471 * Internal: write/update the descriptor part of the image. 2472 */ 2473 static int vmdkWriteDescriptor(PVMDKIMAGE pImage) 2471 * Internal : Prepares the descriptor to write to the image. 2472 */ 2473 static int vmdkDescriptorPrepare(PVMDKIMAGE pImage, uint64_t cbLimit, 2474 void **ppvData, size_t *pcbData) 2474 2475 { 2475 2476 int rc = VINF_SUCCESS; 2476 uint64_t cbLimit;2477 uint64_t uOffset;2478 PVMDKFILE pDescFile;2479 2480 if (pImage->pDescData)2481 {2482 /* Separate descriptor file. */2483 uOffset = 0;2484 cbLimit = 0;2485 pDescFile = pImage->pFile;2486 }2487 else2488 {2489 /* Embedded descriptor file. */2490 uOffset = VMDK_SECTOR2BYTE(pImage->pExtents[0].uDescriptorSector);2491 cbLimit = VMDK_SECTOR2BYTE(pImage->pExtents[0].cDescriptorSectors);2492 pDescFile = pImage->pExtents[0].pFile;2493 }2494 /* Bail out if there is no file to write to. */2495 if (pDescFile == NULL)2496 return VERR_INVALID_PARAMETER;2497 2477 2498 2478 /* … … 2535 2515 break; 2536 2516 } 2537 pszDescriptor New = pszDescriptor;2517 pszDescriptor = pszDescriptorNew; 2538 2518 cbDescriptor += cb + 4 * _1K; 2539 2519 } … … 2552 2532 if (RT_SUCCESS(rc)) 2553 2533 { 2554 rc = vmdkFileWriteSync(pImage, pDescFile, uOffset, pszDescriptor, cbLimit ? cbLimit : offDescriptor, NULL); 2555 if (RT_FAILURE(rc)) 2556 rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error writing descriptor in '%s'"), pImage->pszFilename); 2557 } 2558 2559 if (RT_SUCCESS(rc) && !cbLimit) 2560 { 2561 rc = vmdkFileSetSize(pImage, pDescFile, offDescriptor); 2562 if (RT_FAILURE(rc)) 2563 rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error truncating descriptor in '%s'"), pImage->pszFilename); 2564 } 2565 2566 if (RT_SUCCESS(rc)) 2567 pImage->Descriptor.fDirty = false; 2568 2569 RTMemFree(pszDescriptor); 2534 *ppvData = pszDescriptor; 2535 *pcbData = offDescriptor; 2536 } 2537 2570 2538 return rc; 2571 2539 } 2572 2540 2573 2541 /** 2574 * Internal: write/update the descriptor part of the image - async version.2575 */ 2576 static int vmdkWriteDescriptor Async(PVMDKIMAGE pImage, PVDIOCTX pIoCtx)2542 * Internal: write/update the descriptor part of the image. 2543 */ 2544 static int vmdkWriteDescriptor(PVMDKIMAGE pImage) 2577 2545 { 2578 2546 int rc = VINF_SUCCESS; … … 2580 2548 uint64_t uOffset; 2581 2549 PVMDKFILE pDescFile; 2550 void *pvDescriptor; 2551 size_t cbDescriptor; 2582 2552 2583 2553 if (pImage->pDescData) … … 2599 2569 return VERR_INVALID_PARAMETER; 2600 2570 2601 /* 2602 * Allocate temporary descriptor buffer. 2603 * In case there is no limit allocate a default 2604 * and increase if required. 2605 */ 2606 size_t cbDescriptor = cbLimit ? cbLimit : 4 * _1K; 2607 char *pszDescriptor = (char *)RTMemAllocZ(cbDescriptor); 2608 unsigned offDescriptor = 0; 2609 2610 if (!pszDescriptor) 2611 return VERR_NO_MEMORY; 2612 2613 for (unsigned i = 0; i < pImage->Descriptor.cLines; i++) 2614 { 2615 const char *psz = pImage->Descriptor.aLines[i]; 2616 size_t cb = strlen(psz); 2617 2618 /* 2619 * Increase the descriptor if there is no limit and 2620 * there is not enough room left for this line. 2621 */ 2622 if (offDescriptor + cb + 1 > cbDescriptor) 2623 { 2624 if (cbLimit) 2625 { 2626 rc = vmdkError(pImage, VERR_BUFFER_OVERFLOW, RT_SRC_POS, N_("VMDK: descriptor too long in '%s'"), pImage->pszFilename); 2627 break; 2628 } 2629 else 2630 { 2631 char *pszDescriptorNew = NULL; 2632 LogFlow(("Increasing descriptor cache\n")); 2633 2634 pszDescriptorNew = (char *)RTMemRealloc(pszDescriptor, cbDescriptor + cb + 4 * _1K); 2635 if (!pszDescriptorNew) 2636 { 2637 rc = VERR_NO_MEMORY; 2638 break; 2639 } 2640 pszDescriptorNew = pszDescriptor; 2641 cbDescriptor += cb + 4 * _1K; 2642 } 2643 } 2644 2645 if (cb > 0) 2646 { 2647 memcpy(pszDescriptor + offDescriptor, psz, cb); 2648 offDescriptor += cb; 2649 } 2650 2651 memcpy(pszDescriptor + offDescriptor, "\n", 1); 2652 offDescriptor++; 2653 } 2654 2571 rc = vmdkDescriptorPrepare(pImage, cbLimit, &pvDescriptor, &cbDescriptor); 2655 2572 if (RT_SUCCESS(rc)) 2656 2573 { 2657 rc = vmdkFileWriteMetaAsync(pImage, pDescFile, uOffset, pszDescriptor, cbLimit ? cbLimit : offDescriptor, pIoCtx, NULL, NULL); 2574 rc = vmdkFileWriteSync(pImage, pDescFile, uOffset, pvDescriptor, cbLimit ? cbLimit : cbDescriptor, NULL); 2575 if (RT_FAILURE(rc)) 2576 rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error writing descriptor in '%s'"), pImage->pszFilename); 2577 } 2578 2579 if (RT_SUCCESS(rc) && !cbLimit) 2580 { 2581 rc = vmdkFileSetSize(pImage, pDescFile, cbDescriptor); 2582 if (RT_FAILURE(rc)) 2583 rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error truncating descriptor in '%s'"), pImage->pszFilename); 2584 } 2585 2586 if (RT_SUCCESS(rc)) 2587 pImage->Descriptor.fDirty = false; 2588 2589 RTMemFree(pvDescriptor); 2590 return rc; 2591 } 2592 2593 /** 2594 * Internal: write/update the descriptor part of the image - async version. 2595 */ 2596 static int vmdkWriteDescriptorAsync(PVMDKIMAGE pImage, PVDIOCTX pIoCtx) 2597 { 2598 int rc = VINF_SUCCESS; 2599 uint64_t cbLimit; 2600 uint64_t uOffset; 2601 PVMDKFILE pDescFile; 2602 void *pvDescriptor; 2603 size_t cbDescriptor; 2604 2605 if (pImage->pDescData) 2606 { 2607 /* Separate descriptor file. */ 2608 uOffset = 0; 2609 cbLimit = 0; 2610 pDescFile = pImage->pFile; 2611 } 2612 else 2613 { 2614 /* Embedded descriptor file. */ 2615 uOffset = VMDK_SECTOR2BYTE(pImage->pExtents[0].uDescriptorSector); 2616 cbLimit = VMDK_SECTOR2BYTE(pImage->pExtents[0].cDescriptorSectors); 2617 pDescFile = pImage->pExtents[0].pFile; 2618 } 2619 /* Bail out if there is no file to write to. */ 2620 if (pDescFile == NULL) 2621 return VERR_INVALID_PARAMETER; 2622 2623 rc = vmdkDescriptorPrepare(pImage, cbLimit, &pvDescriptor, &cbDescriptor); 2624 if (RT_SUCCESS(rc)) 2625 { 2626 rc = vmdkFileWriteMetaAsync(pImage, pDescFile, uOffset, pvDescriptor, cbLimit ? cbLimit : cbDescriptor, pIoCtx, NULL, NULL); 2658 2627 if ( RT_FAILURE(rc) 2659 2628 && rc != VERR_VD_ASYNC_IO_IN_PROGRESS) … … 2663 2632 if (RT_SUCCESS(rc) && !cbLimit) 2664 2633 { 2665 rc = vmdkFileSetSize(pImage, pDescFile, offDescriptor);2634 rc = vmdkFileSetSize(pImage, pDescFile, cbDescriptor); 2666 2635 if (RT_FAILURE(rc)) 2667 2636 rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error truncating descriptor in '%s'"), pImage->pszFilename); … … 2671 2640 pImage->Descriptor.fDirty = false; 2672 2641 2673 RTMemFree(p szDescriptor);2642 RTMemFree(pvDescriptor); 2674 2643 return rc; 2675 2644
Note:
See TracChangeset
for help on using the changeset viewer.