Changeset 33259 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Oct 20, 2010 12:49:55 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 66817
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/VBoxHDD.cpp
r33094 r33259 166 166 * The same as pBase if only one image is used. */ 167 167 PVDIMAGE pLast; 168 169 /** If a merge to one of the parents is running this may be non-NULL 170 * to indicate to what image the writes should be additionally relayed. */ 171 PVDIMAGE pImageRelay; 168 172 169 173 /** Flags representing the modification state. */ … … 1565 1569 * write optimizations. 1566 1570 */ 1567 static int vdWriteHelper(PVBOXHDD pDisk, PVDIMAGE pImage, PVDIMAGE pImageParentOverride, 1568 uint64_t uOffset, const void *pvBuf, size_t cbWrite, 1571 static int vdWriteHelper(PVBOXHDD pDisk, PVDIMAGE pImage, 1572 PVDIMAGE pImageParentOverride, uint64_t uOffset, 1573 const void *pvBuf, size_t cbWrite, 1569 1574 bool fUpdateCache) 1570 1575 { … … 5290 5295 { 5291 5296 /* 5292 * We may need to update the parent uuid of the child coming after the5293 * last image to be merged. We have to reopen it read/write.5297 * We may need to update the parent uuid of the child coming after 5298 * the last image to be merged. We have to reopen it read/write. 5294 5299 * 5295 * This is done before we do the actual merge to prevent an incosistent5296 * chain if the mode change fails for some reason.5300 * This is done before we do the actual merge to prevent an 5301 * inconsistent chain if the mode change fails for some reason. 5297 5302 */ 5298 5303 if (pImageFrom->pNext) … … 5316 5321 break; 5317 5322 } 5323 5324 rc2 = vdThreadFinishWrite(pDisk); 5325 AssertRC(rc2); 5326 fLockWrite = false; 5327 } 5328 5329 /* If the merge is from the last image we have to relay all writes 5330 * to the merge destination as well, so that concurrent writes 5331 * (in case of a live merge) are handled correctly. */ 5332 if (!pImageFrom->pNext) 5333 { 5334 /* Take the write lock. */ 5335 rc2 = vdThreadStartWrite(pDisk); 5336 AssertRC(rc2); 5337 fLockWrite = true; 5338 5339 pDisk->pImageRelay = pImageTo; 5318 5340 5319 5341 rc2 = vdThreadFinishWrite(pDisk); … … 5380 5402 } 5381 5403 } while (uOffset < cbSize); 5404 5405 /* In case we set up a "write proxy" image above we must clear 5406 * this again now to prevent stray writes. Failure or not. */ 5407 if (!pImageFrom->pNext) 5408 { 5409 /* Take the write lock. */ 5410 rc2 = vdThreadStartWrite(pDisk); 5411 AssertRC(rc2); 5412 fLockWrite = true; 5413 5414 pDisk->pImageRelay = NULL; 5415 5416 rc2 = vdThreadFinishWrite(pDisk); 5417 AssertRC(rc2); 5418 fLockWrite = false; 5419 } 5382 5420 } 5383 5421 … … 6475 6513 rc = vdWriteHelper(pDisk, pImage, NULL, uOffset, pvBuf, cbWrite, 6476 6514 true /* fUpdateCache */); 6515 if (RT_FAILURE(rc)) 6516 break; 6517 6518 /* If there is a merge (in the direction towards a parent) running 6519 * concurrently then we have to also "relay" the write to this parent, 6520 * as the merge position might be already past the position where 6521 * this write is going. The "context" of the write can come from the 6522 * natural chain, since merging either already did or will take care 6523 * of the "other" content which is might be needed to fill the block 6524 * to a full allocation size. The cache doesn't need to be touched 6525 * as this write is covered by the previous one. */ 6526 if (RT_UNLIKELY(pDisk->pImageRelay)) 6527 rc = vdWriteHelper(pDisk, pDisk->pImageRelay, NULL, uOffset, 6528 pvBuf, cbWrite, false /* fUpdateCache */); 6477 6529 } while (0); 6478 6530
Note:
See TracChangeset
for help on using the changeset viewer.