From 694cb0b270e4acba08d83b0a520217081011ba28 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 17 Nov 2009 16:10:21 +0000 Subject: [PATCH] * Implemented intermediate base class PackageLeafNode for PackageFile and PackageSymlink with a "fat" interface. * Replaced File and Symlink by fat class LeafNode. * Added Package* object management to Directory and LeafNode. * Implemented packagefs_read_symlink(), so symlinks work now. * Added some missing locking the kernel interface. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34096 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../file_systems/packagefs/Directory.cpp | 34 ++++++++- .../kernel/file_systems/packagefs/Directory.h | 6 ++ .../kernel/file_systems/packagefs/File.cpp | 41 ---------- .../kernel/file_systems/packagefs/File.h | 23 ------ .../kernel/file_systems/packagefs/Jamfile | 4 +- .../file_systems/packagefs/LeafNode.cpp | 74 +++++++++++++++++++ .../kernel/file_systems/packagefs/LeafNode.h | 33 +++++++++ .../kernel/file_systems/packagefs/Node.h | 8 +- .../packagefs/PackageDirectory.cpp | 4 +- .../file_systems/packagefs/PackageDirectory.h | 10 ++- .../file_systems/packagefs/PackageFile.cpp | 5 +- .../file_systems/packagefs/PackageFile.h | 12 ++- .../packagefs/PackageLeafNode.cpp | 26 +++++++ .../file_systems/packagefs/PackageLeafNode.h | 32 ++++++++ .../file_systems/packagefs/PackageNode.cpp | 7 +- .../file_systems/packagefs/PackageNode.h | 13 +++- .../file_systems/packagefs/PackageSymlink.cpp | 27 ++++++- .../file_systems/packagefs/PackageSymlink.h | 13 +++- .../kernel/file_systems/packagefs/Symlink.cpp | 41 ---------- .../kernel/file_systems/packagefs/Symlink.h | 23 ------ .../kernel/file_systems/packagefs/Volume.cpp | 35 ++++++--- .../packagefs/kernel_interface.cpp | 33 ++++++++- 22 files changed, 336 insertions(+), 168 deletions(-) delete mode 100644 src/add-ons/kernel/file_systems/packagefs/File.cpp delete mode 100644 src/add-ons/kernel/file_systems/packagefs/File.h create mode 100644 src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp create mode 100644 src/add-ons/kernel/file_systems/packagefs/LeafNode.h create mode 100644 src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.cpp create mode 100644 src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.h delete mode 100644 src/add-ons/kernel/file_systems/packagefs/Symlink.cpp delete mode 100644 src/add-ons/kernel/file_systems/packagefs/Symlink.h diff --git a/src/add-ons/kernel/file_systems/packagefs/Directory.cpp b/src/add-ons/kernel/file_systems/packagefs/Directory.cpp index eda9f0eb7e..2d98ef6981 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Directory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Directory.cpp @@ -7,14 +7,12 @@ #include "Directory.h" #include "DebugSupport.h" -#include "PackageDirectory.h" Directory::Directory(ino_t id) : Node(id) { - fMode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; } @@ -40,13 +38,43 @@ Directory::Init(Directory* parent, const char* name) } +mode_t +Directory::Mode() const +{ + if (PackageDirectory* packageDirectory = fPackageDirectories.Head()) + return packageDirectory->Mode(); + return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; +} + + +uid_t +Directory::UserID() const +{ + if (PackageDirectory* packageDirectory = fPackageDirectories.Head()) + return packageDirectory->UserID(); + return 0; +} + + +gid_t +Directory::GroupID() const +{ + if (PackageDirectory* packageDirectory = fPackageDirectories.Head()) + return packageDirectory->GroupID(); + return 0; +} + + status_t Directory::AddPackageNode(PackageNode* packageNode) { if (!S_ISDIR(packageNode->Mode())) return B_BAD_VALUE; -// TODO:... + PackageDirectory* packageDirectory + = dynamic_cast(packageNode); + + fPackageDirectories.Add(packageDirectory); return B_OK; } diff --git a/src/add-ons/kernel/file_systems/packagefs/Directory.h b/src/add-ons/kernel/file_systems/packagefs/Directory.h index 32038c5e74..062c56650d 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Directory.h +++ b/src/add-ons/kernel/file_systems/packagefs/Directory.h @@ -7,6 +7,7 @@ #include "Node.h" +#include "PackageDirectory.h" @@ -30,6 +31,10 @@ public: virtual status_t Init(Directory* parent, const char* name); + virtual mode_t Mode() const; + virtual uid_t UserID() const; + virtual gid_t GroupID() const; + virtual status_t AddPackageNode(PackageNode* packageNode); void AddChild(Node* node); @@ -47,6 +52,7 @@ public: private: NodeNameHashTable fChildTable; NodeList fChildList; + PackageDirectoryList fPackageDirectories; DirectoryIteratorList fIterators; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/File.cpp b/src/add-ons/kernel/file_systems/packagefs/File.cpp deleted file mode 100644 index 0d7731d059..0000000000 --- a/src/add-ons/kernel/file_systems/packagefs/File.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Distributed under the terms of the MIT License. - */ - - -#include "File.h" - -#include "PackageFile.h" - - -File::File(ino_t id) - : - Node(id) -{ - fMode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH; -} - - -File::~File() -{ -} - - -status_t -File::Init(Directory* parent, const char* name) -{ - return Node::Init(parent, name); -} - - -status_t -File::AddPackageNode(PackageNode* packageNode) -{ - if (!S_ISREG(packageNode->Mode())) - return B_BAD_VALUE; - -// TODO:... - - return B_OK; -} diff --git a/src/add-ons/kernel/file_systems/packagefs/File.h b/src/add-ons/kernel/file_systems/packagefs/File.h deleted file mode 100644 index b8c378aeff..0000000000 --- a/src/add-ons/kernel/file_systems/packagefs/File.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Distributed under the terms of the MIT License. - */ -#ifndef FILE_H -#define FILE_H - - -#include "Node.h" - - -class File : public Node { -public: - File(ino_t id); - virtual ~File(); - - virtual status_t Init(Directory* parent, const char* name); - - virtual status_t AddPackageNode(PackageNode* packageNode); -}; - - -#endif // FILE_H diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile b/src/add-ons/kernel/file_systems/packagefs/Jamfile index e9fb6dc740..8c18036147 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Jamfile +++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile @@ -12,16 +12,16 @@ DEFINES += B_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT ; HAIKU_PACKAGE_FS_SOURCES = DebugSupport.cpp Directory.cpp - File.cpp kernel_interface.cpp + LeafNode.cpp Node.cpp Package.cpp PackageDirectory.cpp PackageDomain.cpp PackageFile.cpp + PackageLeafNode.cpp PackageNode.cpp PackageSymlink.cpp - Symlink.cpp Volume.cpp ; diff --git a/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp b/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp new file mode 100644 index 0000000000..df8d8cb525 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/LeafNode.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "LeafNode.h" + + +LeafNode::LeafNode(ino_t id) + : + Node(id) +{ +} + + +LeafNode::~LeafNode() +{ +} + + +status_t +LeafNode::Init(Directory* parent, const char* name) +{ + return Node::Init(parent, name); +} + + +mode_t +LeafNode::Mode() const +{ + if (PackageLeafNode* packageNode = fPackageNodes.Head()) + return packageNode->Mode(); + return S_IFREG | S_IRUSR | S_IRGRP | S_IROTH; +} + + +uid_t +LeafNode::UserID() const +{ + if (PackageLeafNode* packageNode = fPackageNodes.Head()) + return packageNode->UserID(); + return 0; +} + + +gid_t +LeafNode::GroupID() const +{ + if (PackageLeafNode* packageNode = fPackageNodes.Head()) + return packageNode->GroupID(); + return 0; +} + + +status_t +LeafNode::AddPackageNode(PackageNode* packageNode) +{ + if (S_ISDIR(packageNode->Mode())) + return B_BAD_VALUE; + + fPackageNodes.Add(dynamic_cast(packageNode)); + + return B_OK; +} + + +const char* +LeafNode::SymlinkPath() const +{ + if (PackageLeafNode* packageNode = fPackageNodes.Head()) + return packageNode->SymlinkPath(); + return NULL; +} diff --git a/src/add-ons/kernel/file_systems/packagefs/LeafNode.h b/src/add-ons/kernel/file_systems/packagefs/LeafNode.h new file mode 100644 index 0000000000..b36b8f6f33 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/LeafNode.h @@ -0,0 +1,33 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef LEAF_NODE_H +#define LEAF_NODE_H + + +#include "Node.h" +#include "PackageLeafNode.h" + + +class LeafNode : public Node { +public: + LeafNode(ino_t id); + virtual ~LeafNode(); + + virtual status_t Init(Directory* parent, const char* name); + + virtual mode_t Mode() const; + virtual uid_t UserID() const; + virtual gid_t GroupID() const; + + virtual status_t AddPackageNode(PackageNode* packageNode); + + const char* SymlinkPath() const; + +private: + PackageLeafNodeList fPackageNodes; +}; + + +#endif // LEAF_NODE_H diff --git a/src/add-ons/kernel/file_systems/packagefs/Node.h b/src/add-ons/kernel/file_systems/packagefs/Node.h index 793e3c9bcc..9df909c788 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Node.h +++ b/src/add-ons/kernel/file_systems/packagefs/Node.h @@ -40,12 +40,12 @@ public: Node*& IDHashTableNext() { return fIDHashTableNext; } - mode_t Mode() const { return fMode; } - uid_t UserID() const { return fUserID; } - gid_t GroupID() const { return fGroupID; } - virtual status_t Init(Directory* parent, const char* name); + virtual mode_t Mode() const = 0; + virtual uid_t UserID() const = 0; + virtual gid_t GroupID() const = 0; + virtual status_t AddPackageNode(PackageNode* packageNode) = 0; protected: diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageDirectory.cpp index e551dbe217..02876e1d41 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageDirectory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageDirectory.cpp @@ -7,7 +7,9 @@ #include "PackageDirectory.h" -PackageDirectory::PackageDirectory() +PackageDirectory::PackageDirectory(mode_t mode) + : + PackageNode(mode) { } diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageDirectory.h b/src/add-ons/kernel/file_systems/packagefs/PackageDirectory.h index 21a25c8cc3..e2d01fb043 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageDirectory.h +++ b/src/add-ons/kernel/file_systems/packagefs/PackageDirectory.h @@ -6,12 +6,15 @@ #define PACKAGE_DIRECTORY_H +#include + #include "PackageNode.h" -class PackageDirectory : public PackageNode { +class PackageDirectory : public PackageNode, + public DoublyLinkedListLinkImpl { public: - PackageDirectory(); + PackageDirectory(mode_t mode); virtual ~PackageDirectory(); void AddChild(PackageNode* node); @@ -42,4 +45,7 @@ PackageDirectory::NextChild(PackageNode* node) const } +typedef DoublyLinkedList PackageDirectoryList; + + #endif // PACKAGE_DIRECTORY_H diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageFile.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageFile.cpp index 07883d5bb8..46534c8dfc 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageFile.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageFile.cpp @@ -7,7 +7,10 @@ #include "PackageFile.h" -PackageFile::PackageFile() +PackageFile::PackageFile(mode_t mode, const PackageData& data) + : + PackageLeafNode(mode), + fData(data) { } diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageFile.h b/src/add-ons/kernel/file_systems/packagefs/PackageFile.h index 07ff1a4612..3232104d77 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageFile.h +++ b/src/add-ons/kernel/file_systems/packagefs/PackageFile.h @@ -6,13 +6,19 @@ #define PACKAGE_FILE_H -#include "PackageNode.h" +#include "PackageData.h" + +#include "PackageLeafNode.h" -class PackageFile : public PackageNode { +class PackageFile : public PackageLeafNode { public: - PackageFile(); + PackageFile(mode_t mode, + const PackageData& data); virtual ~PackageFile(); + +private: + PackageData fData; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.cpp new file mode 100644 index 0000000000..c8fcd51702 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "PackageLeafNode.h" + + +PackageLeafNode::PackageLeafNode(mode_t mode) + : + PackageNode(mode) +{ +} + + +PackageLeafNode::~PackageLeafNode() +{ +} + + +const char* +PackageLeafNode::SymlinkPath() const +{ + return NULL; +} diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.h b/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.h new file mode 100644 index 0000000000..01bbce1028 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLeafNode.h @@ -0,0 +1,32 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef PACKAGE_LEAF_NODE_H +#define PACKAGE_LEAF_NODE_H + + +#include "PackageNode.h" + + +class PackageData; + + +class PackageLeafNode : public PackageNode { +public: + PackageLeafNode(mode_t mode); + virtual ~PackageLeafNode(); + + virtual const char* SymlinkPath() const; + +public: + SinglyLinkedListLink fListLink; +}; + + +typedef SinglyLinkedList > PackageLeafNodeList; + + +#endif // PACKAGE_LEAF_NODE_H diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageNode.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageNode.cpp index 56df511ed1..8134b3fbc6 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageNode.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageNode.cpp @@ -12,10 +12,13 @@ #include "DebugSupport.h" -PackageNode::PackageNode() +PackageNode::PackageNode(mode_t mode) : fParent(NULL), - fName(NULL) + fName(NULL), + fMode(mode), + fUserID(0), + fGroupID(0) { } diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageNode.h b/src/add-ons/kernel/file_systems/packagefs/PackageNode.h index 5db12f1632..291b431964 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageNode.h +++ b/src/add-ons/kernel/file_systems/packagefs/PackageNode.h @@ -16,7 +16,7 @@ class PackageDirectory; class PackageNode : public SinglyLinkedListLinkImpl { public: - PackageNode(); + PackageNode(mode_t mode); virtual ~PackageNode(); PackageDirectory* Parent() const { return fParent; } @@ -25,13 +25,20 @@ public: virtual status_t Init(PackageDirectory* parent, const char* name); - void SetMode(mode_t mode) { fMode = mode; } mode_t Mode() const { return fMode; } -private: + uid_t UserID() const { return fUserID; } + void SetUserID(uid_t id) { fUserID = id; } + + gid_t GroupID() const { return fGroupID; } + void SetGroupID(gid_t id) { fGroupID = id; } + +protected: PackageDirectory* fParent; char* fName; mode_t fMode; + uid_t fUserID; + gid_t fGroupID; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageSymlink.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageSymlink.cpp index 53c4de1e1f..d23c8bea64 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageSymlink.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageSymlink.cpp @@ -6,12 +6,37 @@ #include "PackageSymlink.h" +#include +#include -PackageSymlink::PackageSymlink() + +PackageSymlink::PackageSymlink(mode_t mode) + : + PackageLeafNode(mode), + fSymlinkPath(NULL) { } PackageSymlink::~PackageSymlink() { + free(fSymlinkPath); +} + + +status_t +PackageSymlink::SetSymlinkPath(const char* path) +{ + if (path == NULL) + return B_OK; + + fSymlinkPath = strdup(path); + return fSymlinkPath != NULL ? B_OK : B_NO_MEMORY; +} + + +const char* +PackageSymlink::SymlinkPath() const +{ + return fSymlinkPath; } diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageSymlink.h b/src/add-ons/kernel/file_systems/packagefs/PackageSymlink.h index 62d9e94c43..5979422a05 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageSymlink.h +++ b/src/add-ons/kernel/file_systems/packagefs/PackageSymlink.h @@ -6,13 +6,20 @@ #define PACKAGE_SYMLINK_H -#include "PackageNode.h" +#include "PackageLeafNode.h" -class PackageSymlink : public PackageNode { +class PackageSymlink : public PackageLeafNode { public: - PackageSymlink(); + PackageSymlink(mode_t mode); virtual ~PackageSymlink(); + + status_t SetSymlinkPath(const char* path); + + virtual const char* SymlinkPath() const; + +private: + char* fSymlinkPath; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/Symlink.cpp b/src/add-ons/kernel/file_systems/packagefs/Symlink.cpp deleted file mode 100644 index 3e812df8ee..0000000000 --- a/src/add-ons/kernel/file_systems/packagefs/Symlink.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Distributed under the terms of the MIT License. - */ - - -#include "Symlink.h" - -#include "PackageSymlink.h" - - -Symlink::Symlink(ino_t id) - : - Node(id) -{ - fMode = S_IFLNK | S_IRUSR | S_IRGRP | S_IROTH; -} - - -Symlink::~Symlink() -{ -} - - -status_t -Symlink::Init(Directory* parent, const char* name) -{ - return Node::Init(parent, name); -} - - -status_t -Symlink::AddPackageNode(PackageNode* packageNode) -{ - if (!S_ISLNK(packageNode->Mode())) - return B_BAD_VALUE; - -// TODO:... - - return B_OK; -} diff --git a/src/add-ons/kernel/file_systems/packagefs/Symlink.h b/src/add-ons/kernel/file_systems/packagefs/Symlink.h deleted file mode 100644 index 989915c2cd..0000000000 --- a/src/add-ons/kernel/file_systems/packagefs/Symlink.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Distributed under the terms of the MIT License. - */ -#ifndef SYMLINK_H -#define SYMLINK_H - - -#include "Node.h" - - -class Symlink : public Node { -public: - Symlink(ino_t id); - virtual ~Symlink(); - - virtual status_t Init(Directory* parent, const char* name); - - virtual status_t AddPackageNode(PackageNode* packageNode); -}; - - -#endif // SYMLINK_H diff --git a/src/add-ons/kernel/file_systems/packagefs/Volume.cpp b/src/add-ons/kernel/file_systems/packagefs/Volume.cpp index 338fca6a96..5ed64f1e7d 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Volume.cpp @@ -25,12 +25,11 @@ #include "DebugSupport.h" #include "Directory.h" -#include "File.h" +#include "LeafNode.h" #include "kernel_interface.h" #include "PackageDirectory.h" #include "PackageFile.h" #include "PackageSymlink.h" -#include "Symlink.h" // node ID of the root directory @@ -133,14 +132,30 @@ struct Volume::PackageLoaderContentHandler : PackageContentHandler { RETURN_ERROR(B_BAD_DATA); } + status_t error; + // create the package node PackageNode* node; if (S_ISREG(entry->Mode())) { - node = new(std::nothrow) PackageFile; + // file + node = new(std::nothrow) PackageFile(entry->Mode(), entry->Data()); } else if (S_ISLNK(entry->Mode())) { - node = new(std::nothrow) PackageSymlink; + // symlink + PackageSymlink* symlink = new(std::nothrow) PackageSymlink( + entry->Mode()); + if (symlink == NULL) + RETURN_ERROR(B_NO_MEMORY); + + error = symlink->SetSymlinkPath(entry->SymlinkPath()); + if (error != B_OK) { + delete symlink; + return error; + } + + node = symlink; } else if (S_ISDIR(entry->Mode())) { - node = new(std::nothrow) PackageDirectory; + // directory + node = new(std::nothrow) PackageDirectory(entry->Mode()); } else RETURN_ERROR(B_BAD_DATA); @@ -148,12 +163,10 @@ struct Volume::PackageLoaderContentHandler : PackageContentHandler { RETURN_ERROR(B_NO_MEMORY); ObjectDeleter nodeDeleter(node); - status_t error = node->Init(parentDir, entry->Name()); + error = node->Init(parentDir, entry->Name()); if (error != B_OK) RETURN_ERROR(error); - node->SetMode(entry->Mode()); - // add it to the parent directory if (parentDir != NULL) parentDir->AddChild(node); @@ -579,10 +592,8 @@ Volume::_CreateNode(mode_t mode, Directory* parent, const char* name, Node*& _node) { Node* node; - if (S_ISREG(mode)) - node = new(std::nothrow) File(fNextNodeID++); - else if (S_ISLNK(mode)) - node = new(std::nothrow) Symlink(fNextNodeID++); + if (S_ISREG(mode) || S_ISLNK(mode)) + node = new(std::nothrow) LeafNode(fNextNodeID++); else if (S_ISDIR(mode)) node = new(std::nothrow) Directory(fNextNodeID++); else diff --git a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp index d0cf4e4921..bef87fb4b4 100644 --- a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp @@ -8,6 +8,7 @@ #include +#include #include #include @@ -18,6 +19,7 @@ #include "DebugSupport.h" #include "Directory.h" +#include "LeafNode.h" #include "Volume.h" @@ -200,9 +202,30 @@ packagefs_put_vnode(fs_volume* fsVolume, fs_vnode* fsNode, bool reenter) static status_t packagefs_read_symlink(fs_volume* fsVolume, fs_vnode* fsNode, char* buffer, - size_t* bufferSize) + size_t* _bufferSize) { - return B_UNSUPPORTED; + Volume* volume = (Volume*)fsVolume->private_volume; + Node* node = (Node*)fsNode->private_node; + + FUNCTION("volume: %p, node: %p (%lld)\n", volume, node, node->ID()); + TOUCH(volume); + + NodeReadLocker nodeLocker(node); + + if (!S_ISLNK(node->Mode())) + return B_BAD_VALUE; + + const char* linkPath = dynamic_cast(node)->SymlinkPath(); + if (linkPath == NULL) { + *_bufferSize = 0; + return B_OK; + } + + size_t toCopy = std::min(strlen(linkPath), *_bufferSize); + memcpy(buffer, linkPath, toCopy); + *_bufferSize = toCopy; + + return B_OK; } @@ -211,7 +234,6 @@ packagefs_access(fs_volume* fsVolume, fs_vnode* fsNode, int mode) { Volume* volume = (Volume*)fsVolume->private_volume; Node* node = (Node*)fsNode->private_node; - TOUCH(volume); FUNCTION("volume: %p, node: %p (%lld)\n", volume, node, node->ID()); TOUCH(volume); @@ -220,6 +242,8 @@ packagefs_access(fs_volume* fsVolume, fs_vnode* fsNode, int mode) if (mode & W_OK) return B_READ_ONLY_DEVICE; + NodeReadLocker nodeLocker(node); + // get node permissions int userPermissions = (node->Mode() & S_IRWXU) >> 6; int groupPermissions = (node->Mode() & S_IRWXG) >> 3; @@ -259,6 +283,8 @@ packagefs_read_stat(fs_volume* fsVolume, fs_vnode* fsNode, struct stat* st) FUNCTION("volume: %p, node: %p (%lld)\n", volume, node, node->ID()); TOUCH(volume); + NodeReadLocker nodeLocker(node); + // TODO: Fill in correctly! st->st_mode = node->Mode(); st->st_nlink = 1; @@ -418,6 +444,7 @@ packagefs_open_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** _cookie) Directory* dir = dynamic_cast(node); // create a cookie + NodeWriteLocker dirLocker(dir); DirectoryCookie* cookie = new(std::nothrow) DirectoryCookie(dir); if (cookie == NULL) RETURN_ERROR(B_NO_MEMORY);