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:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user