ext2: Return more than a single dirent at a time in ext2_read_dir().
* similar to what mmlr did in hrev45575 for bfs.
This commit is contained in:
@@ -108,8 +108,8 @@ DirectoryIterator::Get(char* name, size_t* _nameLength, ino_t* _id)
|
|||||||
entry->InodeID(), entry->Length(), length, entry->FileType());
|
entry->InodeID(), entry->Length(), length, entry->FileType());
|
||||||
|
|
||||||
if (*_nameLength > 0) {
|
if (*_nameLength > 0) {
|
||||||
if (*_nameLength < length)
|
if (length + 1 > *_nameLength)
|
||||||
length = *_nameLength - 1;
|
return B_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
memcpy(name, entry->name, length);
|
memcpy(name, entry->name, length);
|
||||||
name[length] = '\0';
|
name[length] = '\0';
|
||||||
|
|||||||
@@ -1414,27 +1414,44 @@ ext2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
|||||||
struct dirent *dirent, size_t bufferSize, uint32 *_num)
|
struct dirent *dirent, size_t bufferSize, uint32 *_num)
|
||||||
{
|
{
|
||||||
DirectoryIterator *iterator = (DirectoryIterator *)_cookie;
|
DirectoryIterator *iterator = (DirectoryIterator *)_cookie;
|
||||||
|
Volume* volume = (Volume*)_volume->private_volume;
|
||||||
|
|
||||||
size_t length = bufferSize;
|
uint32 maxCount = *_num;
|
||||||
|
uint32 count = 0;
|
||||||
|
|
||||||
|
while (count < maxCount && bufferSize > sizeof(struct dirent)) {
|
||||||
|
|
||||||
|
size_t length = bufferSize - sizeof(struct dirent) + 1;
|
||||||
ino_t id;
|
ino_t id;
|
||||||
|
|
||||||
status_t status = iterator->GetNext(dirent->d_name, &length, &id);
|
status_t status = iterator->GetNext(dirent->d_name, &length, &id);
|
||||||
if (status == B_ENTRY_NOT_FOUND) {
|
if (status == B_ENTRY_NOT_FOUND)
|
||||||
*_num = 0;
|
break;
|
||||||
return B_OK;
|
|
||||||
} else if (status != B_OK)
|
if (status == B_BUFFER_OVERFLOW) {
|
||||||
|
// the remaining name buffer length was too small
|
||||||
|
if (count == 0)
|
||||||
|
return B_BUFFER_OVERFLOW;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = iterator->Next();
|
status = iterator->Next();
|
||||||
if (status != B_OK && status != B_ENTRY_NOT_FOUND)
|
if (status != B_OK && status != B_ENTRY_NOT_FOUND)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
Volume* volume = (Volume*)_volume->private_volume;
|
|
||||||
|
|
||||||
dirent->d_dev = volume->ID();
|
dirent->d_dev = volume->ID();
|
||||||
dirent->d_ino = id;
|
dirent->d_ino = id;
|
||||||
dirent->d_reclen = sizeof(struct dirent) + length;
|
dirent->d_reclen = sizeof(struct dirent) + length;
|
||||||
|
|
||||||
*_num = 1;
|
bufferSize -= dirent->d_reclen;
|
||||||
|
dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*_num = count;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user