Kernel: Handle allocation failure in ProcFS and friends

There were many places in which allocation failure was noticed but
ignored.
This commit is contained in:
sin-ack 2021-08-14 12:39:51 +00:00 committed by Andreas Kling
parent 134dbe2607
commit 748938ea59
Notes: sideshowbarker 2024-07-18 05:42:35 +09:00
8 changed files with 196 additions and 92 deletions

View file

@ -37,13 +37,12 @@ UNMAP_AFTER_INIT ProcFSComponentRegistry::ProcFSComponentRegistry()
{
}
RefPtr<ProcFS> ProcFS::create()
KResultOr<NonnullRefPtr<ProcFS>> ProcFS::try_create()
{
return adopt_ref_if_nonnull(new (nothrow) ProcFS);
return adopt_nonnull_ref_or_enomem(new (nothrow) ProcFS());
}
ProcFS::ProcFS()
: m_root_inode(ProcFSComponentRegistry::the().root_directory().to_inode(*this))
{
}
@ -53,6 +52,11 @@ ProcFS::~ProcFS()
KResult ProcFS::initialize()
{
auto root_inode = ProcFSComponentRegistry::the().root_directory().to_inode(*this);
if (root_inode.is_error())
return root_inode.error();
m_root_inode = static_cast<NonnullRefPtr<ProcFSDirectoryInode>>(root_inode.release_value());
return KSuccess;
}
@ -104,9 +108,9 @@ KResult ProcFSInode::truncate(u64)
return EPERM;
}
NonnullRefPtr<ProcFSGlobalInode> ProcFSGlobalInode::create(const ProcFS& fs, const ProcFSExposedComponent& component)
KResultOr<NonnullRefPtr<ProcFSGlobalInode>> ProcFSGlobalInode::try_create(const ProcFS& fs, const ProcFSExposedComponent& component)
{
return adopt_ref(*new (nothrow) ProcFSGlobalInode(fs, component));
return adopt_nonnull_ref_or_enomem(new (nothrow) ProcFSGlobalInode(fs, component));
}
ProcFSGlobalInode::ProcFSGlobalInode(const ProcFS& fs, const ProcFSExposedComponent& component)
@ -169,9 +173,9 @@ KResultOr<size_t> ProcFSGlobalInode::write_bytes(off_t offset, size_t count, con
return m_associated_component->write_bytes(offset, count, buffer, fd);
}
NonnullRefPtr<ProcFSDirectoryInode> ProcFSDirectoryInode::create(const ProcFS& procfs, const ProcFSExposedComponent& component)
KResultOr<NonnullRefPtr<ProcFSDirectoryInode>> ProcFSDirectoryInode::try_create(const ProcFS& procfs, const ProcFSExposedComponent& component)
{
return adopt_ref(*new (nothrow) ProcFSDirectoryInode(procfs, component));
return adopt_nonnull_ref_or_enomem(new (nothrow) ProcFSDirectoryInode(procfs, component));
}
ProcFSDirectoryInode::ProcFSDirectoryInode(const ProcFS& fs, const ProcFSExposedComponent& component)
@ -203,15 +207,21 @@ KResult ProcFSDirectoryInode::traverse_as_directory(Function<bool(FileSystem::Di
KResultOr<NonnullRefPtr<Inode>> ProcFSDirectoryInode::lookup(StringView name)
{
MutexLocker locker(procfs().m_lock);
auto component = m_associated_component->lookup(name);
if (!component)
return ENOMEM;
return component->to_inode(procfs());
auto maybe_component = m_associated_component->lookup(name);
if (maybe_component.is_error())
return maybe_component.error();
auto component = maybe_component.release_value();
auto maybe_inode = component->to_inode(procfs());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
NonnullRefPtr<ProcFSLinkInode> ProcFSLinkInode::create(const ProcFS& procfs, const ProcFSExposedComponent& component)
KResultOr<NonnullRefPtr<ProcFSLinkInode>> ProcFSLinkInode::try_create(const ProcFS& procfs, const ProcFSExposedComponent& component)
{
return adopt_ref(*new (nothrow) ProcFSLinkInode(procfs, component));
return adopt_nonnull_ref_or_enomem(new (nothrow) ProcFSLinkInode(procfs, component));
}
ProcFSLinkInode::ProcFSLinkInode(const ProcFS& fs, const ProcFSExposedComponent& component)
@ -243,9 +253,9 @@ KResultOr<size_t> ProcFSProcessAssociatedInode::write_bytes(off_t, size_t, const
VERIFY_NOT_REACHED();
}
NonnullRefPtr<ProcFSProcessDirectoryInode> ProcFSProcessDirectoryInode::create(const ProcFS& procfs, ProcessID pid)
KResultOr<NonnullRefPtr<ProcFSProcessDirectoryInode>> ProcFSProcessDirectoryInode::try_create(const ProcFS& procfs, ProcessID pid)
{
return adopt_ref_if_nonnull(new (nothrow) ProcFSProcessDirectoryInode(procfs, pid)).release_nonnull();
return adopt_nonnull_ref_or_enomem(new (nothrow) ProcFSProcessDirectoryInode(procfs, pid));
}
ProcFSProcessDirectoryInode::ProcFSProcessDirectoryInode(const ProcFS& procfs, ProcessID pid)
@ -294,32 +304,73 @@ KResultOr<NonnullRefPtr<Inode>> ProcFSProcessDirectoryInode::lookup(StringView n
auto process = Process::from_pid(associated_pid());
if (!process)
return ESRCH;
if (name == "fd")
return ProcFSProcessSubDirectoryInode::create(procfs(), SegmentedProcFSIndex::ProcessSubDirectory::FileDescriptions, associated_pid());
if (name == "stacks")
return ProcFSProcessSubDirectoryInode::create(procfs(), SegmentedProcFSIndex::ProcessSubDirectory::Stacks, associated_pid());
if (name == "unveil")
return ProcFSProcessPropertyInode::create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::Unveil, associated_pid());
if (name == "pledge")
return ProcFSProcessPropertyInode::create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::Pledge, associated_pid());
if (name == "fds")
return ProcFSProcessPropertyInode::create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::FileDescriptions, associated_pid());
if (name == "exe")
return ProcFSProcessPropertyInode::create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::BinaryLink, associated_pid());
if (name == "cwd")
return ProcFSProcessPropertyInode::create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::CurrentWorkDirectoryLink, associated_pid());
if (name == "perf_events")
return ProcFSProcessPropertyInode::create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::PerformanceEvents, associated_pid());
if (name == "vm")
return ProcFSProcessPropertyInode::create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::VirtualMemoryStats, associated_pid());
if (name == "root")
return ProcFSProcessPropertyInode::create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::RootLink, associated_pid());
if (name == "fd") {
auto maybe_inode = ProcFSProcessSubDirectoryInode::try_create(procfs(), SegmentedProcFSIndex::ProcessSubDirectory::FileDescriptions, associated_pid());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
if (name == "stacks") {
auto maybe_inode = ProcFSProcessSubDirectoryInode::try_create(procfs(), SegmentedProcFSIndex::ProcessSubDirectory::Stacks, associated_pid());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
if (name == "unveil") {
auto maybe_inode = ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::Unveil, associated_pid());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
if (name == "pledge") {
auto maybe_inode = ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::Pledge, associated_pid());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
if (name == "fds") {
auto maybe_inode = ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::FileDescriptions, associated_pid());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
if (name == "exe") {
auto maybe_inode = ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::BinaryLink, associated_pid());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
if (name == "cwd") {
auto maybe_inode = ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::CurrentWorkDirectoryLink, associated_pid());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
if (name == "perf_events") {
auto maybe_inode = ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::PerformanceEvents, associated_pid());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
if (name == "vm") {
auto maybe_inode = ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::VirtualMemoryStats, associated_pid());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
if (name == "root") {
auto maybe_inode = ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::RootLink, associated_pid());
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
return ENOENT;
}
NonnullRefPtr<ProcFSProcessSubDirectoryInode> ProcFSProcessSubDirectoryInode::create(const ProcFS& procfs, SegmentedProcFSIndex::ProcessSubDirectory sub_directory_type, ProcessID pid)
KResultOr<NonnullRefPtr<ProcFSProcessSubDirectoryInode>> ProcFSProcessSubDirectoryInode::try_create(const ProcFS& procfs, SegmentedProcFSIndex::ProcessSubDirectory sub_directory_type, ProcessID pid)
{
return adopt_ref_if_nonnull(new (nothrow) ProcFSProcessSubDirectoryInode(procfs, sub_directory_type, pid)).release_nonnull();
return adopt_nonnull_ref_or_enomem(new (nothrow) ProcFSProcessSubDirectoryInode(procfs, sub_directory_type, pid));
}
ProcFSProcessSubDirectoryInode::ProcFSProcessSubDirectoryInode(const ProcFS& procfs, SegmentedProcFSIndex::ProcessSubDirectory sub_directory_type, ProcessID pid)
@ -384,12 +435,18 @@ KResultOr<NonnullRefPtr<Inode>> ProcFSProcessSubDirectoryInode::lookup(StringVie
return ESRCH;
RefPtr<Inode> inode;
switch (m_sub_directory_type) {
case SegmentedProcFSIndex::ProcessSubDirectory::FileDescriptions:
inode = process->lookup_file_descriptions_directory(procfs(), name);
break;
case SegmentedProcFSIndex::ProcessSubDirectory::Stacks:
inode = process->lookup_stacks_directory(procfs(), name);
break;
case SegmentedProcFSIndex::ProcessSubDirectory::FileDescriptions: {
auto maybe_inode = process->lookup_file_descriptions_directory(procfs(), name);
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
case SegmentedProcFSIndex::ProcessSubDirectory::Stacks: {
auto maybe_inode = process->lookup_stacks_directory(procfs(), name);
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
default:
VERIFY_NOT_REACHED();
}
@ -398,17 +455,17 @@ KResultOr<NonnullRefPtr<Inode>> ProcFSProcessSubDirectoryInode::lookup(StringVie
return inode.release_nonnull();
}
NonnullRefPtr<ProcFSProcessPropertyInode> ProcFSProcessPropertyInode::create_for_file_description_link(const ProcFS& procfs, unsigned file_description_index, ProcessID pid)
KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> ProcFSProcessPropertyInode::try_create_for_file_description_link(const ProcFS& procfs, unsigned file_description_index, ProcessID pid)
{
return adopt_ref_if_nonnull(new (nothrow) ProcFSProcessPropertyInode(procfs, file_description_index, pid)).release_nonnull();
return adopt_nonnull_ref_or_enomem(new (nothrow) ProcFSProcessPropertyInode(procfs, file_description_index, pid));
}
NonnullRefPtr<ProcFSProcessPropertyInode> ProcFSProcessPropertyInode::create_for_thread_stack(const ProcFS& procfs, ThreadID stack_thread_index, ProcessID pid)
KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> ProcFSProcessPropertyInode::try_create_for_thread_stack(const ProcFS& procfs, ThreadID stack_thread_index, ProcessID pid)
{
return adopt_ref_if_nonnull(new (nothrow) ProcFSProcessPropertyInode(procfs, stack_thread_index, pid)).release_nonnull();
return adopt_nonnull_ref_or_enomem(new (nothrow) ProcFSProcessPropertyInode(procfs, stack_thread_index, pid));
}
NonnullRefPtr<ProcFSProcessPropertyInode> ProcFSProcessPropertyInode::create_for_pid_property(const ProcFS& procfs, SegmentedProcFSIndex::MainProcessProperty main_property_type, ProcessID pid)
KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> ProcFSProcessPropertyInode::try_create_for_pid_property(const ProcFS& procfs, SegmentedProcFSIndex::MainProcessProperty main_property_type, ProcessID pid)
{
return adopt_ref_if_nonnull(new (nothrow) ProcFSProcessPropertyInode(procfs, main_property_type, pid)).release_nonnull();
return adopt_nonnull_ref_or_enomem(new (nothrow) ProcFSProcessPropertyInode(procfs, main_property_type, pid));
}
ProcFSProcessPropertyInode::ProcFSProcessPropertyInode(const ProcFS& procfs, SegmentedProcFSIndex::MainProcessProperty main_property_type, ProcessID pid)

View file

@ -28,7 +28,7 @@ class ProcFS final : public FileSystem {
public:
virtual ~ProcFS() override;
static RefPtr<ProcFS> create();
static KResultOr<NonnullRefPtr<ProcFS>> try_create();
virtual KResult initialize() override;
virtual StringView class_name() const override { return "ProcFS"sv; }
@ -38,7 +38,7 @@ public:
private:
ProcFS();
NonnullRefPtr<ProcFSDirectoryInode> m_root_inode;
RefPtr<ProcFSDirectoryInode> m_root_inode;
};
class ProcFSInode : public Inode {
@ -69,7 +69,7 @@ class ProcFSGlobalInode : public ProcFSInode {
friend class ProcFS;
public:
static NonnullRefPtr<ProcFSGlobalInode> create(const ProcFS&, const ProcFSExposedComponent&);
static KResultOr<NonnullRefPtr<ProcFSGlobalInode>> try_create(const ProcFS&, const ProcFSExposedComponent&);
virtual ~ProcFSGlobalInode() override {};
StringView name() const;
@ -92,7 +92,7 @@ class ProcFSLinkInode : public ProcFSGlobalInode {
friend class ProcFS;
public:
static NonnullRefPtr<ProcFSLinkInode> create(const ProcFS&, const ProcFSExposedComponent&);
static KResultOr<NonnullRefPtr<ProcFSLinkInode>> try_create(const ProcFS&, const ProcFSExposedComponent&);
protected:
ProcFSLinkInode(const ProcFS&, const ProcFSExposedComponent&);
@ -103,7 +103,7 @@ class ProcFSDirectoryInode final : public ProcFSGlobalInode {
friend class ProcFS;
public:
static NonnullRefPtr<ProcFSDirectoryInode> create(const ProcFS&, const ProcFSExposedComponent&);
static KResultOr<NonnullRefPtr<ProcFSDirectoryInode>> try_create(const ProcFS&, const ProcFSExposedComponent&);
virtual ~ProcFSDirectoryInode() override;
protected:
@ -132,7 +132,7 @@ class ProcFSProcessDirectoryInode final : public ProcFSProcessAssociatedInode {
friend class ProcFS;
public:
static NonnullRefPtr<ProcFSProcessDirectoryInode> create(const ProcFS&, ProcessID);
static KResultOr<NonnullRefPtr<ProcFSProcessDirectoryInode>> try_create(const ProcFS&, ProcessID);
private:
ProcFSProcessDirectoryInode(const ProcFS&, ProcessID);
@ -149,7 +149,7 @@ class ProcFSProcessSubDirectoryInode final : public ProcFSProcessAssociatedInode
friend class ProcFS;
public:
static NonnullRefPtr<ProcFSProcessSubDirectoryInode> create(const ProcFS&, SegmentedProcFSIndex::ProcessSubDirectory, ProcessID);
static KResultOr<NonnullRefPtr<ProcFSProcessSubDirectoryInode>> try_create(const ProcFS&, SegmentedProcFSIndex::ProcessSubDirectory, ProcessID);
private:
ProcFSProcessSubDirectoryInode(const ProcFS&, SegmentedProcFSIndex::ProcessSubDirectory, ProcessID);
@ -168,9 +168,9 @@ class ProcFSProcessPropertyInode final : public ProcFSProcessAssociatedInode {
friend class ProcFS;
public:
static NonnullRefPtr<ProcFSProcessPropertyInode> create_for_file_description_link(const ProcFS&, unsigned, ProcessID);
static NonnullRefPtr<ProcFSProcessPropertyInode> create_for_thread_stack(const ProcFS&, ThreadID, ProcessID);
static NonnullRefPtr<ProcFSProcessPropertyInode> create_for_pid_property(const ProcFS&, SegmentedProcFSIndex::MainProcessProperty, ProcessID);
static KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> try_create_for_file_description_link(const ProcFS&, unsigned, ProcessID);
static KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> try_create_for_thread_stack(const ProcFS&, ThreadID, ProcessID);
static KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> try_create_for_pid_property(const ProcFS&, SegmentedProcFSIndex::MainProcessProperty, ProcessID);
private:
ProcFSProcessPropertyInode(const ProcFS&, SegmentedProcFSIndex::MainProcessProperty, ProcessID);

View file

@ -926,17 +926,27 @@ KResult ProcFSRootDirectory::traverse_as_directory(unsigned fsid, Function<bool(
return KSuccess;
}
RefPtr<ProcFSExposedComponent> ProcFSRootDirectory::lookup(StringView name)
KResultOr<NonnullRefPtr<ProcFSExposedComponent>> ProcFSRootDirectory::lookup(StringView name)
{
if (auto candidate = ProcFSExposedDirectory::lookup(name); !candidate.is_null())
return candidate;
auto maybe_candidate = ProcFSExposedDirectory::lookup(name);
if (maybe_candidate.is_error()) {
if (maybe_candidate.error() != ENOENT) {
return maybe_candidate.error();
}
} else {
return maybe_candidate.release_value();
}
String process_directory_name = name;
auto pid = process_directory_name.to_uint<unsigned>();
if (!pid.has_value())
return {};
return ESRCH;
auto actual_pid = pid.value();
return Process::from_pid(actual_pid);
auto maybe_process = Process::from_pid(actual_pid);
if (maybe_process)
return maybe_process.release_nonnull();
return ENOENT;
}
UNMAP_AFTER_INIT ProcFSRootDirectory::ProcFSRootDirectory()

View file

@ -551,7 +551,7 @@ private:
public:
// ^ProcFSExposedComponent stats
virtual InodeIndex component_index() const override;
virtual NonnullRefPtr<Inode> to_inode(const ProcFS& procfs_instance) const override;
virtual KResultOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const override;
virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
virtual mode_t required_mode() const override { return 0555; }
virtual uid_t owner_user() const override { return uid(); }
@ -567,10 +567,10 @@ public:
mode_t binary_link_required_mode() const;
KResultOr<size_t> procfs_get_thread_stack(ThreadID thread_id, KBufferBuilder& builder) const;
KResult traverse_stacks_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const;
RefPtr<Inode> lookup_stacks_directory(const ProcFS&, StringView name) const;
KResultOr<NonnullRefPtr<Inode>> lookup_stacks_directory(const ProcFS&, StringView name) const;
KResultOr<size_t> procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const;
KResult traverse_file_descriptions_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const;
RefPtr<Inode> lookup_file_descriptions_directory(const ProcFS&, StringView name) const;
KResultOr<NonnullRefPtr<Inode>> lookup_file_descriptions_directory(const ProcFS&, StringView name) const;
private:
inline PerformanceEventBuffer* current_perf_events_buffer()

View file

@ -170,19 +170,31 @@ KResultOr<size_t> ProcFSExposedLink::read_bytes(off_t offset, size_t count, User
return nread;
}
NonnullRefPtr<Inode> ProcFSExposedLink::to_inode(const ProcFS& procfs_instance) const
KResultOr<NonnullRefPtr<Inode>> ProcFSExposedLink::to_inode(const ProcFS& procfs_instance) const
{
return ProcFSLinkInode::create(procfs_instance, *this);
auto maybe_inode = ProcFSLinkInode::try_create(procfs_instance, *this);
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
NonnullRefPtr<Inode> ProcFSExposedComponent::to_inode(const ProcFS& procfs_instance) const
KResultOr<NonnullRefPtr<Inode>> ProcFSExposedComponent::to_inode(const ProcFS& procfs_instance) const
{
return ProcFSGlobalInode::create(procfs_instance, *this);
auto maybe_inode = ProcFSGlobalInode::try_create(procfs_instance, *this);
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
NonnullRefPtr<Inode> ProcFSExposedDirectory::to_inode(const ProcFS& procfs_instance) const
KResultOr<NonnullRefPtr<Inode>> ProcFSExposedDirectory::to_inode(const ProcFS& procfs_instance) const
{
return ProcFSDirectoryInode::create(procfs_instance, *this);
auto maybe_inode = ProcFSDirectoryInode::try_create(procfs_instance, *this);
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
void ProcFSExposedDirectory::add_component(const ProcFSExposedComponent&)
@ -190,14 +202,14 @@ void ProcFSExposedDirectory::add_component(const ProcFSExposedComponent&)
TODO();
}
RefPtr<ProcFSExposedComponent> ProcFSExposedDirectory::lookup(StringView name)
KResultOr<NonnullRefPtr<ProcFSExposedComponent>> ProcFSExposedDirectory::lookup(StringView name)
{
for (auto& component : m_components) {
if (component.name() == name) {
return component;
}
}
return {};
return ENOENT;
}
KResult ProcFSExposedDirectory::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const

View file

@ -69,7 +69,7 @@ public:
StringView name() const { return m_name->view(); }
virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, FileDescription*) const { VERIFY_NOT_REACHED(); }
virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); }
virtual RefPtr<ProcFSExposedComponent> lookup(StringView) { VERIFY_NOT_REACHED(); };
virtual KResultOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView) { VERIFY_NOT_REACHED(); };
virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer&, FileDescription*) { return KResult(EROFS); }
virtual size_t size() const { return 0; }
@ -84,7 +84,7 @@ public:
return KSuccess;
}
virtual NonnullRefPtr<Inode> to_inode(const ProcFS& procfs_instance) const;
virtual KResultOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const;
virtual InodeIndex component_index() const { return m_component_index; }
@ -106,7 +106,7 @@ class ProcFSExposedDirectory
public:
virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
virtual RefPtr<ProcFSExposedComponent> lookup(StringView name) override;
virtual KResultOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView name) override;
void add_component(const ProcFSExposedComponent&);
virtual void prepare_for_deletion() override
@ -117,7 +117,7 @@ public:
}
virtual mode_t required_mode() const override { return 0555; }
virtual NonnullRefPtr<Inode> to_inode(const ProcFS& procfs_instance) const override final;
virtual KResultOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const override final;
protected:
explicit ProcFSExposedDirectory(StringView name);
@ -128,7 +128,7 @@ protected:
class ProcFSExposedLink : public ProcFSExposedComponent {
public:
virtual NonnullRefPtr<Inode> to_inode(const ProcFS& procfs_instance) const override final;
virtual KResultOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const override final;
virtual KResultOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription* description) const override;
@ -142,7 +142,7 @@ class ProcFSRootDirectory final : public ProcFSExposedDirectory {
friend class ProcFSComponentRegistry;
public:
virtual RefPtr<ProcFSExposedComponent> lookup(StringView name) override;
virtual KResultOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView name) override;
static NonnullRefPtr<ProcFSRootDirectory> must_create();
virtual ~ProcFSRootDirectory();

View file

@ -45,9 +45,12 @@ InodeIndex Process::component_index() const
return SegmentedProcFSIndex::build_segmented_index_for_pid_directory(pid());
}
NonnullRefPtr<Inode> Process::to_inode(const ProcFS& procfs_instance) const
KResultOr<NonnullRefPtr<Inode>> Process::to_inode(const ProcFS& procfs_instance) const
{
return ProcFSProcessDirectoryInode::create(procfs_instance, m_protected_values.pid);
auto maybe_inode = ProcFSProcessDirectoryInode::try_create(procfs_instance, m_protected_values.pid);
if (maybe_inode.is_error())
return maybe_inode.error();
return maybe_inode.release_value();
}
KResult Process::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
@ -80,18 +83,28 @@ KResult Process::traverse_stacks_directory(unsigned fsid, Function<bool(FileSyst
return KSuccess;
}
RefPtr<Inode> Process::lookup_stacks_directory(const ProcFS& procfs, StringView name) const
KResultOr<NonnullRefPtr<Inode>> Process::lookup_stacks_directory(const ProcFS& procfs, StringView name) const
{
RefPtr<ProcFSProcessPropertyInode> thread_stack_inode;
KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> thread_stack_inode { ENOENT };
// FIXME: Try to exit the loop earlier
for_each_thread([&](const Thread& thread) {
int tid = thread.tid().value();
VERIFY(!(tid < 0));
if (name == String::number(tid)) {
thread_stack_inode = ProcFSProcessPropertyInode::create_for_thread_stack(procfs, thread.tid(), pid());
auto maybe_inode = ProcFSProcessPropertyInode::try_create_for_thread_stack(procfs, thread.tid(), pid());
if (maybe_inode.is_error()) {
thread_stack_inode = maybe_inode.error();
return;
}
thread_stack_inode = maybe_inode.release_value();
}
});
return thread_stack_inode;
if (thread_stack_inode.is_error())
return thread_stack_inode.error();
return thread_stack_inode.release_value();
}
KResultOr<size_t> Process::procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const
@ -121,9 +134,9 @@ KResult Process::traverse_file_descriptions_directory(unsigned fsid, Function<bo
return KSuccess;
}
RefPtr<Inode> Process::lookup_file_descriptions_directory(const ProcFS& procfs, StringView name) const
KResultOr<NonnullRefPtr<Inode>> Process::lookup_file_descriptions_directory(const ProcFS& procfs, StringView name) const
{
RefPtr<ProcFSProcessPropertyInode> file_description_link;
KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> file_description_link { ENOENT };
// FIXME: Try to exit the loop earlier
size_t count = 0;
fds().enumerate([&](auto& file_description_metadata) {
@ -132,11 +145,20 @@ RefPtr<Inode> Process::lookup_file_descriptions_directory(const ProcFS& procfs,
return;
}
if (name == String::number(count)) {
file_description_link = ProcFSProcessPropertyInode::create_for_file_description_link(procfs, static_cast<unsigned>(count), pid());
auto maybe_inode = ProcFSProcessPropertyInode::try_create_for_file_description_link(procfs, static_cast<unsigned>(count), pid());
if (maybe_inode.is_error()) {
file_description_link = maybe_inode.error();
return;
}
file_description_link = maybe_inode.release_value();
}
count++;
});
return file_description_link;
if (file_description_link.is_error())
return file_description_link.error();
return file_description_link.release_value();
}
KResult Process::procfs_get_pledge_stats(KBufferBuilder& builder) const

View file

@ -90,7 +90,10 @@ KResultOr<FlatPtr> Process::sys$mount(Userspace<const Syscall::SC_mount_params*>
fs = Plan9FS::create(*description);
} else if (fs_type == "proc"sv || fs_type == "ProcFS"sv) {
fs = ProcFS::create();
auto maybe_fs = ProcFS::try_create();
if (maybe_fs.is_error())
return maybe_fs.error();
fs = maybe_fs.release_value();
} else if (fs_type == "devpts"sv || fs_type == "DevPtsFS"sv) {
fs = DevPtsFS::create();
} else if (fs_type == "dev"sv || fs_type == "DevFS"sv) {