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:
@@ -99,6 +99,13 @@ Directory::FileSize() const
|
||||
}
|
||||
|
||||
|
||||
Node*
|
||||
Directory::GetNode()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Directory::AddPackageNode(PackageNode* packageNode)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "Node.h"
|
||||
#include "PackageDirectory.h"
|
||||
#include "UnpackingNode.h"
|
||||
|
||||
|
||||
struct DirectoryIterator : DoublyLinkedListLinkImpl<DirectoryIterator> {
|
||||
@@ -23,7 +24,7 @@ struct DirectoryIterator : DoublyLinkedListLinkImpl<DirectoryIterator> {
|
||||
typedef DoublyLinkedList<DirectoryIterator> DirectoryIteratorList;
|
||||
|
||||
|
||||
class Directory : public Node {
|
||||
class Directory : public Node, public UnpackingNode {
|
||||
public:
|
||||
Directory(ino_t id);
|
||||
virtual ~Directory();
|
||||
@@ -39,6 +40,8 @@ public:
|
||||
virtual timespec ModifiedTime() const;
|
||||
virtual off_t FileSize() const;
|
||||
|
||||
virtual Node* GetNode();
|
||||
|
||||
virtual status_t AddPackageNode(PackageNode* packageNode);
|
||||
virtual void RemovePackageNode(PackageNode* packageNode);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ HAIKU_PACKAGE_FS_SOURCES =
|
||||
Resolvable.cpp
|
||||
UnpackingAttributeCookie.cpp
|
||||
UnpackingAttributeDirectoryCookie.cpp
|
||||
UnpackingNode.cpp
|
||||
Version.cpp
|
||||
Volume.cpp
|
||||
;
|
||||
|
||||
@@ -98,6 +98,13 @@ LeafNode::FileSize() const
|
||||
}
|
||||
|
||||
|
||||
Node*
|
||||
LeafNode::GetNode()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
LeafNode::AddPackageNode(PackageNode* packageNode)
|
||||
{
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
|
||||
#include "Node.h"
|
||||
#include "PackageLeafNode.h"
|
||||
#include "UnpackingNode.h"
|
||||
|
||||
|
||||
class LeafNode : public Node {
|
||||
class LeafNode : public Node, public UnpackingNode {
|
||||
public:
|
||||
LeafNode(ino_t id);
|
||||
virtual ~LeafNode();
|
||||
@@ -26,6 +27,8 @@ public:
|
||||
virtual timespec ModifiedTime() const;
|
||||
virtual off_t FileSize() const;
|
||||
|
||||
virtual Node* GetNode();
|
||||
|
||||
virtual status_t AddPackageNode(PackageNode* packageNode);
|
||||
virtual void RemovePackageNode(PackageNode* packageNode);
|
||||
|
||||
|
||||
@@ -53,11 +53,6 @@ public:
|
||||
virtual timespec ModifiedTime() 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,
|
||||
size_t* bufferSize) = 0;
|
||||
virtual status_t Read(io_request* request) = 0;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "UnpackingNode.h"
|
||||
|
||||
|
||||
UnpackingNode::~UnpackingNode()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* 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 newNode = false;
|
||||
UnpackingNode* unpackingNode;
|
||||
Node* node = directory->FindChild(packageNode->Name());
|
||||
if (node == NULL) {
|
||||
status_t error = _CreateNode(packageNode->Mode(), directory,
|
||||
packageNode->Name(), node);
|
||||
|
||||
if (node != NULL) {
|
||||
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)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
node = unpackingNode->GetNode();
|
||||
newNode = true;
|
||||
}
|
||||
|
||||
BReference<Node> nodeReference(node);
|
||||
|
||||
status_t error = node->AddPackageNode(packageNode);
|
||||
status_t error = unpackingNode->AddPackageNode(packageNode);
|
||||
if (error != B_OK) {
|
||||
// remove the node, if created before
|
||||
if (newNode)
|
||||
@@ -971,7 +980,7 @@ Volume::_AddPackageNode(Directory* directory, PackageNode* packageNode,
|
||||
if (newNode) {
|
||||
notify_entry_created(ID(), directory->ID(), node->Name(),
|
||||
node->ID());
|
||||
} else if (packageNode == node->GetPackageNode()) {
|
||||
} else if (packageNode == unpackingNode->GetPackageNode()) {
|
||||
// The new package node has become the one representing the node.
|
||||
// Send stat changed notification for directories and entry
|
||||
// removed + created notifications for files and symlinks.
|
||||
@@ -999,15 +1008,19 @@ void
|
||||
Volume::_RemovePackageNode(Directory* directory, PackageNode* packageNode,
|
||||
Node* node, bool notify)
|
||||
{
|
||||
UnpackingNode* unpackingNode = dynamic_cast<UnpackingNode*>(node);
|
||||
if (unpackingNode == NULL)
|
||||
return;
|
||||
|
||||
BReference<Node> nodeReference(node);
|
||||
|
||||
PackageNode* headPackageNode = node->GetPackageNode();
|
||||
node->RemovePackageNode(packageNode);
|
||||
PackageNode* headPackageNode = unpackingNode->GetPackageNode();
|
||||
unpackingNode->RemovePackageNode(packageNode);
|
||||
|
||||
// If the node doesn't have any more package nodes attached, remove it
|
||||
// completely.
|
||||
bool nodeRemoved = false;
|
||||
if (node->GetPackageNode() == NULL) {
|
||||
if (unpackingNode->GetPackageNode() == NULL) {
|
||||
// we get and put the vnode to notify the VFS
|
||||
// TODO: We should probably only do that, if the node is known to the
|
||||
// VFS in the first place.
|
||||
@@ -1050,19 +1063,21 @@ Volume::_RemovePackageNode(Directory* directory, PackageNode* packageNode,
|
||||
|
||||
|
||||
status_t
|
||||
Volume::_CreateNode(mode_t mode, Directory* parent, const char* name,
|
||||
Node*& _node)
|
||||
Volume::_CreateUnpackingNode(mode_t mode, Directory* parent, const char* name,
|
||||
UnpackingNode*& _node)
|
||||
{
|
||||
Node* node;
|
||||
UnpackingNode* unpackingNode;
|
||||
if (S_ISREG(mode) || S_ISLNK(mode))
|
||||
node = new(std::nothrow) LeafNode(fNextNodeID++);
|
||||
unpackingNode = new(std::nothrow) LeafNode(fNextNodeID++);
|
||||
else if (S_ISDIR(mode))
|
||||
node = new(std::nothrow) Directory(fNextNodeID++);
|
||||
unpackingNode = new(std::nothrow) Directory(fNextNodeID++);
|
||||
else
|
||||
RETURN_ERROR(B_UNSUPPORTED);
|
||||
|
||||
if (node == NULL)
|
||||
if (unpackingNode == NULL)
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
|
||||
Node* node = unpackingNode->GetNode();
|
||||
BReference<Node> nodeReference(node, true);
|
||||
|
||||
status_t error = node->Init(parent, name);
|
||||
@@ -1075,7 +1090,7 @@ Volume::_CreateNode(mode_t mode, Directory* parent, const char* name,
|
||||
nodeReference.Detach();
|
||||
// we keep the initial node reference for this table
|
||||
|
||||
_node = node;
|
||||
_node = unpackingNode;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -1327,23 +1342,25 @@ Volume::_CreateShineThroughDirectories(const char* shineThroughSetting)
|
||||
}
|
||||
|
||||
// create the directory
|
||||
Node* directory;
|
||||
error = _CreateNode(S_IFDIR, fRootDirectory, directoryName, directory);
|
||||
UnpackingNode* directory;
|
||||
error = _CreateUnpackingNode(S_IFDIR, fRootDirectory, directoryName,
|
||||
directory);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
// 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) {
|
||||
_RemoveNode(directory);
|
||||
_RemoveNode(directoryNode);
|
||||
RETURN_ERROR(error);
|
||||
}
|
||||
|
||||
// bind the directory
|
||||
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
|
||||
// vfs_bind_mount_directory() got one
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
class Directory;
|
||||
class Node;
|
||||
class PackageFSRoot;
|
||||
class UnpackingNode;
|
||||
|
||||
|
||||
enum MountType {
|
||||
@@ -117,8 +118,9 @@ private:
|
||||
PackageNode* packageNode, Node* node,
|
||||
bool notify);
|
||||
|
||||
status_t _CreateNode(mode_t mode, Directory* parent,
|
||||
const char* name, Node*& _node);
|
||||
status_t _CreateUnpackingNode(mode_t mode,
|
||||
Directory* parent, const char* name,
|
||||
UnpackingNode*& _node);
|
||||
// does *not* return a reference
|
||||
void _RemoveNode(Node* node);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user