Kernel: Make RAMFS pass along the inode type when traversing as a dir

RAMFS was passing 0, which lead to the userspace seeing all entries as
DT_UNKNOWN when iterating over the directory contents.
To repro prior to this commit, simply check `echo /tmp/*/`.
This commit is contained in:
Ali Mohammad Pur 2023-12-01 21:07:25 +03:30 committed by Andreas Kling
parent 24a7df9b09
commit b545427d53
Notes: sideshowbarker 2024-07-17 06:39:26 +09:00
3 changed files with 63 additions and 4 deletions

View file

@ -37,4 +37,27 @@ unsigned RAMFS::next_inode_index()
return m_next_inode_index++;
}
u8 RAMFS::internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const
{
switch (static_cast<FileType>(entry.file_type)) {
case FileType::Directory:
return DT_DIR;
case FileType::Character:
return DT_CHR;
case FileType::Block:
return DT_BLK;
case FileType::Regular:
return DT_REG;
case FileType::FIFO:
return DT_FIFO;
case FileType::Link:
return DT_LNK;
case FileType::Socket:
return DT_SOCK;
case FileType::Unknown:
default:
return DT_UNKNOWN;
}
}
}

View file

@ -27,6 +27,19 @@ public:
virtual Inode& root_inode() override;
virtual u8 internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const override;
enum class FileType : u8 {
Directory,
Character,
Block,
Regular,
FIFO,
Link,
Socket,
Unknown,
};
private:
RAMFS();

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/RAMFS/FileSystem.h>
#include <Kernel/FileSystem/RAMFS/Inode.h>
#include <Kernel/Tasks/Process.h>
@ -49,6 +50,28 @@ InodeMetadata RAMFSInode::metadata() const
return m_metadata;
}
static RAMFS::FileType file_type_from_mode(mode_t mode)
{
switch (mode & S_IFMT) {
case S_IFDIR:
return RAMFS::FileType::Directory;
case S_IFCHR:
return RAMFS::FileType::Character;
case S_IFBLK:
return RAMFS::FileType::Block;
case S_IFREG:
return RAMFS::FileType::Regular;
case S_IFIFO:
return RAMFS::FileType::FIFO;
case S_IFLNK:
return RAMFS::FileType::Link;
case S_IFSOCK:
return RAMFS::FileType::Socket;
default:
return RAMFS::FileType::Unknown;
}
}
ErrorOr<void> RAMFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
@ -56,15 +79,15 @@ ErrorOr<void> RAMFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSyste
if (!is_directory())
return ENOTDIR;
TRY(callback({ "."sv, identifier(), 0 }));
TRY(callback({ "."sv, identifier(), to_underlying(RAMFS::FileType::Directory) }));
if (m_root_directory_inode) {
TRY(callback({ ".."sv, identifier(), 0 }));
TRY(callback({ ".."sv, identifier(), to_underlying(RAMFS::FileType::Directory) }));
} else if (auto parent = m_parent.strong_ref()) {
TRY(callback({ ".."sv, parent->identifier(), 0 }));
TRY(callback({ ".."sv, parent->identifier(), to_underlying(RAMFS::FileType::Directory) }));
}
for (auto& child : m_children) {
TRY(callback({ child.name->view(), child.inode->identifier(), 0 }));
TRY(callback({ child.name->view(), child.inode->identifier(), to_underlying(file_type_from_mode(child.inode->metadata().mode)) }));
}
return {};
}