VirtualBox

Changeset 31777 in vbox


Ignore:
Timestamp:
Aug 19, 2010 9:50:39 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
64963
Message:

Main/Medium: Resize operation

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/MediumImpl.cpp

    r31746 r31777  
    401401};
    402402
     403class Medium::ResizeTask : public Medium::Task
     404{
     405public:
     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
     428private:
     429    virtual HRESULT handler();
     430
     431    bool mfKeepMediumLockList;
     432};
     433
    403434class Medium::ResetTask : public Medium::Task
    404435{
     
    621652
    622653/**
     654 * Implementation code for the "resize" task.
     655 */
     656HRESULT Medium::ResizeTask::handler()
     657{
     658    return mMedium->taskResizeHandler(*this);
     659}
     660
     661
     662/**
    623663 * Implementation code for the "reset" task.
    624664 */
     
    24972537    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    24982538
    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;
    25022603}
    25032604
     
    66416742}
    66426743
     6744/**
     6745 * Implementation code for the "resize" task.
     6746 *
     6747 * @param task
     6748 * @return
     6749 */
     6750HRESULT 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
    66436842/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/include/MediumImpl.h

    r31698 r31777  
    289289    class CloneTask;
    290290    class CompactTask;
     291    class ResizeTask;
    291292    class ResetTask;
    292293    class DeleteTask;
     
    297298    friend class CloneTask;
    298299    friend class CompactTask;
     300    friend class ResizeTask;
    299301    friend class ResetTask;
    300302    friend class DeleteTask;
     
    311313    HRESULT taskResetHandler(Medium::ResetTask &task);
    312314    HRESULT taskCompactHandler(Medium::CompactTask &task);
     315    HRESULT taskResizeHandler(Medium::ResizeTask &task);
    313316
    314317    struct Data;            // opaque data struct, defined in MediumImpl.cpp
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette