From 441b85e1cc56ed04ee4dedbd37d98186ad0a1e74 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 19 Jun 2011 15:29:22 +0200 Subject: [PATCH] Assign node IDs to packagefs nodes Fixes module loading. elf_load_image() checks the node ID to verify whether an image was already loaded, so giving all nodes the same ID only gets one image loaded. The IDs don't necessarily match the ones the kernel packagefs assigns, which could be a problem later on. --- .../file_systems/packagefs/packagefs.cpp | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp index eb6abc7f92..067d6596ec 100644 --- a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp +++ b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp @@ -64,6 +64,7 @@ struct PackageNode : DoublyLinkedListLinkImpl { fVolume(volume), fParentDirectory(NULL), fName(NULL), + fNodeID(0), fMode(mode) { fModifiedTime.tv_sec = 0; @@ -75,10 +76,11 @@ struct PackageNode : DoublyLinkedListLinkImpl { free(fName); } - status_t Init(PackageDirectory* parentDir, const char* name) + status_t Init(PackageDirectory* parentDir, const char* name, ino_t nodeID) { fParentDirectory = parentDir; fName = strdup(name); + fNodeID = nodeID; return fName != NULL ? B_OK : B_NO_MEMORY; } @@ -93,6 +95,11 @@ struct PackageNode : DoublyLinkedListLinkImpl { return fName; } + ino_t NodeID() const + { + return fNodeID; + } + mode_t Mode() const { return fMode; @@ -112,6 +119,7 @@ protected: PackageVolume* fVolume; PackageDirectory* fParentDirectory; char* fName; + ino_t fNodeID; mode_t fMode; timespec fModifiedTime; }; @@ -269,6 +277,7 @@ private: struct PackageVolume : BReferenceable { PackageVolume() : + fNextNodeID(1), fRootDirectory(this, S_IFDIR), fBufferCache(B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB, 2), fDataReaderFactory(&fBufferCache), @@ -284,7 +293,12 @@ struct PackageVolume : BReferenceable { status_t Init(int fd) { - status_t error = fBufferCache.Init(); + status_t error = fRootDirectory.Init(&fRootDirectory, ".", + NextNodeID()); + if (error != B_OK) + return error; + + error = fBufferCache.Init(); if (error != B_OK) return error; @@ -300,6 +314,11 @@ struct PackageVolume : BReferenceable { return &fRootDirectory; } + ino_t NextNodeID() + { + return fNextNodeID++; + } + void AddNode(PackageNode* node) { fRootDirectory.AddChild(node); @@ -324,6 +343,7 @@ struct PackageVolume : BReferenceable { } private: + ino_t fNextNodeID; PackageDirectory fRootDirectory; BBlockBufferCacheNoLock fBufferCache; BPackageDataReaderFactory fDataReaderFactory; @@ -408,7 +428,7 @@ struct PackageLoaderContentHandler : BPackageContentHandler { if (node == NULL) RETURN_ERROR(B_NO_MEMORY); - error = node->Init(parentDir, entry->Name()); + error = node->Init(parentDir, entry->Name(), fVolume->NextNodeID()); if (error != B_OK) { delete node; RETURN_ERROR(error); @@ -539,6 +559,11 @@ struct File : ::Node { return fFile->Size(); } + virtual ino_t Inode() const + { + return fFile->NodeID(); + } + private: PackageFile* fFile; }; @@ -600,6 +625,11 @@ struct Symlink : ::Node { return strlen(fSymlink->SymlinkPath()) + 1; } + virtual ino_t Inode() const + { + return fSymlink->NodeID(); + } + private: PackageSymlink* fSymlink; }; @@ -644,6 +674,11 @@ struct Directory : ::Directory { return fDirectory->Mode() & S_IFMT; } + virtual ino_t Inode() const + { + return fDirectory->NodeID(); + } + virtual status_t Open(void** _cookie, int mode) { if ((mode & O_ACCMODE) != O_RDONLY && (mode & O_ACCMODE) != O_RDWR)