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.
This commit is contained in:
parent
22a808885b
commit
8ae81ef94e
@ -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()
|
||||
{
|
||||
}
|
25
src/add-ons/kernel/file_systems/packagefs/AttributeCookie.h
Normal file
25
src/add-ons/kernel/file_systems/packagefs/AttributeCookie.h
Normal file
@ -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 <sys/stat.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
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
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#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
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <util/OpenHashTable.h>
|
||||
|
||||
|
||||
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;
|
||||
|
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "UnpackingAttributeCookie.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
|
||||
#include <package/hpkg/DataReader.h>
|
||||
#include <package/hpkg/PackageData.h>
|
||||
#include <package/hpkg/PackageDataReader.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#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<BPackageDataReader> 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;
|
||||
}
|
@ -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
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
|
||||
#include <fs_info.h>
|
||||
@ -18,6 +17,7 @@
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#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<BPackageDataReader> 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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user