From aeb6fc9eca1b3684f835b648e44ca877e29296ab Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 10 Feb 2014 22:16:48 +0100 Subject: [PATCH] packagefs: Move Volume::PackagesDirectory to top level Also make it a BReferenceable and fix Volume::fPackagesDirectory leak. --- .../kernel/file_systems/packagefs/Jamfile | 1 + .../packagefs/volume/PackagesDirectory.cpp | 94 ++++++++++++++ .../packagefs/volume/PackagesDirectory.h | 39 ++++++ .../file_systems/packagefs/volume/Volume.cpp | 117 +----------------- .../file_systems/packagefs/volume/Volume.h | 4 +- 5 files changed, 141 insertions(+), 114 deletions(-) create mode 100644 src/add-ons/kernel/file_systems/packagefs/volume/PackagesDirectory.cpp create mode 100644 src/add-ons/kernel/file_systems/packagefs/volume/PackagesDirectory.h diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile b/src/add-ons/kernel/file_systems/packagefs/Jamfile index 601bea20e7..47e4b2184c 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Jamfile +++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile @@ -51,6 +51,7 @@ HAIKU_PACKAGE_FS_SOURCES = PackageLinkSymlink.cpp PackageNode.cpp PackageNodeAttribute.cpp + PackagesDirectory.cpp PackageSettings.cpp PackageSymlink.cpp Resolvable.cpp diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/PackagesDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/volume/PackagesDirectory.cpp new file mode 100644 index 0000000000..34e4b7c412 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/volume/PackagesDirectory.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2009-2014, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "PackagesDirectory.h" + +#include + +#include +#include +#include + +#include "DebugSupport.h" + + +PackagesDirectory::PackagesDirectory() + : + fPath(NULL), + fDirFD(-1) +{ +} + + +PackagesDirectory::~PackagesDirectory() +{ + if (fDirFD >= 0) + close(fDirFD); + + free(fPath); +} + + +status_t PackagesDirectory::Init(const char* path, dev_t mountPointDeviceID, + ino_t mountPointNodeID, struct stat& _st) +{ + // Open the directory. We want the path be interpreted depending on from + // where it came (kernel or userland), but we always want a FD in the + // kernel I/O context. There's no VFS service method to do that for us, + // so we need to do that ourselves. + bool calledFromKernel + = team_get_current_team_id() == team_get_kernel_team_id(); + // Not entirely correct, but good enough for now. The only + // alternative is to have that information passed in as well. + + struct vnode* vnode; + status_t error; + if (path != NULL) { + error = vfs_get_vnode_from_path(path, calledFromKernel, &vnode); + } else { + // No path given -- use the "packages" directory at our mount point. + error = vfs_entry_ref_to_vnode(mountPointDeviceID, mountPointNodeID, + "packages", &vnode); + } + if (error != B_OK) { + ERROR("Failed to open package domain \"%s\"\n", strerror(error)); + RETURN_ERROR(error); + } + + fDirFD = vfs_open_vnode(vnode, O_RDONLY, true); + + if (fDirFD < 0) { + ERROR("Failed to open package domain \"%s\"\n", strerror(fDirFD)); + vfs_put_vnode(vnode); + RETURN_ERROR(fDirFD); + } + // Our vnode reference has been transferred to the FD. + + // Is it a directory at all? + struct stat& st = _st; + if (fstat(fDirFD, &st) < 0) + RETURN_ERROR(errno); + + fDeviceID = st.st_dev; + fNodeID = st.st_ino; + + // get a normalized path + KPath normalizedPath; + if (normalizedPath.InitCheck() != B_OK) + RETURN_ERROR(normalizedPath.InitCheck()); + + char* normalizedPathBuffer = normalizedPath.LockBuffer(); + error = vfs_entry_ref_to_path(fDeviceID, fNodeID, NULL, true, + normalizedPathBuffer, normalizedPath.BufferSize()); + if (error != B_OK) + RETURN_ERROR(error); + + fPath = strdup(normalizedPathBuffer); + if (fPath == NULL) + RETURN_ERROR(B_NO_MEMORY); + + return B_OK; +} diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/PackagesDirectory.h b/src/add-ons/kernel/file_systems/packagefs/volume/PackagesDirectory.h new file mode 100644 index 0000000000..85b2e61279 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/volume/PackagesDirectory.h @@ -0,0 +1,39 @@ +/* + * Copyright 2009-2014, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef PACKAGES_DIRECTORY_H +#define PACKAGES_DIRECTORY_H + + +#include + +#include + + +class PackagesDirectory : public BReferenceable { +public: + PackagesDirectory(); + ~PackagesDirectory(); + + const char* Path() const + { return fPath; } + int DirectoryFD() const + { return fDirFD; } + dev_t DeviceID() const + { return fDeviceID; } + ino_t NodeID() const + { return fNodeID; } + + status_t Init(const char* path, dev_t mountPointDeviceID, + ino_t mountPointNodeID, struct stat& _st); + +private: + char* fPath; + int fDirFD; + dev_t fDeviceID; + ino_t fNodeID; +}; + + +#endif // PACKAGES_DIRECTORY_H diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp index 7433c70870..66f9113c61 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2009-2014, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -24,8 +24,6 @@ #include #include -#include -#include #include #include "AttributeIndex.h" @@ -37,6 +35,7 @@ #include "PackageFSRoot.h" #include "PackageLinkDirectory.h" #include "PackageLinksDirectory.h" +#include "PackagesDirectory.h" #include "Resolvable.h" #include "SizeIndex.h" #include "UnpackingLeafNode.h" @@ -71,115 +70,6 @@ static const char* const kActivationFilePath // #pragma mark - ShineThroughDirectory -struct Volume::PackagesDirectory { - PackagesDirectory() - : - fPath(NULL), - fDirFD(-1) - { - } - - - ~PackagesDirectory() - { - if (fDirFD >= 0) - close(fDirFD); - - free(fPath); - } - - const char* Path() const - { - return fPath; - } - - int DirectoryFD() const - { - return fDirFD; - } - - dev_t DeviceID() const - { - return fDeviceID; - } - - ino_t NodeID() const - { - return fNodeID; - } - - status_t Init(const char* path, dev_t mountPointDeviceID, - ino_t mountPointNodeID, struct stat& _st) - { - // Open the directory. We want the path be interpreted depending on from - // where it came (kernel or userland), but we always want a FD in the - // kernel I/O context. There's no VFS service method to do that for us, - // so we need to do that ourselves. - bool calledFromKernel - = team_get_current_team_id() == team_get_kernel_team_id(); - // Not entirely correct, but good enough for now. The only - // alternative is to have that information passed in as well. - - struct vnode* vnode; - status_t error; - if (path != NULL) { - error = vfs_get_vnode_from_path(path, calledFromKernel, &vnode); - } else { - // No path given -- use the "packages" directory at our mount point. - error = vfs_entry_ref_to_vnode(mountPointDeviceID, mountPointNodeID, - "packages", &vnode); - } - if (error != B_OK) { - ERROR("Failed to open package domain \"%s\"\n", strerror(error)); - RETURN_ERROR(error); - } - - fDirFD = vfs_open_vnode(vnode, O_RDONLY, true); - - if (fDirFD < 0) { - ERROR("Failed to open package domain \"%s\"\n", strerror(fDirFD)); - vfs_put_vnode(vnode); - RETURN_ERROR(fDirFD); - } - // Our vnode reference has been transferred to the FD. - - // Is it a directory at all? - struct stat& st = _st; - if (fstat(fDirFD, &st) < 0) - RETURN_ERROR(errno); - - fDeviceID = st.st_dev; - fNodeID = st.st_ino; - - // get a normalized path - KPath normalizedPath; - if (normalizedPath.InitCheck() != B_OK) - RETURN_ERROR(normalizedPath.InitCheck()); - - char* normalizedPathBuffer = normalizedPath.LockBuffer(); - error = vfs_entry_ref_to_path(fDeviceID, fNodeID, NULL, true, - normalizedPathBuffer, normalizedPath.BufferSize()); - if (error != B_OK) - RETURN_ERROR(error); - - fPath = strdup(normalizedPathBuffer); - if (fPath == NULL) - RETURN_ERROR(B_NO_MEMORY); - - return B_OK; - } - -private: - char* fPath; - int fDirFD; - dev_t fDeviceID; - ino_t fNodeID; -}; - - -// #pragma mark - ShineThroughDirectory - - struct Volume::ShineThroughDirectory : public Directory { ShineThroughDirectory(ino_t id) : @@ -323,6 +213,9 @@ Volume::~Volume() if (fRootDirectory != NULL) fRootDirectory->ReleaseReference(); + if (fPackagesDirectory != NULL) + fPackagesDirectory->ReleaseReference(); + rw_lock_destroy(&fLock); } diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h index 4df34f8995..d87f00bb9e 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h +++ b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h @@ -1,5 +1,5 @@ /* - * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2009-2014, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #ifndef VOLUME_H @@ -27,6 +27,7 @@ class Directory; class PackageFSRoot; +class PackagesDirectory; class UnpackingNode; typedef IndexHashTable::Iterator IndexDirIterator; @@ -106,7 +107,6 @@ private: const OldNodeAttributes& oldAttributes); private: - struct PackagesDirectory; struct ShineThroughDirectory; struct ActivationChangeRequest;