ramfs: Keep track of attribute indexed state better and add assertions.

The "ASSERT(!fInIndex || fInIndex != inIndex);" one, tracking
state transitions, catches the underlying cause of #19252.
This commit is contained in:
Augustin Cavalier
2025-08-28 16:57:13 -04:00
parent 6818591003
commit 4e09216c77
2 changed files with 20 additions and 12 deletions
@@ -26,6 +26,7 @@ Attribute::Attribute(Volume *volume, Node *node, const char *name,
// destructor
Attribute::~Attribute()
{
ASSERT(fIndex == NULL);
}
// InitCheck
@@ -101,6 +102,9 @@ Attribute::WriteAt(off_t offset, const void *buffer, size_t size,
void
Attribute::SetIndex(AttributeIndex *index, bool inIndex)
{
ASSERT(fIndex == NULL || index == NULL || fIndex == index);
ASSERT(!fInIndex || fInIndex != inIndex);
fIndex = index;
fInIndex = inIndex;
}
@@ -237,8 +237,7 @@ AttributeIndexImpl::CountEntries() const
// Changed
status_t
AttributeIndexImpl::Changed(Attribute *attribute, const uint8 *oldKey,
size_t oldLength)
AttributeIndexImpl::Changed(Attribute *attribute, const uint8 *oldKey, size_t oldLength)
{
fVolume->AssertWriteLocked();
@@ -261,17 +260,16 @@ AttributeIndexImpl::Changed(Attribute *attribute, const uint8 *oldKey,
}
// remove and re-insert the attribute
it.Remove();
attribute->SetIndex(this, false);
}
}
// re-insert the attribute
if (fKeyLength > 0 && attribute->GetSize() != (off_t)fKeyLength) {
attribute->SetIndex(this, false);
ASSERT(!attribute->IsInIndex());
} else {
error = fAttributes->Insert(attribute);
if (error == B_OK)
attribute->SetIndex(this, true);
else
attribute->SetIndex(NULL, false);
}
}
return error;
@@ -281,7 +279,9 @@ AttributeIndexImpl::Changed(Attribute *attribute, const uint8 *oldKey,
status_t
AttributeIndexImpl::Added(Attribute *attribute)
{
PRINT("AttributeIndex::Add(%p)\n", attribute);
PRINT("AttributeIndex::Add(%p)\n", attribute);
fVolume->AssertWriteLocked();
status_t error = (attribute ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
size_t size = attribute->GetSize();
@@ -300,13 +300,17 @@ PRINT("AttributeIndex::Add(%p)\n", attribute);
bool
AttributeIndexImpl::Removed(Attribute *attribute)
{
PRINT("AttributeIndex::Removed(%p)\n", attribute);
bool result = (attribute && attribute->GetIndex() == this);
if (result) {
if (attribute->IsInIndex())
fAttributes->Remove(attribute, attribute);
PRINT("AttributeIndex::Removed(%p)\n", attribute);
fVolume->AssertWriteLocked();
if (attribute == NULL || attribute->GetIndex() != this)
return false;
bool result = true;
if (attribute->IsInIndex())
result = (fAttributes->Remove(attribute, attribute) == B_OK);
if (result)
attribute->SetIndex(NULL, false);
}
return result;
}