mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 11:47:35 +00:00
Kernel: Use ErrorOr in BlockBased and Ext2 filesystem raw read and write
These functions used to return booleans which withheld useful error information for callers. Internally they would suppress and convert Error objects. We now log or propagate these errors up the stack.
This commit is contained in:
parent
df6b9cdb0c
commit
cf45370c47
5 changed files with 34 additions and 43 deletions
|
@ -169,44 +169,40 @@ ErrorOr<void> BlockBasedFileSystem::write_block(BlockIndex index, const UserOrKe
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockBasedFileSystem::raw_read(BlockIndex index, UserOrKernelBuffer& buffer)
|
ErrorOr<void> BlockBasedFileSystem::raw_read(BlockIndex index, UserOrKernelBuffer& buffer)
|
||||||
{
|
{
|
||||||
auto base_offset = index.value() * m_logical_block_size;
|
auto base_offset = index.value() * m_logical_block_size;
|
||||||
auto nread = file_description().read(buffer, base_offset, m_logical_block_size);
|
auto nread = TRY(file_description().read(buffer, base_offset, m_logical_block_size));
|
||||||
VERIFY(!nread.is_error());
|
VERIFY(nread == m_logical_block_size);
|
||||||
VERIFY(nread.value() == m_logical_block_size);
|
return {};
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockBasedFileSystem::raw_write(BlockIndex index, const UserOrKernelBuffer& buffer)
|
ErrorOr<void> BlockBasedFileSystem::raw_write(BlockIndex index, const UserOrKernelBuffer& buffer)
|
||||||
{
|
{
|
||||||
auto base_offset = index.value() * m_logical_block_size;
|
auto base_offset = index.value() * m_logical_block_size;
|
||||||
auto nwritten = file_description().write(base_offset, buffer, m_logical_block_size);
|
auto nwritten = TRY(file_description().write(base_offset, buffer, m_logical_block_size));
|
||||||
VERIFY(!nwritten.is_error());
|
VERIFY(nwritten == m_logical_block_size);
|
||||||
VERIFY(nwritten.value() == m_logical_block_size);
|
return {};
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockBasedFileSystem::raw_read_blocks(BlockIndex index, size_t count, UserOrKernelBuffer& buffer)
|
ErrorOr<void> BlockBasedFileSystem::raw_read_blocks(BlockIndex index, size_t count, UserOrKernelBuffer& buffer)
|
||||||
{
|
{
|
||||||
auto current = buffer;
|
auto current = buffer;
|
||||||
for (auto block = index.value(); block < (index.value() + count); block++) {
|
for (auto block = index.value(); block < (index.value() + count); block++) {
|
||||||
if (!raw_read(BlockIndex { block }, current))
|
TRY(raw_read(BlockIndex { block }, current));
|
||||||
return false;
|
|
||||||
current = current.offset(logical_block_size());
|
current = current.offset(logical_block_size());
|
||||||
}
|
}
|
||||||
return true;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockBasedFileSystem::raw_write_blocks(BlockIndex index, size_t count, const UserOrKernelBuffer& buffer)
|
ErrorOr<void> BlockBasedFileSystem::raw_write_blocks(BlockIndex index, size_t count, const UserOrKernelBuffer& buffer)
|
||||||
{
|
{
|
||||||
auto current = buffer;
|
auto current = buffer;
|
||||||
for (auto block = index.value(); block < (index.value() + count); block++) {
|
for (auto block = index.value(); block < (index.value() + count); block++) {
|
||||||
if (!raw_write(block, current))
|
TRY(raw_write(block, current));
|
||||||
return false;
|
|
||||||
current = current.offset(logical_block_size());
|
current = current.offset(logical_block_size());
|
||||||
}
|
}
|
||||||
return true;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> BlockBasedFileSystem::write_blocks(BlockIndex index, unsigned count, const UserOrKernelBuffer& data, bool allow_cache)
|
ErrorOr<void> BlockBasedFileSystem::write_blocks(BlockIndex index, unsigned count, const UserOrKernelBuffer& data, bool allow_cache)
|
||||||
|
|
|
@ -29,11 +29,11 @@ protected:
|
||||||
ErrorOr<void> read_block(BlockIndex, UserOrKernelBuffer*, size_t count, size_t offset = 0, bool allow_cache = true) const;
|
ErrorOr<void> read_block(BlockIndex, UserOrKernelBuffer*, size_t count, size_t offset = 0, bool allow_cache = true) const;
|
||||||
ErrorOr<void> read_blocks(BlockIndex, unsigned count, UserOrKernelBuffer&, bool allow_cache = true) const;
|
ErrorOr<void> read_blocks(BlockIndex, unsigned count, UserOrKernelBuffer&, bool allow_cache = true) const;
|
||||||
|
|
||||||
bool raw_read(BlockIndex, UserOrKernelBuffer&);
|
ErrorOr<void> raw_read(BlockIndex, UserOrKernelBuffer&);
|
||||||
bool raw_write(BlockIndex, const UserOrKernelBuffer&);
|
ErrorOr<void> raw_write(BlockIndex, const UserOrKernelBuffer&);
|
||||||
|
|
||||||
bool raw_read_blocks(BlockIndex index, size_t count, UserOrKernelBuffer&);
|
ErrorOr<void> raw_read_blocks(BlockIndex index, size_t count, UserOrKernelBuffer&);
|
||||||
bool raw_write_blocks(BlockIndex index, size_t count, const UserOrKernelBuffer&);
|
ErrorOr<void> raw_write_blocks(BlockIndex index, size_t count, const UserOrKernelBuffer&);
|
||||||
|
|
||||||
ErrorOr<void> write_block(BlockIndex, const UserOrKernelBuffer&, size_t count, size_t offset = 0, bool allow_cache = true);
|
ErrorOr<void> write_block(BlockIndex, const UserOrKernelBuffer&, size_t count, size_t offset = 0, bool allow_cache = true);
|
||||||
ErrorOr<void> write_blocks(BlockIndex, unsigned count, const UserOrKernelBuffer&, bool allow_cache = true);
|
ErrorOr<void> write_blocks(BlockIndex, unsigned count, const UserOrKernelBuffer&, bool allow_cache = true);
|
||||||
|
|
|
@ -63,14 +63,12 @@ Ext2FS::~Ext2FS()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Ext2FS::flush_super_block()
|
ErrorOr<void> Ext2FS::flush_super_block()
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_lock);
|
MutexLocker locker(m_lock);
|
||||||
VERIFY((sizeof(ext2_super_block) % logical_block_size()) == 0);
|
VERIFY((sizeof(ext2_super_block) % logical_block_size()) == 0);
|
||||||
auto super_block_buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&m_super_block);
|
auto super_block_buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&m_super_block);
|
||||||
bool success = raw_write_blocks(2, (sizeof(ext2_super_block) / logical_block_size()), super_block_buffer);
|
return raw_write_blocks(2, (sizeof(ext2_super_block) / logical_block_size()), super_block_buffer);
|
||||||
VERIFY(success);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ext2_group_desc& Ext2FS::group_descriptor(GroupIndex group_index) const
|
const ext2_group_desc& Ext2FS::group_descriptor(GroupIndex group_index) const
|
||||||
|
@ -87,8 +85,7 @@ ErrorOr<void> Ext2FS::initialize()
|
||||||
|
|
||||||
VERIFY((sizeof(ext2_super_block) % logical_block_size()) == 0);
|
VERIFY((sizeof(ext2_super_block) % logical_block_size()) == 0);
|
||||||
auto super_block_buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&m_super_block);
|
auto super_block_buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&m_super_block);
|
||||||
bool success = raw_read_blocks(2, (sizeof(ext2_super_block) / logical_block_size()), super_block_buffer);
|
TRY(raw_read_blocks(2, (sizeof(ext2_super_block) / logical_block_size()), super_block_buffer));
|
||||||
VERIFY(success);
|
|
||||||
|
|
||||||
auto const& super_block = this->super_block();
|
auto const& super_block = this->super_block();
|
||||||
if constexpr (EXT2_DEBUG) {
|
if constexpr (EXT2_DEBUG) {
|
||||||
|
@ -679,7 +676,12 @@ void Ext2FS::flush_writes()
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_lock);
|
MutexLocker locker(m_lock);
|
||||||
if (m_super_block_dirty) {
|
if (m_super_block_dirty) {
|
||||||
flush_super_block();
|
auto result = flush_super_block();
|
||||||
|
if (result.is_error()) {
|
||||||
|
dbgln("Ext2FS[{}]::flush_writes(): Failed to write superblock: {}", fsid(), result.error());
|
||||||
|
// FIXME: We should handle this error.
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
m_super_block_dirty = false;
|
m_super_block_dirty = false;
|
||||||
}
|
}
|
||||||
if (m_block_group_descriptors_dirty) {
|
if (m_block_group_descriptors_dirty) {
|
||||||
|
|
|
@ -122,7 +122,7 @@ private:
|
||||||
ErrorOr<void> write_ext2_inode(InodeIndex, ext2_inode const&);
|
ErrorOr<void> write_ext2_inode(InodeIndex, ext2_inode const&);
|
||||||
bool find_block_containing_inode(InodeIndex, BlockIndex& block_index, unsigned& offset) const;
|
bool find_block_containing_inode(InodeIndex, BlockIndex& block_index, unsigned& offset) const;
|
||||||
|
|
||||||
bool flush_super_block();
|
ErrorOr<void> flush_super_block();
|
||||||
|
|
||||||
virtual StringView class_name() const override { return "Ext2FS"sv; }
|
virtual StringView class_name() const override { return "Ext2FS"sv; }
|
||||||
virtual Ext2FSInode& root_inode() override;
|
virtual Ext2FSInode& root_inode() override;
|
||||||
|
|
|
@ -234,10 +234,10 @@ ErrorOr<void> ISO9660FS::parse_volume_set()
|
||||||
|
|
||||||
auto current_block_index = first_data_area_block;
|
auto current_block_index = first_data_area_block;
|
||||||
while (true) {
|
while (true) {
|
||||||
bool result = raw_read(BlockIndex { current_block_index }, block_buffer);
|
auto result = raw_read(BlockIndex { current_block_index }, block_buffer);
|
||||||
if (!result) {
|
if (result.is_error()) {
|
||||||
dbgln_if(ISO9660_DEBUG, "Failed to read volume descriptor from ISO file");
|
dbgln_if(ISO9660_DEBUG, "Failed to read volume descriptor from ISO file: {}", result.error());
|
||||||
return EIO;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const* header = reinterpret_cast<ISO::VolumeDescriptorHeader const*>(block->data());
|
auto const* header = reinterpret_cast<ISO::VolumeDescriptorHeader const*>(block->data());
|
||||||
|
@ -387,11 +387,7 @@ ErrorOr<NonnullRefPtr<ISO9660FS::DirectoryEntry>> ISO9660FS::directory_entry_for
|
||||||
|
|
||||||
auto blocks = TRY(KBuffer::try_create_with_size(data_length, Memory::Region::Access::Read | Memory::Region::Access::Write, "ISO9660FS: Directory traversal buffer"));
|
auto blocks = TRY(KBuffer::try_create_with_size(data_length, Memory::Region::Access::Read | Memory::Region::Access::Write, "ISO9660FS: Directory traversal buffer"));
|
||||||
auto blocks_buffer = UserOrKernelBuffer::for_kernel_buffer(blocks->data());
|
auto blocks_buffer = UserOrKernelBuffer::for_kernel_buffer(blocks->data());
|
||||||
auto did_read = raw_read_blocks(BlockBasedFileSystem::BlockIndex { extent_location }, data_length / logical_block_size(), blocks_buffer);
|
TRY(raw_read_blocks(BlockBasedFileSystem::BlockIndex { extent_location }, data_length / logical_block_size(), blocks_buffer));
|
||||||
if (!did_read) {
|
|
||||||
return EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto entry = TRY(DirectoryEntry::try_create(extent_location, data_length, move(blocks)));
|
auto entry = TRY(DirectoryEntry::try_create(extent_location, data_length, move(blocks)));
|
||||||
m_directory_entry_cache.set(key, entry);
|
m_directory_entry_cache.set(key, entry);
|
||||||
|
|
||||||
|
@ -428,10 +424,7 @@ ErrorOr<size_t> ISO9660Inode::read_bytes(off_t offset, size_t size, UserOrKernel
|
||||||
auto buffer_offset = buffer.offset(nread);
|
auto buffer_offset = buffer.offset(nread);
|
||||||
dbgln_if(ISO9660_VERY_DEBUG, "ISO9660Inode::read_bytes: Reading {} bytes into buffer offset {}/{}, logical block index: {}", bytes_to_read, nread, total_bytes, current_block_index.value());
|
dbgln_if(ISO9660_VERY_DEBUG, "ISO9660Inode::read_bytes: Reading {} bytes into buffer offset {}/{}, logical block index: {}", bytes_to_read, nread, total_bytes, current_block_index.value());
|
||||||
|
|
||||||
if (bool result = const_cast<ISO9660FS&>(fs()).raw_read(current_block_index, block_buffer); !result) {
|
TRY(const_cast<ISO9660FS&>(fs()).raw_read(current_block_index, block_buffer));
|
||||||
return EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRY(buffer_offset.write(block->data() + initial_offset, bytes_to_read));
|
TRY(buffer_offset.write(block->data() + initial_offset, bytes_to_read));
|
||||||
|
|
||||||
nread += bytes_to_read;
|
nread += bytes_to_read;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue