[haiku-commits] r35651 - haiku/trunk/src/add-ons/kernel/file_systems/udf

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 28 Feb 2010 06:35:31 +0100 (CET)

Author: mmlr
Date: 2010-02-28 06:35:31 +0100 (Sun, 28 Feb 2010)
New Revision: 35651
Changeset: http://dev.haiku-os.org/changeset/35651/haiku

Modified:
   haiku/trunk/src/add-ons/kernel/file_systems/udf/Icb.h
Log:
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).


Modified: haiku/trunk/src/add-ons/kernel/file_systems/udf/Icb.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/udf/Icb.h       2010-02-28 
00:50:01 UTC (rev 35650)
+++ haiku/trunk/src/add-ons/kernel/file_systems/udf/Icb.h       2010-02-28 
05:35:31 UTC (rev 35651)
@@ -203,12 +203,20 @@
                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.
+               TRACE(("Icb::_Read: reading block. offset = %Ld, length: %ld\n",
+                       blockOffset, readLength));
+
+               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) {
@@ -216,83 +224,20 @@
                                break;
                        }
 
-                       size_t fullBlockBytesLeft = fullBlocksLeft << 
volume->BlockShift();
-                       size_t readLength = fullBlockBytesLeft < extent.length()
-                               ? fullBlockBytesLeft : extent.length();
+                       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, 0, readLength);
+                       if (data == NULL)
+                               break;
+                       memcpy(buffer, data + blockOffset, readLength);
+                       block_cache_put(volume->BlockCache(), diskBlock);
+               }
 
-                       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;
-               }                                       
+               bytesLeft -= readLength;
+               bytesRead += readLength;
+               pos += readLength;
+               buffer += readLength;
        }                                
        
        *length = bytesRead;


Other related posts: