Kernel: Ext2 filesystem now holds 10 preallocated block buffers

Inodes can query blocks from this buffer. This allows allocation of
blocks to not fail during normal operations. Also less stress on
kmalloc.
This commit is contained in:
Bananymous
2023-09-25 14:22:32 +03:00
parent 0e67c6318b
commit 669b2ace4e
4 changed files with 158 additions and 102 deletions

View File

@@ -9,6 +9,37 @@ namespace Kernel
class Ext2FS final : public FileSystem
{
public:
class BlockBufferWrapper
{
BAN_NON_COPYABLE(BlockBufferWrapper);
BAN_NON_MOVABLE(BlockBufferWrapper);
public:
BlockBufferWrapper(BAN::Span<uint8_t> buffer, bool& used)
: m_buffer(buffer)
, m_used(used)
{
ASSERT(m_used);
}
~BlockBufferWrapper()
{
m_used = false;
}
size_t size() const { return m_buffer.size(); }
uint8_t* data() { return m_buffer.data(); }
const uint8_t* data() const { return m_buffer.data(); }
uint8_t& operator[](size_t index) { return m_buffer[index]; }
uint8_t operator[](size_t index) const { return m_buffer[index]; }
private:
BAN::Span<uint8_t> m_buffer;
bool& m_used;
};
public:
static BAN::ErrorOr<Ext2FS*> create(Partition&);
@@ -26,10 +57,12 @@ namespace Kernel
BAN::ErrorOr<void> delete_inode(uint32_t);
BAN::ErrorOr<void> resize_inode(uint32_t, size_t);
void read_block(uint32_t, BAN::Span<uint8_t>);
void write_block(uint32_t, BAN::Span<const uint8_t>);
void read_block(uint32_t, BlockBufferWrapper&);
void write_block(uint32_t, const BlockBufferWrapper&);
void sync_superblock();
BlockBufferWrapper get_block_buffer();
BAN::ErrorOr<uint32_t> reserve_free_block(uint32_t primary_bgd);
const Ext2::Superblock& superblock() const { return m_superblock; }
@@ -39,11 +72,30 @@ namespace Kernel
uint32_t block;
uint32_t offset;
};
BAN::ErrorOr<BlockLocation> locate_inode(uint32_t);
BlockLocation locate_inode(uint32_t);
BlockLocation locate_block_group_descriptior(uint32_t);
uint32_t block_size() const { return 1024 << superblock().log_block_size; }
class BlockBufferManager
{
public:
BlockBufferManager() = default;
BlockBufferWrapper get_buffer();
BAN::ErrorOr<void> initialize(size_t block_size);
private:
struct BlockBuffer
{
BAN::Vector<uint8_t> buffer;
bool used { false };
};
private:
BAN::Array<BlockBuffer, 10> m_buffers;
};
private:
RecursiveSpinLock m_lock;
@@ -52,6 +104,8 @@ namespace Kernel
BAN::RefPtr<Inode> m_root_inode;
BAN::Vector<uint32_t> m_superblock_backups;
BlockBufferManager m_buffer_manager;
Ext2::Superblock m_superblock;
friend class Ext2Inode;

View File

@@ -39,7 +39,7 @@ namespace Kernel
virtual BAN::ErrorOr<void> truncate_impl(size_t) override;
private:
BAN::ErrorOr<uint32_t> fs_block_of_data_block_index(uint32_t data_block_index);
uint32_t fs_block_of_data_block_index(uint32_t data_block_index);
BAN::ErrorOr<uint32_t> allocate_new_block();
BAN::ErrorOr<void> sync();