packagefs: Set and unset node parents in Directory rather than Node::Init.

This way we can ASSERT() that the node doesn't belong to some other
directory.
This commit is contained in:
Augustin Cavalier
2024-09-11 15:20:35 -04:00
parent cb29c48dfa
commit dfb09e12b1
10 changed files with 45 additions and 41 deletions
@@ -31,9 +31,9 @@ Directory::~Directory()
status_t status_t
Directory::Init(Directory* parent, const String& name) Directory::Init(const String& name)
{ {
status_t error = Node::Init(parent, name); status_t error = Node::Init(name);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -80,8 +80,11 @@ void
Directory::AddChild(Node* node) Directory::AddChild(Node* node)
{ {
ASSERT_WRITE_LOCKED_RW_LOCK(&fLock); ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
ASSERT(node->Parent() == NULL);
fChildTable.Insert(node); fChildTable.Insert(node);
fChildList.Add(node); fChildList.Add(node);
node->_SetParent(this);
node->AcquireReference(); node->AcquireReference();
} }
@@ -90,10 +93,13 @@ void
Directory::RemoveChild(Node* node) Directory::RemoveChild(Node* node)
{ {
ASSERT_WRITE_LOCKED_RW_LOCK(&fLock); ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
ASSERT(node->Parent() == this);
Node* nextNode = fChildList.GetNext(node); Node* nextNode = fChildList.GetNext(node);
fChildTable.Remove(node); fChildTable.Remove(node);
fChildList.Remove(node); fChildList.Remove(node);
node->_SetParent(NULL);
node->ReleaseReference(); node->ReleaseReference();
// adjust directory iterators pointing to the removed child // adjust directory iterators pointing to the removed child
@@ -27,7 +27,7 @@ public:
Directory(ino_t id); Directory(ino_t id);
virtual ~Directory(); virtual ~Directory();
virtual status_t Init(Directory* parent, const String& name); virtual status_t Init(const String& name);
virtual mode_t Mode() const; virtual mode_t Mode() const;
virtual off_t FileSize() const; virtual off_t FileSize() const;
@@ -23,26 +23,37 @@ Node::Node(ino_t id)
fName(), fName(),
fFlags(0) fFlags(0)
{ {
rw_lock_init(&fLock, "packagefs node");
} }
Node::~Node() Node::~Node()
{ {
rw_lock_destroy(&fLock);
} }
status_t status_t
Node::Init(Directory* parent, const String& name) Node::Init(const String& name)
{ {
fParent = parent;
fName = name; fName = name;
fFlags = 0; fFlags = 0;
return B_OK; return B_OK;
} }
void
Node::SetID(ino_t id)
{
fID = id;
}
void
Node::_SetParent(Directory* parent)
{
fParent = parent;
}
status_t status_t
Node::VFSInit(dev_t deviceID) Node::VFSInit(dev_t deviceID)
{ {
@@ -58,20 +69,6 @@ Node::VFSUninit()
} }
void
Node::SetID(ino_t id)
{
fID = id;
}
void
Node::SetParent(Directory* parent)
{
fParent = parent;
}
uid_t uid_t
Node::UserID() const Node::UserID() const
{ {
@@ -57,7 +57,8 @@ public:
Node*& IDHashTableNext() Node*& IDHashTableNext()
{ return fIDHashTableNext; } { return fIDHashTableNext; }
virtual status_t Init(Directory* parent, const String& name); virtual status_t Init(const String& name);
void SetID(ino_t id);
virtual status_t VFSInit(dev_t deviceID); virtual status_t VFSInit(dev_t deviceID);
// base class version must be called on // base class version must be called on
@@ -67,9 +68,6 @@ public:
inline bool IsKnownToVFS() const; inline bool IsKnownToVFS() const;
inline bool HasVFSInitError() const; inline bool HasVFSInitError() const;
void SetID(ino_t id);
void SetParent(Directory* parent);
virtual mode_t Mode() const = 0; virtual mode_t Mode() const = 0;
virtual uid_t UserID() const; virtual uid_t UserID() const;
virtual gid_t GroupID() const; virtual gid_t GroupID() const;
@@ -92,6 +90,11 @@ public:
virtual void* IndexCookieForAttribute(const StringKey& name) virtual void* IndexCookieForAttribute(const StringKey& name)
const; const;
private:
friend class Directory;
void _SetParent(Directory* parent);
protected: protected:
rw_lock fLock; rw_lock fLock;
ino_t fID; ino_t fID;
@@ -220,7 +220,7 @@ UnpackingLeafNode::CloneTransferPackageNodes(ino_t id, UnpackingNode*& _newNode)
if (clone == NULL) if (clone == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
status_t error = clone->Init(Parent(), Name()); status_t error = clone->Init(Name());
if (error != B_OK) { if (error != B_OK) {
delete clone; delete clone;
return error; return error;
@@ -45,10 +45,10 @@ PackageLinkDirectory::~PackageLinkDirectory()
status_t status_t
PackageLinkDirectory::Init(Directory* parent, Package* package) PackageLinkDirectory::Init(Package* package)
{ {
// init the directory/node // init the directory/node
status_t error = Init(parent, package->VersionedName()); status_t error = Init(package->VersionedName());
if (error != B_OK) if (error != B_OK)
RETURN_ERROR(error); RETURN_ERROR(error);
@@ -60,9 +60,9 @@ PackageLinkDirectory::Init(Directory* parent, Package* package)
status_t status_t
PackageLinkDirectory::Init(Directory* parent, const String& name) PackageLinkDirectory::Init(const String& name)
{ {
return Directory::Init(parent, name); return Directory::Init(name);
} }
@@ -227,7 +227,7 @@ PackageLinkDirectory::_UpdateDependencies(PackageLinksListener* listener)
if (link == NULL) if (link == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
status_t error = link->Init(this, dependency->FileName()); status_t error = link->Init(dependency->FileName());
if (error != B_OK) { if (error != B_OK) {
delete link; delete link;
RETURN_ERROR(error); RETURN_ERROR(error);
@@ -271,7 +271,7 @@ PackageLinkDirectory::_CreateOrUpdateLink(Link*& link, Package* package,
if (link == NULL) if (link == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
status_t error = link->Init(this, name); status_t error = link->Init(name);
if (error != B_OK) if (error != B_OK)
RETURN_ERROR(error); RETURN_ERROR(error);
@@ -19,8 +19,8 @@ public:
PackageLinkDirectory(); PackageLinkDirectory();
virtual ~PackageLinkDirectory(); virtual ~PackageLinkDirectory();
status_t Init(Directory* parent, Package* package); status_t Init(Package* package);
virtual status_t Init(Directory* parent, const String& name); virtual status_t Init(const String& name);
virtual timespec ModifiedTime() const; virtual timespec ModifiedTime() const;
@@ -48,7 +48,7 @@ PackageLinksDirectory::AddPackage(Package* package)
BReference<PackageLinkDirectory> linkDirectoryReference(linkDirectory, BReference<PackageLinkDirectory> linkDirectoryReference(linkDirectory,
true); true);
status_t error = linkDirectory->Init(this, package); status_t error = linkDirectory->Init(package);
if (error != B_OK) if (error != B_OK)
RETURN_ERROR(error); RETURN_ERROR(error);
@@ -68,7 +68,7 @@ PackageFSRoot::Init()
if (fPackageLinksDirectory == NULL) if (fPackageLinksDirectory == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
status_t error = fPackageLinksDirectory->Init(NULL, status_t error = fPackageLinksDirectory->Init(
StringConstants::Get().kPackageLinksDirectoryName); StringConstants::Get().kPackageLinksDirectoryName);
if (error != B_OK) if (error != B_OK)
RETURN_ERROR(error); RETURN_ERROR(error);
@@ -402,7 +402,7 @@ Volume::Mount(const char* parameterString)
= new ::RootDirectory(kRootDirectoryID, st.st_mtim); = new ::RootDirectory(kRootDirectoryID, st.st_mtim);
if (fRootDirectory == NULL) if (fRootDirectory == NULL)
RETURN_ERROR(B_NO_MEMORY); RETURN_ERROR(B_NO_MEMORY);
fRootDirectory->Init(NULL, volumeNameString); fRootDirectory->Init(volumeNameString);
fNodes.Insert(fRootDirectory); fNodes.Insert(fRootDirectory);
fRootDirectory->AcquireReference(); fRootDirectory->AcquireReference();
// one reference for the table // one reference for the table
@@ -1410,7 +1410,7 @@ Volume::_CreateUnpackingNode(mode_t mode, Directory* parent, const String& name,
Node* node = unpackingNode->GetNode(); Node* node = unpackingNode->GetNode();
BReference<Node> nodeReference(node, true); BReference<Node> nodeReference(node, true);
status_t error = node->Init(parent, name); status_t error = node->Init(name);
if (error != B_OK) if (error != B_OK)
RETURN_ERROR(error); RETURN_ERROR(error);
@@ -1711,7 +1711,7 @@ Volume::_CreateShineThroughDirectory(Directory* parent, const char* name,
if (!nameString.SetTo(name)) if (!nameString.SetTo(name))
RETURN_ERROR(B_NO_MEMORY); RETURN_ERROR(B_NO_MEMORY);
status_t error = directory->Init(parent, nameString); status_t error = directory->Init(nameString);
if (error != B_OK) if (error != B_OK)
RETURN_ERROR(error); RETURN_ERROR(error);
@@ -1855,7 +1855,6 @@ Volume::_AddPackageLinksDirectory()
NodeWriteLocker rootDirectoryWriteLocker(fRootDirectory); NodeWriteLocker rootDirectoryWriteLocker(fRootDirectory);
NodeWriteLocker packageLinksDirectoryWriteLocker(packageLinksDirectory); NodeWriteLocker packageLinksDirectoryWriteLocker(packageLinksDirectory);
packageLinksDirectory->SetParent(fRootDirectory);
fRootDirectory->AddChild(packageLinksDirectory); fRootDirectory->AddChild(packageLinksDirectory);
_AddPackageLinksNode(packageLinksDirectory); _AddPackageLinksNode(packageLinksDirectory);
@@ -1879,7 +1878,6 @@ Volume::_RemovePackageLinksDirectory()
if (packageLinksDirectory->Parent() == fRootDirectory) { if (packageLinksDirectory->Parent() == fRootDirectory) {
packageLinksDirectory->SetListener(NULL); packageLinksDirectory->SetListener(NULL);
fRootDirectory->RemoveChild(packageLinksDirectory); fRootDirectory->RemoveChild(packageLinksDirectory);
packageLinksDirectory->SetParent(NULL);
} }
} }