The whole reading was seriously confused. It tried to use the block cache for
multiple blocks at a time which it doesn't do as it always only returns one block (and actually completely ignores the provided offset and length). It only didn't crash after that because it would in the end always only memcpy length >> block shift bytes which ends up being pretty small in most cases. Since it does block wise mapping it can't do multiple blocks anyway, and really using the block cache for this is all wrong because this should really use a file map to resolve the block mapping and then use the file cache instead. Still this at least gets it working. Beware though that protected DVD content will make the block cache panic, as reading these blocks without prior setting the drive up correctly will fail (the drive will stall the reads). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35651 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
cd4e946773
commit
4f3f1911cd
@ -203,25 +203,17 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
|
||||
off_t blockOffset
|
||||
= pos - off_t((pos >> volume->BlockShift()) << volume->BlockShift());
|
||||
|
||||
size_t fullBlocksLeft = bytesLeft >> volume->BlockShift();
|
||||
size_t readLength = volume->BlockSize() - blockOffset;
|
||||
if (bytesLeft < readLength)
|
||||
readLength = bytesLeft;
|
||||
if (extent.length() < readLength)
|
||||
readLength = extent.length();
|
||||
|
||||
if (fullBlocksLeft > 0 && blockOffset == 0) {
|
||||
TRACE(("Icb::_Read(): reading full block (or more)\n"));
|
||||
// Block aligned and at least one full block left. Read
|
||||
// in using block_cache_get_etc() calls.
|
||||
off_t diskBlock;
|
||||
status = volume->MapBlock(extent, &diskBlock);
|
||||
if (status != B_OK) {
|
||||
TRACE_ERROR(("Icb::_Read: could not map extent\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
size_t fullBlockBytesLeft = fullBlocksLeft << volume->BlockShift();
|
||||
size_t readLength = fullBlockBytesLeft < extent.length()
|
||||
? fullBlockBytesLeft : extent.length();
|
||||
TRACE(("Icb::_Read: reading block. offset = %Ld, length: %ld\n",
|
||||
blockOffset, readLength));
|
||||
|
||||
if (isEmpty) {
|
||||
TRACE(("Icb::_Read(): reading %ld empty bytes as zeros\n",
|
||||
TRACE(("Icb::_Read: reading %ld empty bytes as zeros\n",
|
||||
readLength));
|
||||
memset(buffer, 0, readLength);
|
||||
} else {
|
||||
@ -231,16 +223,14 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
|
||||
TRACE_ERROR(("Icb::_Read: could not map extent\n"));
|
||||
break;
|
||||
}
|
||||
TRACE(("Icb::_Read(): reading %ld bytes from disk block %Ld "
|
||||
"using block_cache_get_etc()\n", readLength, diskBlock));
|
||||
size_t length = readLength >> volume->BlockShift();
|
||||
|
||||
TRACE(("Icb::_Read: %ld bytes from disk block %Ld using "
|
||||
"block_cache_get_etc()\n", readLength, diskBlock));
|
||||
uint8 *data = (uint8*)block_cache_get_etc(volume->BlockCache(),
|
||||
diskBlock, pos, length);
|
||||
if (data == NULL) {
|
||||
status = B_BAD_DATA;
|
||||
diskBlock, 0, readLength);
|
||||
if (data == NULL)
|
||||
break;
|
||||
}
|
||||
memcpy(buffer, data, length);
|
||||
memcpy(buffer, data + blockOffset, readLength);
|
||||
block_cache_put(volume->BlockCache(), diskBlock);
|
||||
}
|
||||
|
||||
@ -248,51 +238,6 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
|
||||
bytesRead += readLength;
|
||||
pos += readLength;
|
||||
buffer += readLength;
|
||||
} else {
|
||||
off_t partialOffset;
|
||||
size_t partialLength;
|
||||
if (blockOffset == 0) {
|
||||
// Block aligned, but only a partial block's worth remaining.
|
||||
// Read in remaining bytes of file
|
||||
partialOffset = 0;
|
||||
partialLength = bytesLeft;
|
||||
} else {
|
||||
// Not block aligned, so just read up to the next block boundary.
|
||||
partialOffset = blockOffset;
|
||||
partialLength = volume->BlockSize() - blockOffset;
|
||||
if (bytesLeft < partialLength)
|
||||
partialLength = bytesLeft;
|
||||
}
|
||||
TRACE(("Icb::_Read: reading partial block. partialOffset = %Ld, "
|
||||
"partialLength: %ld\n",partialOffset, partialLength));
|
||||
|
||||
if (isEmpty) {
|
||||
TRACE(("Icb::_Read: reading %ld empty bytes as zeros\n",
|
||||
partialLength));
|
||||
memset(buffer, 0, partialLength);
|
||||
} else {
|
||||
off_t diskBlock;
|
||||
status = volume->MapBlock(extent, &diskBlock);
|
||||
if (status != B_OK) {
|
||||
TRACE_ERROR(("Icb::_Read: could not map extent\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE(("Icb::_Read: %ld bytes from disk block %Ld using "
|
||||
"block_cache_get_etc()\n", partialLength, diskBlock));
|
||||
uint8 *data = (uint8*)block_cache_get_etc(volume->BlockCache(),
|
||||
diskBlock, 0, partialLength);
|
||||
if (data == NULL)
|
||||
break;
|
||||
memcpy(buffer, data + partialOffset, partialLength);
|
||||
block_cache_put(volume->BlockCache(), diskBlock);
|
||||
}
|
||||
|
||||
bytesLeft -= partialLength;
|
||||
bytesRead += partialLength;
|
||||
pos += partialLength;
|
||||
buffer += partialLength;
|
||||
}
|
||||
}
|
||||
|
||||
*length = bytesRead;
|
||||
|
Loading…
Reference in New Issue
Block a user