1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:28:10 +00:00

Kernel: Convert the DiskBackedFS write API to take "const u8*"

This way clients are not required to have instantiated ByteBuffers
and can choose whatever memory scheme works best for them.

Also converted some of the Ext2FS code to use stack buffers instead.
This commit is contained in:
Andreas Kling 2019-09-30 11:20:51 +02:00
parent 1fc2612667
commit 922fd703c9
4 changed files with 29 additions and 32 deletions

View file

@ -81,15 +81,13 @@ DiskBackedFS::~DiskBackedFS()
{ {
} }
bool DiskBackedFS::write_block(unsigned index, const ByteBuffer& data) bool DiskBackedFS::write_block(unsigned index, const u8* data)
{ {
#ifdef DBFS_DEBUG #ifdef DBFS_DEBUG
kprintf("DiskBackedFileSystem::write_block %u, size=%u\n", index, data.size()); kprintf("DiskBackedFileSystem::write_block %u, size=%u\n", index, data.size());
#endif #endif
ASSERT(data.size() == block_size());
auto& entry = cache().get(index); auto& entry = cache().get(index);
memcpy(entry.data, data.data(), data.size()); memcpy(entry.data, data, block_size());
entry.is_dirty = true; entry.is_dirty = true;
entry.has_data = true; entry.has_data = true;
@ -97,13 +95,13 @@ bool DiskBackedFS::write_block(unsigned index, const ByteBuffer& data)
return true; return true;
} }
bool DiskBackedFS::write_blocks(unsigned index, unsigned count, const ByteBuffer& data) bool DiskBackedFS::write_blocks(unsigned index, unsigned count, const u8* data)
{ {
#ifdef DBFS_DEBUG #ifdef DBFS_DEBUG
kprintf("DiskBackedFileSystem::write_blocks %u x%u\n", index, count); kprintf("DiskBackedFileSystem::write_blocks %u x%u\n", index, count);
#endif #endif
for (unsigned i = 0; i < count; ++i) for (unsigned i = 0; i < count; ++i)
write_block(index + i, data.slice(i * block_size(), block_size())); write_block(index + i, data + i * block_size());
return true; return true;
} }

View file

@ -22,8 +22,8 @@ protected:
bool read_block(unsigned index, u8* buffer) const; bool read_block(unsigned index, u8* buffer) const;
bool read_blocks(unsigned index, unsigned count, u8* buffer) const; bool read_blocks(unsigned index, unsigned count, u8* buffer) const;
bool write_block(unsigned index, const ByteBuffer&); bool write_block(unsigned index, const u8*);
bool write_blocks(unsigned index, unsigned count, const ByteBuffer&); bool write_blocks(unsigned index, unsigned count, const u8*);
private: private:
DiskCache& cache() const; DiskCache& cache() const;

View file

@ -10,6 +10,7 @@
//#define EXT2_DEBUG //#define EXT2_DEBUG
static const size_t max_block_size = 4096;
static const ssize_t max_inline_symlink_length = 60; static const ssize_t max_inline_symlink_length = 60;
static u8 to_ext2_file_type(mode_t mode) static u8 to_ext2_file_type(mode_t mode)
@ -121,8 +122,11 @@ bool Ext2FS::initialize()
kprintf("ext2fs: desc size = %u\n", EXT2_DESC_SIZE(&super_block)); kprintf("ext2fs: desc size = %u\n", EXT2_DESC_SIZE(&super_block));
#endif #endif
set_block_size(EXT2_BLOCK_SIZE(&super_block)); set_block_size(EXT2_BLOCK_SIZE(&super_block));
ASSERT(block_size() <= (int)max_block_size);
m_block_group_count = ceil_div(super_block.s_blocks_count, super_block.s_blocks_per_group); m_block_group_count = ceil_div(super_block.s_blocks_count, super_block.s_blocks_per_group);
if (m_block_group_count == 0) { if (m_block_group_count == 0) {
@ -157,16 +161,16 @@ InodeIdentifier Ext2FS::root_inode() const
return { fsid(), EXT2_ROOT_INO }; return { fsid(), EXT2_ROOT_INO };
} }
ByteBuffer Ext2FS::read_block_containing_inode(unsigned inode, unsigned& block_index, unsigned& offset) const bool Ext2FS::read_block_containing_inode(unsigned inode, unsigned& block_index, unsigned& offset, u8* buffer) const
{ {
LOCKER(m_lock); LOCKER(m_lock);
auto& super_block = this->super_block(); auto& super_block = this->super_block();
if (inode != EXT2_ROOT_INO && inode < EXT2_FIRST_INO(&super_block)) if (inode != EXT2_ROOT_INO && inode < EXT2_FIRST_INO(&super_block))
return {}; return false;
if (inode > super_block.s_inodes_count) if (inode > super_block.s_inodes_count)
return {}; return false;
auto& bgd = group_descriptor(group_index_from_inode(inode)); auto& bgd = group_descriptor(group_index_from_inode(inode));
@ -174,10 +178,7 @@ ByteBuffer Ext2FS::read_block_containing_inode(unsigned inode, unsigned& block_i
block_index = bgd.bg_inode_table + (offset >> EXT2_BLOCK_SIZE_BITS(&super_block)); block_index = bgd.bg_inode_table + (offset >> EXT2_BLOCK_SIZE_BITS(&super_block));
offset &= block_size() - 1; offset &= block_size() - 1;
auto buffer = ByteBuffer::create_uninitialized(block_size()); return read_block(block_index, buffer);
if (!read_block(block_index, buffer.data()))
return {};
return buffer;
} }
Ext2FS::BlockListShape Ext2FS::compute_block_list_shape(unsigned blocks) Ext2FS::BlockListShape Ext2FS::compute_block_list_shape(unsigned blocks)
@ -290,7 +291,7 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
--remaining_blocks; --remaining_blocks;
} }
stream.fill_to_end(0); stream.fill_to_end(0);
bool success = write_block(e2inode.i_block[EXT2_IND_BLOCK], block_contents); bool success = write_block(e2inode.i_block[EXT2_IND_BLOCK], block_contents.data());
ASSERT(success); ASSERT(success);
} }
@ -373,7 +374,7 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
} }
if (ind_block_dirty) { if (ind_block_dirty) {
bool success = write_block(indirect_block_index, ind_block_contents); bool success = write_block(indirect_block_index, ind_block_contents.data());
ASSERT(success); ASSERT(success);
} }
} }
@ -385,7 +386,7 @@ bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2in
} }
if (dind_block_dirty) { if (dind_block_dirty) {
bool success = write_block(e2inode.i_block[EXT2_DIND_BLOCK], dind_block_contents); bool success = write_block(e2inode.i_block[EXT2_DIND_BLOCK], dind_block_contents.data());
ASSERT(success); ASSERT(success);
} }
} }
@ -509,7 +510,7 @@ void Ext2FS::flush_block_group_descriptor_table()
LOCKER(m_lock); LOCKER(m_lock);
unsigned blocks_to_write = ceil_div(m_block_group_count * (unsigned)sizeof(ext2_group_desc), block_size()); unsigned blocks_to_write = ceil_div(m_block_group_count * (unsigned)sizeof(ext2_group_desc), block_size());
unsigned first_block_of_bgdt = block_size() == 1024 ? 2 : 1; unsigned first_block_of_bgdt = block_size() == 1024 ? 2 : 1;
write_blocks(first_block_of_bgdt, blocks_to_write, m_cached_group_descriptor_table); write_blocks(first_block_of_bgdt, blocks_to_write, m_cached_group_descriptor_table.data());
} }
Ext2FSInode::Ext2FSInode(Ext2FS& fs, unsigned index) Ext2FSInode::Ext2FSInode(Ext2FS& fs, unsigned index)
@ -585,15 +586,15 @@ RefPtr<Inode> Ext2FS::get_inode(InodeIdentifier inode) const
unsigned block_index; unsigned block_index;
unsigned offset; unsigned offset;
auto block = read_block_containing_inode(inode.index(), block_index, offset); u8 block[max_block_size];
if (!block) if (!read_block_containing_inode(inode.index(), block_index, offset, block))
return {}; return {};
auto it = m_inode_cache.find(inode.index()); auto it = m_inode_cache.find(inode.index());
if (it != m_inode_cache.end()) if (it != m_inode_cache.end())
return (*it).value; return (*it).value;
auto new_inode = adopt(*new Ext2FSInode(const_cast<Ext2FS&>(*this), inode.index())); auto new_inode = adopt(*new Ext2FSInode(const_cast<Ext2FS&>(*this), inode.index()));
memcpy(&new_inode->m_raw_inode, reinterpret_cast<ext2_inode*>(block.offset_pointer(offset)), sizeof(ext2_inode)); memcpy(&new_inode->m_raw_inode, reinterpret_cast<ext2_inode*>(block + offset), sizeof(ext2_inode));
m_inode_cache.set(inode.index(), new_inode); m_inode_cache.set(inode.index(), new_inode);
return new_inode; return new_inode;
} }
@ -644,9 +645,7 @@ ssize_t Ext2FSInode::read_bytes(off_t offset, ssize_t count, u8* buffer, FileDes
//kprintf("ok let's do it, read(%u, %u) -> blocks %u thru %u, oifb: %u\n", offset, count, first_block_logical_index, last_block_logical_index, offset_into_first_block); //kprintf("ok let's do it, read(%u, %u) -> blocks %u thru %u, oifb: %u\n", offset, count, first_block_logical_index, last_block_logical_index, offset_into_first_block);
#endif #endif
// Biggest block size should be 4096.. u8 block[max_block_size];
u8 block[4096];
ASSERT(block_size < (int)sizeof(block));
for (int bi = first_block_logical_index; remaining_count && bi <= last_block_logical_index; ++bi) { for (int bi = first_block_logical_index; remaining_count && bi <= last_block_logical_index; ++bi) {
bool success = fs().read_block(m_block_list[bi], block); bool success = fs().read_block(m_block_list[bi], block);
@ -779,7 +778,7 @@ ssize_t Ext2FSInode::write_bytes(off_t offset, ssize_t count, const u8* data, Fi
#ifdef EXT2_DEBUG #ifdef EXT2_DEBUG
dbgprintf("Ext2FSInode::write_bytes: writing block %u (offset_into_block: %u)\n", m_block_list[bi], offset_into_block); dbgprintf("Ext2FSInode::write_bytes: writing block %u (offset_into_block: %u)\n", m_block_list[bi], offset_into_block);
#endif #endif
bool success = fs().write_block(m_block_list[bi], block); bool success = fs().write_block(m_block_list[bi], block.data());
if (!success) { if (!success) {
kprintf("Ext2FSInode::write_bytes: write_block(%u) failed (lbi: %u)\n", m_block_list[bi], bi); kprintf("Ext2FSInode::write_bytes: write_block(%u) failed (lbi: %u)\n", m_block_list[bi], bi);
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
@ -985,10 +984,10 @@ bool Ext2FS::write_ext2_inode(unsigned inode, const ext2_inode& e2inode)
LOCKER(m_lock); LOCKER(m_lock);
unsigned block_index; unsigned block_index;
unsigned offset; unsigned offset;
auto block = read_block_containing_inode(inode, block_index, offset); u8 block[max_block_size];
if (!block) if (!read_block_containing_inode(inode, block_index, offset, block))
return false; return false;
memcpy(reinterpret_cast<ext2_inode*>(block.offset_pointer(offset)), &e2inode, inode_size()); memcpy(reinterpret_cast<ext2_inode*>(block + offset), &e2inode, inode_size());
bool success = write_block(block_index, block); bool success = write_block(block_index, block);
ASSERT(success); ASSERT(success);
return success; return success;
@ -1177,7 +1176,7 @@ bool Ext2FS::set_inode_allocation_state(InodeIndex inode_index, bool new_state)
} }
bitmap.set(bit_index, new_state); bitmap.set(bit_index, new_state);
success = write_block(bgd.bg_inode_bitmap, block); success = write_block(bgd.bg_inode_bitmap, block.data());
ASSERT(success); ASSERT(success);
// Update superblock // Update superblock
@ -1241,7 +1240,7 @@ bool Ext2FS::set_block_allocation_state(BlockIndex block_index, bool new_state)
} }
bitmap.set(bit_index, new_state); bitmap.set(bit_index, new_state);
success = write_block(bgd.bg_block_bitmap, block); success = write_block(bgd.bg_block_bitmap, block.data());
ASSERT(success); ASSERT(success);
// Update superblock // Update superblock

View file

@ -87,7 +87,7 @@ private:
unsigned inode_size() const; unsigned inode_size() const;
bool write_ext2_inode(InodeIndex, const ext2_inode&); bool write_ext2_inode(InodeIndex, const ext2_inode&);
ByteBuffer read_block_containing_inode(InodeIndex inode, BlockIndex& block_index, unsigned& offset) const; bool read_block_containing_inode(InodeIndex inode, BlockIndex& block_index, unsigned& offset, u8* buffer) const;
ByteBuffer read_super_block() const; ByteBuffer read_super_block() const;
bool write_super_block(const ext2_super_block&); bool write_super_block(const ext2_super_block&);