* Replace wrong file_cache call with block_cache_get_etc() in Icb::_Read()

* Clean up

I've succefully copied data from a udf partition.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27159 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Salvatore Benedetto
2008-08-22 19:19:35 +00:00
parent 2e39d2c54f
commit 9fd15595d6
2 changed files with 139 additions and 132 deletions
+67 -60
View File
@@ -143,26 +143,30 @@ template <class DescriptorList>
status_t status_t
Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint32 *block) Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint32 *block)
{ {
TRACE(("Icb::_Read(): list: %p, pos: %Ld, buffer: %p, length: (%p)->%ld\n", TRACE(("Icb::_Read(): list = %p, pos = %Ld, buffer = %p, length = %ld\n",
&list, pos, _buffer, length, (length ? *length : 0))); &list, pos, _buffer, (length ? *length : 0)));
uint64 bytesLeftInFile = uint64(pos) > Length() ? 0 : Length() - pos; uint64 bytesLeftInFile = uint64(pos) > Length() ? 0 : Length() - pos;
size_t bytesLeft = (*length >= bytesLeftInFile) ? bytesLeftInFile : *length; size_t bytesLeft = (*length >= bytesLeftInFile) ? bytesLeftInFile : *length;
size_t bytesRead = 0; size_t bytesRead = 0;
Volume *volume = GetVolume(); Volume *volume = GetVolume();
status_t error = B_OK; status_t status = B_OK;
uint8 *buffer = (uint8 *)_buffer; uint8 *buffer = (uint8 *)_buffer;
bool isFirstBlock = true; bool isFirstBlock = true;
while (bytesLeft > 0 && !error) { while (bytesLeft > 0) {
TRACE(("Icb::_Read(): pos: %Ld\n, bytesLeft: %ld\n", pos, bytesLeft));
TRACE(("Icb::_Read(): pos: %Ld, bytesLeft: %ld\n", pos, bytesLeft));
long_address extent; long_address extent;
bool isEmpty = false; bool isEmpty = false;
error = list.FindExtent(pos, &extent, &isEmpty); status = list.FindExtent(pos, &extent, &isEmpty);
if (!error) { if (status != B_OK) {
TRACE_ERROR(("Icb::_Read: error finding extent for offset %Ld. "
"status = 0x%lx `%s'\n", pos, status, strerror(status)));
break;
}
TRACE(("Icb::_Read(): found extent for offset %Ld: (block: %ld, " TRACE(("Icb::_Read(): found extent for offset %Ld: (block: %ld, "
"partition: %d, length: %ld, type: %d)\n", pos, extent.block(), "partition: %d, length: %ld, type: %d)\n", pos, extent.block(),
extent.partition(), extent.length(), extent.type())); extent.partition(), extent.length(), extent.type()));
@@ -178,13 +182,15 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
break; break;
default: default:
TRACE_ERROR(("Icb::_Read(): Invalid extent type " TRACE_ERROR(("Icb::_Read(): Invalid extent type found: %d\n",
"found: %d\n", extent.type())); extent.type()));
error = B_ERROR; status = B_ERROR;
break; break;
} }
if (!error) { if (status != B_OK)
break;
// Note the unmapped first block of the total read in // Note the unmapped first block of the total read in
// the block output parameter if provided // the block output parameter if provided
if (isFirstBlock) { if (isFirstBlock) {
@@ -193,54 +199,60 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
*block = extent.block(); *block = extent.block();
} }
off_t blockOffset = pos - off_t((pos >> volume->BlockShift()) off_t blockOffset
<< volume->BlockShift()); = pos - off_t((pos >> volume->BlockShift()) << volume->BlockShift());
size_t fullBlocksLeft = bytesLeft >> volume->BlockShift(); size_t fullBlocksLeft = bytesLeft >> volume->BlockShift();
if (fullBlocksLeft > 0 && blockOffset == 0) { if (fullBlocksLeft > 0 && blockOffset == 0) {
TRACE(("Icb::_Read(): reading full block (or more)\n")); TRACE(("Icb::_Read(): reading full block (or more)\n"));
// Block aligned and at least one full block left. Read // Block aligned and at least one full block left. Read
// in using cached_read() calls. // in using block_cache_get_etc() calls.
off_t diskBlock; off_t diskBlock;
error = volume->MapBlock(extent, &diskBlock); status = volume->MapBlock(extent, &diskBlock);
if (!error) { if (status != B_OK) {
size_t fullBlockBytesLeft = TRACE_ERROR(("Icb::_Read: could not map extent\n"));
fullBlocksLeft << volume->BlockShift(); break;
}
size_t fullBlockBytesLeft = fullBlocksLeft << volume->BlockShift();
size_t readLength = fullBlockBytesLeft < extent.length() size_t readLength = fullBlockBytesLeft < extent.length()
? fullBlockBytesLeft : extent.length(); ? fullBlockBytesLeft : extent.length();
if (isEmpty) { if (isEmpty) {
TRACE(("Icb::_Read(): reading %ld empty bytes " TRACE(("Icb::_Read(): reading %ld empty bytes as zeros\n",
"as zeros\n", readLength)); readLength));
memset(buffer, 0, readLength); memset(buffer, 0, readLength);
} else { } else {
off_t diskBlock; off_t diskBlock;
error = volume->MapBlock(extent, &diskBlock); status = volume->MapBlock(extent, &diskBlock);
if (!error) { if (status != B_OK) {
TRACE(("Icb::_Read(): reading %ld bytes from " TRACE_ERROR(("Icb::_Read: could not map extent\n"));
"disk block %Ld using cached_read()\n", break;
readLength, diskBlock));
size_t length = readLength >> volume->BlockShift();
error = file_cache_read(volume->BlockCache(),
NULL, pos, buffer, &length);
} }
TRACE(("Icb::_Read(): reading %ld bytes from disk block %Ld "
"using block_cache_get_etc()\n", readLength, diskBlock));
size_t length = readLength >> volume->BlockShift();
uint8 *data = (uint8*)block_cache_get_etc(volume->BlockCache(),
diskBlock, pos, length);
if (data == NULL) {
status = B_BAD_DATA;
break;
}
memcpy(buffer, data, length);
block_cache_put(volume->BlockCache(), diskBlock);
} }
if (!error) {
bytesLeft -= readLength; bytesLeft -= readLength;
bytesRead += readLength; bytesRead += readLength;
pos += readLength; pos += readLength;
buffer += readLength; buffer += readLength;
}
}
} else { } else {
PRINT(("partial block\n"));
off_t partialOffset; off_t partialOffset;
size_t partialLength; size_t partialLength;
if (blockOffset == 0) { if (blockOffset == 0) {
// Block aligned, but only a partial block's worth remaining. Read // Block aligned, but only a partial block's worth remaining.
// in remaining bytes of file // Read in remaining bytes of file
partialOffset = 0; partialOffset = 0;
partialLength = bytesLeft; partialLength = bytesLeft;
} else { } else {
@@ -250,46 +262,41 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
if (bytesLeft < partialLength) if (bytesLeft < partialLength)
partialLength = bytesLeft; partialLength = bytesLeft;
} }
TRACE(("Icb::_Read: reading partial block. partialOffset = %Ld, "
PRINT(("partialOffset: %Ld\n", partialOffset)); "partialLength: %ld\n",partialOffset, partialLength));
PRINT(("partialLength: %ld\n", partialLength));
if (isEmpty) { if (isEmpty) {
PRINT(("reading %ld empty bytes as zeros\n", partialLength)); TRACE(("Icb::_Read: reading %ld empty bytes as zeros\n",
partialLength));
memset(buffer, 0, partialLength); memset(buffer, 0, partialLength);
} else { } else {
off_t diskBlock; off_t diskBlock;
error = volume->MapBlock(extent, &diskBlock); status = volume->MapBlock(extent, &diskBlock);
if (!error) { if (status != B_OK) {
PRINT(("reading %ld bytes from disk block %Ld using get_block()\n", TRACE_ERROR(("Icb::_Read: could not map extent\n"));
partialLength, diskBlock)); break;
uint8 *data = (uint8*)block_cache_get_etc((void*)volume->BlockCache(), diskBlock, 0, partialLength); }
error = data ? B_OK : B_BAD_DATA;
if (!error) { TRACE(("Icb::_Read: %ld bytes from disk block %Ld using "
memcpy(buffer, data+partialOffset, partialLength); "block_cache_get_etc()\n", partialLength, diskBlock));
block_cache_put(volume->BlockCache(), 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);
} }
if (!error) {
bytesLeft -= partialLength; bytesLeft -= partialLength;
bytesRead += partialLength; bytesRead += partialLength;
pos += partialLength; pos += partialLength;
buffer += partialLength; buffer += partialLength;
} }
} }
}
} else {
PRINT(("error finding extent for offset %Ld: 0x%lx, `%s'", pos,
error, strerror(error)));
break;
}
}
*length = bytesRead; *length = bytesRead;
RETURN(error); return status;
} }
@@ -40,8 +40,7 @@ Volume::~Volume()
/*! \brief Attempts to mount the given device. /*! \brief Attempts to mount the given device.
\param volumeStart The block on the given device whereat the volume begins. \param lenght The length of the device in number of blocks
\param volumeLength The block length of the volume on the given device.
*/ */
status_t status_t
Volume::Mount(const char *deviceName, off_t offset, off_t length, Volume::Mount(const char *deviceName, off_t offset, off_t length,
@@ -282,6 +281,7 @@ Volume::Mount(const char *deviceName, off_t offset, off_t length,
RETURN(status); RETURN(status);
} }
const char* const char*
Volume::Name() const { Volume::Name() const {
return fName.Utf8(); return fName.Utf8();