diff options
author | Andreas Kling <kling@serenityos.org> | 2021-07-16 02:39:41 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-16 02:40:53 +0200 |
commit | 41c0009f6d3db0f1a8baecbabc65c2464534dd31 (patch) | |
tree | e8a36d656e86fde6b71b3df058dfd097a5d92bee /Kernel/FileSystem/Ext2FileSystem.cpp | |
parent | abbd237ec174b3cd9138b65b28d40cdad62f50f8 (diff) | |
download | serenity-41c0009f6d3db0f1a8baecbabc65c2464534dd31.zip |
Kernel/Ext2FS: Don't hog inode lock in traverse_as_directory()
Reimplement directory traversal in terms of read_bytes() instead of
doing direct block access. This lets us avoid taking the inode lock
while iterating over the directory contents.
Diffstat (limited to 'Kernel/FileSystem/Ext2FileSystem.cpp')
-rw-r--r-- | Kernel/FileSystem/Ext2FileSystem.cpp | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp index 9127306fda..62a245c51b 100644 --- a/Kernel/FileSystem/Ext2FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FileSystem.cpp @@ -1079,25 +1079,21 @@ Ext2FS::FeaturesReadOnly Ext2FS::get_features_readonly() const KResult Ext2FSInode::traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)> callback) const { - Locker locker(m_lock); VERIFY(is_directory()); u8 buffer[max_block_size]; auto buf = UserOrKernelBuffer::for_kernel_buffer(buffer); auto block_size = fs().block_size(); - bool allow_cache = true; - - if (m_block_list.is_empty()) - m_block_list = compute_block_list(); + auto file_size = size(); // Directory entries are guaranteed not to span multiple blocks, // so we can iterate over blocks separately. - for (auto& block_index : m_block_list) { - VERIFY(block_index.value() != 0); - if (auto result = fs().read_block(block_index, &buf, block_size, 0, allow_cache); result.is_error()) { - return result; - } + + for (u64 offset = 0; offset < file_size; offset += block_size) { + if (auto result = read_bytes(offset, block_size, buf, nullptr); result.is_error()) + return result.error(); + auto* entry = reinterpret_cast<ext2_dir_entry_2*>(buffer); auto* entries_end = reinterpret_cast<ext2_dir_entry_2*>(buffer + block_size); while (entry < entries_end) { |