aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-07-22 23:04:23 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-07-22 23:04:23 +0200
commit0de79775bfcc8ed32726072352d4c0f95ea6b539 (patch)
tree3bcf743040e62b722ecb114bb7e4fa6ba1e3ae6a
parent2152ce6a77e10823ba13d462af8da5a3b1f88ace (diff)
downloadkernel-0de79775bfcc8ed32726072352d4c0f95ea6b539.tar.xz
kernel-0de79775bfcc8ed32726072352d4c0f95ea6b539.zip
kernel/vfs: fix device node resolution
-rw-r--r--kernel/kernel/filesystem/vfs.cpp46
-rw-r--r--kernel/kernel/filesystem/vfs.hpp1
2 files changed, 26 insertions, 21 deletions
diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp
index f4457dda..e1d539d8 100644
--- a/kernel/kernel/filesystem/vfs.cpp
+++ b/kernel/kernel/filesystem/vfs.cpp
@@ -107,6 +107,30 @@ namespace kernel::filesystem
}
auto [dentry, mount] = resolved_path.value();
+ auto inode = dentry->get_inode();
+
+ if (inode->is_device())
+ {
+ auto number = inode->raw_device();
+ if (!number)
+ {
+ return kstd::failure(vfs_errc::no_such_device);
+ }
+
+ auto type = inode->is_block_device() ? file_type::block : file_type::character;
+ auto resolved_device = device_number_registry::get().resolve(*number, type);
+ if (!resolved_device)
+ {
+ return kstd::failure(resolved_device.error());
+ }
+
+ auto device_dentry = kstd::make_shared<struct dentry>(
+ dentry->parent(), kstd::make_shared<device_inode>(*resolved_device, inode), dentry->name());
+
+ mount->increment_ref_count();
+ return device_dentry;
+ }
+
mount->increment_ref_count();
return dentry;
}
@@ -351,6 +375,7 @@ namespace kernel::filesystem
}
next_dentry = kstd::make_shared<dentry>(current_dentry, *found_inode, part);
+ current_dentry->add_child(next_dentry);
}
else if (next_dentry->has_flag(dentry::dentry_flags::is_mount_point))
{
@@ -393,28 +418,7 @@ namespace kernel::filesystem
}
continue;
}
- else if (next_dentry->get_inode()->is_device())
- {
- auto number = (next_dentry->get_inode())->raw_device();
- if (!number)
- {
- return kstd::failure(vfs_errc::no_such_device);
- }
-
- // TODO: in the future we may need to support fifos, UNIX domain socket, etc. here
- auto type = next_dentry->get_inode()->is_block_device() ? file_type::block : file_type::character;
- auto resolved = device_number_registry::get().resolve(*number, type);
- if (!resolved)
- {
- return kstd::failure(resolved.error());
- }
-
- next_dentry = kstd::make_shared<dentry>(
- current_dentry,
- kstd::shared_ptr<inode>(kstd::make_shared<device_inode>(*resolved, next_dentry->get_inode())), part);
- }
- current_dentry->add_child(next_dentry);
current_dentry = next_dentry;
}
return std::pair{current_dentry, current_mount};
diff --git a/kernel/kernel/filesystem/vfs.hpp b/kernel/kernel/filesystem/vfs.hpp
index 445952a0..1b8cf89a 100644
--- a/kernel/kernel/filesystem/vfs.hpp
+++ b/kernel/kernel/filesystem/vfs.hpp
@@ -4,6 +4,7 @@
#include <kernel/filesystem/dentry.hpp>
#include <kernel/filesystem/devfs/filesystem.hpp>
#include <kernel/filesystem/filesystem.hpp>
+#include <kernel/filesystem/inode.hpp>
#include <kernel/filesystem/mount.hpp>
#include <kernel/filesystem/mount_table.hpp>
#include <kernel/filesystem/vfs_types.hpp>