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
|
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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user