mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
Ext2FS: Factor out block list generation and writing into functions.
This commit is contained in:
parent
6fb4033709
commit
29dfb4ae13
Notes:
sideshowbarker
2024-07-19 15:58:52 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/29dfb4ae13f
3 changed files with 89 additions and 6 deletions
|
@ -43,7 +43,7 @@ public:
|
|||
m_buffer[m_offset++] = value[i];
|
||||
}
|
||||
|
||||
void fillToEnd(byte ch)
|
||||
void fill_to_end(byte ch)
|
||||
{
|
||||
while (m_offset < m_buffer.size())
|
||||
m_buffer[m_offset++] = ch;
|
||||
|
|
|
@ -151,6 +151,80 @@ ByteBuffer Ext2FS::read_block_containing_inode(unsigned inode, unsigned& blockIn
|
|||
return readBlock(blockIndex);
|
||||
}
|
||||
|
||||
Ext2FS::BlockListShape Ext2FS::compute_block_list_shape(unsigned blocks)
|
||||
{
|
||||
BlockListShape shape;
|
||||
const unsigned entries_per_block = EXT2_ADDR_PER_BLOCK(&super_block());
|
||||
unsigned blocks_remaining = blocks;
|
||||
shape.direct_blocks = min((unsigned)EXT2_NDIR_BLOCKS, blocks_remaining);
|
||||
blocks_remaining -= shape.direct_blocks;
|
||||
if (!blocks_remaining)
|
||||
return shape;
|
||||
shape.indirect_blocks = min(blocks_remaining, entries_per_block);
|
||||
blocks_remaining -= shape.indirect_blocks;
|
||||
shape.meta_blocks += 1;
|
||||
if (!blocks_remaining)
|
||||
return shape;
|
||||
ASSERT_NOT_REACHED();
|
||||
// FIXME: Support dind/tind blocks.
|
||||
shape.doubly_indirect_blocks = min(blocks_remaining, entries_per_block * entries_per_block);
|
||||
blocks_remaining -= shape.doubly_indirect_blocks;
|
||||
if (!blocks_remaining)
|
||||
return shape;
|
||||
shape.triply_indirect_blocks = min(blocks_remaining, entries_per_block * entries_per_block * entries_per_block);
|
||||
blocks_remaining -= shape.triply_indirect_blocks;
|
||||
// FIXME: What do we do for files >= 16GB?
|
||||
ASSERT(!blocks_remaining);
|
||||
return shape;
|
||||
}
|
||||
|
||||
bool Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2inode, Vector<BlockIndex>&& blocks)
|
||||
{
|
||||
dbgprintf("Ext2FS: writing %u block(s) to i_block array\n", min((size_t)EXT2_NDIR_BLOCKS, blocks.size()));
|
||||
|
||||
auto old_shape = compute_block_list_shape(e2inode.i_blocks / (2 << super_block().s_log_block_size));
|
||||
auto new_shape = compute_block_list_shape(blocks.size());
|
||||
|
||||
Vector<BlockIndex> new_meta_blocks;
|
||||
if (new_shape.meta_blocks > old_shape.meta_blocks) {
|
||||
new_meta_blocks = allocate_blocks(group_index_from_inode(inode_index), new_shape.meta_blocks - old_shape.meta_blocks);
|
||||
}
|
||||
|
||||
unsigned output_block_index = 0;
|
||||
unsigned remaining_blocks = blocks.size();
|
||||
for (unsigned i = 0; i < new_shape.direct_blocks; ++i) {
|
||||
e2inode.i_block[i] = blocks[output_block_index++];
|
||||
--remaining_blocks;
|
||||
}
|
||||
write_ext2_inode(inode_index, e2inode);
|
||||
|
||||
if (!remaining_blocks)
|
||||
return true;
|
||||
|
||||
if (!e2inode.i_block[EXT2_IND_BLOCK]) {
|
||||
e2inode.i_block[EXT2_IND_BLOCK] = new_meta_blocks.take_last();
|
||||
write_ext2_inode(inode_index, e2inode);
|
||||
}
|
||||
|
||||
{
|
||||
auto block_contents = ByteBuffer::create_uninitialized(blockSize());
|
||||
BufferStream stream(block_contents);
|
||||
ASSERT(new_shape.indirect_blocks <= EXT2_ADDR_PER_BLOCK(&super_block()));
|
||||
for (unsigned i = 0; i < new_shape.indirect_blocks; ++i) {
|
||||
stream << blocks[output_block_index++];
|
||||
--remaining_blocks;
|
||||
}
|
||||
stream.fill_to_end(0);
|
||||
writeBlock(e2inode.i_block[EXT2_IND_BLOCK], block_contents);
|
||||
}
|
||||
|
||||
if (!remaining_blocks)
|
||||
return true;
|
||||
|
||||
// FIXME: Implement!
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
Vector<unsigned> Ext2FS::block_list_for_inode(const ext2_inode& e2inode, bool include_block_list_blocks) const
|
||||
{
|
||||
unsigned entriesPerBlock = EXT2_ADDR_PER_BLOCK(&super_block());
|
||||
|
@ -558,7 +632,7 @@ bool Ext2FS::write_directory_inode(unsigned directoryInode, Vector<DirectoryEntr
|
|||
}
|
||||
}
|
||||
|
||||
stream.fillToEnd(0);
|
||||
stream.fill_to_end(0);
|
||||
|
||||
#if 0
|
||||
kprintf("data to write (%u):\n", directoryData.size());
|
||||
|
@ -986,10 +1060,8 @@ RetainPtr<Inode> Ext2FS::create_inode(InodeIdentifier parent_id, const String& n
|
|||
// FIXME: Implement writing out indirect blocks!
|
||||
ASSERT(blocks.size() < EXT2_NDIR_BLOCKS);
|
||||
|
||||
dbgprintf("Ext2FS: writing %u blocks to i_block array\n", min((size_t)EXT2_NDIR_BLOCKS, blocks.size()));
|
||||
for (unsigned i = 0; i < min((size_t)EXT2_NDIR_BLOCKS, blocks.size()); ++i) {
|
||||
e2inode->i_block[i] = blocks[i];
|
||||
}
|
||||
success = write_block_list_for_inode(inode_id, *e2inode, move(blocks));
|
||||
ASSERT(success);
|
||||
|
||||
dbgprintf("Ext2FS: writing initial metadata for inode %u\n", inode_id);
|
||||
e2inode->i_flags = 0;
|
||||
|
|
|
@ -93,6 +93,7 @@ private:
|
|||
unsigned group_index_from_inode(unsigned) const;
|
||||
|
||||
Vector<unsigned> block_list_for_inode(const ext2_inode&, bool include_block_list_blocks = false) const;
|
||||
bool write_block_list_for_inode(InodeIndex, ext2_inode&, Vector<BlockIndex>&&);
|
||||
|
||||
void dump_block_bitmap(unsigned groupIndex) const;
|
||||
void dump_inode_bitmap(unsigned groupIndex) const;
|
||||
|
@ -109,6 +110,16 @@ private:
|
|||
void uncache_inode(InodeIndex);
|
||||
void free_inode(Ext2FSInode&);
|
||||
|
||||
struct BlockListShape {
|
||||
unsigned direct_blocks { 0 };
|
||||
unsigned indirect_blocks { 0 };
|
||||
unsigned doubly_indirect_blocks { 0 };
|
||||
unsigned triply_indirect_blocks { 0 };
|
||||
unsigned meta_blocks { 0 };
|
||||
};
|
||||
|
||||
BlockListShape compute_block_list_shape(unsigned blocks);
|
||||
|
||||
unsigned m_blockGroupCount { 0 };
|
||||
|
||||
mutable ByteBuffer m_cached_super_block;
|
||||
|
|
Loading…
Reference in a new issue