Remove package related dependencies from Node

* Move package related methods from Node to new interface UnpackingNode.
* LeafNode and Directory derive from UnpackingNode now.
* Adjust Volume implementation accordingly.
This commit is contained in:
Ingo Weinhold
2011-11-25 06:17:55 +01:00
parent 5167a80703
commit 20142717e7
10 changed files with 106 additions and 30 deletions
@@ -99,6 +99,13 @@ Directory::FileSize() const
} }
Node*
Directory::GetNode()
{
return this;
}
status_t status_t
Directory::AddPackageNode(PackageNode* packageNode) Directory::AddPackageNode(PackageNode* packageNode)
{ {
@@ -8,6 +8,7 @@
#include "Node.h" #include "Node.h"
#include "PackageDirectory.h" #include "PackageDirectory.h"
#include "UnpackingNode.h"
struct DirectoryIterator : DoublyLinkedListLinkImpl<DirectoryIterator> { struct DirectoryIterator : DoublyLinkedListLinkImpl<DirectoryIterator> {
@@ -23,7 +24,7 @@ struct DirectoryIterator : DoublyLinkedListLinkImpl<DirectoryIterator> {
typedef DoublyLinkedList<DirectoryIterator> DirectoryIteratorList; typedef DoublyLinkedList<DirectoryIterator> DirectoryIteratorList;
class Directory : public Node { class Directory : public Node, public UnpackingNode {
public: public:
Directory(ino_t id); Directory(ino_t id);
virtual ~Directory(); virtual ~Directory();
@@ -39,6 +40,8 @@ public:
virtual timespec ModifiedTime() const; virtual timespec ModifiedTime() const;
virtual off_t FileSize() const; virtual off_t FileSize() const;
virtual Node* GetNode();
virtual status_t AddPackageNode(PackageNode* packageNode); virtual status_t AddPackageNode(PackageNode* packageNode);
virtual void RemovePackageNode(PackageNode* packageNode); virtual void RemovePackageNode(PackageNode* packageNode);
@@ -30,6 +30,7 @@ HAIKU_PACKAGE_FS_SOURCES =
Resolvable.cpp Resolvable.cpp
UnpackingAttributeCookie.cpp UnpackingAttributeCookie.cpp
UnpackingAttributeDirectoryCookie.cpp UnpackingAttributeDirectoryCookie.cpp
UnpackingNode.cpp
Version.cpp Version.cpp
Volume.cpp Volume.cpp
; ;
@@ -98,6 +98,13 @@ LeafNode::FileSize() const
} }
Node*
LeafNode::GetNode()
{
return this;
}
status_t status_t
LeafNode::AddPackageNode(PackageNode* packageNode) LeafNode::AddPackageNode(PackageNode* packageNode)
{ {
@@ -8,9 +8,10 @@
#include "Node.h" #include "Node.h"
#include "PackageLeafNode.h" #include "PackageLeafNode.h"
#include "UnpackingNode.h"
class LeafNode : public Node { class LeafNode : public Node, public UnpackingNode {
public: public:
LeafNode(ino_t id); LeafNode(ino_t id);
virtual ~LeafNode(); virtual ~LeafNode();
@@ -26,6 +27,8 @@ public:
virtual timespec ModifiedTime() const; virtual timespec ModifiedTime() const;
virtual off_t FileSize() const; virtual off_t FileSize() const;
virtual Node* GetNode();
virtual status_t AddPackageNode(PackageNode* packageNode); virtual status_t AddPackageNode(PackageNode* packageNode);
virtual void RemovePackageNode(PackageNode* packageNode); virtual void RemovePackageNode(PackageNode* packageNode);
@@ -53,11 +53,6 @@ public:
virtual timespec ModifiedTime() const = 0; virtual timespec ModifiedTime() const = 0;
virtual off_t FileSize() const = 0; virtual off_t FileSize() const = 0;
virtual status_t AddPackageNode(PackageNode* packageNode) = 0;
virtual void RemovePackageNode(PackageNode* packageNode) = 0;
virtual PackageNode* GetPackageNode() = 0;
virtual status_t Read(off_t offset, void* buffer, virtual status_t Read(off_t offset, void* buffer,
size_t* bufferSize) = 0; size_t* bufferSize) = 0;
virtual status_t Read(io_request* request) = 0; virtual status_t Read(io_request* request) = 0;
@@ -0,0 +1,12 @@
/*
* Copyright 2011, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "UnpackingNode.h"
UnpackingNode::~UnpackingNode()
{
}
@@ -0,0 +1,29 @@
/*
* Copyright 2011, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef UNPACKING_NODE_H
#define UNPACKING_NODE_H
#include <SupportDefs.h>
class Node;
class PackageNode;
class UnpackingNode {
public:
virtual ~UnpackingNode();
virtual Node* GetNode() = 0;
virtual status_t AddPackageNode(PackageNode* packageNode) = 0;
virtual void RemovePackageNode(PackageNode* packageNode) = 0;
virtual PackageNode* GetPackageNode() = 0;
};
#endif // UNPACKING_NODE_H
@@ -949,17 +949,26 @@ Volume::_AddPackageNode(Directory* directory, PackageNode* packageNode,
bool notify, Node*& _node) bool notify, Node*& _node)
{ {
bool newNode = false; bool newNode = false;
UnpackingNode* unpackingNode;
Node* node = directory->FindChild(packageNode->Name()); Node* node = directory->FindChild(packageNode->Name());
if (node == NULL) {
status_t error = _CreateNode(packageNode->Mode(), directory, if (node != NULL) {
packageNode->Name(), node); unpackingNode = dynamic_cast<UnpackingNode*>(node);
if (unpackingNode == NULL)
RETURN_ERROR(B_BAD_VALUE);
} else {
status_t error = _CreateUnpackingNode(packageNode->Mode(), directory,
packageNode->Name(), unpackingNode);
if (error != B_OK) if (error != B_OK)
RETURN_ERROR(error); RETURN_ERROR(error);
node = unpackingNode->GetNode();
newNode = true; newNode = true;
} }
BReference<Node> nodeReference(node); BReference<Node> nodeReference(node);
status_t error = node->AddPackageNode(packageNode); status_t error = unpackingNode->AddPackageNode(packageNode);
if (error != B_OK) { if (error != B_OK) {
// remove the node, if created before // remove the node, if created before
if (newNode) if (newNode)
@@ -971,7 +980,7 @@ Volume::_AddPackageNode(Directory* directory, PackageNode* packageNode,
if (newNode) { if (newNode) {
notify_entry_created(ID(), directory->ID(), node->Name(), notify_entry_created(ID(), directory->ID(), node->Name(),
node->ID()); node->ID());
} else if (packageNode == node->GetPackageNode()) { } else if (packageNode == unpackingNode->GetPackageNode()) {
// The new package node has become the one representing the node. // The new package node has become the one representing the node.
// Send stat changed notification for directories and entry // Send stat changed notification for directories and entry
// removed + created notifications for files and symlinks. // removed + created notifications for files and symlinks.
@@ -999,15 +1008,19 @@ void
Volume::_RemovePackageNode(Directory* directory, PackageNode* packageNode, Volume::_RemovePackageNode(Directory* directory, PackageNode* packageNode,
Node* node, bool notify) Node* node, bool notify)
{ {
UnpackingNode* unpackingNode = dynamic_cast<UnpackingNode*>(node);
if (unpackingNode == NULL)
return;
BReference<Node> nodeReference(node); BReference<Node> nodeReference(node);
PackageNode* headPackageNode = node->GetPackageNode(); PackageNode* headPackageNode = unpackingNode->GetPackageNode();
node->RemovePackageNode(packageNode); unpackingNode->RemovePackageNode(packageNode);
// If the node doesn't have any more package nodes attached, remove it // If the node doesn't have any more package nodes attached, remove it
// completely. // completely.
bool nodeRemoved = false; bool nodeRemoved = false;
if (node->GetPackageNode() == NULL) { if (unpackingNode->GetPackageNode() == NULL) {
// we get and put the vnode to notify the VFS // we get and put the vnode to notify the VFS
// TODO: We should probably only do that, if the node is known to the // TODO: We should probably only do that, if the node is known to the
// VFS in the first place. // VFS in the first place.
@@ -1050,19 +1063,21 @@ Volume::_RemovePackageNode(Directory* directory, PackageNode* packageNode,
status_t status_t
Volume::_CreateNode(mode_t mode, Directory* parent, const char* name, Volume::_CreateUnpackingNode(mode_t mode, Directory* parent, const char* name,
Node*& _node) UnpackingNode*& _node)
{ {
Node* node; UnpackingNode* unpackingNode;
if (S_ISREG(mode) || S_ISLNK(mode)) if (S_ISREG(mode) || S_ISLNK(mode))
node = new(std::nothrow) LeafNode(fNextNodeID++); unpackingNode = new(std::nothrow) LeafNode(fNextNodeID++);
else if (S_ISDIR(mode)) else if (S_ISDIR(mode))
node = new(std::nothrow) Directory(fNextNodeID++); unpackingNode = new(std::nothrow) Directory(fNextNodeID++);
else else
RETURN_ERROR(B_UNSUPPORTED); RETURN_ERROR(B_UNSUPPORTED);
if (node == NULL) if (unpackingNode == NULL)
RETURN_ERROR(B_NO_MEMORY); RETURN_ERROR(B_NO_MEMORY);
Node* node = unpackingNode->GetNode();
BReference<Node> nodeReference(node, true); BReference<Node> nodeReference(node, true);
status_t error = node->Init(parent, name); status_t error = node->Init(parent, name);
@@ -1075,7 +1090,7 @@ Volume::_CreateNode(mode_t mode, Directory* parent, const char* name,
nodeReference.Detach(); nodeReference.Detach();
// we keep the initial node reference for this table // we keep the initial node reference for this table
_node = node; _node = unpackingNode;
return B_OK; return B_OK;
} }
@@ -1327,23 +1342,25 @@ Volume::_CreateShineThroughDirectories(const char* shineThroughSetting)
} }
// create the directory // create the directory
Node* directory; UnpackingNode* directory;
error = _CreateNode(S_IFDIR, fRootDirectory, directoryName, directory); error = _CreateUnpackingNode(S_IFDIR, fRootDirectory, directoryName,
directory);
if (error != B_OK) if (error != B_OK)
RETURN_ERROR(error); RETURN_ERROR(error);
// publish its vnode, so the VFS will find it without asking us // publish its vnode, so the VFS will find it without asking us
error = PublishVNode(directory); Node* directoryNode = directory->GetNode();
error = PublishVNode(directoryNode);
if (error != B_OK) { if (error != B_OK) {
_RemoveNode(directory); _RemoveNode(directoryNode);
RETURN_ERROR(error); RETURN_ERROR(error);
} }
// bind the directory // bind the directory
error = vfs_bind_mount_directory(st.st_dev, st.st_ino, fFSVolume->id, error = vfs_bind_mount_directory(st.st_dev, st.st_ino, fFSVolume->id,
directory->ID()); directoryNode->ID());
PutVNode(directory->ID()); PutVNode(directoryNode->ID());
// release our reference again -- on success // release our reference again -- on success
// vfs_bind_mount_directory() got one // vfs_bind_mount_directory() got one
@@ -21,6 +21,7 @@
class Directory; class Directory;
class Node; class Node;
class PackageFSRoot; class PackageFSRoot;
class UnpackingNode;
enum MountType { enum MountType {
@@ -117,8 +118,9 @@ private:
PackageNode* packageNode, Node* node, PackageNode* packageNode, Node* node,
bool notify); bool notify);
status_t _CreateNode(mode_t mode, Directory* parent, status_t _CreateUnpackingNode(mode_t mode,
const char* name, Node*& _node); Directory* parent, const char* name,
UnpackingNode*& _node);
// does *not* return a reference // does *not* return a reference
void _RemoveNode(Node* node); void _RemoveNode(Node* node);