1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 09:27:35 +00:00

Kernel: Modernize Error handling when serializing directory entries

This commit is contained in:
Tim Schumacher 2023-02-07 12:01:31 +01:00 committed by Linus Groh
parent ccc871e608
commit 23e10a30ad

View file

@ -220,43 +220,35 @@ ErrorOr<size_t> OpenFileDescription::get_dir_entries(UserOrKernelBuffer& output_
return EIO; return EIO;
size_t remaining = size; size_t remaining = size;
ErrorOr<void> error;
u8 stack_buffer[PAGE_SIZE]; u8 stack_buffer[PAGE_SIZE];
Bytes temp_buffer(stack_buffer, sizeof(stack_buffer)); Bytes temp_buffer(stack_buffer, sizeof(stack_buffer));
DeprecatedOutputMemoryStream stream { temp_buffer }; DeprecatedOutputMemoryStream stream { temp_buffer };
auto flush_stream_to_output_buffer = [&error, &stream, &remaining, &output_buffer]() -> bool { auto flush_stream_to_output_buffer = [&stream, &remaining, &output_buffer]() -> ErrorOr<void> {
if (error.is_error())
return false;
if (stream.size() == 0) if (stream.size() == 0)
return true; return {};
if (remaining < stream.size()) {
error = EINVAL; if (remaining < stream.size())
return false; return Error::from_errno(EINVAL);
}
if (auto result = output_buffer.write(stream.bytes()); result.is_error()) { TRY(output_buffer.write(stream.bytes()));
error = result.release_error();
return false;
}
output_buffer = output_buffer.offset(stream.size()); output_buffer = output_buffer.offset(stream.size());
remaining -= stream.size(); remaining -= stream.size();
stream.reset(); stream.reset();
return true; return {};
}; };
ErrorOr<void> result = VirtualFileSystem::the().traverse_directory_inode(*m_inode, [&flush_stream_to_output_buffer, &error, &stream, this](auto& entry) -> ErrorOr<void> { ErrorOr<void> result = VirtualFileSystem::the().traverse_directory_inode(*m_inode, [&flush_stream_to_output_buffer, &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()) TRY(flush_stream_to_output_buffer());
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 {}; return {};
}); });
flush_stream_to_output_buffer();
if (result.is_error()) { if (result.is_error()) {
// We should only return EFAULT when the userspace buffer is too small, // We should only return EFAULT when the userspace buffer is too small,
@ -266,8 +258,8 @@ ErrorOr<size_t> OpenFileDescription::get_dir_entries(UserOrKernelBuffer& output_
return result.release_error(); return result.release_error();
} }
if (error.is_error()) TRY(flush_stream_to_output_buffer());
return error.release_error();
return size - remaining; return size - remaining;
} }