Compare commits
No commits in common. "bb38807ed1fdeb0b38555ede879c1fb63b3c7770" and "29ccd43c7ac12005f22c14c744afc500fcdeb903" have entirely different histories.
bb38807ed1
...
29ccd43c7a
121
src/fs.cpp
121
src/fs.cpp
@ -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 {};
|
||||
}
|
||||
|
||||
105
src/fs.hpp
105
src/fs.hpp
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user