diff --git a/kernel/kernel/FS/TmpFS/Inode.cpp b/kernel/kernel/FS/TmpFS/Inode.cpp index c0a14bc5..13e7e8f0 100644 --- a/kernel/kernel/FS/TmpFS/Inode.cpp +++ b/kernel/kernel/FS/TmpFS/Inode.cpp @@ -276,9 +276,51 @@ namespace Kernel return BAN::RefPtr(inode); } - BAN::ErrorOr TmpDirectoryInode::list_next_inodes_impl(off_t, DirectoryEntryList*, size_t) + BAN::ErrorOr TmpDirectoryInode::list_next_inodes_impl(off_t data_block_index, DirectoryEntryList* list, size_t list_len) { - return BAN::Error::from_errno(ENOTSUP); + if (list_len < (size_t)blksize()) + { + dprintln("buffer is too small"); + return BAN::Error::from_errno(ENOBUFS); + } + + auto block_index = this->block_index(data_block_index); + + list->entry_count = 0; + + // if we reach a non-allocated block, it marks the end + if (!block_index.has_value()) + return {}; + + auto* dirp = list->array; + + const size_t byte_count = BAN::Math::min(size() - data_block_index * blksize(), blksize()); + m_fs.with_block_buffer(block_index.value(), [&](BAN::ByteSpan bytespan) { + bytespan = bytespan.slice(0, byte_count); + + while (bytespan.size() > 0) + { + const auto& entry = bytespan.as(); + + if (entry.type != DT_UNKNOWN) + { + // TODO: dirents should be aligned + + dirp->dirent.d_ino = entry.ino; + dirp->dirent.d_type = entry.type; + strncpy(dirp->dirent.d_name, entry.name, entry.name_len); + dirp->dirent.d_name[entry.name_len] = '\0'; + dirp->rec_len = sizeof(DirectoryEntry) + entry.name_len + 1; + dirp = dirp->next(); + + list->entry_count++; + } + + bytespan = bytespan.slice(entry.rec_len); + } + }); + + return {}; } BAN::ErrorOr TmpDirectoryInode::create_file_impl(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid)