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:
parent
0e67c6318b
commit
669b2ace4e
|
@ -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();
|
||||
|
|
|
@ -90,16 +90,17 @@ namespace Kernel
|
|||
dprintln(" inodes/group {}", m_superblock.inodes_per_group);
|
||||
#endif
|
||||
|
||||
TRY(m_buffer_manager.initialize(block_size()));
|
||||
|
||||
{
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(block_size()));
|
||||
auto block_buffer = m_buffer_manager.get_buffer();
|
||||
|
||||
if (superblock().rev_level == Ext2::Enum::GOOD_OLD_REV)
|
||||
{
|
||||
// In revision 0 all blockgroups contain superblock backup
|
||||
TRY(m_superblock_backups.reserve(number_of_block_groups - 1));
|
||||
for (uint32_t i = 1; i < number_of_block_groups; i++)
|
||||
MUST(block_buffer.push_back(i));
|
||||
MUST(m_superblock_backups.push_back(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -118,7 +119,7 @@ namespace Kernel
|
|||
|
||||
for (uint32_t bg : m_superblock_backups)
|
||||
{
|
||||
read_block(superblock().first_data_block + superblock().blocks_per_group * bg, block_buffer.span());
|
||||
read_block(superblock().first_data_block + superblock().blocks_per_group * bg, block_buffer);
|
||||
Ext2::Superblock& superblock_backup = *(Ext2::Superblock*)block_buffer.data();
|
||||
if (superblock_backup.magic != Ext2::Enum::SUPER_MAGIC)
|
||||
derrorln("superblock backup at block {} is invalid ({4H})", bg, superblock_backup.magic);
|
||||
|
@ -145,11 +146,8 @@ namespace Kernel
|
|||
|
||||
const uint32_t block_size = this->block_size();
|
||||
|
||||
BAN::Vector<uint8_t> bgd_buffer;
|
||||
TRY(bgd_buffer.resize(block_size));
|
||||
|
||||
BAN::Vector<uint8_t> inode_bitmap;
|
||||
TRY(inode_bitmap.resize(block_size));
|
||||
auto bgd_buffer = m_buffer_manager.get_buffer();
|
||||
auto inode_bitmap = m_buffer_manager.get_buffer();
|
||||
|
||||
uint32_t current_group = -1;
|
||||
BlockLocation bgd_location {};
|
||||
|
@ -165,7 +163,7 @@ namespace Kernel
|
|||
current_group = ino_group;
|
||||
|
||||
bgd_location = locate_block_group_descriptior(current_group);
|
||||
read_block(bgd_location.block, bgd_buffer.span());
|
||||
read_block(bgd_location.block, bgd_buffer);
|
||||
|
||||
bgd = (Ext2::BlockGroupDescriptor*)(bgd_buffer.data() + bgd_location.offset);
|
||||
if (bgd->free_inodes_count == 0)
|
||||
|
@ -174,7 +172,7 @@ namespace Kernel
|
|||
continue;
|
||||
}
|
||||
|
||||
read_block(bgd->inode_bitmap, inode_bitmap.span());
|
||||
read_block(bgd->inode_bitmap, inode_bitmap);
|
||||
}
|
||||
|
||||
const uint32_t ino_bitmap_byte = ino_index / 8;
|
||||
|
@ -183,10 +181,10 @@ namespace Kernel
|
|||
continue;
|
||||
|
||||
inode_bitmap[ino_bitmap_byte] |= 1 << ino_bitmap_bit;
|
||||
write_block(bgd->inode_bitmap, inode_bitmap.span());
|
||||
write_block(bgd->inode_bitmap, inode_bitmap);
|
||||
|
||||
bgd->free_inodes_count--;
|
||||
write_block(bgd_location.block, bgd_buffer.span());
|
||||
write_block(bgd_location.block, bgd_buffer);
|
||||
|
||||
const uint32_t inode_table_offset = ino_index * superblock().inode_size;
|
||||
const BlockLocation inode_location
|
||||
|
@ -198,11 +196,11 @@ namespace Kernel
|
|||
// NOTE: we don't need inode bitmap anymore, so we can reuse it
|
||||
auto& inode_buffer = inode_bitmap;
|
||||
|
||||
read_block(inode_location.block, inode_buffer.span());
|
||||
read_block(inode_location.block, inode_buffer);
|
||||
memcpy(inode_buffer.data() + inode_location.offset, &ext2_inode, sizeof(Ext2::Inode));
|
||||
if (superblock().inode_size > sizeof(Ext2::Inode))
|
||||
memset(inode_buffer.data() + inode_location.offset + sizeof(Ext2::Inode), 0, superblock().inode_size - sizeof(Ext2::Inode));
|
||||
write_block(inode_location.block, inode_buffer.span());
|
||||
write_block(inode_location.block, inode_buffer);
|
||||
|
||||
m_superblock.free_inodes_count--;
|
||||
sync_superblock();
|
||||
|
@ -214,7 +212,7 @@ namespace Kernel
|
|||
return BAN::Error::from_error_code(ErrorCode::Ext2_Corrupted);
|
||||
}
|
||||
|
||||
void Ext2FS::read_block(uint32_t block, BAN::Span<uint8_t> buffer)
|
||||
void Ext2FS::read_block(uint32_t block, BlockBufferWrapper& buffer)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
|
@ -228,7 +226,7 @@ namespace Kernel
|
|||
MUST(m_partition.read_sectors(sectors_before + (block - 2) * sectors_per_block, sectors_per_block, buffer.data()));
|
||||
}
|
||||
|
||||
void Ext2FS::write_block(uint32_t block, BAN::Span<const uint8_t> buffer)
|
||||
void Ext2FS::write_block(uint32_t block, const BlockBufferWrapper& buffer)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
|
@ -268,6 +266,13 @@ namespace Kernel
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
Ext2FS::BlockBufferWrapper Ext2FS::get_block_buffer()
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
return m_buffer_manager.get_buffer();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<uint32_t> Ext2FS::reserve_free_block(uint32_t primary_bgd)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
@ -275,25 +280,20 @@ namespace Kernel
|
|||
if (m_superblock.r_blocks_count >= m_superblock.free_blocks_count)
|
||||
return BAN::Error::from_errno(ENOSPC);
|
||||
|
||||
const uint32_t block_size = this->block_size();
|
||||
|
||||
BAN::Vector<uint8_t> bgd_buffer;
|
||||
TRY(bgd_buffer.resize(block_size));
|
||||
|
||||
BAN::Vector<uint8_t> block_bitmap;
|
||||
TRY(block_bitmap.resize(block_size));
|
||||
auto bgd_buffer = m_buffer_manager.get_buffer();
|
||||
auto block_bitmap = m_buffer_manager.get_buffer();
|
||||
|
||||
auto check_block_group =
|
||||
[&](uint32_t block_group) -> uint32_t
|
||||
{
|
||||
auto bgd_location = locate_block_group_descriptior(block_group);
|
||||
read_block(bgd_location.block, bgd_buffer.span());
|
||||
read_block(bgd_location.block, bgd_buffer);
|
||||
|
||||
auto& bgd = *(Ext2::BlockGroupDescriptor*)(bgd_buffer.data() + bgd_location.offset);
|
||||
if (bgd.free_blocks_count == 0)
|
||||
return 0;
|
||||
|
||||
read_block(bgd.block_bitmap, block_bitmap.span());
|
||||
read_block(bgd.block_bitmap, block_bitmap);
|
||||
for (uint32_t block_offset = 0; block_offset < m_superblock.blocks_per_group; block_offset++)
|
||||
{
|
||||
const uint32_t fs_block_index = m_superblock.first_data_block + m_superblock.blocks_per_group * block_group + block_offset;
|
||||
|
@ -306,10 +306,10 @@ namespace Kernel
|
|||
continue;
|
||||
|
||||
block_bitmap[byte] |= 1 << bit;
|
||||
write_block(bgd.block_bitmap, block_bitmap.span());
|
||||
write_block(bgd.block_bitmap, block_bitmap);
|
||||
|
||||
bgd.free_blocks_count--;
|
||||
write_block(bgd_location.block, bgd_buffer.span());
|
||||
write_block(bgd_location.block, bgd_buffer);
|
||||
|
||||
m_superblock.free_blocks_count--;
|
||||
sync_superblock();
|
||||
|
@ -334,7 +334,7 @@ namespace Kernel
|
|||
return BAN::Error::from_error_code(ErrorCode::Ext2_Corrupted);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<Ext2FS::BlockLocation> Ext2FS::locate_inode(uint32_t ino)
|
||||
Ext2FS::BlockLocation Ext2FS::locate_inode(uint32_t ino)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
|
@ -342,15 +342,14 @@ namespace Kernel
|
|||
|
||||
const uint32_t block_size = this->block_size();
|
||||
|
||||
BAN::Vector<uint8_t> bgd_buffer;
|
||||
TRY(bgd_buffer.resize(block_size));
|
||||
auto bgd_buffer = m_buffer_manager.get_buffer();
|
||||
|
||||
const uint32_t inode_group = (ino - 1) / superblock().inodes_per_group;
|
||||
const uint32_t inode_index = (ino - 1) % superblock().inodes_per_group;
|
||||
|
||||
auto bgd_location = locate_block_group_descriptior(inode_group);
|
||||
|
||||
read_block(bgd_location.block, bgd_buffer.span());
|
||||
read_block(bgd_location.block, bgd_buffer);
|
||||
|
||||
auto& bgd = *(Ext2::BlockGroupDescriptor*)(bgd_buffer.data() + bgd_location.offset);
|
||||
|
||||
|
@ -397,4 +396,26 @@ namespace Kernel
|
|||
};
|
||||
}
|
||||
|
||||
Ext2FS::BlockBufferWrapper Ext2FS::BlockBufferManager::get_buffer()
|
||||
{
|
||||
for (auto& buffer : m_buffers)
|
||||
{
|
||||
if (buffer.used)
|
||||
continue;
|
||||
buffer.used = true;
|
||||
return Ext2FS::BlockBufferWrapper(buffer.buffer.span(), buffer.used);
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Ext2FS::BlockBufferManager::initialize(size_t block_size)
|
||||
{
|
||||
for (auto& buffer : m_buffers)
|
||||
{
|
||||
TRY(buffer.buffer.resize(block_size));
|
||||
buffer.used = false;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
|
@ -23,12 +23,10 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<BAN::RefPtr<Inode>> Ext2Inode::create(Ext2FS& fs, uint32_t inode_ino)
|
||||
{
|
||||
auto inode_location = TRY(fs.locate_inode(inode_ino));
|
||||
auto inode_location = fs.locate_inode(inode_ino);
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(fs.block_size()));
|
||||
|
||||
fs.read_block(inode_location.block, block_buffer.span());
|
||||
auto block_buffer = fs.get_block_buffer();
|
||||
fs.read_block(inode_location.block, block_buffer);
|
||||
|
||||
auto& inode = *(Ext2::Inode*)(block_buffer.data() + inode_location.offset);
|
||||
|
||||
|
@ -38,10 +36,10 @@ namespace Kernel
|
|||
return BAN::RefPtr<Inode>::adopt(result);
|
||||
}
|
||||
|
||||
#define VERIFY_AND_READ_BLOCK(expr) do { const uint32_t block_index = expr; ASSERT(block_index); m_fs.read_block(block_index, block_buffer.span()); } while (false)
|
||||
#define VERIFY_AND_READ_BLOCK(expr) do { const uint32_t block_index = expr; ASSERT(block_index); m_fs.read_block(block_index, block_buffer); } while (false)
|
||||
#define VERIFY_AND_RETURN(expr) ({ const uint32_t result = expr; ASSERT(result); return result; })
|
||||
|
||||
BAN::ErrorOr<uint32_t> Ext2Inode::fs_block_of_data_block_index(uint32_t data_block_index)
|
||||
uint32_t Ext2Inode::fs_block_of_data_block_index(uint32_t data_block_index)
|
||||
{
|
||||
ASSERT(data_block_index < blocks());
|
||||
|
||||
|
@ -53,8 +51,7 @@ namespace Kernel
|
|||
|
||||
data_block_index -= 12;
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(blksize()));
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
|
||||
// Singly indirect block
|
||||
if (data_block_index < indices_per_block)
|
||||
|
@ -115,8 +112,7 @@ namespace Kernel
|
|||
|
||||
const uint32_t block_size = blksize();
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(block_size));
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
|
||||
const uint32_t first_block = offset / block_size;
|
||||
const uint32_t last_block = BAN::Math::div_round_up<uint32_t>(offset + count, block_size);
|
||||
|
@ -125,8 +121,8 @@ namespace Kernel
|
|||
|
||||
for (uint32_t data_block_index = first_block; data_block_index < last_block; data_block_index++)
|
||||
{
|
||||
uint32_t block_index = TRY(fs_block_of_data_block_index(data_block_index));
|
||||
m_fs.read_block(block_index, block_buffer.span());
|
||||
uint32_t block_index = fs_block_of_data_block_index(data_block_index);
|
||||
m_fs.read_block(block_index, block_buffer);
|
||||
|
||||
uint32_t copy_offset = (offset + n_read) % block_size;
|
||||
uint32_t to_copy = BAN::Math::min<uint32_t>(block_size - copy_offset, count - n_read);
|
||||
|
@ -153,8 +149,7 @@ namespace Kernel
|
|||
|
||||
const uint32_t block_size = blksize();
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(block_size));
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
|
||||
const uint8_t* u8buffer = (const uint8_t*)buffer;
|
||||
|
||||
|
@ -163,14 +158,14 @@ namespace Kernel
|
|||
// Write partial block
|
||||
if (offset % block_size)
|
||||
{
|
||||
uint32_t block_index = TRY(fs_block_of_data_block_index(offset / block_size));
|
||||
uint32_t block_index = fs_block_of_data_block_index(offset / block_size);
|
||||
uint32_t block_offset = offset % block_size;
|
||||
|
||||
uint32_t to_copy = BAN::Math::min<uint32_t>(block_size - block_offset, to_write);
|
||||
|
||||
m_fs.read_block(block_index, block_buffer.span());
|
||||
m_fs.read_block(block_index, block_buffer);
|
||||
memcpy(block_buffer.data() + block_offset, u8buffer, to_copy);
|
||||
m_fs.write_block(block_index, block_buffer.span());
|
||||
m_fs.write_block(block_index, block_buffer);
|
||||
|
||||
u8buffer += to_copy;
|
||||
offset += to_copy;
|
||||
|
@ -179,9 +174,10 @@ namespace Kernel
|
|||
|
||||
while (to_write >= block_size)
|
||||
{
|
||||
uint32_t block_index = TRY(fs_block_of_data_block_index(offset / block_size));
|
||||
uint32_t block_index = fs_block_of_data_block_index(offset / block_size);
|
||||
|
||||
m_fs.write_block(block_index, BAN::Span<const uint8_t>(u8buffer, block_size));
|
||||
memcpy(block_buffer.data(), u8buffer, block_buffer.size());
|
||||
m_fs.write_block(block_index, block_buffer);
|
||||
|
||||
u8buffer += block_size;
|
||||
offset += block_size;
|
||||
|
@ -190,11 +186,11 @@ namespace Kernel
|
|||
|
||||
if (to_write > 0)
|
||||
{
|
||||
uint32_t block_index = TRY(fs_block_of_data_block_index(offset / block_size));
|
||||
uint32_t block_index = fs_block_of_data_block_index(offset / block_size);
|
||||
|
||||
m_fs.read_block(block_index, block_buffer.span());
|
||||
m_fs.read_block(block_index, block_buffer);
|
||||
memcpy(block_buffer.data(), u8buffer, to_write);
|
||||
m_fs.write_block(block_index, block_buffer.span());
|
||||
m_fs.write_block(block_index, block_buffer);
|
||||
}
|
||||
|
||||
return count;
|
||||
|
@ -216,23 +212,22 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(block_size));
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
|
||||
if (uint32_t rem = m_inode.size % block_size)
|
||||
{
|
||||
uint32_t last_block_index = TRY(fs_block_of_data_block_index(current_data_blocks - 1));
|
||||
uint32_t last_block_index = fs_block_of_data_block_index(current_data_blocks - 1);
|
||||
|
||||
m_fs.read_block(last_block_index, block_buffer.span());
|
||||
m_fs.read_block(last_block_index, block_buffer);
|
||||
memset(block_buffer.data() + rem, 0, block_size - rem);
|
||||
m_fs.write_block(last_block_index, block_buffer.span());
|
||||
m_fs.write_block(last_block_index, block_buffer);
|
||||
}
|
||||
|
||||
memset(block_buffer.data(), 0, block_size);
|
||||
while (blocks() < needed_data_blocks)
|
||||
{
|
||||
uint32_t block_index = TRY(allocate_new_block());
|
||||
m_fs.write_block(block_index, block_buffer.span());
|
||||
m_fs.write_block(block_index, block_buffer);
|
||||
}
|
||||
|
||||
m_inode.size = new_size;
|
||||
|
@ -254,12 +249,11 @@ namespace Kernel
|
|||
}
|
||||
|
||||
const uint32_t block_size = blksize();
|
||||
const uint32_t block_index = TRY(fs_block_of_data_block_index(offset));
|
||||
const uint32_t block_index = fs_block_of_data_block_index(offset);
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(block_size));
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
|
||||
m_fs.read_block(block_index, block_buffer.span());
|
||||
m_fs.read_block(block_index, block_buffer);
|
||||
|
||||
// First determine if we have big enough list
|
||||
{
|
||||
|
@ -356,8 +350,8 @@ namespace Kernel
|
|||
const uint32_t inode_index = TRY(m_fs.create_inode(ext2_inode));
|
||||
|
||||
const uint32_t block_size = m_fs.block_size();
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(block_size));
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
|
||||
auto write_inode = [&](uint32_t entry_offset, uint32_t entry_rec_len)
|
||||
{
|
||||
|
@ -392,8 +386,8 @@ namespace Kernel
|
|||
goto needs_new_block;
|
||||
|
||||
// Try to insert inode to last data block
|
||||
block_index = TRY(fs_block_of_data_block_index(data_block_count - 1));
|
||||
m_fs.read_block(block_index, block_buffer.span());
|
||||
block_index = fs_block_of_data_block_index(data_block_count - 1);
|
||||
m_fs.read_block(block_index, block_buffer);
|
||||
|
||||
while (entry_offset < block_size)
|
||||
{
|
||||
|
@ -406,7 +400,7 @@ namespace Kernel
|
|||
if (entry.inode == 0 && needed_entry_len <= entry.rec_len)
|
||||
{
|
||||
write_inode(entry_offset, entry.rec_len);
|
||||
m_fs.write_block(block_index, block_buffer.span());
|
||||
m_fs.write_block(block_index, block_buffer);
|
||||
return {};
|
||||
}
|
||||
else if (needed_entry_len <= entry.rec_len - entry_min_rec_len)
|
||||
|
@ -415,7 +409,7 @@ namespace Kernel
|
|||
entry.rec_len = entry_min_rec_len;
|
||||
|
||||
write_inode(entry_offset + entry.rec_len, new_rec_len);
|
||||
m_fs.write_block(block_index, block_buffer.span());
|
||||
m_fs.write_block(block_index, block_buffer);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -425,9 +419,9 @@ namespace Kernel
|
|||
needs_new_block:
|
||||
block_index = TRY(allocate_new_block());
|
||||
|
||||
m_fs.read_block(block_index, block_buffer.span());
|
||||
m_fs.read_block(block_index, block_buffer);
|
||||
write_inode(0, block_size);
|
||||
m_fs.write_block(block_index, block_buffer.span());
|
||||
m_fs.write_block(block_index, block_buffer);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -435,7 +429,7 @@ needs_new_block:
|
|||
#define READ_OR_ALLOCATE_BASE_BLOCK(index_) \
|
||||
do { \
|
||||
if (m_inode.block[index_] != 0) \
|
||||
m_fs.read_block(m_inode.block[index_], block_buffer.span()); \
|
||||
m_fs.read_block(m_inode.block[index_], block_buffer); \
|
||||
else \
|
||||
{ \
|
||||
m_inode.block[index_] = TRY(m_fs.reserve_free_block(block_group())); \
|
||||
|
@ -446,13 +440,13 @@ needs_new_block:
|
|||
#define READ_OR_ALLOCATE_INDIRECT_BLOCK(result_, buffer_index_, parent_block_) \
|
||||
uint32_t result_ = ((uint32_t*)block_buffer.data())[buffer_index_]; \
|
||||
if (result_ != 0) \
|
||||
m_fs.read_block(result_, block_buffer.span()); \
|
||||
m_fs.read_block(result_, block_buffer); \
|
||||
else \
|
||||
{ \
|
||||
const uint32_t new_block_ = TRY(m_fs.reserve_free_block(block_group())); \
|
||||
\
|
||||
((uint32_t*)block_buffer.data())[buffer_index_] = new_block_; \
|
||||
m_fs.write_block(parent_block_, block_buffer.span()); \
|
||||
m_fs.write_block(parent_block_, block_buffer); \
|
||||
\
|
||||
result_ = new_block_; \
|
||||
memset(block_buffer.data(), 0x00, block_buffer.size()); \
|
||||
|
@ -465,7 +459,7 @@ needs_new_block:
|
|||
\
|
||||
ASSERT(((uint32_t*)block_buffer.data())[buffer_index_] == 0); \
|
||||
((uint32_t*)block_buffer.data())[buffer_index_] = block_; \
|
||||
m_fs.write_block(parent_block_, block_buffer.span()); \
|
||||
m_fs.write_block(parent_block_, block_buffer); \
|
||||
\
|
||||
m_inode.blocks += blocks_per_fs_block; \
|
||||
update_and_sync(); \
|
||||
|
@ -503,8 +497,7 @@ needs_new_block:
|
|||
|
||||
block_array_index -= 12;
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(blksize()));
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
|
||||
// singly indirect block
|
||||
if (block_array_index < indices_per_fs_block)
|
||||
|
@ -544,25 +537,14 @@ needs_new_block:
|
|||
|
||||
BAN::ErrorOr<void> Ext2Inode::sync()
|
||||
{
|
||||
auto inode_location_or_error = m_fs.locate_inode(ino());
|
||||
if (inode_location_or_error.is_error())
|
||||
{
|
||||
dwarnln("Open inode not found from filesystem");
|
||||
return BAN::Error::from_error_code(ErrorCode::Ext2_Corrupted);
|
||||
}
|
||||
auto inode_location = m_fs.locate_inode(ino());
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
|
||||
auto inode_location = inode_location_or_error.release_value();
|
||||
|
||||
const uint32_t block_size = blksize();
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(block_size));
|
||||
|
||||
m_fs.read_block(inode_location.block, block_buffer.span());
|
||||
m_fs.read_block(inode_location.block, block_buffer);
|
||||
if (memcmp(block_buffer.data() + inode_location.offset, &m_inode, sizeof(Ext2::Inode)))
|
||||
{
|
||||
memcpy(block_buffer.data() + inode_location.offset, &m_inode, sizeof(Ext2::Inode));
|
||||
m_fs.write_block(inode_location.block, block_buffer.span());
|
||||
m_fs.write_block(inode_location.block, block_buffer);
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -575,13 +557,12 @@ needs_new_block:
|
|||
const uint32_t block_size = blksize();
|
||||
const uint32_t data_block_count = blocks();
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(block_size));
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
|
||||
for (uint32_t i = 0; i < data_block_count; i++)
|
||||
{
|
||||
const uint32_t block_index = TRY(fs_block_of_data_block_index(i));
|
||||
m_fs.read_block(block_index, block_buffer.span());
|
||||
const uint32_t block_index = fs_block_of_data_block_index(i);
|
||||
m_fs.read_block(block_index, block_buffer);
|
||||
|
||||
const uint8_t* block_buffer_end = block_buffer.data() + block_size;
|
||||
const uint8_t* entry_addr = block_buffer.data();
|
||||
|
|
Loading…
Reference in New Issue