diff --git a/kernel/src/fs/VFS.h b/kernel/src/fs/VFS.h index 02d8813c..6f63c238 100644 --- a/kernel/src/fs/VFS.h +++ b/kernel/src/fs/VFS.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -48,6 +49,8 @@ namespace VFS m_handles--; } + virtual dev_t host_device_id() const = 0; + virtual ~FileSystem() = default; protected: @@ -101,6 +104,11 @@ namespace VFS return StringView {}; } + virtual dev_t device_id() const + { + return luna_dev_makedev(0, 0); + } + // Metadata accessors virtual usize size() const = 0; diff --git a/kernel/src/fs/devices/DeviceRegistry.cpp b/kernel/src/fs/devices/DeviceRegistry.cpp index fa487beb..59ce97bf 100644 --- a/kernel/src/fs/devices/DeviceRegistry.cpp +++ b/kernel/src/fs/devices/DeviceRegistry.cpp @@ -74,4 +74,10 @@ namespace DeviceRegistry return {}; } + + dev_t next_null_device_id() + { + static u32 next_minor = 0; + return luna_dev_makedev(0, next_minor++); + } } diff --git a/kernel/src/fs/devices/DeviceRegistry.h b/kernel/src/fs/devices/DeviceRegistry.h index a68c4039..e698969f 100644 --- a/kernel/src/fs/devices/DeviceRegistry.h +++ b/kernel/src/fs/devices/DeviceRegistry.h @@ -20,4 +20,7 @@ namespace DeviceRegistry mode_t mode = 0666); Result init(); + + // Used for file systems (like tmpfs) that do not have a host device. + dev_t next_null_device_id(); } diff --git a/kernel/src/fs/tmpfs/FileSystem.cpp b/kernel/src/fs/tmpfs/FileSystem.cpp index b2ef9b7d..b6739514 100644 --- a/kernel/src/fs/tmpfs/FileSystem.cpp +++ b/kernel/src/fs/tmpfs/FileSystem.cpp @@ -55,10 +55,18 @@ namespace TmpFS inode->set_fs(*this, {}); inode->set_inode_number(m_next_inode_number++, {}); inode->set_device(device, {}); + // FIXME: This should be queried from Device directly, but Device doesn't have an API to store and retrieve its + // device ID atm. + inode->set_device_id(luna_dev_makedev(major, minor), {}); return (SharedPtr)inode; } + FileSystem::FileSystem() + { + m_host_device_id = DeviceRegistry::next_null_device_id(); + } + Result FileSystem::set_mount_dir(SharedPtr parent) { return m_root_inode->replace_entry(parent, ".."); diff --git a/kernel/src/fs/tmpfs/FileSystem.h b/kernel/src/fs/tmpfs/FileSystem.h index bec93b30..579dc282 100644 --- a/kernel/src/fs/tmpfs/FileSystem.h +++ b/kernel/src/fs/tmpfs/FileSystem.h @@ -27,16 +27,23 @@ namespace TmpFS static Result> create(); + dev_t host_device_id() const override + { + return m_host_device_id; + } + virtual ~FileSystem() = default; private: - FileSystem() = default; + FileSystem(); void set_root(SharedPtr root); SharedPtr m_root_inode; Atomic m_next_inode_number { 2 }; + + dev_t m_host_device_id; }; class FileInode : public VFS::FileInode @@ -251,11 +258,21 @@ namespace TmpFS m_device = device; } + void set_device_id(dev_t id, Badge) + { + m_device_id = id; + } + VFS::FileSystem* fs() const override { return m_fs; } + dev_t device_id() const override + { + return m_device_id; + } + usize inode_number() const override { return m_inode_number; @@ -340,6 +357,7 @@ namespace TmpFS u32 m_uid { 0 }; u32 m_gid { 0 }; u32 m_nlinks { 0 }; + dev_t m_device_id { 0 }; }; class DirInode : public VFS::Inode diff --git a/kernel/src/sys/stat.cpp b/kernel/src/sys/stat.cpp index c40e7017..3820dd08 100644 --- a/kernel/src/sys/stat.cpp +++ b/kernel/src/sys/stat.cpp @@ -40,6 +40,8 @@ Result sys_fstatat(Registers*, SyscallArgs args) kstat.st_uid = inode->uid(); kstat.st_gid = inode->gid(); kstat.st_size = inode->size(); + kstat.st_dev = inode->fs()->host_device_id(); + kstat.st_rdev = inode->device_id(); if (!MemoryManager::copy_to_user_typed(st, &kstat)) return err(EFAULT); diff --git a/libc/include/bits/struct_stat.h b/libc/include/bits/struct_stat.h index 8b53603e..038ceb7a 100644 --- a/libc/include/bits/struct_stat.h +++ b/libc/include/bits/struct_stat.h @@ -10,9 +10,11 @@ struct stat ino_t st_ino; mode_t st_mode; nlink_t st_nlink; + dev_t st_dev; uid_t st_uid; gid_t st_gid; off_t st_size; + dev_t st_rdev; }; #endif