mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 14:38:11 +00:00
Kernel/FileSystem: Mark ext2 inode block list non-const
The block list required a bit of work, and now the only method being declared const to bypass its const-iness is the read_bytes method that calls a new method called compute_block_list_with_exclusive_locking that takes care of proper locking before trying to update the block list data of the ext2 inode.
This commit is contained in:
parent
843bd43c5b
commit
4f4717e351
2 changed files with 24 additions and 3 deletions
|
@ -798,6 +798,19 @@ ErrorOr<NonnullLockRefPtr<Inode>> Ext2FS::get_inode(InodeIdentifier inode) const
|
|||
return new_inode;
|
||||
}
|
||||
|
||||
ErrorOr<void> Ext2FSInode::compute_block_list_with_exclusive_locking()
|
||||
{
|
||||
// Note: We verify that the inode mutex is being held locked. Because only the read_bytes_locked()
|
||||
// method uses this method and the mutex can be locked in shared mode when reading the Inode if
|
||||
// it is an ext2 regular file, but also in exclusive mode, when the Inode is an ext2 directory and being
|
||||
// traversed, we use another exclusive lock to ensure we always mutate the block list safely.
|
||||
VERIFY(m_inode_lock.is_locked());
|
||||
MutexLocker block_list_locker(m_block_list_lock);
|
||||
if (m_block_list.is_empty())
|
||||
m_block_list = TRY(compute_block_list());
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<size_t> Ext2FSInode::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const
|
||||
{
|
||||
MutexLocker inode_locker(m_inode_lock);
|
||||
|
@ -817,8 +830,12 @@ ErrorOr<size_t> Ext2FSInode::read_bytes(off_t offset, size_t count, UserOrKernel
|
|||
return nread;
|
||||
}
|
||||
|
||||
if (m_block_list.is_empty())
|
||||
m_block_list = TRY(compute_block_list());
|
||||
// Note: We bypass the const declaration of this method, but this is a strong
|
||||
// requirement to be able to accomplish the read operation successfully.
|
||||
// We call this special method becuase it locks a separate mutex to ensure we
|
||||
// update the block list of the inode safely, as the m_inode_lock is locked in
|
||||
// shared mode.
|
||||
TRY(const_cast<Ext2FSInode&>(*this).compute_block_list_with_exclusive_locking());
|
||||
|
||||
if (m_block_list.is_empty()) {
|
||||
dmesgln("Ext2FSInode[{}]::read_bytes(): Empty block list", identifier());
|
||||
|
|
|
@ -61,6 +61,8 @@ private:
|
|||
ErrorOr<void> grow_triply_indirect_block(BlockBasedFileSystem::BlockIndex, size_t, Span<BlockBasedFileSystem::BlockIndex>, Vector<BlockBasedFileSystem::BlockIndex>&, unsigned&);
|
||||
ErrorOr<void> shrink_triply_indirect_block(BlockBasedFileSystem::BlockIndex, size_t, size_t, unsigned&);
|
||||
ErrorOr<void> flush_block_list();
|
||||
|
||||
ErrorOr<void> compute_block_list_with_exclusive_locking();
|
||||
ErrorOr<Vector<BlockBasedFileSystem::BlockIndex>> compute_block_list() const;
|
||||
ErrorOr<Vector<BlockBasedFileSystem::BlockIndex>> compute_block_list_with_meta_blocks() const;
|
||||
ErrorOr<Vector<BlockBasedFileSystem::BlockIndex>> compute_block_list_impl(bool include_block_list_blocks) const;
|
||||
|
@ -70,9 +72,11 @@ private:
|
|||
Ext2FS const& fs() const;
|
||||
Ext2FSInode(Ext2FS&, InodeIndex);
|
||||
|
||||
mutable Vector<BlockBasedFileSystem::BlockIndex> m_block_list;
|
||||
Vector<BlockBasedFileSystem::BlockIndex> m_block_list;
|
||||
HashMap<NonnullOwnPtr<KString>, InodeIndex> m_lookup_cache;
|
||||
ext2_inode m_raw_inode {};
|
||||
|
||||
Mutex m_block_list_lock { "BlockList"sv };
|
||||
};
|
||||
|
||||
class Ext2FS final : public BlockBasedFileSystem {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue