Changeset 31777 in vbox
- Timestamp:
- Aug 19, 2010 9:50:39 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 64963
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/MediumImpl.cpp
r31746 r31777 401 401 }; 402 402 403 class Medium::ResizeTask : public Medium::Task 404 { 405 public: 406 ResizeTask(Medium *aMedium, 407 uint64_t aSize, 408 Progress *aProgress, 409 MediumLockList *aMediumLockList, 410 bool fKeepMediumLockList = false) 411 : Medium::Task(aMedium, aProgress), 412 mSize(aSize), 413 mpMediumLockList(aMediumLockList), 414 mfKeepMediumLockList(fKeepMediumLockList) 415 { 416 AssertReturnVoidStmt(aMediumLockList != NULL, mRC = E_FAIL); 417 } 418 419 ~ResizeTask() 420 { 421 if (!mfKeepMediumLockList && mpMediumLockList) 422 delete mpMediumLockList; 423 } 424 425 uint64_t mSize; 426 MediumLockList *mpMediumLockList; 427 428 private: 429 virtual HRESULT handler(); 430 431 bool mfKeepMediumLockList; 432 }; 433 403 434 class Medium::ResetTask : public Medium::Task 404 435 { … … 621 652 622 653 /** 654 * Implementation code for the "resize" task. 655 */ 656 HRESULT Medium::ResizeTask::handler() 657 { 658 return mMedium->taskResizeHandler(*this); 659 } 660 661 662 /** 623 663 * Implementation code for the "reset" task. 624 664 */ … … 2497 2537 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2498 2538 2499 NOREF(aLogicalSize); 2500 NOREF(aProgress); 2501 ReturnComNotImplemented(); 2539 HRESULT rc = S_OK; 2540 ComObjPtr <Progress> pProgress; 2541 Medium::Task *pTask = NULL; 2542 2543 try 2544 { 2545 /* We need to lock both the current object, and the tree lock (would 2546 * cause a lock order violation otherwise) for createMediumLockList. */ 2547 AutoMultiWriteLock2 multilock(&m->pVirtualBox->getMediaTreeLockHandle(), 2548 this->lockHandle() 2549 COMMA_LOCKVAL_SRC_POS); 2550 2551 /* Build the medium lock list. */ 2552 MediumLockList *pMediumLockList(new MediumLockList()); 2553 rc = createMediumLockList(true /* fFailIfInaccessible */ , 2554 true /* fMediumLockWrite */, 2555 NULL, 2556 *pMediumLockList); 2557 if (FAILED(rc)) 2558 { 2559 delete pMediumLockList; 2560 throw rc; 2561 } 2562 2563 rc = pMediumLockList->Lock(); 2564 if (FAILED(rc)) 2565 { 2566 delete pMediumLockList; 2567 throw setError(rc, 2568 tr("Failed to lock media when compacting '%s'"), 2569 getLocationFull().c_str()); 2570 } 2571 2572 pProgress.createObject(); 2573 rc = pProgress->init(m->pVirtualBox, 2574 static_cast <IMedium *>(this), 2575 BstrFmt(tr("Compacting medium '%s'"), m->strLocationFull.c_str()), 2576 TRUE /* aCancelable */); 2577 if (FAILED(rc)) 2578 { 2579 delete pMediumLockList; 2580 throw rc; 2581 } 2582 2583 /* setup task object to carry out the operation asynchronously */ 2584 pTask = new Medium::ResizeTask(this, aLogicalSize, pProgress, pMediumLockList); 2585 rc = pTask->rc(); 2586 AssertComRC(rc); 2587 if (FAILED(rc)) 2588 throw rc; 2589 } 2590 catch (HRESULT aRC) { rc = aRC; } 2591 2592 if (SUCCEEDED(rc)) 2593 { 2594 rc = startThread(pTask); 2595 2596 if (SUCCEEDED(rc)) 2597 pProgress.queryInterfaceTo(aProgress); 2598 } 2599 else if (pTask != NULL) 2600 delete pTask; 2601 2602 return rc; 2502 2603 } 2503 2604 … … 6641 6742 } 6642 6743 6744 /** 6745 * Implementation code for the "resize" task. 6746 * 6747 * @param task 6748 * @return 6749 */ 6750 HRESULT Medium::taskResizeHandler(Medium::ResizeTask &task) 6751 { 6752 HRESULT rc = S_OK; 6753 6754 /* Lock all in {parent,child} order. The lock is also used as a 6755 * signal from the task initiator (which releases it only after 6756 * RTThreadCreate()) that we can start the job. */ 6757 AutoWriteLock thisLock(this COMMA_LOCKVAL_SRC_POS); 6758 6759 try 6760 { 6761 PVBOXHDD hdd; 6762 int vrc = VDCreate(m->vdDiskIfaces, &hdd); 6763 ComAssertRCThrow(vrc, E_FAIL); 6764 6765 try 6766 { 6767 /* Open all media in the chain. */ 6768 MediumLockList::Base::const_iterator mediumListBegin = 6769 task.mpMediumLockList->GetBegin(); 6770 MediumLockList::Base::const_iterator mediumListEnd = 6771 task.mpMediumLockList->GetEnd(); 6772 MediumLockList::Base::const_iterator mediumListLast = 6773 mediumListEnd; 6774 mediumListLast--; 6775 for (MediumLockList::Base::const_iterator it = mediumListBegin; 6776 it != mediumListEnd; 6777 ++it) 6778 { 6779 const MediumLock &mediumLock = *it; 6780 const ComObjPtr<Medium> &pMedium = mediumLock.GetMedium(); 6781 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 6782 6783 /* sanity check */ 6784 if (it == mediumListLast) 6785 Assert(pMedium->m->state == MediumState_LockedWrite); 6786 else 6787 Assert(pMedium->m->state == MediumState_LockedRead); 6788 6789 /* Open all media but last in read-only mode. Do not handle 6790 * shareable media, as compaction and sharing are mutually 6791 * exclusive. */ 6792 vrc = VDOpen(hdd, 6793 pMedium->m->strFormat.c_str(), 6794 pMedium->m->strLocationFull.c_str(), 6795 (it == mediumListLast) ? VD_OPEN_FLAGS_NORMAL : VD_OPEN_FLAGS_READONLY, 6796 pMedium->m->vdDiskIfaces); 6797 if (RT_FAILURE(vrc)) 6798 throw setError(VBOX_E_FILE_ERROR, 6799 tr("Could not open the medium storage unit '%s'%s"), 6800 pMedium->m->strLocationFull.c_str(), 6801 vdError(vrc).c_str()); 6802 } 6803 6804 Assert(m->state == MediumState_LockedWrite); 6805 6806 Utf8Str location(m->strLocationFull); 6807 6808 /* unlock before the potentially lengthy operation */ 6809 thisLock.release(); 6810 6811 PDMMEDIAGEOMETRY geo = {0, 0, 0}; /* auto */ 6812 vrc = VDResize(hdd, task.mSize, &geo, &geo, task.mVDOperationIfaces); 6813 if (RT_FAILURE(vrc)) 6814 { 6815 if (vrc == VERR_NOT_SUPPORTED) 6816 throw setError(VBOX_E_NOT_SUPPORTED, 6817 tr("Compacting is not yet supported for medium '%s'"), 6818 location.c_str()); 6819 else if (vrc == VERR_NOT_IMPLEMENTED) 6820 throw setError(E_NOTIMPL, 6821 tr("Compacting is not implemented, medium '%s'"), 6822 location.c_str()); 6823 else 6824 throw setError(VBOX_E_FILE_ERROR, 6825 tr("Could not compact medium '%s'%s"), 6826 location.c_str(), 6827 vdError(vrc).c_str()); 6828 } 6829 } 6830 catch (HRESULT aRC) { rc = aRC; } 6831 6832 VDDestroy(hdd); 6833 } 6834 catch (HRESULT aRC) { rc = aRC; } 6835 6836 /* Everything is explicitly unlocked when the task exits, 6837 * as the task destruction also destroys the media chain. */ 6838 6839 return rc; 6840 } 6841 6643 6842 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ -
trunk/src/VBox/Main/include/MediumImpl.h
r31698 r31777 289 289 class CloneTask; 290 290 class CompactTask; 291 class ResizeTask; 291 292 class ResetTask; 292 293 class DeleteTask; … … 297 298 friend class CloneTask; 298 299 friend class CompactTask; 300 friend class ResizeTask; 299 301 friend class ResetTask; 300 302 friend class DeleteTask; … … 311 313 HRESULT taskResetHandler(Medium::ResetTask &task); 312 314 HRESULT taskCompactHandler(Medium::CompactTask &task); 315 HRESULT taskResizeHandler(Medium::ResizeTask &task); 313 316 314 317 struct Data; // opaque data struct, defined in MediumImpl.cpp
Note:
See TracChangeset
for help on using the changeset viewer.