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",
|
TRACE("DirectoryIterator::GetNext() entries_length %ld name_length %d\n",
|
||||||
entries_length, entry->NameLength());
|
entries_length, entry->NameLength());
|
||||||
|
|
||||||
memcpy(name, entry + 1, entry->NameLength());
|
memcpy(name, entry->name, entry->NameLength());
|
||||||
name[entry->NameLength()] = '\0';
|
name[entry->NameLength()] = '\0';
|
||||||
*_nameLength = entry->NameLength();
|
*_nameLength = entry->NameLength();
|
||||||
free(entries);
|
free(entries);
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id)
|
|||||||
return B_BUFFER_OVERFLOW;
|
return B_BUFFER_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(name, entry + 1, length);
|
memcpy(name, entry->name, length);
|
||||||
name[length] = '\0';
|
name[length] = '\0';
|
||||||
*_nameLength = length;
|
*_nameLength = length;
|
||||||
*_id = entry->InodeID();
|
*_id = entry->InodeID();
|
||||||
@@ -138,19 +138,17 @@ DirectoryIterator::Lookup(const char* name, size_t nameLength, ino_t* _id)
|
|||||||
btrfs_dir_entry* entry = entries;
|
btrfs_dir_entry* entry = entries;
|
||||||
uint16 current = 0;
|
uint16 current = 0;
|
||||||
while (current < length) {
|
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();
|
current += entry->Length();
|
||||||
break;
|
|
||||||
// TODO there could be several entries with the same name hash
|
|
||||||
entry = (btrfs_dir_entry*)((uint8*)entry + entry->Length());
|
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);
|
free(entries);
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user