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:
parent
4ac4d15c3a
commit
5167a80703
@ -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()
|
||||
{
|
||||
}
|
@ -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 <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 "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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 "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();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user