Changeset 97932 in vbox for trunk/src/VBox/Main/src-server
- Timestamp:
- Dec 31, 2022 9:50:09 PM (2 years ago)
- svn:sync-xref-src-repo-rev:
- 155022
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r97931 r97932 497 497 bool fKeepSourceMediumLockList = false, 498 498 bool fKeepTargetMediumLockList = false, 499 bool fNotifyAboutChanges = true, 500 LONG64 aTargetLogicalSize = 0) 499 bool fNotifyAboutChanges = true) 501 500 : Medium::Task(aMedium, aProgress, fNotifyAboutChanges), 502 501 mTarget(aTarget), 503 502 mParent(aParent), 504 mTargetLogicalSize(aTargetLogicalSize),505 503 mpSourceMediumLockList(aSourceMediumLockList), 506 504 mpTargetMediumLockList(aTargetMediumLockList), … … 512 510 mfKeepSourceMediumLockList(fKeepSourceMediumLockList), 513 511 mfKeepTargetMediumLockList(fKeepTargetMediumLockList) 514 515 512 { 516 513 AssertReturnVoidStmt(aTarget != NULL, mRC = E_FAIL); … … 537 534 const ComObjPtr<Medium> mTarget; 538 535 const ComObjPtr<Medium> mParent; 539 LONG64 mTargetLogicalSize;540 536 MediumLockList *mpSourceMediumLockList; 541 537 MediumLockList *mpTargetMediumLockList; … … 3024 3020 ComPtr<IProgress> &aProgress) 3025 3021 { 3026 return resizeAndCloneTo(aTarget, 0, aVariant, aParent, aProgress); 3027 } 3028 3029 /** 3030 * This is a helper function that combines the functionality of 3031 * Medium::cloneTo() and Medium::resize(). The target medium will take the 3032 * contents of the calling medium. 3033 * 3034 * @param aTarget Medium to resize and clone to 3035 * @param aLogicalSize Desired size for targer medium 3036 * @param aVariant 3037 * @param aParent 3038 * @param aProgress 3039 * @return HRESULT 3040 */ 3041 HRESULT Medium::resizeAndCloneTo(const ComPtr<IMedium> &aTarget, 3042 LONG64 aLogicalSize, 3043 const std::vector<MediumVariant_T> &aVariant, 3044 const ComPtr<IMedium> &aParent, 3045 ComPtr<IProgress> &aProgress) 3046 { 3047 /* Check for valid args */ 3022 /** @todo r=klaus The code below needs to be double checked with regard 3023 * to lock order violations, it probably causes lock order issues related 3024 * to the AutoCaller usage. */ 3048 3025 ComAssertRet(aTarget != this, E_INVALIDARG); 3049 CheckComArgExpr(aLogicalSize, aLogicalSize >= 0); 3050 3051 /* Convert args to usable/needed types */ 3026 3052 3027 IMedium *aT = aTarget; 3053 3028 ComObjPtr<Medium> pTarget = static_cast<Medium*>(aT); … … 3059 3034 } 3060 3035 3061 /* Set up variables. Fetch needed data in lockable blocks */3062 3036 HRESULT rc = S_OK; 3063 ComObjPtr<Progress> p TmpProgress;3037 ComObjPtr<Progress> pProgress; 3064 3038 Medium::Task *pTask = NULL; 3065 3066 Utf8Str strSourceName;3067 {3068 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);3069 strSourceName = i_getName();3070 }3071 3072 uint64_t uTargetExistingSize = 0;3073 Utf8Str strTargetName;3074 {3075 AutoReadLock alock(pTarget COMMA_LOCKVAL_SRC_POS);3076 uTargetExistingSize = pTarget->i_getLogicalSize();3077 strTargetName = pTarget->i_getName();3078 }3079 3080 /* Set up internal multi-subprocess progress object */3081 ComObjPtr<Progress> pProgress;3082 pProgress.createObject();3083 rc = pProgress->init(m->pVirtualBox,3084 static_cast<IMedium*>(this),3085 BstrFmt(tr("Resizing medium and cloning into it")).raw(),3086 TRUE, /* aCancelable */3087 2, /* Number of opearations */3088 BstrFmt(tr("Resizing medium before clone")).raw()3089 );3090 3091 if (FAILED(rc))3092 throw rc;3093 3094 /* If target does not exist, handle resize. */3095 if (pTarget->m->state != MediumState_NotCreated && aLogicalSize > 0)3096 {3097 if ((LONG64)uTargetExistingSize != aLogicalSize) {3098 if (!i_isMediumFormatFile())3099 {3100 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);3101 rc = setError(VBOX_E_NOT_SUPPORTED,3102 tr("Sizes of '%s' and '%s' are different and \3103 medium format does not support resing"),3104 strSourceName.c_str(), strTargetName.c_str());3105 throw rc;3106 }3107 3108 /**3109 * Need to lock the target medium as i_resize does do so3110 * automatically.3111 */3112 3113 ComPtr<IToken> pToken;3114 rc = pTarget->LockWrite(pToken.asOutParam());3115 3116 if (FAILED(rc)) throw rc;3117 3118 /**3119 * Have to make own lock list, because "resize" method resizes only3120 * last image in the lock chain.3121 */3122 3123 MediumLockList* pMediumLockListForResize = new MediumLockList();3124 pMediumLockListForResize->Append(pTarget, pTarget->m->state == MediumState_LockedWrite);3125 3126 rc = pMediumLockListForResize->Lock(true /* fSkipOverLockedMedia */);3127 3128 if (FAILED(rc))3129 {3130 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);3131 rc = setError(rc,3132 tr("Failed to lock the medium '%s' to resize before merge"),3133 strTargetName.c_str());3134 delete pMediumLockListForResize;3135 throw rc;3136 }3137 3138 3139 rc = pTarget->i_resize((uint64_t)aLogicalSize, pMediumLockListForResize, &pProgress, true, false);3140 3141 if (FAILED(rc))3142 {3143 /* No need to setError becasue i_resize and i_taskResizeHandler handle this automatically. */3144 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);3145 delete pMediumLockListForResize;3146 throw rc;3147 }3148 3149 delete pMediumLockListForResize;3150 3151 pTarget->m->logicalSize = (uint64_t)aLogicalSize;3152 3153 pToken->Abandon();3154 pToken.setNull();3155 }3156 }3157 3158 /* Report progress to supplied progress argument */3159 if (SUCCEEDED(rc))3160 {3161 pProgress.queryInterfaceTo(aProgress.asOutParam());3162 }3163 3039 3164 3040 try … … 3235 3111 } 3236 3112 3113 pProgress.createObject(); 3114 rc = pProgress->init(m->pVirtualBox, 3115 static_cast <IMedium *>(this), 3116 BstrFmt(tr("Creating clone medium '%s'"), pTarget->m->strLocationFull.c_str()).raw(), 3117 TRUE /* aCancelable */); 3118 if (FAILED(rc)) 3119 { 3120 delete pSourceMediumLockList; 3121 delete pTargetMediumLockList; 3122 throw rc; 3123 } 3124 3237 3125 ULONG mediumVariantFlags = 0; 3238 3126 … … 3251 3139 } 3252 3140 3253 if (pTarget->m->state != MediumState_NotCreated || aLogicalSize == 0) 3254 { 3255 /* setup task object to carry out the operation asynchronously */ 3256 pTask = new Medium::CloneTask(this, pProgress, pTarget, 3257 (MediumVariant_T)mediumVariantFlags, 3258 pParent, UINT32_MAX, UINT32_MAX, 3259 pSourceMediumLockList, pTargetMediumLockList, 3260 false, false, true, 0); 3261 } 3262 else 3263 { 3264 /* setup task object to carry out the operation asynchronously */ 3265 pTask = new Medium::CloneTask(this, pProgress, pTarget, 3266 (MediumVariant_T)mediumVariantFlags, 3267 pParent, UINT32_MAX, UINT32_MAX, 3268 pSourceMediumLockList, pTargetMediumLockList, 3269 false, false, true, aLogicalSize); 3270 } 3271 3141 /* setup task object to carry out the operation asynchronously */ 3142 pTask = new Medium::CloneTask(this, pProgress, pTarget, 3143 (MediumVariant_T)mediumVariantFlags, 3144 pParent, UINT32_MAX, UINT32_MAX, 3145 pSourceMediumLockList, pTargetMediumLockList); 3272 3146 rc = pTask->rc(); 3273 3147 AssertComRC(rc); … … 3287 3161 pProgress.queryInterfaceTo(aProgress.asOutParam()); 3288 3162 } 3289 else if (pTask != NULL) {3163 else if (pTask != NULL) 3290 3164 delete pTask; 3291 throw rc;3292 }3293 3165 3294 3166 return rc; … … 9775 9647 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9776 9648 false /* fMoveByRename */, 9777 (uint64_t) task.mTargetLogicalSize/* cbSize */,9649 0 /* cbSize */, 9778 9650 task.mVariant & ~(MediumVariant_NoCreateDir | MediumVariant_Formatted), 9779 9651 targetId.raw(), … … 9791 9663 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9792 9664 false /* fMoveByRename */, 9793 (uint64_t) task.mTargetLogicalSize/* cbSize */,9665 0 /* cbSize */, 9794 9666 task.midxSrcImageSame, 9795 9667 task.midxDstImageSame,
Note:
See TracChangeset
for help on using the changeset viewer.