1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 22:57:44 +00:00

Kernel: Make Inode::traverse_as_directory() callback return ErrorOr

This allows us to propagate errors from inside the callback with TRY().
This commit is contained in:
Andreas Kling 2021-11-10 15:42:39 +01:00
parent a15ed8743d
commit 5ce753b74d
31 changed files with 154 additions and 151 deletions

View file

@ -91,17 +91,17 @@ ErrorOr<size_t> SysFSUSBDeviceInformation::read_bytes(off_t offset, size_t count
return nread; return nread;
} }
ErrorOr<void> SysFSUSBBusDirectory::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> SysFSUSBBusDirectory::traverse_as_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
SpinlockLocker lock(m_lock); SpinlockLocker lock(m_lock);
// Note: if the parent directory is null, it means something bad happened as this should not happen for the USB directory. // Note: if the parent directory is null, it means something bad happened as this should not happen for the USB directory.
VERIFY(m_parent_directory); VERIFY(m_parent_directory);
callback({ ".", { fsid, component_index() }, 0 }); TRY(callback({ ".", { fsid, component_index() }, 0 }));
callback({ "..", { fsid, m_parent_directory->component_index() }, 0 }); TRY(callback({ "..", { fsid, m_parent_directory->component_index() }, 0 }));
for (auto& device_node : m_device_nodes) { for (auto& device_node : m_device_nodes) {
InodeIdentifier identifier = { fsid, device_node.component_index() }; InodeIdentifier identifier = { fsid, device_node.component_index() };
callback({ device_node.name(), identifier, 0 }); TRY(callback({ device_node.name(), identifier, 0 }));
} }
return {}; return {};
} }

View file

@ -46,7 +46,7 @@ public:
void plug(USB::Device&); void plug(USB::Device&);
void unplug(USB::Device&); void unplug(USB::Device&);
virtual ErrorOr<void> traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(unsigned, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual RefPtr<SysFSComponent> lookup(StringView name) override; virtual RefPtr<SysFSComponent> lookup(StringView name) override;
private: private:

View file

@ -44,21 +44,23 @@ SysFSBlockDevicesDirectory::SysFSBlockDevicesDirectory(SysFSDevicesDirectory con
: SysFSDirectory("block"sv, devices_directory) : SysFSDirectory("block"sv, devices_directory)
{ {
} }
ErrorOr<void> SysFSBlockDevicesDirectory::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
ErrorOr<void> SysFSBlockDevicesDirectory::traverse_as_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
VERIFY(m_parent_directory); VERIFY(m_parent_directory);
callback({ ".", { fsid, component_index() }, 0 }); TRY(callback({ ".", { fsid, component_index() }, 0 }));
callback({ "..", { fsid, m_parent_directory->component_index() }, 0 }); TRY(callback({ "..", { fsid, m_parent_directory->component_index() }, 0 }));
SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> void { return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> ErrorOr<void> {
for (auto& exposed_device : list) { for (auto& exposed_device : list) {
if (!exposed_device.is_block_device()) if (!exposed_device.is_block_device())
continue; continue;
callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 }); TRY(callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 }));
} }
return {};
}); });
return {};
} }
RefPtr<SysFSComponent> SysFSBlockDevicesDirectory::lookup(StringView name) RefPtr<SysFSComponent> SysFSBlockDevicesDirectory::lookup(StringView name)
{ {
return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> RefPtr<SysFSComponent> { return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> RefPtr<SysFSComponent> {
@ -80,21 +82,22 @@ SysFSCharacterDevicesDirectory::SysFSCharacterDevicesDirectory(SysFSDevicesDirec
: SysFSDirectory("char"sv, devices_directory) : SysFSDirectory("char"sv, devices_directory)
{ {
} }
ErrorOr<void> SysFSCharacterDevicesDirectory::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> SysFSCharacterDevicesDirectory::traverse_as_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
VERIFY(m_parent_directory); VERIFY(m_parent_directory);
callback({ ".", { fsid, component_index() }, 0 }); TRY(callback({ ".", { fsid, component_index() }, 0 }));
callback({ "..", { fsid, m_parent_directory->component_index() }, 0 }); TRY(callback({ "..", { fsid, m_parent_directory->component_index() }, 0 }));
SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> void { return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> ErrorOr<void> {
for (auto& exposed_device : list) { for (auto& exposed_device : list) {
if (exposed_device.is_block_device()) if (exposed_device.is_block_device())
continue; continue;
callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 }); TRY(callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 }));
} }
return {};
}); });
return {};
} }
RefPtr<SysFSComponent> SysFSCharacterDevicesDirectory::lookup(StringView name) RefPtr<SysFSComponent> SysFSCharacterDevicesDirectory::lookup(StringView name)
{ {
return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> RefPtr<SysFSComponent> { return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> RefPtr<SysFSComponent> {

View file

@ -105,23 +105,22 @@ InodeMetadata DevPtsFSInode::metadata() const
return m_metadata; return m_metadata;
} }
ErrorOr<void> DevPtsFSInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> DevPtsFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
if (identifier().index() > 1) if (identifier().index() > 1)
return ENOTDIR; return ENOTDIR;
callback({ ".", identifier(), 0 }); TRY(callback({ ".", identifier(), 0 }));
callback({ "..", identifier(), 0 }); TRY(callback({ "..", identifier(), 0 }));
SlavePTY::all_instances().with([&](auto& list) { return SlavePTY::all_instances().with([&](auto& list) -> ErrorOr<void> {
for (SlavePTY& slave_pty : list) { for (SlavePTY& slave_pty : list) {
StringBuilder builder; StringBuilder builder;
builder.appendff("{}", slave_pty.index()); builder.appendff("{}", slave_pty.index());
callback({ builder.string_view(), { fsid(), pty_index_to_inode_index(slave_pty.index()) }, 0 }); TRY(callback({ builder.string_view(), { fsid(), pty_index_to_inode_index(slave_pty.index()) }, 0 }));
} }
return {};
}); });
return {};
} }
ErrorOr<NonnullRefPtr<Inode>> DevPtsFSInode::lookup(StringView name) ErrorOr<NonnullRefPtr<Inode>> DevPtsFSInode::lookup(StringView name)

View file

@ -49,7 +49,7 @@ private:
// ^Inode // ^Inode
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override; virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, OpenFileDescription*) override; virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, OpenFileDescription*) override;

View file

@ -60,7 +60,7 @@ ErrorOr<size_t> DevTmpFSInode::read_bytes(off_t, size_t, UserOrKernelBuffer&, Op
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
ErrorOr<void> DevTmpFSInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const ErrorOr<void> DevTmpFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const
{ {
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
@ -210,14 +210,14 @@ DevTmpFSDirectoryInode::~DevTmpFSDirectoryInode()
{ {
} }
ErrorOr<void> DevTmpFSDirectoryInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> DevTmpFSDirectoryInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(m_inode_lock); MutexLocker locker(m_inode_lock);
callback({ ".", identifier(), 0 }); TRY(callback({ ".", identifier(), 0 }));
callback({ "..", identifier(), 0 }); TRY(callback({ "..", identifier(), 0 }));
for (auto& node : m_nodes) { for (auto& node : m_nodes) {
InodeIdentifier identifier = { fsid(), node.index() }; InodeIdentifier identifier = { fsid(), node.index() };
callback({ node.name(), identifier, 0 }); TRY(callback({ node.name(), identifier, 0 }));
} }
return {}; return {};
} }

View file

@ -49,7 +49,7 @@ protected:
explicit DevTmpFSInode(DevTmpFS&); explicit DevTmpFSInode(DevTmpFS&);
DevTmpFSInode(DevTmpFS&, unsigned, unsigned); DevTmpFSInode(DevTmpFS&, unsigned, unsigned);
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override; virtual ErrorOr<void> flush_metadata() override;
virtual InodeMetadata metadata() const override final; virtual InodeMetadata metadata() const override final;
@ -138,7 +138,7 @@ protected:
virtual ErrorOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override; virtual ErrorOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
virtual ErrorOr<void> remove_child(const StringView& name) override; virtual ErrorOr<void> remove_child(const StringView& name) override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
DevTmpFSDirectoryInode(DevTmpFS&, NonnullOwnPtr<KString> name); DevTmpFSDirectoryInode(DevTmpFS&, NonnullOwnPtr<KString> name);
// ^Inode // ^Inode

View file

@ -1058,7 +1058,7 @@ Ext2FS::FeaturesReadOnly Ext2FS::get_features_readonly() const
return Ext2FS::FeaturesReadOnly::None; return Ext2FS::FeaturesReadOnly::None;
} }
ErrorOr<void> Ext2FSInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> Ext2FSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
VERIFY(is_directory()); VERIFY(is_directory());
@ -1079,8 +1079,7 @@ ErrorOr<void> Ext2FSInode::traverse_as_directory(Function<bool(FileSystem::Direc
while (entry < entries_end) { while (entry < entries_end) {
if (entry->inode != 0) { if (entry->inode != 0) {
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::traverse_as_directory(): inode {}, name_len: {}, rec_len: {}, file_type: {}, name: {}", identifier(), entry->inode, entry->name_len, entry->rec_len, entry->file_type, StringView(entry->name, entry->name_len)); dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::traverse_as_directory(): inode {}, name_len: {}, rec_len: {}, file_type: {}, name: {}", identifier(), entry->inode, entry->name_len, entry->rec_len, entry->file_type, StringView(entry->name, entry->name_len));
if (!callback({ { entry->name, entry->name_len }, { fsid(), entry->inode }, entry->file_type })) TRY(callback({ { entry->name, entry->name_len }, { fsid(), entry->inode }, entry->file_type }));
return {};
} }
entry = (ext2_dir_entry_2*)((char*)entry + entry->rec_len); entry = (ext2_dir_entry_2*)((char*)entry + entry->rec_len);
} }
@ -1167,21 +1166,13 @@ ErrorOr<void> Ext2FSInode::add_child(Inode& child, const StringView& name, mode_
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::add_child(): Adding inode {} with name '{}' and mode {:o} to directory {}", identifier(), child.index(), name, mode, index()); dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::add_child(): Adding inode {} with name '{}' and mode {:o} to directory {}", identifier(), child.index(), name, mode, index());
Vector<Ext2FSDirectoryEntry> entries; Vector<Ext2FSDirectoryEntry> entries;
bool name_already_exists = false; TRY(traverse_as_directory([&](auto& entry) -> ErrorOr<void> {
TRY(traverse_as_directory([&](auto& entry) { if (name == entry.name)
if (name == entry.name) { return EEXIST;
name_already_exists = true;
return false;
}
entries.append({ entry.name, entry.inode.index(), entry.file_type }); entries.append({ entry.name, entry.inode.index(), entry.file_type });
return true; return {};
})); }));
if (name_already_exists) {
dbgln("Ext2FSInode[{}]::add_child(): Name '{}' already exists", identifier(), name);
return EEXIST;
}
TRY(child.increment_link_count()); TRY(child.increment_link_count());
entries.empend(name, child.index(), to_ext2_file_type(mode)); entries.empend(name, child.index(), to_ext2_file_type(mode));
@ -1210,10 +1201,10 @@ ErrorOr<void> Ext2FSInode::remove_child(const StringView& name)
InodeIdentifier child_id { fsid(), child_inode_index }; InodeIdentifier child_id { fsid(), child_inode_index };
Vector<Ext2FSDirectoryEntry> entries; Vector<Ext2FSDirectoryEntry> entries;
TRY(traverse_as_directory([&](auto& entry) { TRY(traverse_as_directory([&](auto& entry) -> ErrorOr<void> {
if (name != entry.name) if (name != entry.name)
entries.append({ entry.name, entry.inode.index(), entry.file_type }); entries.append({ entry.name, entry.inode.index(), entry.file_type });
return true; return {};
})); }));
TRY(write_directory(entries)); TRY(write_directory(entries));
@ -1540,9 +1531,9 @@ ErrorOr<void> Ext2FSInode::populate_lookup_cache() const
return {}; return {};
HashMap<String, InodeIndex> children; HashMap<String, InodeIndex> children;
TRY(traverse_as_directory([&children](auto& entry) { TRY(traverse_as_directory([&children](auto& entry) -> ErrorOr<void> {
children.set(entry.name, entry.inode.index()); children.set(entry.name, entry.inode.index());
return true; return {};
})); }));
VERIFY(m_lookup_cache.is_empty()); VERIFY(m_lookup_cache.is_empty());

View file

@ -40,7 +40,7 @@ private:
// ^Inode // ^Inode
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override; virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& data, OpenFileDescription*) override; virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& data, OpenFileDescription*) override;

View file

@ -447,9 +447,10 @@ InodeMetadata ISO9660Inode::metadata() const
return m_metadata; return m_metadata;
} }
ErrorOr<void> ISO9660Inode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> visitor) const ErrorOr<void> ISO9660Inode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> visitor) const
{ {
Array<u8, max_file_identifier_length> file_identifier_buffer; Array<u8, max_file_identifier_length> file_identifier_buffer;
ErrorOr<void> result;
return fs().visit_directory_record(m_record, [&](ISO::DirectoryRecordHeader const* record) { return fs().visit_directory_record(m_record, [&](ISO::DirectoryRecordHeader const* record) {
StringView filename = get_normalized_filename(*record, file_identifier_buffer); StringView filename = get_normalized_filename(*record, file_identifier_buffer);
@ -458,9 +459,9 @@ ErrorOr<void> ISO9660Inode::traverse_as_directory(Function<bool(FileSystem::Dire
InodeIdentifier id { fsid(), get_inode_index(*record, filename) }; InodeIdentifier id { fsid(), get_inode_index(*record, filename) };
auto entry = FileSystem::DirectoryEntryView(filename, id, static_cast<u8>(record->file_flags)); auto entry = FileSystem::DirectoryEntryView(filename, id, static_cast<u8>(record->file_flags));
if (!visitor(entry)) { result = visitor(entry);
if (result.is_error())
return RecursionDecision::Break; return RecursionDecision::Break;
}
return RecursionDecision::Continue; return RecursionDecision::Continue;
}); });

View file

@ -349,7 +349,7 @@ public:
// ^Inode // ^Inode
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override; virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, OpenFileDescription*) override; virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, OpenFileDescription*) override;

View file

@ -53,7 +53,7 @@ public:
virtual void detach(OpenFileDescription&) { } virtual void detach(OpenFileDescription&) { }
virtual void did_seek(OpenFileDescription&, off_t) { } virtual void did_seek(OpenFileDescription&, off_t) { }
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const = 0; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const = 0;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const = 0; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const = 0;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) = 0; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) = 0;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& data, OpenFileDescription*) = 0; virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& data, OpenFileDescription*) = 0;
virtual ErrorOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) = 0; virtual ErrorOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) = 0;

View file

@ -238,18 +238,17 @@ ErrorOr<size_t> OpenFileDescription::get_dir_entries(UserOrKernelBuffer& output_
return true; return true;
}; };
ErrorOr<void> result = VirtualFileSystem::the().traverse_directory_inode(*m_inode, [&flush_stream_to_output_buffer, &stream, this](auto& entry) { ErrorOr<void> result = VirtualFileSystem::the().traverse_directory_inode(*m_inode, [&flush_stream_to_output_buffer, &error, &stream, this](auto& entry) -> ErrorOr<void> {
size_t serialized_size = sizeof(ino_t) + sizeof(u8) + sizeof(size_t) + sizeof(char) * entry.name.length(); size_t serialized_size = sizeof(ino_t) + sizeof(u8) + sizeof(size_t) + sizeof(char) * entry.name.length();
if (serialized_size > stream.remaining()) { if (serialized_size > stream.remaining()) {
if (!flush_stream_to_output_buffer()) { if (!flush_stream_to_output_buffer())
return false; return error;
}
} }
stream << (u64)entry.inode.index().value(); stream << (u64)entry.inode.index().value();
stream << m_inode->fs().internal_file_type_to_directory_entry_type(entry); stream << m_inode->fs().internal_file_type_to_directory_entry_type(entry);
stream << (u32)entry.name.length(); stream << (u32)entry.name.length();
stream << entry.name.bytes(); stream << entry.name.bytes();
return true; return {};
}); });
flush_stream_to_output_buffer(); flush_stream_to_output_buffer();

View file

@ -828,7 +828,7 @@ ErrorOr<void> Plan9FSInode::flush_metadata()
return {}; return {};
} }
ErrorOr<void> Plan9FSInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> Plan9FSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
// TODO: Should we synthesize "." and ".." here? // TODO: Should we synthesize "." and ".." here?
@ -873,8 +873,13 @@ ErrorOr<void> Plan9FSInode::traverse_as_directory(Function<bool(FileSystem::Dire
u8 type; u8 type;
StringView name; StringView name;
decoder >> qid >> offset >> type >> name; decoder >> qid >> offset >> type >> name;
callback({ name, { fsid(), fs().allocate_fid() }, 0 }); result = callback({ name, { fsid(), fs().allocate_fid() }, 0 });
if (result.is_error())
break;
} }
if (result.is_error())
break;
} }
Plan9FS::Message close_message { fs(), Plan9FS::Message::Type::Tclunk }; Plan9FS::Message close_message { fs(), Plan9FS::Message::Type::Tclunk };

View file

@ -158,7 +158,7 @@ public:
virtual ErrorOr<void> flush_metadata() override; virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& data, OpenFileDescription*) override; virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& data, OpenFileDescription*) override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override; virtual ErrorOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
virtual ErrorOr<void> add_child(Inode&, const StringView& name, mode_t) override; virtual ErrorOr<void> add_child(Inode&, const StringView& name, mode_t) override;

View file

@ -137,7 +137,7 @@ StringView ProcFSGlobalInode::name() const
return m_associated_component->name(); return m_associated_component->name();
} }
ErrorOr<void> ProcFSGlobalInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const ErrorOr<void> ProcFSGlobalInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const
{ {
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
@ -200,7 +200,7 @@ InodeMetadata ProcFSDirectoryInode::metadata() const
metadata.mtime = m_associated_component->modified_time(); metadata.mtime = m_associated_component->modified_time();
return metadata; return metadata;
} }
ErrorOr<void> ProcFSDirectoryInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> ProcFSDirectoryInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(procfs().m_lock); MutexLocker locker(procfs().m_lock);
return m_associated_component->traverse_as_directory(procfs().fsid(), move(callback)); return m_associated_component->traverse_as_directory(procfs().fsid(), move(callback));
@ -285,7 +285,7 @@ ErrorOr<size_t> ProcFSProcessDirectoryInode::read_bytes(off_t, size_t, UserOrKer
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
ErrorOr<void> ProcFSProcessDirectoryInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> ProcFSProcessDirectoryInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(procfs().m_lock); MutexLocker locker(procfs().m_lock);
auto process = Process::from_pid(associated_pid()); auto process = Process::from_pid(associated_pid());
@ -365,7 +365,7 @@ InodeMetadata ProcFSProcessSubDirectoryInode::metadata() const
return metadata; return metadata;
} }
ErrorOr<void> ProcFSProcessSubDirectoryInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> ProcFSProcessSubDirectoryInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(procfs().m_lock); MutexLocker locker(procfs().m_lock);
auto process = Process::from_pid(associated_pid()); auto process = Process::from_pid(associated_pid());
@ -474,7 +474,7 @@ InodeMetadata ProcFSProcessPropertyInode::metadata() const
metadata.mtime = traits->modified_time(); metadata.mtime = traits->modified_time();
return metadata; return metadata;
} }
ErrorOr<void> ProcFSProcessPropertyInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const ErrorOr<void> ProcFSProcessPropertyInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const
{ {
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }

View file

@ -81,7 +81,7 @@ protected:
virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, OpenFileDescription*) override final; virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, OpenFileDescription*) override final;
virtual void did_seek(OpenFileDescription&, off_t) override final; virtual void did_seek(OpenFileDescription&, off_t) override final;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView) override;
virtual ErrorOr<void> truncate(u64) override final; virtual ErrorOr<void> truncate(u64) override final;
virtual ErrorOr<void> set_mtime(time_t) override final; virtual ErrorOr<void> set_mtime(time_t) override final;
@ -111,7 +111,7 @@ protected:
ProcFSDirectoryInode(const ProcFS&, const ProcFSExposedComponent&); ProcFSDirectoryInode(const ProcFS&, const ProcFSExposedComponent&);
// ^Inode // ^Inode
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
}; };
@ -141,7 +141,7 @@ private:
virtual ErrorOr<void> attach(OpenFileDescription& description) override; virtual ErrorOr<void> attach(OpenFileDescription& description) override;
virtual void did_seek(OpenFileDescription&, off_t) override { } virtual void did_seek(OpenFileDescription&, off_t) override { }
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
}; };
@ -158,7 +158,7 @@ private:
virtual ErrorOr<void> attach(OpenFileDescription& description) override; virtual ErrorOr<void> attach(OpenFileDescription& description) override;
virtual void did_seek(OpenFileDescription&, off_t) override; virtual void did_seek(OpenFileDescription&, off_t) override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
@ -181,7 +181,7 @@ private:
virtual ErrorOr<void> attach(OpenFileDescription& description) override; virtual ErrorOr<void> attach(OpenFileDescription& description) override;
virtual void did_seek(OpenFileDescription&, off_t) override; virtual void did_seek(OpenFileDescription&, off_t) override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override final; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override final;

View file

@ -46,15 +46,15 @@ NonnullRefPtr<SysFSRootDirectory> SysFSRootDirectory::create()
return adopt_ref(*new (nothrow) SysFSRootDirectory); return adopt_ref(*new (nothrow) SysFSRootDirectory);
} }
ErrorOr<void> SysFSRootDirectory::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> SysFSRootDirectory::traverse_as_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(SysFSComponentRegistry::the().get_lock()); MutexLocker locker(SysFSComponentRegistry::the().get_lock());
callback({ ".", { fsid, component_index() }, 0 }); TRY(callback({ ".", { fsid, component_index() }, 0 }));
callback({ "..", { fsid, 0 }, 0 }); TRY(callback({ "..", { fsid, 0 }, 0 }));
for (auto& component : m_components) { for (auto& component : m_components) {
InodeIdentifier identifier = { fsid, component.component_index() }; InodeIdentifier identifier = { fsid, component.component_index() };
callback({ component.name(), identifier, 0 }); TRY(callback({ component.name(), identifier, 0 }));
} }
return {}; return {};
} }
@ -125,7 +125,7 @@ ErrorOr<size_t> SysFSInode::read_bytes(off_t offset, size_t count, UserOrKernelB
return m_associated_component->read_bytes(offset, count, buffer, fd); return m_associated_component->read_bytes(offset, count, buffer, fd);
} }
ErrorOr<void> SysFSInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const ErrorOr<void> SysFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const
{ {
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
@ -219,7 +219,7 @@ InodeMetadata SysFSDirectoryInode::metadata() const
metadata.mtime = mepoch; metadata.mtime = mepoch;
return metadata; return metadata;
} }
ErrorOr<void> SysFSDirectoryInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> SysFSDirectoryInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(fs().m_lock); MutexLocker locker(fs().m_lock);
return m_associated_component->traverse_as_directory(fs().fsid(), move(callback)); return m_associated_component->traverse_as_directory(fs().fsid(), move(callback));

View file

@ -19,7 +19,7 @@ class SysFSRootDirectory final : public SysFSDirectory {
public: public:
static NonnullRefPtr<SysFSRootDirectory> create(); static NonnullRefPtr<SysFSRootDirectory> create();
virtual ErrorOr<void> traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(unsigned, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
private: private:
SysFSRootDirectory(); SysFSRootDirectory();
@ -53,7 +53,7 @@ private:
class SysFSBlockDevicesDirectory final : public SysFSDirectory { class SysFSBlockDevicesDirectory final : public SysFSDirectory {
public: public:
static NonnullRefPtr<SysFSBlockDevicesDirectory> must_create(SysFSDevicesDirectory const&); static NonnullRefPtr<SysFSBlockDevicesDirectory> must_create(SysFSDevicesDirectory const&);
virtual ErrorOr<void> traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(unsigned, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual RefPtr<SysFSComponent> lookup(StringView name) override; virtual RefPtr<SysFSComponent> lookup(StringView name) override;
private: private:
@ -63,7 +63,7 @@ private:
class SysFSCharacterDevicesDirectory final : public SysFSDirectory { class SysFSCharacterDevicesDirectory final : public SysFSDirectory {
public: public:
static NonnullRefPtr<SysFSCharacterDevicesDirectory> must_create(SysFSDevicesDirectory const&); static NonnullRefPtr<SysFSCharacterDevicesDirectory> must_create(SysFSDevicesDirectory const&);
virtual ErrorOr<void> traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(unsigned, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual RefPtr<SysFSComponent> lookup(StringView name) override; virtual RefPtr<SysFSComponent> lookup(StringView name) override;
private: private:
@ -135,7 +135,7 @@ public:
protected: protected:
SysFSInode(SysFS const&, SysFSComponent const&); SysFSInode(SysFS const&, SysFSComponent const&);
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override; virtual ErrorOr<void> flush_metadata() override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
@ -168,7 +168,7 @@ protected:
SysFSDirectoryInode(SysFS const&, SysFSComponent const&); SysFSDirectoryInode(SysFS const&, SysFSComponent const&);
// ^Inode // ^Inode
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
}; };

View file

@ -31,16 +31,16 @@ mode_t SysFSComponent::permissions() const
return S_IRUSR | S_IRGRP | S_IROTH; return S_IRUSR | S_IRGRP | S_IROTH;
} }
ErrorOr<void> SysFSDirectory::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> SysFSDirectory::traverse_as_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(SysFSComponentRegistry::the().get_lock()); MutexLocker locker(SysFSComponentRegistry::the().get_lock());
VERIFY(m_parent_directory); VERIFY(m_parent_directory);
callback({ ".", { fsid, component_index() }, 0 }); TRY(callback({ ".", { fsid, component_index() }, 0 }));
callback({ "..", { fsid, m_parent_directory->component_index() }, 0 }); TRY(callback({ "..", { fsid, m_parent_directory->component_index() }, 0 }));
for (auto& component : m_components) { for (auto& component : m_components) {
InodeIdentifier identifier = { fsid, component.component_index() }; InodeIdentifier identifier = { fsid, component.component_index() };
callback({ component.name(), identifier, 0 }); TRY(callback({ component.name(), identifier, 0 }));
} }
return {}; return {};
} }

View file

@ -27,7 +27,7 @@ class SysFSComponent : public RefCounted<SysFSComponent> {
public: public:
virtual StringView name() const { return m_name->view(); } virtual StringView name() const { return m_name->view(); }
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const { return Error::from_errno(ENOTIMPL); } virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const { return Error::from_errno(ENOTIMPL); }
virtual ErrorOr<void> traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); } virtual ErrorOr<void> traverse_as_directory(unsigned, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); }
virtual RefPtr<SysFSComponent> lookup(StringView) { VERIFY_NOT_REACHED(); }; virtual RefPtr<SysFSComponent> lookup(StringView) { VERIFY_NOT_REACHED(); };
virtual mode_t permissions() const; virtual mode_t permissions() const;
virtual ErrorOr<void> truncate(u64) { return EPERM; } virtual ErrorOr<void> truncate(u64) { return EPERM; }
@ -51,7 +51,7 @@ private:
class SysFSDirectory : public SysFSComponent { class SysFSDirectory : public SysFSComponent {
public: public:
virtual ErrorOr<void> traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(unsigned, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual RefPtr<SysFSComponent> lookup(StringView name) override; virtual RefPtr<SysFSComponent> lookup(StringView name) override;
virtual ErrorOr<NonnullRefPtr<SysFSInode>> to_inode(SysFS const& sysfs_instance) const override final; virtual ErrorOr<NonnullRefPtr<SysFSInode>> to_inode(SysFS const& sysfs_instance) const override final;

View file

@ -107,18 +107,18 @@ InodeMetadata TmpFSInode::metadata() const
return m_metadata; return m_metadata;
} }
ErrorOr<void> TmpFSInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> TmpFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared); MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
if (!is_directory()) if (!is_directory())
return ENOTDIR; return ENOTDIR;
callback({ ".", identifier(), 0 }); TRY(callback({ ".", identifier(), 0 }));
callback({ "..", m_parent, 0 }); TRY(callback({ "..", m_parent, 0 }));
for (auto& child : m_children) { for (auto& child : m_children) {
callback({ child.name->view(), child.inode->identifier(), 0 }); TRY(callback({ child.name->view(), child.inode->identifier(), 0 }));
} }
return {}; return {};
} }

View file

@ -54,7 +54,7 @@ public:
// ^Inode // ^Inode
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override; virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override; virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, OpenFileDescription*) override; virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, OpenFileDescription*) override;

View file

@ -162,9 +162,9 @@ bool VirtualFileSystem::is_vfs_root(InodeIdentifier inode) const
return inode == root_inode_id(); return inode == root_inode_id();
} }
ErrorOr<void> VirtualFileSystem::traverse_directory_inode(Inode& dir_inode, Function<bool(FileSystem::DirectoryEntryView const&)> callback) ErrorOr<void> VirtualFileSystem::traverse_directory_inode(Inode& dir_inode, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback)
{ {
return dir_inode.traverse_as_directory([&](auto& entry) { return dir_inode.traverse_as_directory([&](auto& entry) -> ErrorOr<void> {
InodeIdentifier resolved_inode; InodeIdentifier resolved_inode;
if (auto mount = find_mount_for_host(entry.inode)) if (auto mount = find_mount_for_host(entry.inode))
resolved_inode = mount->guest().identifier(); resolved_inode = mount->guest().identifier();
@ -179,8 +179,8 @@ ErrorOr<void> VirtualFileSystem::traverse_directory_inode(Inode& dir_inode, Func
VERIFY(mount->host()); VERIFY(mount->host());
resolved_inode = mount->host()->identifier(); resolved_inode = mount->host()->identifier();
} }
callback({ entry.name, resolved_inode, entry.file_type }); TRY(callback({ entry.name, resolved_inode, entry.file_type }));
return true; return {};
}); });
} }
@ -467,9 +467,9 @@ ErrorOr<void> VirtualFileSystem::rename(StringView old_path, StringView new_path
if (old_inode.index() != new_inode.index() && old_inode.is_directory() && new_inode.is_directory()) { if (old_inode.index() != new_inode.index() && old_inode.is_directory() && new_inode.is_directory()) {
size_t child_count = 0; size_t child_count = 0;
TRY(new_inode.traverse_as_directory([&child_count](auto&) { TRY(new_inode.traverse_as_directory([&child_count](auto&) -> ErrorOr<void> {
++child_count; ++child_count;
return child_count <= 2; return {};
})); }));
if (child_count > 2) if (child_count > 2)
return ENOTEMPTY; return ENOTEMPTY;
@ -710,9 +710,9 @@ ErrorOr<void> VirtualFileSystem::rmdir(StringView path, Custody& base)
} }
size_t child_count = 0; size_t child_count = 0;
TRY(inode.traverse_as_directory([&child_count](auto&) { TRY(inode.traverse_as_directory([&child_count](auto&) -> ErrorOr<void> {
++child_count; ++child_count;
return true; return {};
})); }));
if (child_count != 2) if (child_count != 2)

View file

@ -85,7 +85,7 @@ private:
bool is_vfs_root(InodeIdentifier) const; bool is_vfs_root(InodeIdentifier) const;
ErrorOr<void> traverse_directory_inode(Inode&, Function<bool(FileSystem::DirectoryEntryView const&)>); ErrorOr<void> traverse_directory_inode(Inode&, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>);
Mount* find_mount_for_host(InodeIdentifier); Mount* find_mount_for_host(InodeIdentifier);
Mount* find_mount_for_guest(InodeIdentifier); Mount* find_mount_for_guest(InodeIdentifier);

View file

@ -936,24 +936,26 @@ UNMAP_AFTER_INIT NonnullRefPtr<ProcFSRootDirectory> ProcFSRootDirectory::must_cr
return directory; return directory;
} }
ErrorOr<void> ProcFSRootDirectory::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> ProcFSRootDirectory::traverse_as_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(ProcFSComponentRegistry::the().get_lock()); MutexLocker locker(ProcFSComponentRegistry::the().get_lock());
callback({ ".", { fsid, component_index() }, 0 }); TRY(callback({ ".", { fsid, component_index() }, 0 }));
callback({ "..", { fsid, 0 }, 0 }); TRY(callback({ "..", { fsid, 0 }, 0 }));
for (auto& component : m_components) { for (auto& component : m_components) {
InodeIdentifier identifier = { fsid, component.component_index() }; InodeIdentifier identifier = { fsid, component.component_index() };
callback({ component.name(), identifier, 0 }); TRY(callback({ component.name(), identifier, 0 }));
} }
processes().for_each([&](Process& process) {
VERIFY(!(process.pid() < 0)); return processes().with([&](auto& list) -> ErrorOr<void> {
u64 process_id = (u64)process.pid().value(); for (auto& process : list) {
InodeIdentifier identifier = { fsid, static_cast<InodeIndex>(process_id << 36) }; VERIFY(!(process.pid() < 0));
callback({ String::formatted("{:d}", process.pid().value()), identifier, 0 }); u64 process_id = (u64)process.pid().value();
return IterationDecision::Continue; InodeIdentifier identifier = { fsid, static_cast<InodeIndex>(process_id << 36) };
TRY(callback({ String::formatted("{:d}", process.pid().value()), identifier, 0 }));
}
return {};
}); });
return {};
} }
ErrorOr<NonnullRefPtr<ProcFSExposedComponent>> ProcFSRootDirectory::lookup(StringView name) ErrorOr<NonnullRefPtr<ProcFSExposedComponent>> ProcFSRootDirectory::lookup(StringView name)

View file

@ -566,10 +566,10 @@ public:
ErrorOr<void> procfs_get_current_work_directory_link(KBufferBuilder& builder) const; ErrorOr<void> procfs_get_current_work_directory_link(KBufferBuilder& builder) const;
mode_t binary_link_required_mode() const; mode_t binary_link_required_mode() const;
ErrorOr<size_t> procfs_get_thread_stack(ThreadID thread_id, KBufferBuilder& builder) const; ErrorOr<size_t> procfs_get_thread_stack(ThreadID thread_id, KBufferBuilder& builder) const;
ErrorOr<void> traverse_stacks_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const; ErrorOr<void> traverse_stacks_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const;
ErrorOr<NonnullRefPtr<Inode>> lookup_stacks_directory(const ProcFS&, StringView name) const; ErrorOr<NonnullRefPtr<Inode>> lookup_stacks_directory(const ProcFS&, StringView name) const;
ErrorOr<size_t> procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const; ErrorOr<size_t> procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const;
ErrorOr<void> traverse_file_descriptions_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const; ErrorOr<void> traverse_file_descriptions_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const;
ErrorOr<NonnullRefPtr<Inode>> lookup_file_descriptions_directory(const ProcFS&, StringView name) const; ErrorOr<NonnullRefPtr<Inode>> lookup_file_descriptions_directory(const ProcFS&, StringView name) const;
private: private:
@ -723,7 +723,7 @@ public:
virtual InodeIndex component_index() const override; virtual InodeIndex component_index() const override;
virtual ErrorOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const override; virtual ErrorOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const override;
virtual ErrorOr<void> traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(unsigned, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual mode_t required_mode() const override { return 0555; } virtual mode_t required_mode() const override { return 0555; }
virtual UserID owner_user() const override; virtual UserID owner_user() const override;

View file

@ -232,18 +232,18 @@ ErrorOr<NonnullRefPtr<ProcFSExposedComponent>> ProcFSExposedDirectory::lookup(St
return ENOENT; return ENOENT;
} }
ErrorOr<void> ProcFSExposedDirectory::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> ProcFSExposedDirectory::traverse_as_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(ProcFSComponentRegistry::the().get_lock()); MutexLocker locker(ProcFSComponentRegistry::the().get_lock());
auto parent_directory = m_parent_directory.strong_ref(); auto parent_directory = m_parent_directory.strong_ref();
if (parent_directory.is_null()) if (parent_directory.is_null())
return Error::from_errno(EINVAL); return Error::from_errno(EINVAL);
callback({ ".", { fsid, component_index() }, DT_DIR }); TRY(callback({ ".", { fsid, component_index() }, DT_DIR }));
callback({ "..", { fsid, parent_directory->component_index() }, DT_DIR }); TRY(callback({ "..", { fsid, parent_directory->component_index() }, DT_DIR }));
for (auto& component : m_components) { for (auto& component : m_components) {
InodeIdentifier identifier = { fsid, component.component_index() }; InodeIdentifier identifier = { fsid, component.component_index() };
callback({ component.name(), identifier, 0 }); TRY(callback({ component.name(), identifier, 0 }));
} }
return {}; return {};
} }

View file

@ -67,7 +67,7 @@ class ProcFSExposedComponent : public RefCounted<ProcFSExposedComponent> {
public: public:
StringView name() const { return m_name->view(); } StringView name() const { return m_name->view(); }
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const { VERIFY_NOT_REACHED(); } virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const { VERIFY_NOT_REACHED(); }
virtual ErrorOr<void> traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); } virtual ErrorOr<void> traverse_as_directory(unsigned, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); }
virtual ErrorOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView) { VERIFY_NOT_REACHED(); }; virtual ErrorOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView) { VERIFY_NOT_REACHED(); };
virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer&, OpenFileDescription*) { return EROFS; } virtual ErrorOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer&, OpenFileDescription*) { return EROFS; }
virtual ErrorOr<void> truncate(u64) { return EPERM; } virtual ErrorOr<void> truncate(u64) { return EPERM; }
@ -105,7 +105,7 @@ class ProcFSExposedDirectory
friend class ProcFSComponentRegistry; friend class ProcFSComponentRegistry;
public: public:
virtual ErrorOr<void> traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(unsigned, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView name) override; virtual ErrorOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView name) override;
void add_component(const ProcFSExposedComponent&); void add_component(const ProcFSExposedComponent&);
@ -147,7 +147,7 @@ public:
virtual ~ProcFSRootDirectory(); virtual ~ProcFSRootDirectory();
private: private:
virtual ErrorOr<void> traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(unsigned, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
ProcFSRootDirectory(); ProcFSRootDirectory();
}; };

View file

@ -45,23 +45,23 @@ ErrorOr<NonnullRefPtr<Inode>> Process::ProcessProcFSTraits::to_inode(const ProcF
return TRY(ProcFSProcessDirectoryInode::try_create(procfs_instance, process->pid())); return TRY(ProcFSProcessDirectoryInode::try_create(procfs_instance, process->pid()));
} }
ErrorOr<void> Process::ProcessProcFSTraits::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> Process::ProcessProcFSTraits::traverse_as_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
auto process = m_process.strong_ref(); auto process = m_process.strong_ref();
if (!process) if (!process)
return ESRCH; return ESRCH;
callback({ ".", { fsid, SegmentedProcFSIndex::build_segmented_index_for_pid_directory(process->pid()) }, DT_DIR }); TRY(callback({ ".", { fsid, SegmentedProcFSIndex::build_segmented_index_for_pid_directory(process->pid()) }, DT_DIR }));
callback({ "..", { fsid, ProcFSComponentRegistry::the().root_directory().component_index() }, DT_DIR }); TRY(callback({ "..", { fsid, ProcFSComponentRegistry::the().root_directory().component_index() }, DT_DIR }));
callback({ "fd", { fsid, SegmentedProcFSIndex::build_segmented_index_for_sub_directory(process->pid(), SegmentedProcFSIndex::ProcessSubDirectory::OpenFileDescriptions) }, DT_DIR }); TRY(callback({ "fd", { fsid, SegmentedProcFSIndex::build_segmented_index_for_sub_directory(process->pid(), SegmentedProcFSIndex::ProcessSubDirectory::OpenFileDescriptions) }, DT_DIR }));
callback({ "stacks", { fsid, SegmentedProcFSIndex::build_segmented_index_for_sub_directory(process->pid(), SegmentedProcFSIndex::ProcessSubDirectory::Stacks) }, DT_DIR }); TRY(callback({ "stacks", { fsid, SegmentedProcFSIndex::build_segmented_index_for_sub_directory(process->pid(), SegmentedProcFSIndex::ProcessSubDirectory::Stacks) }, DT_DIR }));
callback({ "unveil", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::Unveil) }, DT_REG }); TRY(callback({ "unveil", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::Unveil) }, DT_REG }));
callback({ "pledge", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::Pledge) }, DT_REG }); TRY(callback({ "pledge", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::Pledge) }, DT_REG }));
callback({ "fds", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::OpenFileDescriptions) }, DT_DIR }); TRY(callback({ "fds", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::OpenFileDescriptions) }, DT_DIR }));
callback({ "exe", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::BinaryLink) }, DT_LNK }); TRY(callback({ "exe", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::BinaryLink) }, DT_LNK }));
callback({ "cwd", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::CurrentWorkDirectoryLink) }, DT_LNK }); TRY(callback({ "cwd", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::CurrentWorkDirectoryLink) }, DT_LNK }));
callback({ "perf_events", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::PerformanceEvents) }, DT_REG }); TRY(callback({ "perf_events", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::PerformanceEvents) }, DT_REG }));
callback({ "vm", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::VirtualMemoryStats) }, DT_REG }); TRY(callback({ "vm", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::VirtualMemoryStats) }, DT_REG }));
return {}; return {};
} }

View file

@ -41,17 +41,19 @@ ErrorOr<size_t> Process::procfs_get_thread_stack(ThreadID thread_id, KBufferBuil
return 0; return 0;
} }
ErrorOr<void> Process::traverse_stacks_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> Process::traverse_stacks_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
callback({ ".", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property(pid(), SegmentedProcFSIndex::ProcessSubDirectory::Stacks, SegmentedProcFSIndex::MainProcessProperty::Reserved) }, 0 }); TRY(callback({ ".", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property(pid(), SegmentedProcFSIndex::ProcessSubDirectory::Stacks, SegmentedProcFSIndex::MainProcessProperty::Reserved) }, 0 }));
callback({ "..", { fsid, m_procfs_traits->component_index() }, 0 }); TRY(callback({ "..", { fsid, m_procfs_traits->component_index() }, 0 }));
for_each_thread([&](const Thread& thread) { return thread_list().with([&](auto& list) -> ErrorOr<void> {
int tid = thread.tid().value(); for (auto const& thread : list) {
InodeIdentifier identifier = { fsid, SegmentedProcFSIndex::build_segmented_index_for_thread_stack(pid(), thread.tid()) }; int tid = thread.tid().value();
callback({ String::number(tid), identifier, 0 }); InodeIdentifier identifier = { fsid, SegmentedProcFSIndex::build_segmented_index_for_thread_stack(pid(), thread.tid()) };
TRY(callback({ String::number(tid), identifier, 0 }));
}
return {};
}); });
return {};
} }
ErrorOr<NonnullRefPtr<Inode>> Process::lookup_stacks_directory(const ProcFS& procfs, StringView name) const ErrorOr<NonnullRefPtr<Inode>> Process::lookup_stacks_directory(const ProcFS& procfs, StringView name) const
@ -87,10 +89,10 @@ ErrorOr<size_t> Process::procfs_get_file_description_link(unsigned fd, KBufferBu
return data->length(); return data->length();
} }
ErrorOr<void> Process::traverse_file_descriptions_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> Process::traverse_file_descriptions_directory(unsigned fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
callback({ ".", { fsid, m_procfs_traits->component_index() }, 0 }); TRY(callback({ ".", { fsid, m_procfs_traits->component_index() }, 0 }));
callback({ "..", { fsid, m_procfs_traits->component_index() }, 0 }); TRY(callback({ "..", { fsid, m_procfs_traits->component_index() }, 0 }));
size_t count = 0; size_t count = 0;
fds().enumerate([&](auto& file_description_metadata) { fds().enumerate([&](auto& file_description_metadata) {
if (!file_description_metadata.is_valid()) { if (!file_description_metadata.is_valid()) {
@ -99,7 +101,8 @@ ErrorOr<void> Process::traverse_file_descriptions_directory(unsigned fsid, Funct
} }
StringBuilder builder; StringBuilder builder;
builder.appendff("{}", count); builder.appendff("{}", count);
callback({ builder.string_view(), { fsid, SegmentedProcFSIndex::build_segmented_index_for_file_description(pid(), count) }, DT_LNK }); // FIXME: Propagate errors from callback.
(void)callback({ builder.string_view(), { fsid, SegmentedProcFSIndex::build_segmented_index_for_file_description(pid(), count) }, DT_LNK });
count++; count++;
}); });
return {}; return {};