From e807d80833d95840f9b2b529debd6f9de2558e2d Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 23 Jun 2011 22:01:59 +0200 Subject: [PATCH] Attribute dir access kernel interface abstraction * Introduce interface AttributeDirectoryCookie and currently only implementation UnpackingAttributeDirectoryCookie. This is an interface for reading/rewinding an attribute directory. * Add abstract virtual Node::OpenAttributeDirectory() method that returns an AttributeDirectoryCookie and implement it for derived classes. * In the kernel interface attribute directory hooks use AttributeDirectoryCookie now. --- .../packagefs/AttributeDirectoryCookie.cpp | 12 ++ .../packagefs/AttributeDirectoryCookie.h | 26 ++++ .../file_systems/packagefs/Directory.cpp | 9 ++ .../kernel/file_systems/packagefs/Directory.h | 2 + .../kernel/file_systems/packagefs/Jamfile | 2 + .../file_systems/packagefs/LeafNode.cpp | 9 ++ .../kernel/file_systems/packagefs/LeafNode.h | 2 + .../kernel/file_systems/packagefs/Node.h | 3 + .../UnpackingAttributeDirectoryCookie.cpp | 116 ++++++++++++++++++ .../UnpackingAttributeDirectoryCookie.h | 39 ++++++ .../packagefs/kernel_interface.cpp | 108 ++-------------- 11 files changed, 229 insertions(+), 99 deletions(-) create mode 100644 src/add-ons/kernel/file_systems/packagefs/AttributeDirectoryCookie.cpp create mode 100644 src/add-ons/kernel/file_systems/packagefs/AttributeDirectoryCookie.h create mode 100644 src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeDirectoryCookie.cpp create mode 100644 src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeDirectoryCookie.h diff --git a/src/add-ons/kernel/file_systems/packagefs/AttributeDirectoryCookie.cpp b/src/add-ons/kernel/file_systems/packagefs/AttributeDirectoryCookie.cpp new file mode 100644 index 0000000000..adbdc629f0 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/AttributeDirectoryCookie.cpp @@ -0,0 +1,12 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "AttributeDirectoryCookie.h" + + +AttributeDirectoryCookie::~AttributeDirectoryCookie() +{ +} diff --git a/src/add-ons/kernel/file_systems/packagefs/AttributeDirectoryCookie.h b/src/add-ons/kernel/file_systems/packagefs/AttributeDirectoryCookie.h new file mode 100644 index 0000000000..eb5d271e16 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/AttributeDirectoryCookie.h @@ -0,0 +1,26 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef ATTRIBUTE_DIRECTORY_COOKIE_H +#define ATTRIBUTE_DIRECTORY_COOKIE_H + + +#include + +#include + + +class AttributeDirectoryCookie { +public: + virtual ~AttributeDirectoryCookie(); + + virtual status_t Close() = 0; + virtual status_t Read(dev_t volumeID, ino_t nodeID, + struct dirent* buffer, size_t bufferSize, + uint32* _count) = 0; + virtual status_t Rewind() = 0; +}; + + +#endif // ATTRIBUTE_DIRECTORY_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 f2b8f7c32c..0962974498 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Directory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Directory.cpp @@ -8,6 +8,7 @@ #include "DebugSupport.h" #include "UnpackingAttributeCookie.h" +#include "UnpackingAttributeDirectoryCookie.h" #include "Utils.h" @@ -172,6 +173,14 @@ Directory::ReadSymlink(void* buffer, size_t* bufferSize) } +status_t +Directory::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie) +{ + return UnpackingAttributeDirectoryCookie::Open(fPackageDirectories.Head(), + _cookie); +} + + status_t Directory::OpenAttribute(const char* name, int openMode, AttributeCookie*& _cookie) diff --git a/src/add-ons/kernel/file_systems/packagefs/Directory.h b/src/add-ons/kernel/file_systems/packagefs/Directory.h index 1bb4b5f7d8..6a73d24fef 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Directory.h +++ b/src/add-ons/kernel/file_systems/packagefs/Directory.h @@ -51,6 +51,8 @@ public: virtual status_t ReadSymlink(void* buffer, size_t* bufferSize); + virtual status_t OpenAttributeDirectory( + AttributeDirectoryCookie*& _cookie); virtual status_t OpenAttribute(const char* name, int openMode, AttributeCookie*& _cookie); diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile b/src/add-ons/kernel/file_systems/packagefs/Jamfile index ee76172acb..12d9dae345 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Jamfile +++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile @@ -8,6 +8,7 @@ UsePrivateHeaders shared ; HAIKU_PACKAGE_FS_SOURCES = AttributeCookie.cpp + AttributeDirectoryCookie.cpp BlockBufferCacheKernel.cpp DebugSupport.cpp Dependency.cpp @@ -28,6 +29,7 @@ HAIKU_PACKAGE_FS_SOURCES = PackageSymlink.cpp Resolvable.cpp UnpackingAttributeCookie.cpp + UnpackingAttributeDirectoryCookie.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 dcb1eb3c5d..b02a48b930 100644 --- a/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp @@ -11,6 +11,7 @@ #include #include "UnpackingAttributeCookie.h" +#include "UnpackingAttributeDirectoryCookie.h" #include "Utils.h" @@ -194,6 +195,14 @@ LeafNode::ReadSymlink(void* buffer, size_t* bufferSize) } +status_t +LeafNode::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie) +{ + return UnpackingAttributeDirectoryCookie::Open(fPackageNodes.Head(), + _cookie); +} + + status_t LeafNode::OpenAttribute(const char* name, int openMode, AttributeCookie*& _cookie) diff --git a/src/add-ons/kernel/file_systems/packagefs/LeafNode.h b/src/add-ons/kernel/file_systems/packagefs/LeafNode.h index 9515c1e4f6..877a9bd3be 100644 --- a/src/add-ons/kernel/file_systems/packagefs/LeafNode.h +++ b/src/add-ons/kernel/file_systems/packagefs/LeafNode.h @@ -38,6 +38,8 @@ public: virtual status_t ReadSymlink(void* buffer, size_t* bufferSize); + virtual status_t OpenAttributeDirectory( + AttributeDirectoryCookie*& _cookie); virtual status_t OpenAttribute(const char* name, int openMode, AttributeCookie*& _cookie); diff --git a/src/add-ons/kernel/file_systems/packagefs/Node.h b/src/add-ons/kernel/file_systems/packagefs/Node.h index af47f5e150..62b1695231 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Node.h +++ b/src/add-ons/kernel/file_systems/packagefs/Node.h @@ -18,6 +18,7 @@ class AttributeCookie; +class AttributeDirectoryCookie; class Directory; class PackageNode; @@ -64,6 +65,8 @@ public: virtual status_t ReadSymlink(void* buffer, size_t* bufferSize) = 0; + virtual status_t OpenAttributeDirectory( + AttributeDirectoryCookie*& _cookie) = 0; virtual status_t OpenAttribute(const char* name, int openMode, AttributeCookie*& _cookie) = 0; diff --git a/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeDirectoryCookie.cpp b/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeDirectoryCookie.cpp new file mode 100644 index 0000000000..3a95440637 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeDirectoryCookie.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "UnpackingAttributeDirectoryCookie.h" + +#include "DebugSupport.h" +#include "PackageNode.h" +#include "Utils.h" + + +UnpackingAttributeDirectoryCookie::UnpackingAttributeDirectoryCookie( + PackageNode* packageNode) + : + fPackageNode(packageNode), + fAttribute(NULL) +{ + if (fPackageNode != NULL) { + fPackageNode->AcquireReference(); + fAttribute = fPackageNode->Attributes().Head(); + } +} + + +UnpackingAttributeDirectoryCookie::~UnpackingAttributeDirectoryCookie() +{ + if (fPackageNode != NULL) + fPackageNode->ReleaseReference(); +} + + +/*static*/ status_t +UnpackingAttributeDirectoryCookie::Open(PackageNode* packageNode, + AttributeDirectoryCookie*& _cookie) +{ + UnpackingAttributeDirectoryCookie* cookie = new(std::nothrow) + UnpackingAttributeDirectoryCookie(packageNode); + if (cookie == NULL) + return B_NO_MEMORY; + + _cookie = cookie; + return B_OK; +} + + +status_t +UnpackingAttributeDirectoryCookie::Close() +{ + return B_OK; +} + + +status_t +UnpackingAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID, + struct dirent* buffer, size_t bufferSize, uint32* _count) +{ + uint32 maxCount = *_count; + uint32 count = 0; + + dirent* previousEntry = NULL; + + while (fAttribute != NULL) { + // don't read more entries than requested + if (count >= maxCount) + break; + + // align the buffer for subsequent entries + if (count > 0) { + addr_t offset = (addr_t)buffer % 8; + if (offset > 0) { + offset = 8 - offset; + if (bufferSize <= offset) + break; + + previousEntry->d_reclen += offset; + buffer = (dirent*)((addr_t)buffer + offset); + bufferSize -= offset; + } + } + + // fill in the entry name -- checks whether the entry fits into the + // buffer + const char* name = fAttribute->Name(); + if (!set_dirent_name(buffer, bufferSize, name, strlen(name))) { + if (count == 0) + RETURN_ERROR(B_BUFFER_OVERFLOW); + break; + } + + // fill in the other data + buffer->d_dev = volumeID; + buffer->d_ino = nodeID; + + count++; + previousEntry = buffer; + bufferSize -= buffer->d_reclen; + buffer = (dirent*)((addr_t)buffer + buffer->d_reclen); + + fAttribute = fPackageNode->Attributes().GetNext(fAttribute); + } + + *_count = count; + return B_OK; +} + + +status_t +UnpackingAttributeDirectoryCookie::Rewind() +{ + if (fPackageNode != NULL) + fAttribute = fPackageNode->Attributes().Head(); + + return B_OK; +} diff --git a/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeDirectoryCookie.h b/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeDirectoryCookie.h new file mode 100644 index 0000000000..0f6bc1baf0 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/UnpackingAttributeDirectoryCookie.h @@ -0,0 +1,39 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef UNPACKING_ATTRIBUTE_DIRECTORY_COOKIE_H +#define UNPACKING_ATTRIBUTE_DIRECTORY_COOKIE_H + + +#include "AttributeDirectoryCookie.h" + + +struct dirent; + +class PackageNode; +class PackageNodeAttribute; + + +class UnpackingAttributeDirectoryCookie : public AttributeDirectoryCookie { +public: + UnpackingAttributeDirectoryCookie( + PackageNode* packageNode); + virtual ~UnpackingAttributeDirectoryCookie(); + + static status_t Open(PackageNode* packageNode, + AttributeDirectoryCookie*& _cookie); + + virtual status_t Close(); + virtual status_t Read(dev_t volumeID, ino_t nodeID, + struct dirent* buffer, size_t bufferSize, + uint32* _count); + virtual status_t Rewind(); + +private: + PackageNode* fPackageNode; + PackageNodeAttribute* fAttribute; +}; + + +#endif // UNPACKING_ATTRIBUTE_DIRECTORY_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 7e140f6e5d..41e6ca6df6 100644 --- a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp @@ -18,6 +18,7 @@ #include #include "AttributeCookie.h" +#include "AttributeDirectoryCookie.h" #include "DebugSupport.h" #include "Directory.h" #include "GlobalFactory.h" @@ -663,50 +664,6 @@ packagefs_rewind_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie) // #pragma mark - Attribute Directories -struct AttributeDirectoryCookie { - Node* node; - PackageNode* packageNode; - PackageNodeAttribute* attribute; - - AttributeDirectoryCookie(Node* node) - : - node(node), - packageNode(node->GetPackageNode()), - attribute(NULL) - { - if (packageNode != NULL) { - packageNode->AcquireReference(); - attribute = packageNode->Attributes().Head(); - } - } - - ~AttributeDirectoryCookie() - { - if (packageNode != NULL) - packageNode->ReleaseReference(); - } - - PackageNodeAttribute* Current() const - { - return attribute; - } - - void Next() - { - if (attribute == NULL) - return; - - attribute = packageNode->Attributes().GetNext(attribute); - } - - void Rewind() - { - if (packageNode != NULL) - attribute = packageNode->Attributes().Head(); - } -}; - - status_t packagefs_open_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** _cookie) { @@ -722,10 +679,10 @@ packagefs_open_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** _cookie) // create a cookie NodeReadLocker nodeLocker(node); - AttributeDirectoryCookie* cookie - = new(std::nothrow) AttributeDirectoryCookie(node); - if (cookie == NULL) - RETURN_ERROR(B_NO_MEMORY); + AttributeDirectoryCookie* cookie; + error = node->OpenAttributeDirectory(cookie); + if (error != B_OK) + RETURN_ERROR(error); *_cookie = cookie; return B_OK; @@ -735,7 +692,8 @@ packagefs_open_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** _cookie) status_t packagefs_close_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie) { - return B_OK; + AttributeDirectoryCookie* cookie = (AttributeDirectoryCookie*)_cookie; + return cookie->Close(); } @@ -771,53 +729,7 @@ packagefs_read_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie, TOUCH(volume); TOUCH(node); - uint32 maxCount = *_count; - uint32 count = 0; - - dirent* previousEntry = NULL; - - while (PackageNodeAttribute* attribute = cookie->Current()) { - // don't read more entries than requested - if (count >= maxCount) - break; - - // align the buffer for subsequent entries - if (count > 0) { - addr_t offset = (addr_t)buffer % 8; - if (offset > 0) { - offset = 8 - offset; - if (bufferSize <= offset) - break; - - previousEntry->d_reclen += offset; - buffer = (dirent*)((addr_t)buffer + offset); - bufferSize -= offset; - } - } - - // fill in the entry name -- checks whether the entry fits into the - // buffer - const char* name = attribute->Name(); - if (!set_dirent_name(buffer, bufferSize, name, strlen(name))) { - if (count == 0) - RETURN_ERROR(B_BUFFER_OVERFLOW); - break; - } - - // fill in the other data - buffer->d_dev = volume->ID(); - buffer->d_ino = node->ID(); - - count++; - previousEntry = buffer; - bufferSize -= buffer->d_reclen; - buffer = (dirent*)((addr_t)buffer + buffer->d_reclen); - - cookie->Next(); - } - - *_count = count; - return B_OK; + return cookie->Read(volume->ID(), node->ID(), buffer, bufferSize, _count); } @@ -833,9 +745,7 @@ packagefs_rewind_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie) TOUCH(volume); TOUCH(node); - cookie->Rewind(); - - return B_OK; + return cookie->Rewind(); }