Changeset 38518 in vbox
- Timestamp:
- Aug 25, 2011 7:46:41 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 73646
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/VHD.cpp
r38469 r38518 1452 1452 1453 1453 /* 1454 * Clip read range to remain in this data block. 1455 */ 1456 cbBuf = RT_MIN(cbBuf, (pImage->cbDataBlock - (cBATEntryIndex * VHD_SECTOR_SIZE))); 1457 1458 /* 1454 1459 * If the block is not allocated the content of the entry is ~0 1455 1460 */ 1456 1461 if (pImage->pBlockAllocationTable[cBlockAllocationTableEntry] == ~0U) 1457 {1458 /* Return block size as read. */1459 *pcbActuallyRead = RT_MIN(cbBuf, pImage->cSectorsPerDataBlock * VHD_SECTOR_SIZE);1460 1462 rc = VERR_VD_BLOCK_FREE; 1461 goto out; 1462 } 1463 1464 uVhdOffset = ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry] + pImage->cDataBlockBitmapSectors + cBATEntryIndex) * VHD_SECTOR_SIZE; 1465 LogFlowFunc(("uVhdOffset=%llu cbBuf=%u\n", uVhdOffset, cbBuf)); 1466 1467 /* 1468 * Clip read range to remain in this data block. 1469 */ 1470 cbBuf = RT_MIN(cbBuf, (pImage->cbDataBlock - (cBATEntryIndex * VHD_SECTOR_SIZE))); 1471 1472 /* Read in the block's bitmap. */ 1473 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 1474 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE, 1475 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, 1476 NULL); 1477 if (RT_SUCCESS(rc)) 1478 { 1479 uint32_t cSectors = 0; 1480 1481 if (vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 1463 { 1464 uVhdOffset = ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry] + pImage->cDataBlockBitmapSectors + cBATEntryIndex) * VHD_SECTOR_SIZE; 1465 LogFlowFunc(("uVhdOffset=%llu cbBuf=%u\n", uVhdOffset, cbBuf)); 1466 1467 /* Read in the block's bitmap. */ 1468 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 1469 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE, 1470 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, 1471 NULL); 1472 if (RT_SUCCESS(rc)) 1482 1473 { 1483 cBATEntryIndex++; 1484 cSectors = 1; 1485 1486 /* 1487 * The first sector being read is marked dirty, read as much as we 1488 * can from child. Note that only sectors that are marked dirty 1489 * must be read from child. 1490 */ 1491 while ( (cSectors < (cbBuf / VHD_SECTOR_SIZE)) 1492 && vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 1474 uint32_t cSectors = 0; 1475 1476 if (vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 1493 1477 { 1494 1478 cBATEntryIndex++; 1495 cSectors++; 1479 cSectors = 1; 1480 1481 /* 1482 * The first sector being read is marked dirty, read as much as we 1483 * can from child. Note that only sectors that are marked dirty 1484 * must be read from child. 1485 */ 1486 while ( (cSectors < (cbBuf / VHD_SECTOR_SIZE)) 1487 && vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 1488 { 1489 cBATEntryIndex++; 1490 cSectors++; 1491 } 1492 1493 cbBuf = cSectors * VHD_SECTOR_SIZE; 1494 1495 LogFlowFunc(("uVhdOffset=%llu cbBuf=%u\n", uVhdOffset, cbBuf)); 1496 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 1497 uVhdOffset, pvBuf, cbBuf, NULL); 1496 1498 } 1497 1498 cbBuf = cSectors * VHD_SECTOR_SIZE; 1499 1500 LogFlowFunc(("uVhdOffset=%llu cbBuf=%u\n", uVhdOffset, cbBuf)); 1501 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 1502 uVhdOffset, pvBuf, cbBuf, NULL); 1499 else 1500 { 1501 /* 1502 * The first sector being read is marked clean, so we should read from 1503 * our parent instead, but only as much as there are the following 1504 * clean sectors, because the block may still contain dirty sectors 1505 * further on. We just need to compute the number of clean sectors 1506 * and pass it to our caller along with the notification that they 1507 * should be read from the parent. 1508 */ 1509 cBATEntryIndex++; 1510 cSectors = 1; 1511 1512 while ( (cSectors < (cbBuf / VHD_SECTOR_SIZE)) 1513 && !vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 1514 { 1515 cBATEntryIndex++; 1516 cSectors++; 1517 } 1518 1519 cbBuf = cSectors * VHD_SECTOR_SIZE; 1520 LogFunc(("Sectors free: uVhdOffset=%llu cbBuf=%u\n", uVhdOffset, cbBuf)); 1521 rc = VERR_VD_BLOCK_FREE; 1522 } 1503 1523 } 1504 1524 else 1505 { 1506 /* 1507 * The first sector being read is marked clean, so we should read from 1508 * our parent instead, but only as much as there are the following 1509 * clean sectors, because the block may still contain dirty sectors 1510 * further on. We just need to compute the number of clean sectors 1511 * and pass it to our caller along with the notification that they 1512 * should be read from the parent. 1513 */ 1514 cBATEntryIndex++; 1515 cSectors = 1; 1516 1517 while ( (cSectors < (cbBuf / VHD_SECTOR_SIZE)) 1518 && !vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 1519 { 1520 cBATEntryIndex++; 1521 cSectors++; 1522 } 1523 1524 cbBuf = cSectors * VHD_SECTOR_SIZE; 1525 LogFunc(("Sectors free: uVhdOffset=%llu cbBuf=%u\n", uVhdOffset, cbBuf)); 1526 rc = VERR_VD_BLOCK_FREE; 1527 } 1528 } 1529 else 1530 AssertMsgFailed(("Reading block bitmap failed rc=%Rrc\n", rc)); 1525 AssertMsgFailed(("Reading block bitmap failed rc=%Rrc\n", rc)); 1526 } 1531 1527 } 1532 1528 else
Note:
See TracChangeset
for help on using the changeset viewer.