Changeset 69886 in vbox
- Timestamp:
- Nov 30, 2017 5:43:25 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dvm/dvm.cpp
r69618 r69886 474 474 { 475 475 PRTDVMINTERNAL pThis = hVolMgr; 476 477 /* 478 * Input validation. 479 */ 476 480 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 477 481 AssertPtrReturn(pfAllocated, VERR_INVALID_POINTER); … … 484 488 VERR_OUT_OF_RANGE); 485 489 486 /* Check whether the range is inuse by the volume manager metadata first. */ 490 /* 491 * Check whether the range is inuse by the volume manager metadata first. 492 */ 487 493 int rc = pThis->pDvmFmtOps->pfnQueryRangeUse(pThis->hVolMgrFmt, off, cb, pfAllocated); 488 if (RT_FAILURE(rc) )494 if (RT_FAILURE(rc) || *pfAllocated) 489 495 return rc; 490 496 491 if (!*pfAllocated) 492 { 493 bool fAllocated = false; 494 495 while ( cb > 0 496 && !fAllocated) 497 /* 498 * Not used by volume manager metadata, so work thru the specified range one 499 * volume / void (free space) at a time. All must be unallocated for us to 500 * reach the end, we return immediately if any portion is allocated. 501 */ 502 while (cb > 0) 503 { 504 /* 505 * Search through all volumes. 506 * 507 * It is not possible to get all start sectors and sizes of all volumes 508 * here because volumes can be scattered around the disk for certain formats. 509 * Linux LVM is one example, it extents of logical volumes don't need to be 510 * contiguous on the medium. 511 */ 512 bool fVolFound = false; 513 PRTDVMVOLUMEINTERNAL pVol; 514 RTListForEach(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode) 497 515 { 498 bool fVolFound = false;499 516 uint64_t cbIntersect; 500 517 uint64_t offVol; 501 502 /* 503 * Search through all volumes. It is not possible to 504 * get all start sectors and sizes of all volumes here 505 * because volumes can be scattered around the disk for certain formats. 506 * Linux LVM is one example, extents of logical volumes don't need to be 507 * contigous on the medium. 508 */ 509 PRTDVMVOLUMEINTERNAL pVol; 510 RTListForEach(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode) 518 bool fIntersect = pThis->pDvmFmtOps->pfnVolumeIsRangeIntersecting(pVol->hVolFmt, off, cb, &offVol, &cbIntersect); 519 if (fIntersect) 511 520 { 512 bool fIntersect = pThis->pDvmFmtOps->pfnVolumeIsRangeIntersecting(pVol->hVolFmt, off, 513 cb, &offVol, 514 &cbIntersect); 515 if (fIntersect) 521 fVolFound = true; 522 if (pVol->pfnQueryBlockStatus) 516 523 { 517 fVolFound = true; 518 if (pVol->pfnQueryBlockStatus) 524 bool fVolAllocated = true; 525 rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect, &fVolAllocated); 526 if (RT_FAILURE(rc) || fVolAllocated) 519 527 { 520 bool fVolAllocated = true; 521 rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect, &fVolAllocated); 522 if (RT_FAILURE(rc)) 523 break; 524 if (fVolAllocated) 525 { 526 fAllocated = true; 527 break; 528 } 528 *pfAllocated = true; 529 return rc; 529 530 } 530 else if (!(pThis->fFlags & DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED))531 fAllocated = true;532 /* else, flag is set, continue. */533 534 cb -= cbIntersect;535 off += cbIntersect;536 break;537 531 } 538 } 539 540 if (!fVolFound) 541 { 542 if (pThis->fFlags & DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED) 543 fAllocated = true; 544 545 cb -= pThis->DvmDisk.cbSector; 546 off += pThis->DvmDisk.cbSector; 532 else if (!(pThis->fFlags & DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED)) 533 { 534 *pfAllocated = true; 535 return VINF_SUCCESS; 536 } 537 /* else, flag is set, continue. */ 538 539 cb -= cbIntersect; 540 off += cbIntersect; 541 break; 547 542 } 548 543 } 549 544 550 *pfAllocated = fAllocated; 551 } 552 545 if (!fVolFound) 546 { 547 if (pThis->fFlags & DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED) 548 { 549 *pfAllocated = true; 550 return VINF_SUCCESS; 551 } 552 553 cb -= pThis->DvmDisk.cbSector; 554 off += pThis->DvmDisk.cbSector; 555 } 556 } 557 558 *pfAllocated = false; 553 559 return rc; 554 560 }
Note:
See TracChangeset
for help on using the changeset viewer.