summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/FileSystem/DevFS.cpp83
-rw-r--r--Kernel/FileSystem/DevFS.h13
-rw-r--r--Kernel/FileSystem/InodeMetadata.h2
-rw-r--r--Kernel/FileSystem/OpenFileDescription.cpp5
-rw-r--r--Kernel/FileSystem/OpenFileDescription.h1
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.cpp1
6 files changed, 60 insertions, 45 deletions
diff --git a/Kernel/FileSystem/DevFS.cpp b/Kernel/FileSystem/DevFS.cpp
index c253bb77b2..882c5e4532 100644
--- a/Kernel/FileSystem/DevFS.cpp
+++ b/Kernel/FileSystem/DevFS.cpp
@@ -19,15 +19,6 @@ DevFS::DevFS()
{
}
-void DevFS::notify_new_device(Device& device)
-{
- // FIXME: Handle KString allocation failure.
- auto name = KString::try_create(device.device_name()).release_value();
- MutexLocker locker(m_lock);
- auto new_device_inode = adopt_ref(*new DevFSDeviceInode(*this, device, move(name)));
- m_root_inode->m_nodes.append(new_device_inode);
-}
-
size_t DevFS::allocate_inode_index()
{
MutexLocker locker(m_lock);
@@ -36,11 +27,6 @@ size_t DevFS::allocate_inode_index()
return 1 + m_next_inode_index.value();
}
-void DevFS::notify_device_removal(Device&)
-{
- TODO();
-}
-
DevFS::~DevFS()
{
}
@@ -48,12 +34,6 @@ DevFS::~DevFS()
KResult DevFS::initialize()
{
m_root_inode = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) DevFSRootDirectoryInode(*this)));
- Device::for_each([&](Device& device) {
- // FIXME: Find a better way to not add MasterPTYs or SlavePTYs!
- if (device.is_master_pty() || (device.is_character_device() && device.major() == 201))
- return;
- notify_new_device(device);
- });
return KSuccess;
}
@@ -214,7 +194,7 @@ KResultOr<NonnullRefPtr<Inode>> DevFSRootDirectoryInode::lookup(StringView name)
}
return ENOENT;
}
-KResultOr<NonnullRefPtr<Inode>> DevFSRootDirectoryInode::create_child(StringView name, mode_t mode, dev_t, UserID, GroupID)
+KResultOr<NonnullRefPtr<Inode>> DevFSRootDirectoryInode::create_child(StringView name, mode_t mode, dev_t device_mode, UserID, GroupID)
{
MutexLocker locker(fs().m_lock);
@@ -232,6 +212,15 @@ KResultOr<NonnullRefPtr<Inode>> DevFSRootDirectoryInode::create_child(StringView
m_nodes.append(*new_directory_inode);
return new_directory_inode;
}
+ if (metadata.is_device()) {
+ auto name_kstring = TRY(KString::try_create(name));
+ unsigned major = major_from_encoded_device(device_mode);
+ unsigned minor = minor_from_encoded_device(device_mode);
+ auto new_device_inode = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) DevFSDeviceInode(fs(), major, minor, is_block_device(mode), move(name_kstring))));
+ TRY(new_device_inode->chmod(mode));
+ m_nodes.append(*new_device_inode);
+ return new_device_inode;
+ }
if (metadata.is_symlink()) {
auto name_kstring = TRY(KString::try_create(name));
auto new_link_inode = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) DevFSLinkInode(fs(), move(name_kstring))));
@@ -256,10 +245,12 @@ InodeMetadata DevFSRootDirectoryInode::metadata() const
return metadata;
}
-DevFSDeviceInode::DevFSDeviceInode(DevFS& fs, Device const& device, NonnullOwnPtr<KString> name)
+DevFSDeviceInode::DevFSDeviceInode(DevFS& fs, unsigned major_number, unsigned minor_number, bool block_device, NonnullOwnPtr<KString> name)
: DevFSInode(fs)
- , m_attached_device(device)
, m_name(move(name))
+ , m_major_number(major_number)
+ , m_minor_number(minor_number)
+ , m_block_device(block_device)
{
}
@@ -275,6 +266,16 @@ KResult DevFSDeviceInode::chown(UserID uid, GroupID gid)
return KSuccess;
}
+KResult DevFSDeviceInode::chmod(mode_t mode)
+{
+ MutexLocker locker(m_inode_lock);
+ mode &= 0777;
+ if (m_required_mode == mode)
+ return KSuccess;
+ m_required_mode = mode;
+ return KSuccess;
+}
+
StringView DevFSDeviceInode::name() const
{
return m_name->view();
@@ -284,12 +285,15 @@ KResultOr<size_t> DevFSDeviceInode::read_bytes(off_t offset, size_t count, UserO
{
MutexLocker locker(m_inode_lock);
VERIFY(!!description);
- if (!m_attached_device->can_read(*description, offset))
- return 0;
- auto nread = const_cast<Device&>(*m_attached_device).read(*description, offset, buffer, count);
- if (nread.is_error())
- return EIO;
- return nread.value();
+ RefPtr<Device> device = Device::get_device(m_major_number, m_minor_number);
+ if (!device)
+ return KResult(ENODEV);
+ if (!device->can_read(*description, offset))
+ return KResult(ENOTIMPL);
+ auto result = const_cast<Device&>(*device).read(*description, offset, buffer, count);
+ if (result.is_error())
+ return result;
+ return result.value();
}
InodeMetadata DevFSDeviceInode::metadata() const
@@ -297,25 +301,28 @@ InodeMetadata DevFSDeviceInode::metadata() const
MutexLocker locker(m_inode_lock);
InodeMetadata metadata;
metadata.inode = { fsid(), index() };
- metadata.mode = (m_attached_device->is_block_device() ? S_IFBLK : S_IFCHR) | m_attached_device->required_mode();
+ metadata.mode = (m_block_device ? S_IFBLK : S_IFCHR) | m_required_mode;
metadata.uid = m_uid;
metadata.gid = m_gid;
metadata.size = 0;
metadata.mtime = mepoch;
- metadata.major_device = m_attached_device->major();
- metadata.minor_device = m_attached_device->minor();
+ metadata.major_device = m_major_number;
+ metadata.minor_device = m_minor_number;
return metadata;
}
KResultOr<size_t> DevFSDeviceInode::write_bytes(off_t offset, size_t count, const UserOrKernelBuffer& buffer, OpenFileDescription* description)
{
MutexLocker locker(m_inode_lock);
VERIFY(!!description);
- if (!m_attached_device->can_write(*description, offset))
- return 0;
- auto nread = const_cast<Device&>(*m_attached_device).write(*description, offset, buffer, count);
- if (nread.is_error())
- return EIO;
- return nread.value();
+ RefPtr<Device> device = Device::get_device(m_major_number, m_minor_number);
+ if (!device)
+ return KResult(ENODEV);
+ if (!device->can_write(*description, offset))
+ return KResult(ENOTIMPL);
+ auto result = const_cast<Device&>(*device).write(*description, offset, buffer, count);
+ if (result.is_error())
+ return result;
+ return result.value();
}
DevFSPtsDirectoryInode::DevFSPtsDirectoryInode(DevFS& fs)
diff --git a/Kernel/FileSystem/DevFS.h b/Kernel/FileSystem/DevFS.h
index accae14ae5..c0860d403d 100644
--- a/Kernel/FileSystem/DevFS.h
+++ b/Kernel/FileSystem/DevFS.h
@@ -24,10 +24,6 @@ public:
virtual KResult initialize() override;
virtual StringView class_name() const override { return "DevFS"sv; }
-
- void notify_new_device(Device&);
- void notify_device_removal(Device&);
-
virtual Inode& root_inode() override;
private:
@@ -76,16 +72,19 @@ public:
virtual ~DevFSDeviceInode() override;
private:
- DevFSDeviceInode(DevFS&, Device const&, NonnullOwnPtr<KString> name);
+ DevFSDeviceInode(DevFS&, unsigned, unsigned, bool, NonnullOwnPtr<KString> name);
// ^Inode
virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual InodeMetadata metadata() const override;
virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, OpenFileDescription*) override;
virtual KResult chown(UserID, GroupID) override;
+ virtual KResult chmod(mode_t) override;
- NonnullRefPtr<Device> m_attached_device;
NonnullOwnPtr<KString> m_name;
-
+ const unsigned m_major_number;
+ const unsigned m_minor_number;
+ const bool m_block_device;
+ mode_t m_required_mode;
UserID m_uid { 0 };
GroupID m_gid { 0 };
};
diff --git a/Kernel/FileSystem/InodeMetadata.h b/Kernel/FileSystem/InodeMetadata.h
index d71865d2fc..03020413d7 100644
--- a/Kernel/FileSystem/InodeMetadata.h
+++ b/Kernel/FileSystem/InodeMetadata.h
@@ -19,6 +19,8 @@ constexpr u32 encoded_device(unsigned major, unsigned minor)
{
return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
}
+static inline unsigned int major_from_encoded_device(dev_t dev) { return (dev & 0xfff00u) >> 8u; }
+static inline unsigned int minor_from_encoded_device(dev_t dev) { return (dev & 0xffu) | ((dev >> 12u) & 0xfff00u); }
inline bool is_directory(mode_t mode) { return (mode & S_IFMT) == S_IFDIR; }
inline bool is_character_device(mode_t mode) { return (mode & S_IFMT) == S_IFCHR; }
diff --git a/Kernel/FileSystem/OpenFileDescription.cpp b/Kernel/FileSystem/OpenFileDescription.cpp
index 05803ecfc6..955b429fa5 100644
--- a/Kernel/FileSystem/OpenFileDescription.cpp
+++ b/Kernel/FileSystem/OpenFileDescription.cpp
@@ -71,6 +71,11 @@ KResult OpenFileDescription::attach()
return m_file->attach(*this);
}
+void OpenFileDescription::set_original_custody(Badge<VirtualFileSystem>, Custody& custody)
+{
+ m_custody = custody;
+}
+
Thread::FileBlocker::BlockFlags OpenFileDescription::should_unblock(Thread::FileBlocker::BlockFlags block_flags) const
{
using BlockFlags = Thread::FileBlocker::BlockFlags;
diff --git a/Kernel/FileSystem/OpenFileDescription.h b/Kernel/FileSystem/OpenFileDescription.h
index 04c3c08e61..2c3f1b1cfa 100644
--- a/Kernel/FileSystem/OpenFileDescription.h
+++ b/Kernel/FileSystem/OpenFileDescription.h
@@ -119,6 +119,7 @@ public:
OwnPtr<OpenFileDescriptionData>& data() { return m_data; }
void set_original_inode(Badge<VirtualFileSystem>, NonnullRefPtr<Inode>&& inode) { m_inode = move(inode); }
+ void set_original_custody(Badge<VirtualFileSystem>, Custody& custody);
KResult truncate(u64);
diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp
index 375355c313..a019e15703 100644
--- a/Kernel/FileSystem/VirtualFileSystem.cpp
+++ b/Kernel/FileSystem/VirtualFileSystem.cpp
@@ -276,6 +276,7 @@ KResultOr<NonnullRefPtr<OpenFileDescription>> VirtualFileSystem::open(StringView
}
auto description = TRY(device->open(options));
description->set_original_inode({}, inode);
+ description->set_original_custody({}, custody);
return description;
}