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.
This commit is contained in:
Ingo Weinhold
2011-07-17 16:54:16 +02:00
parent 533833f646
commit 441b85e1cc
@@ -64,6 +64,7 @@ struct PackageNode : DoublyLinkedListLinkImpl<PackageNode> {
fVolume(volume), fVolume(volume),
fParentDirectory(NULL), fParentDirectory(NULL),
fName(NULL), fName(NULL),
fNodeID(0),
fMode(mode) fMode(mode)
{ {
fModifiedTime.tv_sec = 0; fModifiedTime.tv_sec = 0;
@@ -75,10 +76,11 @@ struct PackageNode : DoublyLinkedListLinkImpl<PackageNode> {
free(fName); free(fName);
} }
status_t Init(PackageDirectory* parentDir, const char* name) status_t Init(PackageDirectory* parentDir, const char* name, ino_t nodeID)
{ {
fParentDirectory = parentDir; fParentDirectory = parentDir;
fName = strdup(name); fName = strdup(name);
fNodeID = nodeID;
return fName != NULL ? B_OK : B_NO_MEMORY; return fName != NULL ? B_OK : B_NO_MEMORY;
} }
@@ -93,6 +95,11 @@ struct PackageNode : DoublyLinkedListLinkImpl<PackageNode> {
return fName; return fName;
} }
ino_t NodeID() const
{
return fNodeID;
}
mode_t Mode() const mode_t Mode() const
{ {
return fMode; return fMode;
@@ -112,6 +119,7 @@ protected:
PackageVolume* fVolume; PackageVolume* fVolume;
PackageDirectory* fParentDirectory; PackageDirectory* fParentDirectory;
char* fName; char* fName;
ino_t fNodeID;
mode_t fMode; mode_t fMode;
timespec fModifiedTime; timespec fModifiedTime;
}; };
@@ -269,6 +277,7 @@ private:
struct PackageVolume : BReferenceable { struct PackageVolume : BReferenceable {
PackageVolume() PackageVolume()
: :
fNextNodeID(1),
fRootDirectory(this, S_IFDIR), fRootDirectory(this, S_IFDIR),
fBufferCache(B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB, 2), fBufferCache(B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB, 2),
fDataReaderFactory(&fBufferCache), fDataReaderFactory(&fBufferCache),
@@ -284,7 +293,12 @@ struct PackageVolume : BReferenceable {
status_t Init(int fd) 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) if (error != B_OK)
return error; return error;
@@ -300,6 +314,11 @@ struct PackageVolume : BReferenceable {
return &fRootDirectory; return &fRootDirectory;
} }
ino_t NextNodeID()
{
return fNextNodeID++;
}
void AddNode(PackageNode* node) void AddNode(PackageNode* node)
{ {
fRootDirectory.AddChild(node); fRootDirectory.AddChild(node);
@@ -324,6 +343,7 @@ struct PackageVolume : BReferenceable {
} }
private: private:
ino_t fNextNodeID;
PackageDirectory fRootDirectory; PackageDirectory fRootDirectory;
BBlockBufferCacheNoLock fBufferCache; BBlockBufferCacheNoLock fBufferCache;
BPackageDataReaderFactory fDataReaderFactory; BPackageDataReaderFactory fDataReaderFactory;
@@ -408,7 +428,7 @@ struct PackageLoaderContentHandler : BPackageContentHandler {
if (node == NULL) if (node == NULL)
RETURN_ERROR(B_NO_MEMORY); RETURN_ERROR(B_NO_MEMORY);
error = node->Init(parentDir, entry->Name()); error = node->Init(parentDir, entry->Name(), fVolume->NextNodeID());
if (error != B_OK) { if (error != B_OK) {
delete node; delete node;
RETURN_ERROR(error); RETURN_ERROR(error);
@@ -539,6 +559,11 @@ struct File : ::Node {
return fFile->Size(); return fFile->Size();
} }
virtual ino_t Inode() const
{
return fFile->NodeID();
}
private: private:
PackageFile* fFile; PackageFile* fFile;
}; };
@@ -600,6 +625,11 @@ struct Symlink : ::Node {
return strlen(fSymlink->SymlinkPath()) + 1; return strlen(fSymlink->SymlinkPath()) + 1;
} }
virtual ino_t Inode() const
{
return fSymlink->NodeID();
}
private: private:
PackageSymlink* fSymlink; PackageSymlink* fSymlink;
}; };
@@ -644,6 +674,11 @@ struct Directory : ::Directory {
return fDirectory->Mode() & S_IFMT; return fDirectory->Mode() & S_IFMT;
} }
virtual ino_t Inode() const
{
return fDirectory->NodeID();
}
virtual status_t Open(void** _cookie, int mode) virtual status_t Open(void** _cookie, int mode)
{ {
if ((mode & O_ACCMODE) != O_RDONLY && (mode & O_ACCMODE) != O_RDWR) if ((mode & O_ACCMODE) != O_RDONLY && (mode & O_ACCMODE) != O_RDWR)