Changeset 38670 in vbox
- Timestamp:
- Sep 7, 2011 9:40:44 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 73883
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
r38644 r38670 260 260 } 261 261 262 static void drvdiskintIoLogEntryRelease(PIOLOGENT pIoLogEnt) 263 { 264 pIoLogEnt->cRefs--; 265 if (!pIoLogEnt->cRefs) 266 RTMemFree(pIoLogEnt); 267 } 268 262 269 /** 263 270 * Record a successful write to the virtual disk. … … 469 476 470 477 /** 478 * Discards the given ranges from the disk. 479 * 480 * @returns VBox status code. 481 * @param pThis Disk integrity driver instance data. 482 * @param paRanges Array of ranges to discard. 483 * @param cRanges Number of ranges in the array. 484 */ 485 static int drvdiskintDiscardRecords(PDRVDISKINTEGRITY pThis, PPDMRANGE paRanges, unsigned cRanges) 486 { 487 int rc = VINF_SUCCESS; 488 489 LogFlowFunc(("pThis=%#p paRanges=%#p cRanges=%u\n", pThis, paRanges, cRanges)); 490 491 for (unsigned i = 0; i < cRanges; i++) 492 { 493 uint64_t offStart = paRanges[i].offStart; 494 size_t cbLeft = paRanges[i].cbRange; 495 496 LogFlowFunc(("Discarding off=%llu cbRange=%zu\n", offStart, cbLeft)); 497 498 while (cbLeft) 499 { 500 size_t cbRange; 501 PDRVDISKSEGMENT pSeg = (PDRVDISKSEGMENT)RTAvlrFileOffsetRangeGet(pThis->pTreeSegments, offStart); 502 503 if (!pSeg) 504 { 505 /* Get next segment */ 506 pSeg = (PDRVDISKSEGMENT)RTAvlrFileOffsetGetBestFit(pThis->pTreeSegments, offStart, true); 507 if ( !pSeg 508 || (RTFOFF)offStart + (RTFOFF)cbLeft <= pSeg->Core.Key) 509 cbRange = cbLeft; 510 else 511 cbRange = pSeg->Core.Key - offStart; 512 513 Assert(!(cbRange % 512)); 514 } 515 else 516 { 517 size_t cbPreLeft, cbPostLeft; 518 519 cbRange = RT_MIN(cbRange, pSeg->Core.KeyLast - offStart + 1); 520 cbPreLeft = offStart - pSeg->Core.Key; 521 cbPostLeft = pSeg->cbSeg - cbRange - cbPreLeft; 522 523 Assert(!(cbRange % 512)); 524 Assert(!(cbPreLeft % 512)); 525 Assert(!(cbPostLeft % 512)); 526 527 LogFlowFunc(("cbRange=%zu cbPreLeft=%zu cbPostLeft=%zu\n", 528 cbRange, cbPreLeft, cbPostLeft)); 529 530 RTAvlrFileOffsetRemove(pThis->pTreeSegments, pSeg->Core.Key); 531 532 if (!cbPreLeft && !cbPostLeft) 533 { 534 /* Just free the whole segment. */ 535 LogFlowFunc(("Freeing whole segment pSeg=%#p\n", pSeg)); 536 RTMemFree(pSeg->pbSeg); 537 for (unsigned idx = 0; idx < pSeg->cIoLogEntries; idx++) 538 drvdiskintIoLogEntryRelease(pSeg->apIoLog[idx]); 539 RTMemFree(pSeg); 540 } 541 else if (cbPreLeft && !cbPostLeft) 542 { 543 /* Realloc to new size and insert. */ 544 LogFlowFunc(("Realloc segment pSeg=%#p\n", pSeg)); 545 pSeg->pbSeg = (uint8_t *)RTMemRealloc(pSeg->pbSeg, cbPreLeft); 546 for (unsigned idx = cbPreLeft / 512; idx < pSeg->cIoLogEntries; idx++) 547 drvdiskintIoLogEntryRelease(pSeg->apIoLog[idx]); 548 pSeg = (PDRVDISKSEGMENT)RTMemRealloc(pSeg, RT_OFFSETOF(DRVDISKSEGMENT, apIoLog[cbPreLeft / 512])); 549 pSeg->Core.KeyLast = pSeg->Core.Key + cbPreLeft - 1; 550 pSeg->cbSeg = cbPreLeft; 551 pSeg->cIoLogEntries = cbPreLeft / 512; 552 bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core); 553 Assert(fInserted); 554 } 555 else if (!cbPreLeft && cbPostLeft) 556 { 557 /* Move data to the front and realloc. */ 558 LogFlowFunc(("Move data and realloc segment pSeg=%#p\n", pSeg)); 559 memmove(pSeg->pbSeg, pSeg->pbSeg + cbRange, cbPostLeft); 560 for (unsigned idx = 0; idx < cbRange / 512; idx++) 561 drvdiskintIoLogEntryRelease(pSeg->apIoLog[idx]); 562 for (unsigned idx = 0; idx < cbPostLeft /512; idx++) 563 pSeg->apIoLog[idx] = pSeg->apIoLog[(cbRange / 512) + idx]; 564 pSeg = (PDRVDISKSEGMENT)RTMemRealloc(pSeg, RT_OFFSETOF(DRVDISKSEGMENT, apIoLog[cbPostLeft / 512])); 565 pSeg->pbSeg = (uint8_t *)RTMemRealloc(pSeg->pbSeg, cbPostLeft); 566 pSeg->Core.Key += cbRange; 567 pSeg->cbSeg = cbPostLeft; 568 pSeg->cIoLogEntries = cbPostLeft / 512; 569 bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core); 570 Assert(fInserted); 571 } 572 else 573 { 574 /* Split the segment into 2 new segments. */ 575 LogFlowFunc(("Split segment pSeg=%#p\n", pSeg)); 576 PDRVDISKSEGMENT pSegPost = (PDRVDISKSEGMENT)RTMemAllocZ(RT_OFFSETOF(DRVDISKSEGMENT, apIoLog[cbPostLeft / 512])); 577 if (pSegPost) 578 { 579 pSegPost->Core.Key = pSeg->Core.Key + cbPreLeft + cbRange; 580 pSegPost->Core.KeyLast = pSeg->Core.KeyLast; 581 pSegPost->cbSeg = cbPostLeft; 582 pSegPost->pbSeg = (uint8_t *)RTMemAllocZ(cbPostLeft); 583 pSegPost->cIoLogEntries = cbPostLeft / 512; 584 if (!pSegPost->pbSeg) 585 RTMemFree(pSegPost); 586 else 587 { 588 memcpy(pSegPost->pbSeg, pSeg->pbSeg + cbPreLeft + cbRange, cbPostLeft); 589 for (unsigned idx = 0; idx < cbPostLeft / 512; idx++) 590 pSegPost->apIoLog[idx] = pSeg->apIoLog[((cbPreLeft + cbRange) / 512) + idx]; 591 592 bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSegPost->Core); 593 Assert(fInserted); 594 } 595 } 596 597 /* Shrink the current segment. */ 598 pSeg->pbSeg = (uint8_t *)RTMemRealloc(pSeg->pbSeg, cbPreLeft); 599 for (unsigned idx = cbPreLeft / 512; idx < (cbPreLeft + cbRange) / 512; idx++) 600 drvdiskintIoLogEntryRelease(pSeg->apIoLog[idx]); 601 pSeg = (PDRVDISKSEGMENT)RTMemRealloc(pSeg, RT_OFFSETOF(DRVDISKSEGMENT, apIoLog[cbPreLeft / 512])); 602 pSeg->Core.KeyLast = pSeg->Core.Key + cbPreLeft - 1; 603 pSeg->cbSeg = cbPreLeft; 604 pSeg->cIoLogEntries = cbPreLeft / 512; 605 bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core); 606 Assert(fInserted); 607 } /* if (cbPreLeft && cbPostLeft) */ 608 } 609 610 offStart += cbRange; 611 cbLeft -= cbRange; 612 } 613 } 614 615 LogFlowFunc(("returns rc=%Rrc\n", rc)); 616 return rc; 617 } 618 619 /** 471 620 * Adds a request to the active list. 472 621 * … … 890 1039 AssertRC(rc2); 891 1040 } 1041 1042 if (pThis->fCheckConsistency) 1043 rc = drvdiskintDiscardRecords(pThis, paRanges, cRanges); 892 1044 893 1045 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.