From 9fd15595d64d2ef4a28eca7ccd711eb4218ac67e Mon Sep 17 00:00:00 2001 From: Salvatore Benedetto Date: Fri, 22 Aug 2008 19:19:35 +0000 Subject: [PATCH] * 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 --- src/add-ons/kernel/file_systems/udf/Icb.h | 267 +++++++++--------- .../kernel/file_systems/udf/Volume.cpp | 4 +- 2 files changed, 139 insertions(+), 132 deletions(-) diff --git a/src/add-ons/kernel/file_systems/udf/Icb.h b/src/add-ons/kernel/file_systems/udf/Icb.h index 52ec11e30b..ab18257c9f 100644 --- a/src/add-ons/kernel/file_systems/udf/Icb.h +++ b/src/add-ons/kernel/file_systems/udf/Icb.h @@ -143,153 +143,160 @@ template status_t 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", - &list, pos, _buffer, length, (length ? *length : 0))); + TRACE(("Icb::_Read(): list = %p, pos = %Ld, buffer = %p, length = %ld\n", + &list, pos, _buffer, (length ? *length : 0))); uint64 bytesLeftInFile = uint64(pos) > Length() ? 0 : Length() - pos; size_t bytesLeft = (*length >= bytesLeftInFile) ? bytesLeftInFile : *length; size_t bytesRead = 0; Volume *volume = GetVolume(); - status_t error = B_OK; + status_t status = B_OK; uint8 *buffer = (uint8 *)_buffer; bool isFirstBlock = true; - while (bytesLeft > 0 && !error) { - - TRACE(("Icb::_Read(): pos: %Ld\n, bytesLeft: %ld\n", pos, bytesLeft)); + while (bytesLeft > 0) { + TRACE(("Icb::_Read(): pos: %Ld, bytesLeft: %ld\n", pos, bytesLeft)); long_address extent; bool isEmpty = false; - error = list.FindExtent(pos, &extent, &isEmpty); - if (!error) { - TRACE(("Icb::_Read(): found extent for offset %Ld: (block: %ld, " - "partition: %d, length: %ld, type: %d)\n", pos, extent.block(), - extent.partition(), extent.length(), extent.type())); - - switch (extent.type()) { - case EXTENT_TYPE_RECORDED: - isEmpty = false; - break; - - case EXTENT_TYPE_ALLOCATED: - case EXTENT_TYPE_UNALLOCATED: - isEmpty = true; - break; - - default: - TRACE_ERROR(("Icb::_Read(): Invalid extent type " - "found: %d\n", extent.type())); - error = B_ERROR; - break; - } - - if (!error) { - // Note the unmapped first block of the total read in - // the block output parameter if provided - if (isFirstBlock) { - isFirstBlock = false; - if (block) - *block = extent.block(); - } - - off_t blockOffset = pos - off_t((pos >> volume->BlockShift()) - << volume->BlockShift()); - size_t fullBlocksLeft = bytesLeft >> volume->BlockShift(); - - 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 cached_read() calls. - off_t diskBlock; - error = volume->MapBlock(extent, &diskBlock); - if (!error) { - size_t fullBlockBytesLeft = - fullBlocksLeft << volume->BlockShift(); - size_t readLength = fullBlockBytesLeft < extent.length() - ? fullBlockBytesLeft : extent.length(); - - if (isEmpty) { - TRACE(("Icb::_Read(): reading %ld empty bytes " - "as zeros\n", readLength)); - memset(buffer, 0, readLength); - } else { - off_t diskBlock; - error = volume->MapBlock(extent, &diskBlock); - if (!error) { - TRACE(("Icb::_Read(): reading %ld bytes from " - "disk block %Ld using cached_read()\n", - readLength, diskBlock)); - size_t length = readLength >> volume->BlockShift(); - error = file_cache_read(volume->BlockCache(), - NULL, pos, buffer, &length); - } - } - - if (!error) { - bytesLeft -= readLength; - bytesRead += readLength; - pos += readLength; - buffer += readLength; - } - } - - } else { - PRINT(("partial block\n")); - 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; - } - - PRINT(("partialOffset: %Ld\n", partialOffset)); - PRINT(("partialLength: %ld\n", partialLength)); - - if (isEmpty) { - PRINT(("reading %ld empty bytes as zeros\n", partialLength)); - memset(buffer, 0, partialLength); - } else { - off_t diskBlock; - error = volume->MapBlock(extent, &diskBlock); - if (!error) { - PRINT(("reading %ld bytes from disk block %Ld using get_block()\n", - partialLength, diskBlock)); - uint8 *data = (uint8*)block_cache_get_etc((void*)volume->BlockCache(), diskBlock, 0, partialLength); - error = data ? B_OK : B_BAD_DATA; - if (!error) { - memcpy(buffer, data+partialOffset, partialLength); - block_cache_put(volume->BlockCache(), diskBlock); - } - } - } - - if (!error) { - bytesLeft -= partialLength; - bytesRead += partialLength; - pos += partialLength; - buffer += partialLength; - } - } - } - } else { - PRINT(("error finding extent for offset %Ld: 0x%lx, `%s'", pos, - error, strerror(error))); + status = list.FindExtent(pos, &extent, &isEmpty); + 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, " + "partition: %d, length: %ld, type: %d)\n", pos, extent.block(), + extent.partition(), extent.length(), extent.type())); + + switch (extent.type()) { + case EXTENT_TYPE_RECORDED: + isEmpty = false; + break; + + case EXTENT_TYPE_ALLOCATED: + case EXTENT_TYPE_UNALLOCATED: + isEmpty = true; + break; + + default: + TRACE_ERROR(("Icb::_Read(): Invalid extent type found: %d\n", + extent.type())); + status = B_ERROR; + break; + } + + if (status != B_OK) + break; + + // Note the unmapped first block of the total read in + // the block output parameter if provided + if (isFirstBlock) { + isFirstBlock = false; + if (block) + *block = extent.block(); + } + + off_t blockOffset + = pos - off_t((pos >> volume->BlockShift()) << volume->BlockShift()); + + size_t fullBlocksLeft = bytesLeft >> volume->BlockShift(); + + 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(); + + if (isEmpty) { + TRACE(("Icb::_Read(): reading %ld empty bytes as zeros\n", + readLength)); + memset(buffer, 0, readLength); + } 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(): 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); + } + + bytesLeft -= readLength; + 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; - RETURN(error); + return status; } diff --git a/src/add-ons/kernel/file_systems/udf/Volume.cpp b/src/add-ons/kernel/file_systems/udf/Volume.cpp index 2b917cc4aa..9e5d2da1d0 100644 --- a/src/add-ons/kernel/file_systems/udf/Volume.cpp +++ b/src/add-ons/kernel/file_systems/udf/Volume.cpp @@ -40,8 +40,7 @@ Volume::~Volume() /*! \brief Attempts to mount the given device. - \param volumeStart The block on the given device whereat the volume begins. - \param volumeLength The block length of the volume on the given device. + \param lenght The length of the device in number of blocks */ status_t 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); } + const char* Volume::Name() const { return fName.Utf8();