ramfs: Properly update indexes when attribute sizes change.

Otherwise we'll have incorrect data in the index.

Part of #19252.
This commit is contained in:
Augustin Cavalier
2025-08-28 19:35:06 -04:00
parent 4e09216c77
commit 8f7bb51e20
2 changed files with 32 additions and 14 deletions
@@ -55,33 +55,49 @@ Attribute::SetType(uint32 type)
status_t status_t
Attribute::SetSize(off_t newSize) Attribute::SetSize(off_t newSize)
{ {
status_t error = B_OK;
off_t oldSize = DataContainer::GetSize(); off_t oldSize = DataContainer::GetSize();
if (newSize != oldSize) { if (newSize == oldSize)
if (fNode) return B_OK;
fNode->MarkModified(B_STAT_MODIFICATION_TIME);
error = DataContainer::Resize(newSize); uint8 oldKey[kMaxIndexKeyLength];
} size_t oldLength = kMaxIndexKeyLength;
GetKey(oldKey, &oldLength);
status_t error = DataContainer::Resize(newSize);
if (error != B_OK)
return error; return error;
off_t changeOffset = (newSize < oldSize) ? newSize : oldSize;
_Changed(oldKey, oldLength, changeOffset, newSize - oldSize);
return B_OK;
} }
// WriteAt // WriteAt
status_t status_t
Attribute::WriteAt(off_t offset, const void *buffer, size_t size, Attribute::WriteAt(off_t offset, const void *buffer, size_t size, size_t *bytesWritten)
size_t *bytesWritten)
{ {
// get the current key for the attribute // store the current key for the attribute
uint8 oldKey[kMaxIndexKeyLength]; uint8 oldKey[kMaxIndexKeyLength];
size_t oldLength = kMaxIndexKeyLength; size_t oldLength = kMaxIndexKeyLength;
GetKey(oldKey, &oldLength); GetKey(oldKey, &oldLength);
// write the new value // write the new value
status_t error = DataContainer::WriteAt(offset, buffer, size, bytesWritten); status_t error = DataContainer::WriteAt(offset, buffer, size, bytesWritten);
if (error != B_OK)
return error;
// update index and live queries
_Changed(oldKey, oldLength, offset, size);
return B_OK;
}
// _Changed
void
Attribute::_Changed(uint8* oldKey, size_t oldLength, off_t changeOffset, ssize_t changeSize)
{
// If there is an index and a change has been made within the key, notify // If there is an index and a change has been made within the key, notify
// the index. // the index.
if (offset < (off_t)kMaxIndexKeyLength && size > 0 && fIndex) if (fIndex != NULL && changeOffset < (off_t)kMaxIndexKeyLength && changeSize != 0)
fIndex->Changed(this, oldKey, oldLength); fIndex->Changed(this, oldKey, oldLength);
// update live queries // update live queries
@@ -92,10 +108,8 @@ Attribute::WriteAt(off_t offset, const void *buffer, size_t size,
oldLength, newKey, newLength); oldLength, newKey, newLength);
// node has been changed // node has been changed
if (fNode && size > 0) if (fNode != NULL && changeSize != 0)
fNode->MarkModified(B_STAT_MODIFICATION_TIME); fNode->MarkModified(B_STAT_MODIFICATION_TIME);
return error;
} }
// SetIndex // SetIndex
@@ -53,6 +53,10 @@ public:
// debugging // debugging
void GetAllocationInfo(AllocationInfo &info); void GetAllocationInfo(AllocationInfo &info);
private:
void _Changed(uint8* oldKey, size_t oldLength,
off_t changeOffset, ssize_t changeSize);
private: private:
Node *fNode; Node *fNode;
String fName; String fName;