ramfs: Correct "reference" (link) counting of Node objects.
* RemoveReference() could delete us immediately, thus we must do all important work before invoking it. * Add assertions about fRefCount and remove a spurious add. * Do not use Link but PublishVNode on the root, as we manually manage when this object is published/deleted. Fixes #18032.
This commit is contained in:
parent
6a8bb0562e
commit
605ecac1ee
@ -66,6 +66,8 @@ Node::Node(Volume *volume, uint8 type)
|
||||
// destructor
|
||||
Node::~Node()
|
||||
{
|
||||
ASSERT(fRefCount == 0);
|
||||
|
||||
// delete all attributes
|
||||
while (Attribute *attribute = fAttributes.First()) {
|
||||
status_t error = DeleteAttribute(attribute);
|
||||
@ -104,9 +106,10 @@ Node::AddReference()
|
||||
void
|
||||
Node::RemoveReference()
|
||||
{
|
||||
ASSERT(fRefCount > 0);
|
||||
if (--fRefCount == 0) {
|
||||
GetVolume()->RemoveVNode(this);
|
||||
fRefCount++;
|
||||
// RemoveVNode can potentially delete us immediately!
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +117,7 @@ Node::RemoveReference()
|
||||
status_t
|
||||
Node::Link(Entry *entry)
|
||||
{
|
||||
PRINT("Node[%Ld]::Link(): %" B_PRId32 " ->...\n", fID, fRefCount);
|
||||
PRINT("Node[%" B_PRIdINO "]::Link(): %" B_PRId32 " ->...\n", fID, fRefCount);
|
||||
fReferrers.Insert(entry);
|
||||
|
||||
status_t error = AddReference();
|
||||
@ -128,10 +131,10 @@ PRINT("Node[%Ld]::Link(): %" B_PRId32 " ->...\n", fID, fRefCount);
|
||||
status_t
|
||||
Node::Unlink(Entry *entry)
|
||||
{
|
||||
PRINT("Node[%Ld]::Unlink(): %" B_PRId32 " ->...\n", fID, fRefCount);
|
||||
RemoveReference();
|
||||
PRINT("Node[%" B_PRIdINO "]::Unlink(): %" B_PRId32 " ->...\n", fID, fRefCount);
|
||||
fReferrers.Remove(entry);
|
||||
|
||||
RemoveReference();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -358,4 +361,3 @@ Node::GetAllocationInfo(AllocationInfo &info)
|
||||
while (GetNextAttribute(&attribute) == B_OK)
|
||||
attribute->GetAllocationInfo(info);
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ Volume::Mount(uint32 flags)
|
||||
// set permissions: -rwxr-xr-x
|
||||
fRootDirectory->SetMode(
|
||||
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
error = fRootDirectory->Link(NULL);
|
||||
error = PublishVNode(fRootDirectory);
|
||||
} else
|
||||
SET_ERROR(error, B_NO_MEMORY);
|
||||
}
|
||||
@ -357,6 +357,7 @@ Volume::RemoveVNode(Node *node)
|
||||
{
|
||||
if (fMounted)
|
||||
return remove_vnode(FSVolume(), node->GetID());
|
||||
|
||||
status_t error = NodeRemoved(node);
|
||||
if (error == B_OK)
|
||||
delete node;
|
||||
|
Loading…
Reference in New Issue
Block a user