diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile b/src/add-ons/kernel/file_systems/packagefs/Jamfile index 0f5ef9500e..9431073366 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Jamfile +++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile @@ -20,10 +20,10 @@ HAIKU_PACKAGE_FS_SOURCES = Package.cpp PackageDirectory.cpp PackageDomain.cpp - PackageFamily.cpp PackageFile.cpp PackageFSRoot.cpp PackageLeafNode.cpp + PackageLinkDirectory.cpp PackageLinksDirectory.cpp PackageNode.cpp PackageNodeAttribute.cpp diff --git a/src/add-ons/kernel/file_systems/packagefs/Package.cpp b/src/add-ons/kernel/file_systems/packagefs/Package.cpp index 0221ce1ed4..487ffd0fdf 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Package.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Package.cpp @@ -25,7 +25,7 @@ Package::Package(PackageDomain* domain, dev_t deviceID, ino_t nodeID) fFileName(NULL), fName(NULL), fVersion(NULL), - fFamily(NULL), + fLinkDirectory(NULL), fFD(-1), fOpenCount(0), fNodeID(nodeID), diff --git a/src/add-ons/kernel/file_systems/packagefs/Package.h b/src/add-ons/kernel/file_systems/packagefs/Package.h index 7d63ac27d1..9ccc759164 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Package.h +++ b/src/add-ons/kernel/file_systems/packagefs/Package.h @@ -20,7 +20,7 @@ class PackageDomain; -class PackageFamily; +class PackageLinkDirectory; class Version; @@ -44,10 +44,11 @@ public: ::Version* Version() const { return fVersion; } - void SetFamily(PackageFamily* family) - { fFamily = family; } - PackageFamily* Family() const - { return fFamily; } + void SetLinkDirectory( + PackageLinkDirectory* linkDirectory) + { fLinkDirectory = linkDirectory; } + PackageLinkDirectory* LinkDirectory() const + { return fLinkDirectory; } Package*& FileNameHashTableNext() { return fFileNameHashTableNext; } @@ -67,7 +68,7 @@ private: char* fFileName; char* fName; ::Version* fVersion; - PackageFamily* fFamily; + PackageLinkDirectory* fLinkDirectory; int fFD; uint32 fOpenCount; Package* fFileNameHashTableNext; diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageFamily.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageFamily.cpp deleted file mode 100644 index 18ca55b67b..0000000000 --- a/src/add-ons/kernel/file_systems/packagefs/PackageFamily.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. - * Distributed under the terms of the MIT License. - */ - - -#include "PackageFamily.h" - -#include -#include - -#include "DebugSupport.h" -#include "Version.h" - - -PackageFamily::PackageFamily() - : - fName(NULL) -{ -} - - -PackageFamily::~PackageFamily() -{ - while (Package* package = fPackages.RemoveHead()) - package->SetFamily(NULL); - - free(fName); -} - - -status_t -PackageFamily::Init(Package* package) -{ - // compute the allocation size needed for the versioned name - size_t nameLength = strlen(package->Name()); - size_t size = nameLength + 1; - - Version* version = package->Version(); - if (version != NULL) { - size += 1 + version->ToString(NULL, 0); - // + 1 for the '-' - } - - // allocate the name and compose it - fName = (char*)malloc(size); - if (fName == NULL) - return B_NO_MEMORY; - - memcpy(fName, package->Name(), nameLength + 1); - if (version != NULL) { - fName[nameLength] = '-'; - version->ToString(fName + nameLength + 1, size - nameLength - 1); - } - - // add the package - AddPackage(package); - - return B_OK; -} - - -void -PackageFamily::AddPackage(Package* package) -{ - fPackages.Add(package); - package->SetFamily(this); -} - - -void -PackageFamily::RemovePackage(Package* package) -{ - ASSERT(package->Family() == this); - - package->SetFamily(NULL); - fPackages.Remove(package); -} diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageFamily.h b/src/add-ons/kernel/file_systems/packagefs/PackageFamily.h deleted file mode 100644 index 33939a0b54..0000000000 --- a/src/add-ons/kernel/file_systems/packagefs/PackageFamily.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. - * Distributed under the terms of the MIT License. - */ -#ifndef PACKAGE_FAMILY_H -#define PACKAGE_FAMILY_H - - -#include - -#include "Package.h" - - -/*! A set of equally named and versioned packages. - This should only happen when the same package is installed in multiple - domains (e.g. common and home). -*/ -class PackageFamily { -public: - PackageFamily(); - ~PackageFamily(); - - status_t Init(Package* package); - - const char* Name() const { return fName; } - - void AddPackage(Package* package); - void RemovePackage(Package* package); - - bool IsEmpty() const - { return fPackages.IsEmpty(); } - - PackageFamily*& HashNext() { return fHashNext; } - -private: - PackageFamily* fHashNext; - char* fName; - PackageList fPackages; -}; - - -struct PackageFamilyHashDefinition { - typedef const char* KeyType; - typedef PackageFamily ValueType; - - size_t HashKey(const char* key) const - { - return hash_hash_string(key); - } - - size_t Hash(const PackageFamily* value) const - { - return HashKey(value->Name()); - } - - bool Compare(const char* key, const PackageFamily* value) const - { - return strcmp(value->Name(), key) == 0; - } - - PackageFamily*& GetLink(PackageFamily* value) const - { - return value->HashNext(); - } -}; - - -typedef BOpenHashTable PackageFamilyHashTable; - - -#endif // PACKAGE_FAMILY_H diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp new file mode 100644 index 0000000000..fa735f3196 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp @@ -0,0 +1,151 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "PackageLinkDirectory.h" + +#include + +#include "EmptyAttributeDirectoryCookie.h" +#include "DebugSupport.h" +#include "Utils.h" +#include "Version.h" + + +PackageLinkDirectory::PackageLinkDirectory() + : + Directory(0) + // the ID needs to be assigned later, when added to a volume +{ + get_real_time(fModifiedTime); +} + + +PackageLinkDirectory::~PackageLinkDirectory() +{ +} + + +status_t +PackageLinkDirectory::Init(Directory* parent, Package* package) +{ + // compute the allocation size needed for the versioned name + size_t nameLength = strlen(package->Name()); + size_t size = nameLength + 1; + + Version* version = package->Version(); + if (version != NULL) { + size += 1 + version->ToString(NULL, 0); + // + 1 for the '-' + } + + // allocate the name and compose it + char* name = (char*)malloc(size); + if (name == NULL) + return B_NO_MEMORY; + MemoryDeleter nameDeleter(name); + + memcpy(name, package->Name(), nameLength + 1); + if (version != NULL) { + name[nameLength] = '-'; + version->ToString(name + nameLength + 1, size - nameLength - 1); + } + + // init the directory/node + status_t error = Init(parent, name); + // TODO: This copies the name unnecessarily! + if (error != B_OK) + RETURN_ERROR(error); + + // add the package + AddPackage(package); + + return B_OK; +} + + +status_t +PackageLinkDirectory::Init(Directory* parent, const char* name) +{ + return Directory::Init(parent, name); +} + + +mode_t +PackageLinkDirectory::Mode() const +{ + return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; +} + + +uid_t +PackageLinkDirectory::UserID() const +{ + return 0; +} + + +gid_t +PackageLinkDirectory::GroupID() const +{ + return 0; +} + + +timespec +PackageLinkDirectory::ModifiedTime() const +{ + return fModifiedTime; +} + + +off_t +PackageLinkDirectory::FileSize() const +{ + return 0; +} + + +status_t +PackageLinkDirectory::OpenAttributeDirectory( + AttributeDirectoryCookie*& _cookie) +{ + AttributeDirectoryCookie* cookie + = new(std::nothrow) EmptyAttributeDirectoryCookie; + if (cookie == NULL) + return B_NO_MEMORY; + + _cookie = cookie; + return B_OK; +} + + +status_t +PackageLinkDirectory::OpenAttribute(const char* name, int openMode, + AttributeCookie*& _cookie) +{ + return B_ENTRY_NOT_FOUND; +} + + +void +PackageLinkDirectory::AddPackage(Package* package) +{ + // TODO: Add in priority order! + fPackages.Add(package); + package->SetLinkDirectory(this); +} + + +void +PackageLinkDirectory::RemovePackage(Package* package) +{ + + ASSERT(package->LinkDirectory() == this); + + package->SetLinkDirectory(NULL); + fPackages.Remove(package); + // TODO: Check whether that was the top priority package! +} diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.h b/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.h new file mode 100644 index 0000000000..6b8841f340 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.h @@ -0,0 +1,44 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef PACKAGE_LINK_DIRECTORY_H +#define PACKAGE_LINK_DIRECTORY_H + + +#include "Directory.h" +#include "Package.h" + + +class PackageLinkDirectory : public Directory { +public: + PackageLinkDirectory(); + virtual ~PackageLinkDirectory(); + + status_t Init(Directory* parent, Package* package); + 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 timespec ModifiedTime() const; + virtual off_t FileSize() const; + + virtual status_t OpenAttributeDirectory( + AttributeDirectoryCookie*& _cookie); + virtual status_t OpenAttribute(const char* name, int openMode, + AttributeCookie*& _cookie); + + void AddPackage(Package* package); + void RemovePackage(Package* package); + + bool IsEmpty() const + { return fPackages.IsEmpty(); } + +private: + timespec fModifiedTime; + PackageList fPackages; +}; + + +#endif // PACKAGE_LINK_DIRECTORY_H diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.cpp index 48a9ac835f..c37182dec6 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.cpp @@ -10,6 +10,7 @@ #include "EmptyAttributeDirectoryCookie.h" #include "DebugSupport.h" +#include "PackageLinkDirectory.h" #include "Utils.h" @@ -30,10 +31,6 @@ PackageLinksDirectory::~PackageLinksDirectory() status_t PackageLinksDirectory::Init(Directory* parent, const char* name) { - status_t error = fPackageFamilies.Init(); - if (error != B_OK) - RETURN_ERROR(error); - return Directory::Init(parent, name); } @@ -98,26 +95,32 @@ PackageLinksDirectory::OpenAttribute(const char* name, int openMode, status_t PackageLinksDirectory::AddPackage(Package* package) { - // Create a package family -- there might already be one, but since that's - // unlikely, we don't bother to check and recheck later. - PackageFamily* packageFamily = new(std::nothrow) PackageFamily; - if (packageFamily == NULL) + // Create a package link directory -- there might already be one, but since + // that's unlikely, we don't bother to check and recheck later. + PackageLinkDirectory* linkDirectory + = new(std::nothrow) PackageLinkDirectory; + if (linkDirectory == NULL) return B_NO_MEMORY; - ObjectDeleter packageFamilyDeleter(packageFamily); + BReference linkDirectoryReference(linkDirectory, + true); - status_t error = packageFamily->Init(package); + status_t error = linkDirectory->Init(this, package); if (error != B_OK) RETURN_ERROR(error); - // add the family + // add the link directory NodeWriteLocker writeLocker(this); - if (PackageFamily* otherPackageFamily - = fPackageFamilies.Lookup(packageFamily->Name())) { - packageFamily->RemovePackage(package); - packageFamily = otherPackageFamily; - packageFamily->AddPackage(package); + if (Node* child = FindChild(linkDirectory->Name())) { + PackageLinkDirectory* otherLinkDirectory + = dynamic_cast(child); + if (otherLinkDirectory != NULL) + RETURN_ERROR(B_BAD_VALUE); + + linkDirectory->RemovePackage(package); + linkDirectory = otherLinkDirectory; + linkDirectory->AddPackage(package); } else - fPackageFamilies.Insert(packageFamilyDeleter.Detach()); + AddChild(linkDirectory); // TODO:... @@ -128,18 +131,20 @@ PackageLinksDirectory::AddPackage(Package* package) void PackageLinksDirectory::RemovePackage(Package* package) { - NodeWriteLocker writeLocker(this); - - PackageFamily* packageFamily = package->Family(); - if (packageFamily == NULL) + // get the package's link directory and remove the package from it + PackageLinkDirectory* linkDirectory = package->LinkDirectory(); + if (linkDirectory == NULL) return; - packageFamily->RemovePackage(package); + BReference linkDirectoryReference(linkDirectory); - if (packageFamily->IsEmpty()) { - fPackageFamilies.Remove(packageFamily); - delete packageFamily; - } + NodeWriteLocker writeLocker(this); + + linkDirectory->RemovePackage(package); + + // if empty, remove the link directory itself + if (linkDirectory->IsEmpty()) + RemoveChild(linkDirectory); // TODO:... } diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.h b/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.h index 0368c80a70..c1659ee324 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.h +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.h @@ -7,7 +7,9 @@ #include "Directory.h" -#include "PackageFamily.h" + + +class Package; class PackageLinksDirectory : public Directory { @@ -33,7 +35,6 @@ public: private: timespec fModifiedTime; - PackageFamilyHashTable fPackageFamilies; };