[haiku-commits] r34138 - in haiku/trunk/src: add-ons/kernel/file_systems/packagefs bin/package

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 19 Nov 2009 17:31:16 +0100 (CET)

Author: bonefish
Date: 2009-11-19 17:31:16 +0100 (Thu, 19 Nov 2009)
New Revision: 34138
Changeset: http://dev.haiku-os.org/changeset/34138/haiku

Modified:
   haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Directory.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Directory.h
   haiku/trunk/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/packagefs/LeafNode.h
   haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Node.h
   haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageFile.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageFile.h
   haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.h
   haiku/trunk/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp
   haiku/trunk/src/bin/package/PackageDataReader.cpp
   haiku/trunk/src/bin/package/PackageDataReader.h
Log:
* Added method PackageDataReader::ReadDataToOutput(), which writes the read
  data to a DataOutput.
* Implemented packagefs' io() hook and changed the read() hook implementation
  to use the file cache. It's now possible to mmap() files and thus execute
  programs.


Modified: haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Directory.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Directory.cpp 
2009-11-19 16:26:40 UTC (rev 34137)
+++ haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Directory.cpp 
2009-11-19 16:31:16 UTC (rev 34138)
@@ -125,6 +125,13 @@
 }
 
 
+status_t
+Directory::Read(io_request* request)
+{
+       return B_IS_A_DIRECTORY;
+}
+
+
 void
 Directory::AddChild(Node* node)
 {

Modified: haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Directory.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Directory.h   
2009-11-19 16:26:40 UTC (rev 34137)
+++ haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Directory.h   
2009-11-19 16:31:16 UTC (rev 34138)
@@ -46,6 +46,7 @@
 
        virtual status_t                        Read(off_t offset, void* buffer,
                                                                        size_t* 
bufferSize);
+       virtual status_t                        Read(io_request* request);
 
                        void                            AddChild(Node* node);
                        void                            RemoveChild(Node* node);

Modified: haiku/trunk/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp  
2009-11-19 16:26:40 UTC (rev 34137)
+++ haiku/trunk/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp  
2009-11-19 16:31:16 UTC (rev 34138)
@@ -118,6 +118,15 @@
 }
 
 
+status_t
+LeafNode::Read(io_request* request)
+{
+       if (PackageLeafNode* packageNode = fPackageNodes.Head())
+               return packageNode->Read(request);
+       return EBADF;
+}
+
+
 const char*
 LeafNode::SymlinkPath() const
 {

Modified: haiku/trunk/src/add-ons/kernel/file_systems/packagefs/LeafNode.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/packagefs/LeafNode.h    
2009-11-19 16:26:40 UTC (rev 34137)
+++ haiku/trunk/src/add-ons/kernel/file_systems/packagefs/LeafNode.h    
2009-11-19 16:31:16 UTC (rev 34138)
@@ -32,6 +32,7 @@
 
        virtual status_t                        Read(off_t offset, void* buffer,
                                                                        size_t* 
bufferSize);
+       virtual status_t                        Read(io_request* request);
 
                        const char*                     SymlinkPath() const;
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Node.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Node.h        
2009-11-19 16:26:40 UTC (rev 34137)
+++ haiku/trunk/src/add-ons/kernel/file_systems/packagefs/Node.h        
2009-11-19 16:31:16 UTC (rev 34138)
@@ -57,6 +57,7 @@
 
        virtual status_t                        Read(off_t offset, void* buffer,
                                                                        size_t* 
bufferSize) = 0;
+       virtual status_t                        Read(io_request* request) = 0;
 
 protected:
                        rw_lock                         fLock;

Modified: haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageFile.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageFile.cpp       
2009-11-19 16:26:40 UTC (rev 34137)
+++ haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageFile.cpp       
2009-11-19 16:31:16 UTC (rev 34138)
@@ -11,6 +11,7 @@
 
 #include <fs_cache.h>
 
+#include "DataOutput.h"
 #include "DataReader.h"
 #include "PackageDataReader.h"
 
@@ -22,6 +23,24 @@
 // #pragma mark - DataAccessor
 
 
+struct PackageFile::IORequestOutput : DataOutput {
+public:
+       IORequestOutput(io_request* request)
+               :
+               fRequest(request)
+       {
+       }
+
+       virtual status_t WriteData(const void* buffer, size_t size)
+       {
+               RETURN_ERROR(write_to_io_request(fRequest, buffer, size));
+       }
+
+private:
+       io_request*     fRequest;
+};
+
+
 struct PackageFile::DataAccessor {
        DataAccessor(PackageData* data)
                :
@@ -73,17 +92,31 @@
                if (offset < 0 || (uint64)offset > fData->UncompressedSize())
                        return B_BAD_VALUE;
 
-               size_t toRead = std::min((uint64)*bufferSize,
+               *bufferSize = std::min((uint64)*bufferSize,
                        fData->UncompressedSize() - offset);
 
+               return file_cache_read(fFileCache, NULL, offset, buffer, 
bufferSize);
+       }
+
+       status_t ReadData(io_request* request)
+       {
+               off_t offset = io_request_offset(request);
+               size_t size = io_request_length(request);
+
+               if (offset < 0 || (uint64)offset > fData->UncompressedSize())
+                       RETURN_ERROR(B_BAD_VALUE);
+
+               size_t toRead = std::min((uint64)size,
+                       fData->UncompressedSize() - offset);
+
                if (toRead > 0) {
+                       IORequestOutput output(request);
                        MutexLocker locker(fLock);
-                       status_t error = fReader->ReadData(offset, buffer, 
toRead);
+                       status_t error = fReader->ReadDataToOutput(offset, 
toRead, &output);
                        if (error != B_OK)
                                RETURN_ERROR(error);
                }
 
-               *bufferSize = toRead;
                return B_OK;
        }
 
@@ -164,3 +197,12 @@
                return B_BAD_VALUE;
        return fDataAccessor->ReadData(offset, buffer, bufferSize);
 }
+
+
+status_t
+PackageFile::Read(io_request* request)
+{
+       if (fDataAccessor == NULL)
+               return B_BAD_VALUE;
+       return fDataAccessor->ReadData(request);
+}

Modified: haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageFile.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageFile.h 
2009-11-19 16:26:40 UTC (rev 34137)
+++ haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageFile.h 
2009-11-19 16:31:16 UTC (rev 34138)
@@ -24,8 +24,10 @@
 
        virtual status_t                        Read(off_t offset, void* buffer,
                                                                        size_t* 
bufferSize);
+       virtual status_t                        Read(io_request* request);
 
 private:
+                       struct IORequestOutput;
                        struct DataAccessor;
 
 private:

Modified: 
haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.cpp   
2009-11-19 16:26:40 UTC (rev 34137)
+++ haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.cpp   
2009-11-19 16:31:16 UTC (rev 34138)
@@ -31,3 +31,10 @@
 {
        return EBADF;
 }
+
+
+status_t
+PackageLeafNode::Read(io_request* request)
+{
+       return EBADF;
+}

Modified: 
haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.h     
2009-11-19 16:26:40 UTC (rev 34137)
+++ haiku/trunk/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.h     
2009-11-19 16:31:16 UTC (rev 34138)
@@ -8,7 +8,9 @@
 
 #include "PackageNode.h"
 
+#include <io_requests.h>
 
+
 class PackageData;
 
 
@@ -21,6 +23,7 @@
 
        virtual status_t                        Read(off_t offset, void* buffer,
                                                                        size_t* 
bufferSize);
+       virtual status_t                        Read(io_request* request);
 
 public:
                        SinglyLinkedListLink<PackageLeafNode> fListLink;

Modified: 
haiku/trunk/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp  
2009-11-19 16:26:40 UTC (rev 34137)
+++ haiku/trunk/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp  
2009-11-19 16:31:16 UTC (rev 34138)
@@ -14,6 +14,7 @@
 #include <fs_info.h>
 #include <fs_interface.h>
 #include <KernelExport.h>
+#include <io_requests.h>
 
 #include <AutoDeleter.h>
 
@@ -249,13 +250,24 @@
 // #pragma mark - Request I/O
 
 
-#if 0
 static status_t
-packagefs_io(fs_volume* volume, fs_vnode* vnode, void* cookie,
+packagefs_io(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
        io_request* request)
 {
+       Volume* volume = (Volume*)fsVolume->private_volume;
+       Node* node = (Node*)fsNode->private_node;
+
+       FUNCTION("volume: %p, node: %p (%lld), cookie: %p, request: %p\n", 
volume,
+               node, node->ID(), cookie, request);
+       TOUCH(volume);
+
+       if (io_request_is_write(request))
+               RETURN_ERROR(B_READ_ONLY_DEVICE);
+
+       status_t error = node->Read(request);
+       notify_io_request(request, error);
+       return error;
 }
-#endif
 
 
 // #pragma mark - Nodes
@@ -517,6 +529,7 @@
        Node* node = (Node*)fsNode->private_node;
 
        FUNCTION("volume: %p, node: %p (%lld)\n", volume, node, node->ID());
+       TOUCH(volume);
 
        if (!S_ISDIR(node->Mode()))
                return B_NOT_A_DIRECTORY;
@@ -702,6 +715,7 @@
        Node* node = (Node*)fsNode->private_node;
 
        FUNCTION("volume: %p, node: %p (%lld)\n", volume, node, node->ID());
+       TOUCH(volume);
 
        status_t error = check_access(node, R_OK);
        if (error != B_OK)
@@ -1087,7 +1101,7 @@
        NULL,   // read_pages,
        NULL,   // write_pages,
 
-       NULL,   // &packagefs_io,
+       &packagefs_io,
        NULL,   // cancel_io()
 
        NULL,   // get_file_map,

Modified: haiku/trunk/src/bin/package/PackageDataReader.cpp
===================================================================
--- haiku/trunk/src/bin/package/PackageDataReader.cpp   2009-11-19 16:26:40 UTC 
(rev 34137)
+++ haiku/trunk/src/bin/package/PackageDataReader.cpp   2009-11-19 16:31:16 UTC 
(rev 34138)
@@ -14,6 +14,7 @@
 #include <haiku_package.h>
 
 #include "BufferCache.h"
+#include "DataOutput.h"
 #include "PackageData.h"
 #include "ZlibDecompressor.h"
 
@@ -25,7 +26,10 @@
 // maximum number of entries in the zlib offset table buffer
 static const uint32 kMaxZlibOffsetTableBufferSize = 512;
 
+static const size_t kUncompressedReaderBufferSize
+       = B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB;
 
+
 // #pragma mark - PackageDataReader
 
 
@@ -41,14 +45,24 @@
 }
 
 
+status_t
+PackageDataReader::ReadData(off_t offset, void* buffer, size_t size)
+{
+       BufferDataOutput output(buffer, size);
+       return ReadDataToOutput(offset, size, &output);
+}
+
+
 // #pragma mark - UncompressedPackageDataReader
 
 
 class UncompressedPackageDataReader : public PackageDataReader {
 public:
-       UncompressedPackageDataReader(DataReader* dataReader)
+       UncompressedPackageDataReader(DataReader* dataReader,
+               BufferCache* bufferCache)
                :
-               PackageDataReader(dataReader)
+               PackageDataReader(dataReader),
+               fBufferCache(bufferCache)
        {
        }
 
@@ -84,9 +98,49 @@
                return fDataReader->ReadData(fOffset + offset, buffer, size);
        }
 
+       virtual status_t ReadDataToOutput(off_t offset, size_t size,
+               DataOutput* output)
+       {
+               if (size == 0)
+                       return B_OK;
+
+               if (offset < 0)
+                       return B_BAD_VALUE;
+
+               if ((uint64)offset > fSize || size > fSize - offset)
+                       return B_BAD_VALUE;
+
+               // get a temporary buffer
+               CachedBuffer* buffer = fBufferCache->GetBuffer(
+                       kUncompressedReaderBufferSize);
+               if (buffer == NULL)
+                       return B_NO_MEMORY;
+               CachedBufferPutter bufferPutter(fBufferCache, &buffer);
+
+               while (size > 0) {
+                       // read into the buffer
+                       size_t toRead = std::min(size, buffer->Size());
+                       status_t error = fDataReader->ReadData(fOffset + offset,
+                               buffer->Buffer(), toRead);
+                       if (error != B_OK)
+                               return error;
+
+                       // write to the output
+                       error = output->WriteData(buffer->Buffer(), toRead);
+                       if (error != B_OK)
+                               return error;
+
+                       offset += toRead;
+                       size -= toRead;
+               }
+
+               return B_OK;
+       }
+
 private:
-       uint64  fOffset;
-       uint64  fSize;
+       BufferCache*    fBufferCache;
+       uint64                  fOffset;
+       uint64                  fSize;
 };
 
 
@@ -161,10 +215,9 @@
                return fChunkSize;
        }
 
-       virtual status_t ReadData(off_t offset, void* _buffer, size_t size)
+       virtual status_t ReadDataToOutput(off_t offset, size_t size,
+               DataOutput* output)
        {
-               uint8* buffer = (uint8*)_buffer;
-
                // check offset and size
                if (size == 0)
                        return B_OK;
@@ -183,7 +236,8 @@
                                == NULL) {
                        return B_NO_MEMORY;
                }
-               CachedBufferPutter uncompressBuffer(fBufferCache, 
&fUncompressBuffer);
+               CachedBufferPutter uncompressBufferPutter(fBufferCache,
+                       &fUncompressBuffer);
 
                if (newBuffer)
                        fUncompressedChunk = -1;
@@ -199,12 +253,13 @@
                        if (error != B_OK)
                                return error;
 
-                       // copy data to buffer
+                       // write data to output
                        size_t toCopy = std::min(size, (size_t)fChunkSize - 
inChunkOffset);
-                       memcpy(buffer, (uint8*)fUncompressBuffer->Buffer() + 
inChunkOffset,
-                               toCopy);
+                       error = output->WriteData(
+                               (uint8*)fUncompressBuffer->Buffer() + 
inChunkOffset, toCopy);
+                       if (error != B_OK)
+                               return error;
 
-                       buffer += toCopy;
                        size -= toCopy;
 
                        chunkIndex++;
@@ -372,7 +427,7 @@
        switch (data.Compression()) {
                case B_HPKG_COMPRESSION_NONE:
                        reader = new(std::nothrow) 
UncompressedPackageDataReader(
-                               dataReader);
+                               dataReader, fBufferCache);
                        break;
                case B_HPKG_COMPRESSION_ZLIB:
                        reader = new(std::nothrow) 
ZlibPackageDataReader(dataReader,

Modified: haiku/trunk/src/bin/package/PackageDataReader.h
===================================================================
--- haiku/trunk/src/bin/package/PackageDataReader.h     2009-11-19 16:26:40 UTC 
(rev 34137)
+++ haiku/trunk/src/bin/package/PackageDataReader.h     2009-11-19 16:31:16 UTC 
(rev 34138)
@@ -10,6 +10,7 @@
 
 
 class BufferCache;
+class DataOutput;
 class PackageData;
 
 
@@ -20,6 +21,11 @@
 
        virtual status_t                        Init(const PackageData& data) = 
0;
 
+       virtual status_t                        ReadData(off_t offset, void* 
buffer,
+                                                                       size_t 
size);
+       virtual status_t                        ReadDataToOutput(off_t offset, 
size_t size,
+                                                                       
DataOutput* output) = 0;
+
        virtual uint64                          Size() const = 0;
        virtual size_t                          BlockSize() const = 0;
 


Other related posts:

  • » [haiku-commits] r34138 - in haiku/trunk/src: add-ons/kernel/file_systems/packagefs bin/package - ingo_weinhold