From 882b03aba9f028dc99fd79499f3e20b52a91a485 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 23 Jun 2011 19:41:56 +0200 Subject: [PATCH] Kernel interface abstraction for attribute access * Introduce interface AttributeCookie and currently only implementation UnpackingAttributeCookie. This is an interface for reading/stat()ing an attribute. * Add abstract virtual Node::OpenAttribute() method that returns an AttributeCookie and implemented it for derived classes. * In the kernel interface attribute hooks use AttributeCookie now. The attribute directory hooks are unchanged. --- .../packagefs/AttributeCookie.cpp | 12 ++ .../file_systems/packagefs/AttributeCookie.h | 25 +++ .../file_systems/packagefs/Directory.cpp | 10 ++ .../kernel/file_systems/packagefs/Directory.h | 3 + .../kernel/file_systems/packagefs/Jamfile | 2 + .../file_systems/packagefs/LeafNode.cpp | 10 ++ .../kernel/file_systems/packagefs/LeafNode.h | 3 + .../kernel/file_systems/packagefs/Node.h | 4 + .../packagefs/UnpackingAttributeCookie.cpp | 142 ++++++++++++++++++ .../packagefs/UnpackingAttributeCookie.h | 41 +++++ .../packagefs/kernel_interface.cpp | 105 ++----------- 11 files changed, 261 insertions(+), 96 deletions(-) create mode 100644 src/add-ons/kernel/file_systems/packagefs/AttributeCookie.cpp create mode 100644 src/add-ons/kernel/file_systems/packagefs/AttributeCookie.h create mode 100644 src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeCookie.cpp create mode 100644 src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeCookie.h diff --git a/src/add-ons/kernel/file_systems/packagefs/AttributeCookie.cpp b/src/add-ons/kernel/file_systems/packagefs/AttributeCookie.cpp new file mode 100644 index 0000000000..2df7b99c4b --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/AttributeCookie.cpp @@ -0,0 +1,12 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "AttributeCookie.h" + + +AttributeCookie::~AttributeCookie() +{ +} diff --git a/src/add-ons/kernel/file_systems/packagefs/AttributeCookie.h b/src/add-ons/kernel/file_systems/packagefs/AttributeCookie.h new file mode 100644 index 0000000000..40ee92c18f --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/AttributeCookie.h @@ -0,0 +1,25 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef ATTRIBUTE_COOKIE_H +#define ATTRIBUTE_COOKIE_H + + +#include + +#include + + +class AttributeCookie { +public: + virtual ~AttributeCookie(); + + virtual status_t Close() = 0; + virtual status_t ReadAttribute(off_t offset, void* buffer, + size_t* bufferSize) = 0; + virtual status_t ReadAttributeStat(struct stat* st) = 0; +}; + + +#endif // ATTRIBUTE_COOKIE_H diff --git a/src/add-ons/kernel/file_systems/packagefs/Directory.cpp b/src/add-ons/kernel/file_systems/packagefs/Directory.cpp index 663afeb52a..f2b8f7c32c 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Directory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Directory.cpp @@ -7,6 +7,7 @@ #include "Directory.h" #include "DebugSupport.h" +#include "UnpackingAttributeCookie.h" #include "Utils.h" @@ -171,6 +172,15 @@ Directory::ReadSymlink(void* buffer, size_t* bufferSize) } +status_t +Directory::OpenAttribute(const char* name, int openMode, + AttributeCookie*& _cookie) +{ + return UnpackingAttributeCookie::Open(fPackageDirectories.Head(), name, + openMode, _cookie); +} + + void Directory::AddChild(Node* node) { diff --git a/src/add-ons/kernel/file_systems/packagefs/Directory.h b/src/add-ons/kernel/file_systems/packagefs/Directory.h index 95c56dd9c9..1bb4b5f7d8 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Directory.h +++ b/src/add-ons/kernel/file_systems/packagefs/Directory.h @@ -51,6 +51,9 @@ public: virtual status_t ReadSymlink(void* buffer, size_t* bufferSize); + virtual status_t OpenAttribute(const char* name, int openMode, + AttributeCookie*& _cookie); + void AddChild(Node* node); void RemoveChild(Node* node); Node* FindChild(const char* name); diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile b/src/add-ons/kernel/file_systems/packagefs/Jamfile index e07bf10a49..ee76172acb 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Jamfile +++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile @@ -7,6 +7,7 @@ UsePrivateHeaders shared ; HAIKU_PACKAGE_FS_SOURCES = + AttributeCookie.cpp BlockBufferCacheKernel.cpp DebugSupport.cpp Dependency.cpp @@ -26,6 +27,7 @@ HAIKU_PACKAGE_FS_SOURCES = PackageNodeAttribute.cpp PackageSymlink.cpp Resolvable.cpp + UnpackingAttributeCookie.cpp Version.cpp Volume.cpp ; diff --git a/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp b/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp index 382441d420..0bd8116f61 100644 --- a/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp @@ -10,6 +10,7 @@ #include +#include "UnpackingAttributeCookie.h" #include "Utils.h" @@ -193,6 +194,15 @@ LeafNode::ReadSymlink(void* buffer, size_t* bufferSize) } +status_t +LeafNode::OpenAttribute(const char* name, int openMode, + AttributeCookie*& _cookie) +{ + return UnpackingAttributeCookie::Open(fPackageNodes.Head(), name, openMode, + _cookie); +} + + const char* LeafNode::SymlinkPath() const { diff --git a/src/add-ons/kernel/file_systems/packagefs/LeafNode.h b/src/add-ons/kernel/file_systems/packagefs/LeafNode.h index 2d3b403ec2..016dab919e 100644 --- a/src/add-ons/kernel/file_systems/packagefs/LeafNode.h +++ b/src/add-ons/kernel/file_systems/packagefs/LeafNode.h @@ -38,6 +38,9 @@ public: virtual status_t ReadSymlink(void* buffer, size_t* bufferSize); + virtual status_t OpenAttribute(const char* name, int openMode, + AttributeCookie*& _cookie); + const char* SymlinkPath() const; private: diff --git a/src/add-ons/kernel/file_systems/packagefs/Node.h b/src/add-ons/kernel/file_systems/packagefs/Node.h index f2ec3576f2..3946fcd269 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Node.h +++ b/src/add-ons/kernel/file_systems/packagefs/Node.h @@ -17,6 +17,7 @@ #include +class AttributeCookie; class Directory; class PackageNode; @@ -63,6 +64,9 @@ public: virtual status_t ReadSymlink(void* buffer, size_t* bufferSize) = 0; + virtual status_t OpenAttribute(const char* name, int openMode, + AttributeCookie*& _cookie) = 0; + protected: rw_lock fLock; ino_t fID; diff --git a/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeCookie.cpp b/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeCookie.cpp new file mode 100644 index 0000000000..2c1fe25a51 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeCookie.cpp @@ -0,0 +1,142 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "UnpackingAttributeCookie.h" + +#include +#include + +#include +#include +#include + +#include + +#include "DebugSupport.h" +#include "GlobalFactory.h" +#include "Package.h" +#include "PackageNode.h" + + +using BPackageKit::BHPKG::BBufferDataReader; +//using BPackageKit::BHPKG::BDataReader; +using BPackageKit::BHPKG::BFDDataReader; +//using BPackageKit::BHPKG::BPackageData; +//using BPackageKit::BHPKG::BPackageDataReader; + + +static status_t +read_package_data(const BPackageData& data, BDataReader* dataReader, + off_t offset, void* buffer, size_t* bufferSize) +{ + // create a BPackageDataReader + BPackageDataReader* reader; + status_t error = GlobalFactory::Default()->CreatePackageDataReader( + dataReader, data, reader); + if (error != B_OK) + RETURN_ERROR(error); + ObjectDeleter readerDeleter(reader); + + // check the offset + if (offset < 0 || (uint64)offset > data.UncompressedSize()) + return B_BAD_VALUE; + + // clamp the size + size_t toRead = std::min((uint64)*bufferSize, + data.UncompressedSize() - offset); + + // read + if (toRead > 0) { + status_t error = reader->ReadData(offset, buffer, toRead); + if (error != B_OK) + RETURN_ERROR(error); + } + + *bufferSize = toRead; + return B_OK; +} + + +UnpackingAttributeCookie::UnpackingAttributeCookie(PackageNode* packageNode, + PackageNodeAttribute* attribute, int openMode) + : + fPackageNode(packageNode), + fPackage(packageNode->GetPackage()), + fAttribute(attribute), + fOpenMode(openMode) +{ + fPackageNode->AcquireReference(); + fPackage->AcquireReference(); +} + + +UnpackingAttributeCookie::~UnpackingAttributeCookie() +{ + fPackageNode->ReleaseReference(); + fPackage->ReleaseReference(); +} + + +/*static*/ status_t +UnpackingAttributeCookie::Open(PackageNode* packageNode, const char* name, + int openMode, AttributeCookie*& _cookie) +{ + if (packageNode == NULL) + return B_ENTRY_NOT_FOUND; + + // get the attribute + PackageNodeAttribute* attribute = packageNode->FindAttribute(name); + if (attribute == NULL) + return B_ENTRY_NOT_FOUND; + + // allocate the cookie + UnpackingAttributeCookie* cookie = new(std::nothrow) + UnpackingAttributeCookie(packageNode, attribute, openMode); + if (cookie == NULL) + RETURN_ERROR(B_NO_MEMORY); + + _cookie = cookie; + return B_OK; +} + + +status_t +UnpackingAttributeCookie::Close() +{ + return B_OK; +} + + +status_t +UnpackingAttributeCookie::ReadAttribute(off_t offset, void* buffer, + size_t* bufferSize) +{ + const BPackageData& data = fAttribute->Data(); + if (data.IsEncodedInline()) { + // inline data + BBufferDataReader dataReader(data.InlineData(), data.CompressedSize()); + return read_package_data(data, &dataReader, offset, buffer, bufferSize); + } + + // data not inline -- open the package + int fd = fPackage->Open(); + if (fd < 0) + RETURN_ERROR(fd); + PackageCloser packageCloser(fPackage); + + BFDDataReader dataReader(fd); + return read_package_data(data, &dataReader, offset, buffer, bufferSize); +} + + +status_t +UnpackingAttributeCookie::ReadAttributeStat(struct stat* st) +{ + st->st_size = fAttribute->Data().UncompressedSize(); + st->st_type = fAttribute->Type(); + + return B_OK; +} diff --git a/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeCookie.h b/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeCookie.h new file mode 100644 index 0000000000..27fec3dbe2 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeCookie.h @@ -0,0 +1,41 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef UNPACKING_ATTRIBUTE_COOKIE_H +#define UNPACKING_ATTRIBUTE_COOKIE_H + + +#include "AttributeCookie.h" + + +class Package; +class PackageNode; +class PackageNodeAttribute; + + +class UnpackingAttributeCookie : public AttributeCookie { +public: + UnpackingAttributeCookie( + PackageNode* packageNode, + PackageNodeAttribute* attribute, + int openMode); + virtual ~UnpackingAttributeCookie(); + + static status_t Open(PackageNode* packageNode, const char* name, + int openMode, AttributeCookie*& _cookie); + + virtual status_t Close(); + virtual status_t ReadAttribute(off_t offset, void* buffer, + size_t* bufferSize); + virtual status_t ReadAttributeStat(struct stat* st); + +private: + PackageNode* fPackageNode; + Package* fPackage; + PackageNodeAttribute* fAttribute; + int fOpenMode; +}; + + +#endif // UNPACKING_ATTRIBUTE_COOKIE_H diff --git a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp index 7868d0ea57..7a5ad75cbe 100644 --- a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp @@ -8,7 +8,6 @@ #include -#include #include #include @@ -18,6 +17,7 @@ #include +#include "AttributeCookie.h" #include "DebugSupport.h" #include "Directory.h" #include "GlobalFactory.h" @@ -25,10 +25,6 @@ #include "Volume.h" -using BPackageKit::BHPKG::BBufferDataReader; -using BPackageKit::BHPKG::BFDDataReader; - - static const uint32 kOptimalIOSize = 64 * 1024; @@ -860,32 +856,6 @@ packagefs_rewind_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie) // #pragma mark - Attribute Operations -struct AttributeCookie { - PackageNode* packageNode; - Package* package; - PackageNodeAttribute* attribute; - int openMode; - - AttributeCookie(PackageNode* packageNode, PackageNodeAttribute* attribute, - int openMode) - : - packageNode(packageNode), - package(packageNode->GetPackage()), - attribute(attribute), - openMode(openMode) - { - packageNode->AcquireReference(); - package->AcquireReference(); - } - - ~AttributeCookie() - { - packageNode->ReleaseReference(); - package->ReleaseReference(); - } -}; - - status_t packagefs_open_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name, int openMode, void** _cookie) @@ -907,21 +877,12 @@ packagefs_open_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name, if (error != B_OK) return error; - // get the package node and the respectively named attribute - PackageNode* packageNode = node->GetPackageNode(); - PackageNodeAttribute* attribute = packageNode != NULL - ? packageNode->FindAttribute(name) : NULL; - if (attribute == NULL) - return B_ENTRY_NOT_FOUND; - - // allocate the cookie - AttributeCookie* cookie = new(std::nothrow) AttributeCookie(packageNode, - attribute, openMode); - if (cookie == NULL) - RETURN_ERROR(B_NO_MEMORY); + AttributeCookie* cookie; + error = node->OpenAttribute(name, openMode, cookie); + if (error != B_OK) + return error; *_cookie = cookie; - return B_OK; } @@ -929,7 +890,8 @@ packagefs_open_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name, status_t packagefs_close_attr(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie) { - return B_OK; + AttributeCookie* cookie = (AttributeCookie*)_cookie; + RETURN_ERROR(cookie->Close()); } @@ -951,38 +913,6 @@ packagefs_free_attr_cookie(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie) } -static status_t -read_package_data(const BPackageData& data, BDataReader* dataReader, off_t offset, - void* buffer, size_t* bufferSize) -{ - // create a BPackageDataReader - BPackageDataReader* reader; - status_t error = GlobalFactory::Default()->CreatePackageDataReader( - dataReader, data, reader); - if (error != B_OK) - RETURN_ERROR(error); - ObjectDeleter readerDeleter(reader); - - // check the offset - if (offset < 0 || (uint64)offset > data.UncompressedSize()) - return B_BAD_VALUE; - - // clamp the size - size_t toRead = std::min((uint64)*bufferSize, - data.UncompressedSize() - offset); - - // read - if (toRead > 0) { - status_t error = reader->ReadData(offset, buffer, toRead); - if (error != B_OK) - RETURN_ERROR(error); - } - - *bufferSize = toRead; - return B_OK; -} - - status_t packagefs_read_attr(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie, off_t offset, void* buffer, size_t* bufferSize) @@ -996,21 +926,7 @@ packagefs_read_attr(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie, TOUCH(volume); TOUCH(node); - const BPackageData& data = cookie->attribute->Data(); - if (data.IsEncodedInline()) { - // inline data - BBufferDataReader dataReader(data.InlineData(), data.CompressedSize()); - return read_package_data(data, &dataReader, offset, buffer, bufferSize); - } - - // data not inline -- open the package - int fd = cookie->package->Open(); - if (fd < 0) - RETURN_ERROR(fd); - PackageCloser packageCloser(cookie->package); - - BFDDataReader dataReader(fd); - return read_package_data(data, &dataReader, offset, buffer, bufferSize); + return cookie->ReadAttribute(offset, buffer, bufferSize); } @@ -1027,10 +943,7 @@ packagefs_read_attr_stat(fs_volume* fsVolume, fs_vnode* fsNode, TOUCH(volume); TOUCH(node); - st->st_size = cookie->attribute->Data().UncompressedSize(); - st->st_type = cookie->attribute->Type(); - - return B_OK; + return cookie->ReadAttributeStat(st); }