Changeset 98044 in vbox for trunk/src/VBox/Main/src-server/MediumImpl.cpp
- Timestamp:
- Jan 10, 2023 8:01:32 PM (2 years ago)
- svn:sync-xref-src-repo-rev:
- 155144
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r98042 r98044 498 498 bool fKeepTargetMediumLockList = false, 499 499 bool fNotifyAboutChanges = true, 500 LONG64aTargetLogicalSize = 0)500 uint64_t aTargetLogicalSize = 0) 501 501 : Medium::Task(aMedium, aProgress, fNotifyAboutChanges), 502 502 mTarget(aTarget), … … 512 512 mfKeepSourceMediumLockList(fKeepSourceMediumLockList), 513 513 mfKeepTargetMediumLockList(fKeepTargetMediumLockList) 514 515 514 { 516 515 AssertReturnVoidStmt(aTarget != NULL, mRC = E_FAIL); … … 537 536 const ComObjPtr<Medium> mTarget; 538 537 const ComObjPtr<Medium> mParent; 539 LONG64mTargetLogicalSize;538 uint64_t mTargetLogicalSize; 540 539 MediumLockList *mpSourceMediumLockList; 541 540 MediumLockList *mpTargetMediumLockList; … … 3025 3024 ComPtr<IProgress> &aProgress) 3026 3025 { 3027 return resizeAndCloneTo(aTarget, 0, aVariant, aParent, aProgress); 3026 /** @todo r=jack: Remove redundancy. Call Medium::resizeAndCloneTo. */ 3027 3028 /** @todo r=klaus The code below needs to be double checked with regard 3029 * to lock order violations, it probably causes lock order issues related 3030 * to the AutoCaller usage. */ 3031 ComAssertRet(aTarget != this, E_INVALIDARG); 3032 3033 IMedium *aT = aTarget; 3034 ComObjPtr<Medium> pTarget = static_cast<Medium*>(aT); 3035 ComObjPtr<Medium> pParent; 3036 if (aParent) 3037 { 3038 IMedium *aP = aParent; 3039 pParent = static_cast<Medium*>(aP); 3040 } 3041 3042 HRESULT rc = S_OK; 3043 ComObjPtr<Progress> pProgress; 3044 Medium::Task *pTask = NULL; 3045 3046 try 3047 { 3048 // locking: we need the tree lock first because we access parent pointers 3049 // and we need to write-lock the media involved 3050 uint32_t cHandles = 3; 3051 LockHandle* pHandles[4] = { &m->pVirtualBox->i_getMediaTreeLockHandle(), 3052 this->lockHandle(), 3053 pTarget->lockHandle() }; 3054 /* Only add parent to the lock if it is not null */ 3055 if (!pParent.isNull()) 3056 pHandles[cHandles++] = pParent->lockHandle(); 3057 AutoWriteLock alock(cHandles, 3058 pHandles 3059 COMMA_LOCKVAL_SRC_POS); 3060 3061 if ( pTarget->m->state != MediumState_NotCreated 3062 && pTarget->m->state != MediumState_Created) 3063 throw pTarget->i_setStateError(); 3064 3065 /* Build the source lock list. */ 3066 MediumLockList *pSourceMediumLockList(new MediumLockList()); 3067 alock.release(); 3068 rc = i_createMediumLockList(true /* fFailIfInaccessible */, 3069 NULL /* pToLockWrite */, 3070 false /* fMediumLockWriteAll */, 3071 NULL, 3072 *pSourceMediumLockList); 3073 alock.acquire(); 3074 if (FAILED(rc)) 3075 { 3076 delete pSourceMediumLockList; 3077 throw rc; 3078 } 3079 3080 /* Build the target lock list (including the to-be parent chain). */ 3081 MediumLockList *pTargetMediumLockList(new MediumLockList()); 3082 alock.release(); 3083 rc = pTarget->i_createMediumLockList(true /* fFailIfInaccessible */, 3084 pTarget /* pToLockWrite */, 3085 false /* fMediumLockWriteAll */, 3086 pParent, 3087 *pTargetMediumLockList); 3088 alock.acquire(); 3089 if (FAILED(rc)) 3090 { 3091 delete pSourceMediumLockList; 3092 delete pTargetMediumLockList; 3093 throw rc; 3094 } 3095 3096 alock.release(); 3097 rc = pSourceMediumLockList->Lock(); 3098 alock.acquire(); 3099 if (FAILED(rc)) 3100 { 3101 delete pSourceMediumLockList; 3102 delete pTargetMediumLockList; 3103 throw setError(rc, 3104 tr("Failed to lock source media '%s'"), 3105 i_getLocationFull().c_str()); 3106 } 3107 alock.release(); 3108 rc = pTargetMediumLockList->Lock(); 3109 alock.acquire(); 3110 if (FAILED(rc)) 3111 { 3112 delete pSourceMediumLockList; 3113 delete pTargetMediumLockList; 3114 throw setError(rc, 3115 tr("Failed to lock target media '%s'"), 3116 pTarget->i_getLocationFull().c_str()); 3117 } 3118 3119 pProgress.createObject(); 3120 rc = pProgress->init(m->pVirtualBox, 3121 static_cast <IMedium *>(this), 3122 BstrFmt(tr("Creating clone medium '%s'"), pTarget->m->strLocationFull.c_str()).raw(), 3123 TRUE /* aCancelable */); 3124 if (FAILED(rc)) 3125 { 3126 delete pSourceMediumLockList; 3127 delete pTargetMediumLockList; 3128 throw rc; 3129 } 3130 3131 ULONG mediumVariantFlags = 0; 3132 3133 if (aVariant.size()) 3134 { 3135 for (size_t i = 0; i < aVariant.size(); i++) 3136 mediumVariantFlags |= (ULONG)aVariant[i]; 3137 } 3138 3139 if (mediumVariantFlags & MediumVariant_Formatted) 3140 { 3141 delete pSourceMediumLockList; 3142 delete pTargetMediumLockList; 3143 throw setError(VBOX_E_NOT_SUPPORTED, 3144 tr("Medium variant 'formatted' applies to floppy images only")); 3145 } 3146 3147 /* setup task object to carry out the operation asynchronously */ 3148 pTask = new Medium::CloneTask(this, pProgress, pTarget, 3149 (MediumVariant_T)mediumVariantFlags, 3150 pParent, UINT32_MAX, UINT32_MAX, 3151 pSourceMediumLockList, pTargetMediumLockList); 3152 rc = pTask->rc(); 3153 AssertComRC(rc); 3154 if (FAILED(rc)) 3155 throw rc; 3156 3157 if (pTarget->m->state == MediumState_NotCreated) 3158 pTarget->m->state = MediumState_Creating; 3159 } 3160 catch (HRESULT aRC) { rc = aRC; } 3161 3162 if (SUCCEEDED(rc)) 3163 { 3164 rc = pTask->createThread(); 3165 pTask = NULL; 3166 if (SUCCEEDED(rc)) 3167 pProgress.queryInterfaceTo(aProgress.asOutParam()); 3168 } 3169 else if (pTask != NULL) 3170 delete pTask; 3171 3172 return rc; 3028 3173 } 3029 3174 … … 3062 3207 /* Set up variables. Fetch needed data in lockable blocks */ 3063 3208 HRESULT rc = S_OK; 3064 ComObjPtr<Progress> pTmpProgress;3065 3209 Medium::Task *pTask = NULL; 3066 3210 … … 3091 3235 3092 3236 if (FAILED(rc)) 3093 throwrc;3237 return rc; 3094 3238 3095 3239 /* If target does not exist, handle resize. */ … … 3099 3243 if (!i_isMediumFormatFile()) 3100 3244 { 3101 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);3102 3245 rc = setError(VBOX_E_NOT_SUPPORTED, 3103 3246 tr("Sizes of '%s' and '%s' are different and \ 3104 3247 medium format does not support resing"), 3105 3248 strSourceName.c_str(), strTargetName.c_str()); 3106 throwrc;3249 return rc; 3107 3250 } 3108 3251 … … 3115 3258 rc = pTarget->LockWrite(pToken.asOutParam()); 3116 3259 3117 if (FAILED(rc)) throwrc;3260 if (FAILED(rc)) return rc; 3118 3261 3119 3262 /** … … 3134 3277 strTargetName.c_str()); 3135 3278 delete pMediumLockListForResize; 3136 throwrc;3279 return rc; 3137 3280 } 3138 3281 … … 3145 3288 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3146 3289 delete pMediumLockListForResize; 3147 throwrc;3290 return rc; 3148 3291 } 3149 3292 … … 3268 3411 pParent, UINT32_MAX, UINT32_MAX, 3269 3412 pSourceMediumLockList, pTargetMediumLockList, 3270 false, false, true, aLogicalSize);3413 false, false, true, (uint64_t)aLogicalSize); 3271 3414 } 3272 3415 … … 3288 3431 pProgress.queryInterfaceTo(aProgress.asOutParam()); 3289 3432 } 3290 else if (pTask != NULL) {3433 else if (pTask != NULL) 3291 3434 delete pTask; 3292 throw rc;3293 }3294 3435 3295 3436 return rc; … … 9776 9917 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9777 9918 false /* fMoveByRename */, 9778 (uint64_t)task.mTargetLogicalSize /* cbSize */,9919 task.mTargetLogicalSize /* cbSize */, 9779 9920 task.mVariant & ~(MediumVariant_NoCreateDir | MediumVariant_Formatted | MediumVariant_VmdkESX | MediumVariant_VmdkRawDisk), 9780 9921 targetId.raw(), … … 9792 9933 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9793 9934 false /* fMoveByRename */, 9794 (uint64_t)task.mTargetLogicalSize /* cbSize */,9935 task.mTargetLogicalSize /* cbSize */, 9795 9936 task.midxSrcImageSame, 9796 9937 task.midxDstImageSame,
Note:
See TracChangeset
for help on using the changeset viewer.