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 // destructor
Attribute::~Attribute() Attribute::~Attribute()
{ {
ASSERT(fIndex == NULL);
} }
// InitCheck // InitCheck
@@ -101,6 +102,9 @@ Attribute::WriteAt(off_t offset, const void *buffer, size_t size,
void void
Attribute::SetIndex(AttributeIndex *index, bool inIndex) Attribute::SetIndex(AttributeIndex *index, bool inIndex)
{ {
ASSERT(fIndex == NULL || index == NULL || fIndex == index);
ASSERT(!fInIndex || fInIndex != inIndex);
fIndex = index; fIndex = index;
fInIndex = inIndex; fInIndex = inIndex;
} }
@@ -237,8 +237,7 @@ AttributeIndexImpl::CountEntries() const
// Changed // Changed
status_t status_t
AttributeIndexImpl::Changed(Attribute *attribute, const uint8 *oldKey, AttributeIndexImpl::Changed(Attribute *attribute, const uint8 *oldKey, size_t oldLength)
size_t oldLength)
{ {
fVolume->AssertWriteLocked(); fVolume->AssertWriteLocked();
@@ -261,17 +260,16 @@ AttributeIndexImpl::Changed(Attribute *attribute, const uint8 *oldKey,
} }
// remove and re-insert the attribute // remove and re-insert the attribute
it.Remove(); it.Remove();
attribute->SetIndex(this, false);
} }
} }
// re-insert the attribute // re-insert the attribute
if (fKeyLength > 0 && attribute->GetSize() != (off_t)fKeyLength) { if (fKeyLength > 0 && attribute->GetSize() != (off_t)fKeyLength) {
attribute->SetIndex(this, false); ASSERT(!attribute->IsInIndex());
} else { } else {
error = fAttributes->Insert(attribute); error = fAttributes->Insert(attribute);
if (error == B_OK) if (error == B_OK)
attribute->SetIndex(this, true); attribute->SetIndex(this, true);
else
attribute->SetIndex(NULL, false);
} }
} }
return error; return error;
@@ -281,7 +279,9 @@ AttributeIndexImpl::Changed(Attribute *attribute, const uint8 *oldKey,
status_t status_t
AttributeIndexImpl::Added(Attribute *attribute) 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); status_t error = (attribute ? B_OK : B_BAD_VALUE);
if (error == B_OK) { if (error == B_OK) {
size_t size = attribute->GetSize(); size_t size = attribute->GetSize();
@@ -300,13 +300,17 @@ PRINT("AttributeIndex::Add(%p)\n", attribute);
bool bool
AttributeIndexImpl::Removed(Attribute *attribute) AttributeIndexImpl::Removed(Attribute *attribute)
{ {
PRINT("AttributeIndex::Removed(%p)\n", attribute); PRINT("AttributeIndex::Removed(%p)\n", attribute);
bool result = (attribute && attribute->GetIndex() == this); fVolume->AssertWriteLocked();
if (result) {
if (attribute->IsInIndex()) if (attribute == NULL || attribute->GetIndex() != this)
fAttributes->Remove(attribute, attribute); return false;
bool result = true;
if (attribute->IsInIndex())
result = (fAttributes->Remove(attribute, attribute) == B_OK);
if (result)
attribute->SetIndex(NULL, false); attribute->SetIndex(NULL, false);
}
return result; return result;
} }