btrfs: Fix name access and hash collision in directory lookup
Use entry->name instead of entry+1 for accessing directory entry names. Fix Lookup() to iterate all entries with the same hash and compare names to find the correct one, returning B_ENTRY_NOT_FOUND if no match is found. Change-Id: I86c3680d830491b3f78c52590047205894e2b5d7 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10449 Reviewed-by: Adrien Destugues <[email protected]> Tested-by: Commit checker robot <[email protected]> Haiku-Format: Haiku-format Bot <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
ba83d20148
commit
119da82d54
@@ -68,7 +68,7 @@ AttributeIterator::GetNext(char* name, size_t* _nameLength)
|
||||
TRACE("DirectoryIterator::GetNext() entries_length %ld name_length %d\n",
|
||||
entries_length, entry->NameLength());
|
||||
|
||||
memcpy(name, entry + 1, entry->NameLength());
|
||||
memcpy(name, entry->name, entry->NameLength());
|
||||
name[entry->NameLength()] = '\0';
|
||||
*_nameLength = entry->NameLength();
|
||||
free(entries);
|
||||
|
||||
@@ -96,7 +96,7 @@ DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id)
|
||||
return B_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
memcpy(name, entry + 1, length);
|
||||
memcpy(name, entry->name, length);
|
||||
name[length] = '\0';
|
||||
*_nameLength = length;
|
||||
*_id = entry->InodeID();
|
||||
@@ -138,19 +138,17 @@ DirectoryIterator::Lookup(const char* name, size_t nameLength, ino_t* _id)
|
||||
btrfs_dir_entry* entry = entries;
|
||||
uint16 current = 0;
|
||||
while (current < length) {
|
||||
if (entry->NameLength() == nameLength
|
||||
&& strncmp((char*)entry->name, name, nameLength) == 0) {
|
||||
*_id = entry->InodeID();
|
||||
free(entries);
|
||||
return B_OK;
|
||||
}
|
||||
current += entry->Length();
|
||||
break;
|
||||
// TODO there could be several entries with the same name hash
|
||||
entry = (btrfs_dir_entry*)((uint8*)entry + entry->Length());
|
||||
}
|
||||
|
||||
TRACE("DirectoryIterator::Lookup() entries_length %ld name_length %d\n",
|
||||
length, entry->NameLength());
|
||||
|
||||
*_id = entry->InodeID();
|
||||
free(entries);
|
||||
|
||||
return B_OK;
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user