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.
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "AttributeDirectoryCookie.h"
|
||||||
|
|
||||||
|
|
||||||
|
AttributeDirectoryCookie::~AttributeDirectoryCookie()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef ATTRIBUTE_DIRECTORY_COOKIE_H
|
||||||
|
#define ATTRIBUTE_DIRECTORY_COOKIE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
#include "UnpackingAttributeCookie.h"
|
#include "UnpackingAttributeCookie.h"
|
||||||
|
#include "UnpackingAttributeDirectoryCookie.h"
|
||||||
#include "Utils.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
|
status_t
|
||||||
Directory::OpenAttribute(const char* name, int openMode,
|
Directory::OpenAttribute(const char* name, int openMode,
|
||||||
AttributeCookie*& _cookie)
|
AttributeCookie*& _cookie)
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ public:
|
|||||||
virtual status_t ReadSymlink(void* buffer,
|
virtual status_t ReadSymlink(void* buffer,
|
||||||
size_t* bufferSize);
|
size_t* bufferSize);
|
||||||
|
|
||||||
|
virtual status_t OpenAttributeDirectory(
|
||||||
|
AttributeDirectoryCookie*& _cookie);
|
||||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
virtual status_t OpenAttribute(const char* name, int openMode,
|
||||||
AttributeCookie*& _cookie);
|
AttributeCookie*& _cookie);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ UsePrivateHeaders shared ;
|
|||||||
|
|
||||||
HAIKU_PACKAGE_FS_SOURCES =
|
HAIKU_PACKAGE_FS_SOURCES =
|
||||||
AttributeCookie.cpp
|
AttributeCookie.cpp
|
||||||
|
AttributeDirectoryCookie.cpp
|
||||||
BlockBufferCacheKernel.cpp
|
BlockBufferCacheKernel.cpp
|
||||||
DebugSupport.cpp
|
DebugSupport.cpp
|
||||||
Dependency.cpp
|
Dependency.cpp
|
||||||
@@ -28,6 +29,7 @@ HAIKU_PACKAGE_FS_SOURCES =
|
|||||||
PackageSymlink.cpp
|
PackageSymlink.cpp
|
||||||
Resolvable.cpp
|
Resolvable.cpp
|
||||||
UnpackingAttributeCookie.cpp
|
UnpackingAttributeCookie.cpp
|
||||||
|
UnpackingAttributeDirectoryCookie.cpp
|
||||||
Version.cpp
|
Version.cpp
|
||||||
Volume.cpp
|
Volume.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "UnpackingAttributeCookie.h"
|
#include "UnpackingAttributeCookie.h"
|
||||||
|
#include "UnpackingAttributeDirectoryCookie.h"
|
||||||
#include "Utils.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
|
status_t
|
||||||
LeafNode::OpenAttribute(const char* name, int openMode,
|
LeafNode::OpenAttribute(const char* name, int openMode,
|
||||||
AttributeCookie*& _cookie)
|
AttributeCookie*& _cookie)
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ public:
|
|||||||
virtual status_t ReadSymlink(void* buffer,
|
virtual status_t ReadSymlink(void* buffer,
|
||||||
size_t* bufferSize);
|
size_t* bufferSize);
|
||||||
|
|
||||||
|
virtual status_t OpenAttributeDirectory(
|
||||||
|
AttributeDirectoryCookie*& _cookie);
|
||||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
virtual status_t OpenAttribute(const char* name, int openMode,
|
||||||
AttributeCookie*& _cookie);
|
AttributeCookie*& _cookie);
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class AttributeCookie;
|
class AttributeCookie;
|
||||||
|
class AttributeDirectoryCookie;
|
||||||
class Directory;
|
class Directory;
|
||||||
class PackageNode;
|
class PackageNode;
|
||||||
|
|
||||||
@@ -64,6 +65,8 @@ public:
|
|||||||
virtual status_t ReadSymlink(void* buffer,
|
virtual status_t ReadSymlink(void* buffer,
|
||||||
size_t* bufferSize) = 0;
|
size_t* bufferSize) = 0;
|
||||||
|
|
||||||
|
virtual status_t OpenAttributeDirectory(
|
||||||
|
AttributeDirectoryCookie*& _cookie) = 0;
|
||||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
virtual status_t OpenAttribute(const char* name, int openMode,
|
||||||
AttributeCookie*& _cookie) = 0;
|
AttributeCookie*& _cookie) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
#include "AttributeCookie.h"
|
#include "AttributeCookie.h"
|
||||||
|
#include "AttributeDirectoryCookie.h"
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
#include "Directory.h"
|
#include "Directory.h"
|
||||||
#include "GlobalFactory.h"
|
#include "GlobalFactory.h"
|
||||||
@@ -663,50 +664,6 @@ packagefs_rewind_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie)
|
|||||||
// #pragma mark - Attribute Directories
|
// #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
|
status_t
|
||||||
packagefs_open_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** _cookie)
|
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
|
// create a cookie
|
||||||
NodeReadLocker nodeLocker(node);
|
NodeReadLocker nodeLocker(node);
|
||||||
AttributeDirectoryCookie* cookie
|
AttributeDirectoryCookie* cookie;
|
||||||
= new(std::nothrow) AttributeDirectoryCookie(node);
|
error = node->OpenAttributeDirectory(cookie);
|
||||||
if (cookie == NULL)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
*_cookie = cookie;
|
*_cookie = cookie;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -735,7 +692,8 @@ packagefs_open_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** _cookie)
|
|||||||
status_t
|
status_t
|
||||||
packagefs_close_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie)
|
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(volume);
|
||||||
TOUCH(node);
|
TOUCH(node);
|
||||||
|
|
||||||
uint32 maxCount = *_count;
|
return cookie->Read(volume->ID(), node->ID(), buffer, bufferSize, _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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -833,9 +745,7 @@ packagefs_rewind_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* _cookie)
|
|||||||
TOUCH(volume);
|
TOUCH(volume);
|
||||||
TOUCH(node);
|
TOUCH(node);
|
||||||
|
|
||||||
cookie->Rewind();
|
return cookie->Rewind();
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user