aboutsummaryrefslogtreecommitdiff
path: root/kernel/src/test_support/filesystem/ext2.cpp
blob: 3627373954b59640be03b82553a36614ff4a8c04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "kernel/test_support/filesystem/ext2.hpp"

#include "kernel/filesystem/ext2/block_group_descriptor.hpp"
#include "kernel/filesystem/ext2/filesystem.hpp"
#include "kernel/filesystem/ext2/inode.hpp"
#include "kernel/filesystem/ext2/superblock.hpp"
#include "kernel/test_support/devices/block_device.hpp"

#include <cstdint>
#include <cstring>

namespace kernel::tests::filesystem::ext2
{
  namespace
  {
    constexpr uint32_t root_directory_data_block = 20;
  }  // namespace

  auto write_bytes(kernel::tests::devices::block_device & device, size_t offset, void const * source, size_t size)
      -> void
  {
    auto const required_size = offset + size;
    if (device.data.size() < required_size)
    {
      device.data.resize(required_size, 0);
    }

    std::memcpy(device.data.data() + offset, source, size);
  }

  auto write_u32(kernel::tests::devices::block_device & device, size_t offset, uint32_t value) -> void
  {
    write_bytes(device, offset, &value, sizeof(value));
  }

  auto setup_mock_ext2_layout(kernel::tests::devices::block_device & device) -> void
  {
    auto superblock = kernel::filesystem::ext2::superblock{};
    superblock.magic = kernel::filesystem::ext2::constants::magic_number;
    superblock.log_block_size = 0;
    superblock.blocks_count = 64;
    superblock.blocks_per_group = 64;
    superblock.inodes_per_group = 32;
    superblock.rev_level = 1;
    superblock.inode_size = 128;
    write_bytes(device, kernel::filesystem::ext2::constants::superblock_offset, &superblock, sizeof(superblock));

    auto group_descriptor = kernel::filesystem::ext2::block_group_descriptor{};
    group_descriptor.inode_table = 5;
    write_bytes(device, 2048, &group_descriptor, sizeof(group_descriptor));

    auto root_inode_data = kernel::filesystem::ext2::inode_data{};
    root_inode_data.mode = kernel::filesystem::ext2::constants::mode_directory;
    root_inode_data.blocks = 2;
    root_inode_data.block[0] = root_directory_data_block;

    auto const root_inode_offset =
        static_cast<size_t>(group_descriptor.inode_table) * kernel::filesystem::ext2::constants::base_block_size +
        (kernel::filesystem::ext2::constants::root_inode_number - 1) * superblock.inode_size;
    write_bytes(device, root_inode_offset, &root_inode_data, sizeof(root_inode_data));
  }
}  // namespace kernel::tests::filesystem::ext2