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

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

Author: mmlr
Date: 2010-02-28 08:50:28 +0100 (Sun, 28 Feb 2010)
New Revision: 35652
Changeset: http://dev.haiku-os.org/changeset/35652/haiku

Modified:
   haiku/trunk/src/add-ons/kernel/file_systems/udf/AllocationDescriptorList.h
   haiku/trunk/src/add-ons/kernel/file_systems/udf/Icb.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/udf/Icb.h
   haiku/trunk/src/add-ons/kernel/file_systems/udf/UdfDebug.h
   haiku/trunk/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp
Log:
* Implement udf_io and udf_get_file_map.
* Add file map and cache and do reads through the file_cache for file ICBs.
* Move the private _Read() backend from the header to the implementation file.
* Read() is now only used for directory iteration.
* Turned off the verbose debug output.
* Minor cleanup.

This fixes the abuse of the block_cache, should allow executables on UDF and
won't panic on protected content.


Modified: 
haiku/trunk/src/add-ons/kernel/file_systems/udf/AllocationDescriptorList.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/udf/AllocationDescriptorList.h  
2010-02-28 05:35:31 UTC (rev 35651)
+++ haiku/trunk/src/add-ons/kernel/file_systems/udf/AllocationDescriptorList.h  
2010-02-28 07:50:28 UTC (rev 35652)
@@ -39,7 +39,7 @@
                                                                Accessor 
accessor = Accessor());
 
        status_t                                FindExtent(off_t start, 
long_address *extent,
-                                                               bool *isEmpty); 
+                                                               bool *isEmpty);
 
 private:
 
@@ -172,7 +172,7 @@
                return B_ENTRY_NOT_FOUND;
 
        // Increment our indices and get the next descriptor
-       // from this extent. 
+       // from this extent.
        fBlockIndex += fAccessor.GetLength(*descriptor);
        fDescriptorIndex++;
        fDescriptorNumber++;

Modified: haiku/trunk/src/add-ons/kernel/file_systems/udf/Icb.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/udf/Icb.cpp     2010-02-28 
05:35:31 UTC (rev 35651)
+++ haiku/trunk/src/add-ons/kernel/file_systems/udf/Icb.cpp     2010-02-28 
07:50:28 UTC (rev 35652)
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------
-//  This software is part of the Haiku distribution and is covered 
+//  This software is part of the Haiku distribution and is covered
 //  by the MIT license.
 //
 //  Copyright (c) 2003 Tyler Dauwalder, tyler@xxxxxxxxxxxxx
@@ -12,10 +12,12 @@
 #include "Utils.h"
 #include "Volume.h"
 
+#include <file_cache.h>
 
+
 status_t
 DirectoryIterator::GetNextEntry(char *name, uint32 *length, ino_t *id)
-{      
+{
        if (!id || !name || !length)
                return B_BAD_VALUE;
 
@@ -103,7 +105,9 @@
        fInitStatus(B_NO_INIT),
        fId(to_vnode_id(address)),
        fFileEntry(&fData),
-       fExtendedEntry(&fData)
+       fExtendedEntry(&fData),
+       fFileCache(NULL),
+       fFileMap(NULL)
 {
        TRACE(("Icb::Icb: volume = %p, address(block = %ld, partition = %d, "
                "length = %ld)\n", volume, address.block(), address.partition(),
@@ -130,11 +134,25 @@
                status = header->tag().init_check(address.block());
        }
 
+       if (IsFile()) {
+               fFileCache = file_cache_create(fVolume->ID(), fId, Length());
+               fFileMap = file_map_create(fVolume->ID(), fId, Length());
+       }
+
        fInitStatus = status;
        TRACE(("Icb::Icb: status = 0x%lx, `%s'\n", status, strerror(status)));
 }
 
 
+Icb::~Icb()
+{
+       if (fFileCache != NULL) {
+               file_cache_delete(fFileCache);
+               file_map_delete(fFileMap);
+       }
+}
+
+
 status_t
 Icb::GetDirectoryIterator(DirectoryIterator **iterator)
 {
@@ -187,6 +205,9 @@
                return B_OK;
        }
 
+       if (fFileCache != NULL)
+               return file_cache_read(fFileCache, NULL, pos, buffer, length);
+
        switch (_IcbTag().descriptor_flags()) {
                case ICB_DESCRIPTOR_TYPE_SHORT: {
                        TRACE(("Icb::Read: descriptor type -> short\n"));
@@ -194,7 +215,7 @@
                        RETURN(_Read(list, pos, buffer, length, block));
                        break;
                }
-       
+
                case ICB_DESCRIPTOR_TYPE_LONG: {
                        TRACE(("Icb::Read: descriptor type -> long\n"));
                        AllocationDescriptorList<LongDescriptorAccessor> 
list(this);
@@ -220,12 +241,205 @@
                        TRACE(("Icb::Read: invalid icb descriptor flags! (flags 
= %d)\n",
                                _IcbTag().descriptor_flags()));
                        RETURN(B_BAD_VALUE);
-                       break;          
+                       break;
        }
 }
 
 
+/*! \brief Does the dirty work of reading using the given DescriptorList object
+       to access the allocation descriptors properly.
+*/
+template <class DescriptorList>
 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 = 
%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 status = B_OK;
+       uint8 *buffer = (uint8 *)_buffer;
+       bool isFirstBlock = true;
+
+       while (bytesLeft > 0) {
+
+               TRACE(("Icb::_Read(): pos: %Ld, bytesLeft: %ld\n", pos, 
bytesLeft));
+               long_address extent;
+               bool isEmpty = false;
+               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 readLength = volume->BlockSize() - blockOffset;
+               if (bytesLeft < readLength)
+                       readLength = bytesLeft;
+               if (extent.length() < readLength)
+                       readLength = 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",
+                               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: %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);
+               }
+
+               bytesLeft -= readLength;
+               bytesRead += readLength;
+               pos += readLength;
+               buffer += readLength;
+       }
+
+       *length = bytesRead;
+
+       return status;
+}
+
+
+status_t
+Icb::GetFileMap(off_t offset, size_t size, file_io_vec *vecs, size_t *count)
+{
+       switch (_IcbTag().descriptor_flags()) {
+               case ICB_DESCRIPTOR_TYPE_SHORT:
+               {
+                       AllocationDescriptorList<ShortDescriptorAccessor> 
list(this,
+                               ShortDescriptorAccessor(0));
+                       return _GetFileMap(list, offset, size, vecs, count);
+               }
+
+               case ICB_DESCRIPTOR_TYPE_LONG:
+               {
+                       AllocationDescriptorList<LongDescriptorAccessor> 
list(this);
+                       return _GetFileMap(list, offset, size, vecs, count);
+               }
+
+               case ICB_DESCRIPTOR_TYPE_EXTENDED:
+               case ICB_DESCRIPTOR_TYPE_EMBEDDED:
+               default:
+               {
+                       // TODO: implement?
+                       return B_UNSUPPORTED;
+               }
+       }
+}
+
+
+template<class DescriptorList>
+status_t
+Icb::_GetFileMap(DescriptorList &list, off_t offset, size_t size,
+       struct file_io_vec *vecs, size_t *count)
+{
+       size_t index = 0;
+       size_t max = *count;
+
+       while (true) {
+               long_address extent;
+               bool isEmpty = false;
+               status_t status = list.FindExtent(offset, &extent, &isEmpty);
+               if (status != B_OK)
+                       return status;
+
+               switch (extent.type()) {
+                       case EXTENT_TYPE_RECORDED:
+                               isEmpty = false;
+                               break;
+
+                       case EXTENT_TYPE_ALLOCATED:
+                       case EXTENT_TYPE_UNALLOCATED:
+                               isEmpty = true;
+                               break;
+
+                       default:
+                               return B_ERROR;
+               }
+
+               if (isEmpty)
+                       vecs[index].offset = -1;
+               else {
+                       off_t diskBlock;
+                       fVolume->MapBlock(extent, &diskBlock);
+                       vecs[index].offset = diskBlock << fVolume->BlockShift();
+               }
+
+               off_t length = extent.length();
+               vecs[index].length = length;
+
+               offset += length;
+               size -= length;
+               index++;
+
+               if (index >= max || size <= vecs[index - 1].length
+                       || offset >= (off_t)Length()) {
+                       *count = index;
+                       return index >= max ? B_BUFFER_OVERFLOW : B_OK;
+               }
+       }
+
+       // can never get here
+       return B_ERROR;
+}
+
+
+status_t
 Icb::Find(const char *filename, ino_t *id)
 {
        TRACE(("Icb::Find: filename = `%s', id = %p\n", filename, id));

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 
05:35:31 UTC (rev 35651)
+++ haiku/trunk/src/add-ons/kernel/file_systems/udf/Icb.h       2010-02-28 
07:50:28 UTC (rev 35652)
@@ -79,6 +79,8 @@
 class Icb {
 public:
                                                                Icb(Volume 
*volume, long_address address);
+                                                               ~Icb();
+
        status_t                                        InitCheck();
        ino_t                                           Id() { return fId; }
 
@@ -105,6 +107,12 @@
        status_t                                        Read(off_t pos, void 
*buffer, size_t *length,
                                                                        uint32 
*block = NULL);
 
+       void *                                          FileCache() { return 
fFileCache; }
+       void *                                          FileMap() { return 
fFileMap; }
+
+       status_t                                        GetFileMap(off_t 
offset, size_t size,
+                                                                       struct 
file_io_vec *vecs, size_t *count);
+
        // for directories only
        status_t                                        
GetDirectoryIterator(DirectoryIterator **iterator);
        status_t                                        Find(const char 
*filename, ino_t *id);
@@ -114,7 +122,7 @@
 private:
        AbstractFileEntry                       *_AbstractEntry() { return 
(_Tag().id()
                                                                        == 
TAGID_EXTENDED_FILE_ENTRY)
-                                                                       ? 
(AbstractFileEntry *)&fExtendedEntry 
+                                                                       ? 
(AbstractFileEntry *)&fExtendedEntry
                                                                        : 
(AbstractFileEntry *)&fFileEntry; }
 
        descriptor_tag                          &_Tag() { return ((icb_header 
*)fData.Block())->tag(); }
@@ -122,130 +130,26 @@
        file_icb_entry                          *_FileEntry() { return 
(file_icb_entry *)fData.Block(); }
        extended_file_icb_entry         &_ExtendedEntry() { return 
*(extended_file_icb_entry *)fData.Block(); }
 
-       template <class DescriptorList>
+       template<class DescriptorList>
+       status_t                                        
_GetFileMap(DescriptorList &list, off_t offset,
+                                                                       size_t 
size, struct file_io_vec *vecs,
+                                                                       size_t 
*count);
+       template<class DescriptorList>
        status_t                                        _Read(DescriptorList 
&list, off_t pos,
                                                                        void 
*buffer, size_t *length, uint32 *block);
 
-private:
        Volume                                          *fVolume;
        CachedBlock                                     fData;
        status_t                                        fInitStatus;
        ino_t                                           fId;
        SinglyLinkedList<DirectoryIterator>             fIteratorList;
        FileEntry<file_icb_entry>                               fFileEntry;
-       FileEntry<extended_file_icb_entry>              fExtendedEntry; 
+       FileEntry<extended_file_icb_entry>              fExtendedEntry;
+       void *                                          fFileCache;
+       void *                                          fFileMap;
 };
 
 
-/*! \brief Does the dirty work of reading using the given DescriptorList object
-       to access the allocation descriptors properly.
-*/
-template <class DescriptorList>
-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 = 
%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 status = B_OK;
-       uint8 *buffer = (uint8 *)_buffer;
-       bool isFirstBlock = true;
-
-       while (bytesLeft > 0) {
-
-               TRACE(("Icb::_Read(): pos: %Ld, bytesLeft: %ld\n", pos, 
bytesLeft));
-               long_address extent;
-               bool isEmpty = false;
-               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 readLength = volume->BlockSize() - blockOffset;
-               if (bytesLeft < readLength)
-                       readLength = bytesLeft;
-               if (extent.length() < readLength)
-                       readLength = 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",
-                               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: %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);
-               }
-
-               bytesLeft -= readLength;
-               bytesRead += readLength;
-               pos += readLength;
-               buffer += readLength;
-       }                                
-       
-       *length = bytesRead;
-       
-       return status;
-}
-
-
 template <class Descriptor>
 FileEntry<Descriptor>::FileEntry(CachedBlock *descriptorBlock)
        : fDescriptorBlock(descriptorBlock)

Modified: haiku/trunk/src/add-ons/kernel/file_systems/udf/UdfDebug.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/udf/UdfDebug.h  2010-02-28 
05:35:31 UTC (rev 35651)
+++ haiku/trunk/src/add-ons/kernel/file_systems/udf/UdfDebug.h  2010-02-28 
07:50:28 UTC (rev 35652)
@@ -1,5 +1,5 @@
 //----------------------------------------------------------------------
-//  This software is part of the OpenBeOS distribution and is covered 
+//  This software is part of the OpenBeOS distribution and is covered
 //  by the OpenBeOS license.
 //
 //  This version copyright (c) 2003 Tyler Dauwalder, tyler@xxxxxxxxxxxxx
@@ -31,15 +31,15 @@
 #      include <stdarg.h>
 extern "C" int         vsprintf(char *s, const char *format, va_list arg);
 #      include <fcntl.h>
-#      define __out dbg_printf         
+#      define __out dbg_printf
        void dbg_printf(const char *format,...);
        void initialize_debugger(const char *filename);
 #else
-#      if !_KERNEL_MODE 
-//#            include <stdio.h> 
-#              define __out printf 
-#      else 
-//#            include <null.h> 
+#      if !_KERNEL_MODE
+//#            include <stdio.h>
+#              define __out printf
+#      else
+//#            include <null.h>
 #              define __out dprintf
 #      endif
 #      include <stdio.h>
@@ -64,10 +64,10 @@
 public:
        DebugHelper(const char *className = NULL, uint8 tabCount = 1);
        ~DebugHelper();
-       
+
        uint8 TabCount() const { return fTabCount; }
        const char* ClassName() const { return fClassName; }
-       
+
 private:
        uint8 fTabCount;
        char *fClassName;
@@ -98,14 +98,14 @@
        #else
                #define INITIALIZE_DEBUGGING_OUTPUT_FILE(filename) ;
        #endif
-       
+
        #define DEBUG_INIT_SILENT(className)                    \
-               DebugHelper _debugHelper(className, 2);                 
+               DebugHelper _debugHelper(className, 2);
 
        #define DEBUG_INIT(className)           \
                DEBUG_INIT_SILENT(className);   \
                PRINT(("\n"));
-               
+
        #define DEBUG_INIT_ETC(className, arguments)                            
                        \
                DEBUG_INIT_SILENT(className)                                    
                                        \
                {                                                               
                                                                        \
@@ -119,10 +119,10 @@
                        __out arguments;                                        
                                                        \
                        __out("):\n");                                          
                                                        \
                }
-               
+
        #define DUMP_INIT(className)    \
-               DEBUG_INIT_SILENT(className);   
-                               
+               DEBUG_INIT_SILENT(className);
+
        #define PRINT(x) {                                                      
                                                        \
                {                                                               
                                                                        \
                        PRINT_INDENT();                                         
                                                        \
@@ -164,21 +164,21 @@
                        }                                                       
                                                \
                }                                                               
                                                \
        }
-       
+
        #define PRINT_DIVIDER() \
                PRINT_INDENT();         \
                
SIMPLE_PRINT(("------------------------------------------------------------\n"));
-               
+
        #define DUMP(object)                            \
                {                                                               
\
                        (object).dump();                        \
-               }               
-       
+               }
+
        #define PDUMP(objectPointer)            \
                {                                                               
\
                        (objectPointer)->dump();        \
-               }               
-       
+               }
+
        #define REPORT_ERROR(error) {                                           
                                        \
                LPRINT(("returning error 0x%lx, `%s'\n", error, 
strerror(error)));      \
        }
@@ -205,9 +205,9 @@
        #define FATAL(x) {                                                      
        \
                PRINT(("fatal error: ")); SIMPLE_PRINT(x);      \
        }
-       
+
        #define DBG(x) x ;
-       
+
 #else  // ifdef DEBUG
        #define INITIALIZE_DEBUGGING_OUTPUT_FILE(filename) ;
        #define DEBUG_INIT_SILENT(className)    ;
@@ -228,7 +228,7 @@
        #define DBG(x) ;
 #endif // ifdef DEBUG else
 
-#define TRACE(x) dprintf x
+#define TRACE(x) /*dprintf x*/
 #define TRACE_ERROR(x) dprintf x
 
 // These macros turn on or off extensive and generally unnecessary

Modified: haiku/trunk/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp        
2010-02-28 05:35:31 UTC (rev 35651)
+++ haiku/trunk/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp        
2010-02-28 07:50:28 UTC (rev 35652)
@@ -16,6 +16,8 @@
 #include <KernelExport.h>
 #include <util/kernel_cpp.h>
 
+#include <io_requests.h>
+
 #include "Icb.h"
 #include "Recognition.h"
 #include "Utils.h"
@@ -37,6 +39,28 @@
 extern fs_vnode_ops gUDFVnodeOps;
 
 
+//     #pragma mark - io callbacks
+
+
+static status_t
+iterative_io_get_vecs_hook(void *cookie, io_request *request, off_t offset,
+       size_t size, struct file_io_vec *vecs, size_t *count)
+{
+       Icb *icb = (Icb *)cookie;
+       return file_map_translate(icb->FileMap(), offset, size, vecs, count,
+               icb->GetVolume()->BlockSize());
+}
+
+
+static status_t
+iterative_io_finished_hook(void *cookie, io_request *request, status_t status,
+       bool partialTransfer, size_t bytesTransferred)
+{
+       // nothing to do
+       return B_OK;
+}
+
+
 //     #pragma mark - fs_volume_ops fuctions
 
 
@@ -266,7 +290,7 @@
 
 static status_t
 udf_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie)
-{      
+{
        TRACE(("udf_free_cookie: _volume = %p, _node = %p\n", _volume, _node));
        return B_OK;
 }
@@ -274,7 +298,7 @@
 
 static status_t
 udf_access(fs_volume* _volume, fs_vnode* _node, int accessMode)
-{      
+{
        TRACE(("udf_access: _volume = %p, _node = %p\n", _volume, _node));
        return B_OK;
 }
@@ -299,6 +323,34 @@
 
 
 static status_t
+udf_io(fs_volume *volume, fs_vnode *vnode, void *cookie, io_request *request)
+{
+       if (io_request_is_write(request)) {
+               notify_io_request(request, B_READ_ONLY_DEVICE);
+               return B_READ_ONLY_DEVICE;
+       }
+
+       Icb *icb = (Icb *)vnode->private_node;
+       if (icb->FileCache() == NULL) {
+               notify_io_request(request, B_BAD_VALUE);
+               return B_BAD_VALUE;
+       }
+
+       return do_iterative_fd_io(((Volume *)volume->private_volume)->Device(),
+               request, iterative_io_get_vecs_hook, 
iterative_io_finished_hook, icb);
+}
+
+
+static status_t
+udf_get_file_map(fs_volume *_volume, fs_vnode *vnode, off_t offset, size_t 
size,
+       struct file_io_vec *vecs, size_t *count)
+{
+       Icb *icb = (Icb *)vnode->private_node;
+       return icb->GetFileMap(offset, size, vecs, count);
+}
+
+
+static status_t
 udf_open_dir(fs_volume *volume, fs_vnode *vnode, void **cookie)
 {
        TRACE(("udf_open_dir: volume = %p, vnode = %p\n", volume, vnode));
@@ -568,11 +620,11 @@
        NULL,   // write_pages
 
        /* asynchronous I/O */
-       NULL,   // io()
+       &udf_io,
        NULL,   // cancel_io()
 
        /* cache file access */
-       NULL,   // &udf_get_file_map,
+       &udf_get_file_map,
 
        /* common operations */
        NULL,   // ioctl


Other related posts:

  • » [haiku-commits] r35652 - haiku/trunk/src/add-ons/kernel/file_systems/udf - mmlr