aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/include/kernel/filesystem/ext2/inode.hpp2
-rw-r--r--kernel/src/filesystem/ext2/inode.cpp16
-rw-r--r--kernel/src/filesystem/open_file_descriptor.tests.cpp13
3 files changed, 20 insertions, 11 deletions
diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp
index b4a3cc4..b8f892a 100644
--- a/kernel/include/kernel/filesystem/ext2/inode.hpp
+++ b/kernel/include/kernel/filesystem/ext2/inode.hpp
@@ -20,7 +20,7 @@ namespace kernel::filesystem::ext2
{
uint16_t mode;
uint16_t uid;
- uint32_t size;
+ uint32_t size; // TODO BA-FS26 signed?
uint32_t atime;
uint32_t ctime;
uint32_t mtime;
diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp
index 5b6bcb3..1914c70 100644
--- a/kernel/src/filesystem/ext2/inode.cpp
+++ b/kernel/src/filesystem/ext2/inode.cpp
@@ -5,6 +5,8 @@
#include <kapi/system.hpp>
+#include <kstd/cstring>
+
#include <algorithm>
#include <cstddef>
#include <cstdint>
@@ -23,6 +25,17 @@ namespace kernel::filesystem::ext2
auto inode::read(void * buffer, size_t offset, size_t size) const -> size_t
{
+ // TODO BA-FS26 use revision 1 size
+ auto const max_readable = static_cast<size_t>(m_data.size) - offset;
+ auto const requested_size = std::min(size, max_readable);
+
+ if (is_symbolic_link() && m_data.size <= sizeof(m_data.block))
+ {
+ auto inline_target = reinterpret_cast<uint8_t const *>(m_data.block.data());
+ kstd::libc::memcpy(static_cast<uint8_t *>(buffer), inline_target + offset, requested_size);
+ return requested_size;
+ }
+
auto block_index = offset / m_filesystem->get_block_size();
auto in_block_offset = offset % m_filesystem->get_block_size();
@@ -40,7 +53,8 @@ namespace kernel::filesystem::ext2
auto const block_start_offset = block_number * m_filesystem->get_block_size();
auto const read_offset = block_start_offset + in_block_offset;
- auto const bytes_to_read = std::min(size - bytes_read, m_filesystem->get_block_size() - in_block_offset);
+ auto const bytes_to_read =
+ std::min(requested_size - bytes_read, m_filesystem->get_block_size() - in_block_offset);
bytes_read +=
m_filesystem->backing_inode()->read(static_cast<uint8_t *>(buffer) + bytes_read, read_offset, bytes_to_read);
diff --git a/kernel/src/filesystem/open_file_descriptor.tests.cpp b/kernel/src/filesystem/open_file_descriptor.tests.cpp
index 095e203..53835ba 100644
--- a/kernel/src/filesystem/open_file_descriptor.tests.cpp
+++ b/kernel/src/filesystem/open_file_descriptor.tests.cpp
@@ -1,4 +1,5 @@
#include <kernel/filesystem/open_file_descriptor.hpp>
+
#include <kernel/filesystem/vfs.hpp>
#include <kernel/test_support/filesystem/inode.hpp>
#include <kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp>
@@ -83,17 +84,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope
{
kstd::vector<std::byte> buffer(32);
auto bytes_read = ofd->read(buffer.data(), buffer.size());
- REQUIRE(bytes_read == 32);
- REQUIRE(ofd->offset() == 32);
+ REQUIRE(bytes_read == 7);
+ REQUIRE(ofd->offset() == 7);
std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(bytes_read)};
- auto const content_end = buffer_as_str.find('\0');
- REQUIRE(buffer_as_str.substr(0, content_end) == "info_1\n");
-
- for (auto i = content_end; i < buffer_as_str.size(); ++i)
- {
- REQUIRE(buffer_as_str[i] == '\0');
- }
+ REQUIRE(buffer_as_str == "info_1\n");
}
THEN("the file can be read multiple times")