Changeset 38521 in vbox
- Timestamp:
- Aug 25, 2011 8:23:13 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/VHD.cpp
r38519 r38521 2284 2284 2285 2285 /* 2286 * Clip read range to remain in this data block. 2287 */ 2288 cbRead = RT_MIN(cbRead, (pImage->cbDataBlock - (cBATEntryIndex * VHD_SECTOR_SIZE))); 2289 2290 /* 2286 2291 * If the block is not allocated the content of the entry is ~0 2287 2292 */ 2288 2293 if (pImage->pBlockAllocationTable[cBlockAllocationTableEntry] == ~0U) 2289 { 2290 /* Return block size as read. */ 2291 *pcbActuallyRead = RT_MIN(cbRead, pImage->cSectorsPerDataBlock * VHD_SECTOR_SIZE); 2292 return VERR_VD_BLOCK_FREE; 2293 } 2294 2295 uVhdOffset = ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry] + pImage->cDataBlockBitmapSectors + cBATEntryIndex) * VHD_SECTOR_SIZE; 2296 LogFlowFunc(("uVhdOffset=%llu cbRead=%u\n", uVhdOffset, cbRead)); 2297 2298 /* 2299 * Clip read range to remain in this data block. 2300 */ 2301 cbRead = RT_MIN(cbRead, (pImage->cbDataBlock - (cBATEntryIndex * VHD_SECTOR_SIZE))); 2302 2303 /* Read in the block's bitmap. */ 2304 PVDMETAXFER pMetaXfer; 2305 rc = vdIfIoIntFileReadMetaAsync(pImage->pIfIo, pImage->pStorage, 2306 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE, 2307 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, 2308 pIoCtx, &pMetaXfer, NULL, NULL); 2309 2310 if (RT_SUCCESS(rc)) 2311 { 2312 uint32_t cSectors = 0; 2313 2314 vdIfIoIntMetaXferRelease(pImage->pIfIo, pMetaXfer); 2315 if (vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 2294 rc = VERR_VD_BLOCK_FREE; 2295 else 2296 { 2297 uVhdOffset = ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry] + pImage->cDataBlockBitmapSectors + cBATEntryIndex) * VHD_SECTOR_SIZE; 2298 LogFlowFunc(("uVhdOffset=%llu cbRead=%u\n", uVhdOffset, cbRead)); 2299 2300 /* Read in the block's bitmap. */ 2301 PVDMETAXFER pMetaXfer; 2302 rc = vdIfIoIntFileReadMetaAsync(pImage->pIfIo, pImage->pStorage, 2303 ((uint64_t)pImage->pBlockAllocationTable[cBlockAllocationTableEntry]) * VHD_SECTOR_SIZE, 2304 pImage->pu8Bitmap, pImage->cbDataBlockBitmap, 2305 pIoCtx, &pMetaXfer, NULL, NULL); 2306 2307 if (RT_SUCCESS(rc)) 2316 2308 { 2317 cBATEntryIndex++; 2318 cSectors = 1; 2319 2320 /* 2321 * The first sector being read is marked dirty, read as much as we 2322 * can from child. Note that only sectors that are marked dirty 2323 * must be read from child. 2324 */ 2325 while ( (cSectors < (cbRead / VHD_SECTOR_SIZE)) 2326 && vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 2309 uint32_t cSectors = 0; 2310 2311 vdIfIoIntMetaXferRelease(pImage->pIfIo, pMetaXfer); 2312 if (vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 2327 2313 { 2328 2314 cBATEntryIndex++; 2329 cSectors++; 2315 cSectors = 1; 2316 2317 /* 2318 * The first sector being read is marked dirty, read as much as we 2319 * can from child. Note that only sectors that are marked dirty 2320 * must be read from child. 2321 */ 2322 while ( (cSectors < (cbRead / VHD_SECTOR_SIZE)) 2323 && vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 2324 { 2325 cBATEntryIndex++; 2326 cSectors++; 2327 } 2328 2329 cbRead = cSectors * VHD_SECTOR_SIZE; 2330 2331 LogFlowFunc(("uVhdOffset=%llu cbRead=%u\n", uVhdOffset, cbRead)); 2332 rc = vdIfIoIntFileReadUserAsync(pImage->pIfIo, pImage->pStorage, 2333 uVhdOffset, pIoCtx, cbRead); 2330 2334 } 2331 2332 cbRead = cSectors * VHD_SECTOR_SIZE; 2333 2334 LogFlowFunc(("uVhdOffset=%llu cbRead=%u\n", uVhdOffset, cbRead)); 2335 rc = vdIfIoIntFileReadUserAsync(pImage->pIfIo, pImage->pStorage, 2336 uVhdOffset, pIoCtx, cbRead); 2335 else 2336 { 2337 /* 2338 * The first sector being read is marked clean, so we should read from 2339 * our parent instead, but only as much as there are the following 2340 * clean sectors, because the block may still contain dirty sectors 2341 * further on. We just need to compute the number of clean sectors 2342 * and pass it to our caller along with the notification that they 2343 * should be read from the parent. 2344 */ 2345 cBATEntryIndex++; 2346 cSectors = 1; 2347 2348 while ( (cSectors < (cbRead / VHD_SECTOR_SIZE)) 2349 && !vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 2350 { 2351 cBATEntryIndex++; 2352 cSectors++; 2353 } 2354 2355 cbRead = cSectors * VHD_SECTOR_SIZE; 2356 LogFunc(("Sectors free: uVhdOffset=%llu cbRead=%u\n", uVhdOffset, cbRead)); 2357 rc = VERR_VD_BLOCK_FREE; 2358 } 2337 2359 } 2338 2360 else 2339 { 2340 /* 2341 * The first sector being read is marked clean, so we should read from 2342 * our parent instead, but only as much as there are the following 2343 * clean sectors, because the block may still contain dirty sectors 2344 * further on. We just need to compute the number of clean sectors 2345 * and pass it to our caller along with the notification that they 2346 * should be read from the parent. 2347 */ 2348 cBATEntryIndex++; 2349 cSectors = 1; 2350 2351 while ( (cSectors < (cbRead / VHD_SECTOR_SIZE)) 2352 && !vhdBlockBitmapSectorContainsData(pImage, cBATEntryIndex)) 2353 { 2354 cBATEntryIndex++; 2355 cSectors++; 2356 } 2357 2358 cbRead = cSectors * VHD_SECTOR_SIZE; 2359 LogFunc(("Sectors free: uVhdOffset=%llu cbRead=%u\n", uVhdOffset, cbRead)); 2360 rc = VERR_VD_BLOCK_FREE; 2361 } 2362 } 2363 else 2364 AssertMsg(rc == VERR_VD_NOT_ENOUGH_METADATA, ("Reading block bitmap failed rc=%Rrc\n", rc)); 2361 AssertMsg(rc == VERR_VD_NOT_ENOUGH_METADATA, ("Reading block bitmap failed rc=%Rrc\n", rc)); 2362 } 2365 2363 } 2366 2364 else
Note:
See TracChangeset
for help on using the changeset viewer.