Compare commits

..

No commits in common. "bb38807ed1fdeb0b38555ede879c1fb63b3c7770" and "29ccd43c7ac12005f22c14c744afc500fcdeb903" have entirely different histories.

2 changed files with 59 additions and 167 deletions

View File

@ -8,6 +8,8 @@
namespace vc5::filesys {
using BlockData = std::array<u8, block_size>;
namespace {
auto inode_mode(INodeType type) -> u16
@ -113,7 +115,7 @@ auto Fs::append_to_directory(INode& dir_inode, const DirEntry& entry)
for (u16 i = 0; i < inode_ndir_blocks; ++i) {
auto dir_entry_block = dir_inode.blocks[i];
auto block = read_block<IntBlock<u16>>(dir_entry_block);
auto block = read_block<BlockData>(dir_entry_block);
if (not block)
return std::unexpected(block.error());
}
@ -153,11 +155,11 @@ auto Fs::inode_last_block_id(const INode& inode) -> Result<u16>
auto block_id = inode.blocks[inode_ind_block];
assert(block_id != 0);
auto ind_block = read_block<IntBlock<u16>>(block_id);
auto ind_block = read_block<BlockData>(block_id);
if (not ind_block)
return std::unexpected(ind_block.error());
return ind_block->data[inode.blocks_count - inode_ind_block];
return ind_block.value()[inode.blocks_count - inode_ind_block];
} else if (inode.blocks_count == inode_dind_block) {
@ -167,18 +169,18 @@ auto Fs::inode_last_block_id(const INode& inode) -> Result<u16>
auto first_block_id = inode.blocks[inode_dind_block];
assert(first_block_id != 0);
auto first_ind_block = read_block<IntBlock<u16>>(first_block_id);
auto first_ind_block = read_block<BlockData>(first_block_id);
if (not first_ind_block)
return std::unexpected(first_ind_block.error());
auto second_block_id
= first_ind_block->data[inode.blocks_count - inode_dind_block];
= first_ind_block.value()[inode.blocks_count - inode_dind_block];
auto second_ind_block = read_block<IntBlock<u16>>(second_block_id);
auto second_ind_block = read_block<BlockData>(second_block_id);
if (not second_ind_block)
return std::unexpected(second_ind_block.error());
return second_ind_block->data[inode.blocks_count - inode_dind_block];
return second_ind_block.value()[inode.blocks_count - inode_dind_block];
} else {
return std::unexpected("inode at capacity");
@ -297,95 +299,6 @@ auto Fs::sync_to_disk() -> Result<void>
return {};
}
class BeWriter {
public:
template <typename Data>
BeWriter(Data* data)
: m_data(reinterpret_cast<u8*>(data)) {};
template <typename Int>
requires std::is_integral_v<Int>
auto operator<<(Int v) -> BeWriter&
{
for (std::size_t i = 0; i < sizeof(Int); ++i) {
*m_data = v >> (sizeof(Int) - i - 1) * 8 & 0xff;
m_data++;
}
return *this;
}
template <std::size_t size>
requires(size % 8 == 0)
auto operator<<(const std::bitset<size>& bitmap) -> BeWriter&
{
for (std::size_t bit = 0; bit < bitmap.size(); bit += 8) {
u8 v = 0;
for (std::size_t i = 0; i < 8; ++i)
v |= bitmap[bit + i] << i;
*this << v;
}
return *this;
}
template <typename Elem, std::size_t size>
requires std::is_integral_v<Elem>
auto operator<<(const std::array<Elem, size>& array) -> BeWriter&
{
for (auto elem : array)
*this << elem;
return *this;
}
private:
u8* m_data;
};
class BeReader {
public:
template <typename Data>
BeReader(const Data* data)
: m_data(reinterpret_cast<const u8*>(data)) {};
template <typename Int>
requires std::is_integral_v<Int>
auto operator>>(Int& v) -> BeReader&
{
v = 0;
for (std::size_t i = 0; i < sizeof(Int); ++i) {
v |= *m_data << (sizeof(Int) - i - 1) * 8;
m_data++;
}
return *this;
}
template <std::size_t size>
requires(size % 8 == 0)
auto operator>>(std::bitset<size>& bitmap) -> BeReader&
{
for (std::size_t bit = 0; bit < bitmap.size(); bit += 8) {
u8 v;
*this >> v;
for (std::size_t i = 0; i < 8; ++i)
bitmap[bit + i] = v >> i & 1;
}
return *this;
}
template <typename Elem, std::size_t size>
requires std::is_integral_v<Elem>
auto operator>>(std::array<Elem, size>& array) -> BeReader&
{
for (auto& elem : array)
*this >> elem;
return *this;
}
private:
const u8* m_data;
};
using BlockData = std::array<u8, block_size>;
template <typename Data>
requires(sizeof(Data) <= block_size)
auto Fs::read_block_part(u16 block_id, u16 offset) -> Result<Data>
@ -412,9 +325,9 @@ auto Fs::write_block_part(u16 block_id, const Data& data, u16 offset)
BlockData block = {};
m_disk->read(block.data(), block_id);
auto writer = BeWriter(block.data() + offset);
data.write(writer);
std::memcpy(block.data(),
reinterpret_cast<const uint8_t*>(&data) + offset,
sizeof(Data));
m_disk->write(block.data(), block_id);
return {};
@ -427,10 +340,8 @@ auto Fs::read_block(u16 block_id) -> Result<Data>
BlockData block = {};
m_disk->read(block.data(), block_id);
auto reader = BeReader(block.data());
Data data;
data.read(reader);
std::memcpy(reinterpret_cast<uint8_t*>(&data), block.data(), sizeof(Data));
return data;
}
@ -440,10 +351,8 @@ template <typename Data>
auto Fs::write_block(const Data& data, u16 block_id) -> Result<void>
{
BlockData block = {};
auto writer = BeWriter(block.data());
data.write(writer);
std::memcpy(
block.data(), reinterpret_cast<const uint8_t*>(&data), sizeof(Data));
m_disk->write(block.data(), block_id);
return {};
}

View File

@ -3,7 +3,6 @@
#include "block_device.hpp"
#include "types.hpp"
#include <bitset>
#include <concepts>
#include <cstddef>
#include <expected>
#include <string_view>
@ -21,16 +20,6 @@ struct DirEntry {
u16 next;
u16 name_len;
std::array<char, name_max_len> name;
template <typename Writer> void write(Writer& w) const
{
w << inode << next << name_len << name;
}
template <typename Reader> auto read(Reader& r)
{
r >> inode >> next >> name_len >> name;
}
};
constexpr u16 inode_size = 32;
@ -57,18 +46,6 @@ struct INode {
u16 last_block_size;
u32 size;
std::array<u16, inode_blocks_count> blocks;
template <typename Writer> void write(Writer& w) const
{
w << mode << blocks_count << links_count << last_block_size << size
<< blocks;
}
template <typename Reader> auto read(Reader& r)
{
r >> mode >> blocks_count >> links_count >> last_block_size >> size
>> blocks;
}
};
static_assert(sizeof(INode) <= inode_size);
@ -88,50 +65,12 @@ struct Superblock {
u16 inode_blocks_count;
std::array<u16, iblocks_max_count> iblocks;
std::bitset<inodes_max_count> inode_bitmap;
template <typename Writer> void write(Writer& w) const
{
w << volume_id << fs_version << blocks_count << blocks_free
<< root_inode << inode_blocks_count << iblocks << inode_bitmap;
}
template <typename Reader> auto read(Reader& r)
{
r >> volume_id >> fs_version >> blocks_count >> blocks_free
>> root_inode >> inode_blocks_count >> iblocks >> inode_bitmap;
}
};
static_assert(sizeof(Superblock) <= block_size);
struct BlocksBitmap {
std::bitset<blocks_max_count> bitmap;
template <typename Writer> void write(Writer& w) const
{
w << bitmap;
}
template <typename Reader> auto read(Reader& r)
{
r >> bitmap;
}
};
template <typename Int>
requires std::is_integral_v<Int>
struct IntBlock {
std::array<u16, block_size / sizeof(Int)> data;
template <typename Writer> void write(Writer& w) const
{
w << data;
}
template <typename Reader> auto read(Reader& r)
{
r >> data;
}
};
static_assert(sizeof(BlocksBitmap) <= block_size);
@ -210,4 +149,48 @@ private:
BlocksBitmap m_blocks_bitmap = {};
};
class ByteReader {
public:
template <typename Data>
ByteReader(const Data* data)
: m_data(reinterpret_cast<const u8*>(data)) {};
template <typename Data>
requires std::is_integral_v<Data>
auto operator>>(Data& v) -> ByteReader&
{
v = 0;
for (std::size_t i = 0; i < sizeof(Data); ++i) {
v |= *m_data << (sizeof(Data) - i - 1) * 8;
m_data++;
}
return *this;
}
private:
const u8* m_data;
};
class ByteWriter {
public:
template <typename Data>
ByteWriter(Data* data)
: m_data(reinterpret_cast<u8*>(data)) {};
template <typename Data>
requires std::is_integral_v<Data>
auto operator>>(Data& v) -> ByteWriter&
{
v = 0;
for (std::size_t i = 0; i < sizeof(Data); ++i) {
*m_data = v >> (sizeof(Data) - i - 1) * 8 & 0xff;
m_data++;
}
return *this;
}
private:
u8* m_data;
};
}