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:
Jerome Duval 2013-05-02 19:27:55 +02:00
parent 795f13d6f2
commit c33b645d33
2 changed files with 37 additions and 20 deletions

View File

@ -108,8 +108,8 @@ DirectoryIterator::Get(char* name, size_t* _nameLength, ino_t* _id)
entry->InodeID(), entry->Length(), length, entry->FileType());
if (*_nameLength > 0) {
if (*_nameLength < length)
length = *_nameLength - 1;
if (length + 1 > *_nameLength)
return B_BUFFER_OVERFLOW;
memcpy(name, entry->name, length);
name[length] = '\0';

View File

@ -1414,27 +1414,44 @@ ext2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
struct dirent *dirent, size_t bufferSize, uint32 *_num)
{
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;
status_t status = iterator->GetNext(dirent->d_name, &length, &id);
if (status == B_ENTRY_NOT_FOUND) {
*_num = 0;
return B_OK;
} else if (status != B_OK)
if (status == B_ENTRY_NOT_FOUND)
break;
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;
status = iterator->Next();
if (status != B_OK && status != B_ENTRY_NOT_FOUND)
return status;
Volume* volume = (Volume*)_volume->private_volume;
dirent->d_dev = volume->ID();
dirent->d_ino = id;
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;
}