mirror of
https://github.com/RGBCube/serenity
synced 2025-05-16 23:15:07 +00:00
Kernel+SystemServer: Defer creation of device nodes to userspace
Don't create these device nodes in the Kernel, so we essentially enforce userspace (SystemServer) to take control of this operation and to decide how to create these device nodes. This makes the DevFS to resemble linux devtmpfs, and allows us to remove a bunch of unneeded overriding implementations of device name creation in the Kernel.
This commit is contained in:
parent
fcc046047f
commit
e0d712c6f7
7 changed files with 144 additions and 45 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue