packagefs: Move Volume::PackagesDirectory to top level
Also make it a BReferenceable and fix Volume::fPackagesDirectory leak.
This commit is contained in:
@@ -51,6 +51,7 @@ HAIKU_PACKAGE_FS_SOURCES =
|
||||
PackageLinkSymlink.cpp
|
||||
PackageNode.cpp
|
||||
PackageNodeAttribute.cpp
|
||||
PackagesDirectory.cpp
|
||||
PackageSettings.cpp
|
||||
PackageSymlink.cpp
|
||||
Resolvable.cpp
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2009-2014, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "PackagesDirectory.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <fs/KPath.h>
|
||||
#include <team.h>
|
||||
#include <vfs.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2009-2014, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PACKAGES_DIRECTORY_H
|
||||
#define PACKAGES_DIRECTORY_H
|
||||
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <Referenceable.h>
|
||||
|
||||
|
||||
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
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009-2013, Ingo Weinhold, [email protected].
|
||||
* Copyright 2009-2014, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
#include <AutoDeleter.h>
|
||||
#include <PackagesDirectoryDefs.h>
|
||||
|
||||
#include <fs/KPath.h>
|
||||
#include <team.h>
|
||||
#include <vfs.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user