diff options
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/FileSystem/Ext2FileSystem.cpp | 93 | ||||
-rw-r--r-- | Kernel/FileSystem/Ext2FileSystem.h | 3 |
2 files changed, 46 insertions, 50 deletions
diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp index 8995f4acb8..21bd4b0ecf 100644 --- a/Kernel/FileSystem/Ext2FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FileSystem.cpp @@ -230,68 +230,68 @@ Ext2FS::BlockListShape Ext2FS::compute_block_list_shape(unsigned blocks) const return shape; } -KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e2inode, const Vector<BlockIndex>& blocks) +KResult Ext2FSInode::flush_block_list() { LOCKER(m_lock); - if (blocks.is_empty()) { - e2inode.i_blocks = 0; - memset(e2inode.i_block, 0, sizeof(e2inode.i_block)); - write_ext2_inode(inode_index, e2inode); + if (m_block_list.is_empty()) { + m_raw_inode.i_blocks = 0; + memset(m_raw_inode.i_block, 0, sizeof(m_raw_inode.i_block)); + fs().write_ext2_inode(index(), m_raw_inode); return KSuccess; } // NOTE: There is a mismatch between i_blocks and blocks.size() since i_blocks includes meta blocks and blocks.size() does not. - auto old_block_count = ceil_div(static_cast<size_t>(e2inode.i_size), block_size()); + auto old_block_count = ceil_div(static_cast<size_t>(m_raw_inode.i_size), fs().block_size()); - auto old_shape = compute_block_list_shape(old_block_count); - auto new_shape = compute_block_list_shape(blocks.size()); + auto old_shape = fs().compute_block_list_shape(old_block_count); + auto new_shape = fs().compute_block_list_shape(m_block_list.size()); - Vector<BlockIndex> new_meta_blocks; + Vector<Ext2FS::BlockIndex> new_meta_blocks; if (new_shape.meta_blocks > old_shape.meta_blocks) { - auto blocks_or_error = allocate_blocks(group_index_from_inode(inode_index), new_shape.meta_blocks - old_shape.meta_blocks); + auto blocks_or_error = fs().allocate_blocks(fs().group_index_from_inode(index()), new_shape.meta_blocks - old_shape.meta_blocks); if (blocks_or_error.is_error()) return blocks_or_error.error(); new_meta_blocks = blocks_or_error.release_value(); } - e2inode.i_blocks = (blocks.size() + new_shape.meta_blocks) * (block_size() / 512); + m_raw_inode.i_blocks = (m_block_list.size() + new_shape.meta_blocks) * (fs().block_size() / 512); bool inode_dirty = false; unsigned output_block_index = 0; - unsigned remaining_blocks = blocks.size(); + unsigned remaining_blocks = m_block_list.size(); for (unsigned i = 0; i < new_shape.direct_blocks; ++i) { - if (e2inode.i_block[i] != blocks[output_block_index]) + if (m_raw_inode.i_block[i] != m_block_list[output_block_index]) inode_dirty = true; - e2inode.i_block[i] = blocks[output_block_index].value(); + m_raw_inode.i_block[i] = m_block_list[output_block_index].value(); ++output_block_index; --remaining_blocks; } if (inode_dirty) { if constexpr (EXT2_DEBUG) { - dbgln("Ext2FS: Writing {} direct block(s) to i_block array of inode {}", min((size_t)EXT2_NDIR_BLOCKS, blocks.size()), inode_index); - for (size_t i = 0; i < min((size_t)EXT2_NDIR_BLOCKS, blocks.size()); ++i) - dbgln(" + {}", blocks[i]); + dbgln("Ext2FS: Writing {} direct block(s) to i_block array of inode {}", min((size_t)EXT2_NDIR_BLOCKS, m_block_list.size()), index()); + for (size_t i = 0; i < min((size_t)EXT2_NDIR_BLOCKS, m_block_list.size()); ++i) + dbgln(" + {}", m_block_list[i]); } - write_ext2_inode(inode_index, e2inode); + fs().write_ext2_inode(index(), m_raw_inode); inode_dirty = false; } if (!remaining_blocks) return KSuccess; - const unsigned entries_per_block = EXT2_ADDR_PER_BLOCK(&super_block()); + const unsigned entries_per_block = EXT2_ADDR_PER_BLOCK(&fs().super_block()); - bool ind_block_new = !e2inode.i_block[EXT2_IND_BLOCK]; + bool ind_block_new = !m_raw_inode.i_block[EXT2_IND_BLOCK]; if (ind_block_new) { - BlockIndex new_indirect_block = new_meta_blocks.take_last(); - if (e2inode.i_block[EXT2_IND_BLOCK] != new_indirect_block) + Ext2FS::BlockIndex new_indirect_block = new_meta_blocks.take_last(); + if (m_raw_inode.i_block[EXT2_IND_BLOCK] != new_indirect_block) inode_dirty = true; - e2inode.i_block[EXT2_IND_BLOCK] = new_indirect_block.value(); + m_raw_inode.i_block[EXT2_IND_BLOCK] = new_indirect_block.value(); if (inode_dirty) { - dbgln_if(EXT2_DEBUG, "Ext2FS: Adding the indirect block to i_block array of inode {}", inode_index); - write_ext2_inode(inode_index, e2inode); + dbgln_if(EXT2_DEBUG, "Ext2FS: Adding the indirect block to i_block array of inode {}", index()); + fs().write_ext2_inode(index(), m_raw_inode); inode_dirty = false; } } @@ -301,19 +301,19 @@ KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e remaining_blocks -= new_shape.indirect_blocks; output_block_index += new_shape.indirect_blocks; } else { - auto block_contents = ByteBuffer::create_uninitialized(block_size()); + auto block_contents = ByteBuffer::create_uninitialized(fs().block_size()); OutputMemoryStream stream { block_contents }; VERIFY(new_shape.indirect_blocks <= entries_per_block); for (unsigned i = 0; i < new_shape.indirect_blocks; ++i) { - stream << blocks[output_block_index++].value(); + stream << m_block_list[output_block_index++].value(); --remaining_blocks; } stream.fill_to_end(0); auto buffer = UserOrKernelBuffer::for_kernel_buffer(stream.data()); - auto result = write_block(e2inode.i_block[EXT2_IND_BLOCK], buffer, stream.size()); + auto result = fs().write_block(m_raw_inode.i_block[EXT2_IND_BLOCK], buffer, stream.size()); if (result.is_error()) return result; } @@ -323,15 +323,15 @@ KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e bool dind_block_dirty = false; - bool dind_block_new = !e2inode.i_block[EXT2_DIND_BLOCK]; + bool dind_block_new = !m_raw_inode.i_block[EXT2_DIND_BLOCK]; if (dind_block_new) { - BlockIndex new_dindirect_block = new_meta_blocks.take_last(); - if (e2inode.i_block[EXT2_DIND_BLOCK] != new_dindirect_block) + Ext2FS::BlockIndex new_dindirect_block = new_meta_blocks.take_last(); + if (m_raw_inode.i_block[EXT2_DIND_BLOCK] != new_dindirect_block) inode_dirty = true; - e2inode.i_block[EXT2_DIND_BLOCK] = new_dindirect_block.value(); + m_raw_inode.i_block[EXT2_DIND_BLOCK] = new_dindirect_block.value(); if (inode_dirty) { - dbgln_if(EXT2_DEBUG, "Ext2FS: Adding the doubly-indirect block to i_block array of inode {}", inode_index); - write_ext2_inode(inode_index, e2inode); + dbgln_if(EXT2_DEBUG, "Ext2FS: Adding the doubly-indirect block to i_block array of inode {}", index()); + fs().write_ext2_inode(index(), m_raw_inode); inode_dirty = false; } } @@ -343,13 +343,13 @@ KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e } else { unsigned indirect_block_count = divide_rounded_up(new_shape.doubly_indirect_blocks, entries_per_block); - auto dind_block_contents = ByteBuffer::create_uninitialized(block_size()); + auto dind_block_contents = ByteBuffer::create_uninitialized(fs().block_size()); if (dind_block_new) { dind_block_contents.zero_fill(); dind_block_dirty = true; } else { auto buffer = UserOrKernelBuffer::for_kernel_buffer(dind_block_contents.data()); - auto result = read_block(e2inode.i_block[EXT2_DIND_BLOCK], &buffer, block_size()); + auto result = fs().read_block(m_raw_inode.i_block[EXT2_DIND_BLOCK], &buffer, fs().block_size()); if (result.is_error()) { dbgln("Ext2FS: write_block_list_for_inode had error: {}", result.error()); return result; @@ -361,7 +361,7 @@ KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e for (unsigned i = 0; i < indirect_block_count; ++i) { bool ind_block_dirty = false; - BlockIndex indirect_block_index = dind_block_as_pointers[i]; + Ext2FS::BlockIndex indirect_block_index = dind_block_as_pointers[i]; bool ind_block_new = !indirect_block_index; if (ind_block_new) { @@ -370,13 +370,13 @@ KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e dind_block_dirty = true; } - auto ind_block_contents = ByteBuffer::create_uninitialized(block_size()); + auto ind_block_contents = ByteBuffer::create_uninitialized(fs().block_size()); if (ind_block_new) { ind_block_contents.zero_fill(); ind_block_dirty = true; } else { auto buffer = UserOrKernelBuffer::for_kernel_buffer(ind_block_contents.data()); - auto result = read_block(indirect_block_index, &buffer, block_size()); + auto result = fs().read_block(indirect_block_index, &buffer, fs().block_size()); if (result.is_error()) { dbgln("Ext2FS: write_block_list_for_inode had error: {}", result.error()); return result; @@ -390,7 +390,7 @@ KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e VERIFY(entries_to_write <= entries_per_block); for (unsigned j = 0; j < entries_to_write; ++j) { - BlockIndex output_block = blocks[output_block_index++]; + Ext2FS::BlockIndex output_block = m_block_list[output_block_index++]; if (ind_block_as_pointers[j] != output_block) { ind_block_as_pointers[j] = output_block.value(); ind_block_dirty = true; @@ -406,7 +406,7 @@ KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e if (ind_block_dirty) { auto buffer = UserOrKernelBuffer::for_kernel_buffer(ind_block_contents.data()); - int err = write_block(indirect_block_index, buffer, block_size()); + int err = fs().write_block(indirect_block_index, buffer, fs().block_size()); VERIFY(err >= 0); } } @@ -419,7 +419,7 @@ KResult Ext2FS::write_block_list_for_inode(InodeIndex inode_index, ext2_inode& e if (dind_block_dirty) { auto buffer = UserOrKernelBuffer::for_kernel_buffer(dind_block_contents.data()); - int err = write_block(e2inode.i_block[EXT2_DIND_BLOCK], buffer, block_size()); + int err = fs().write_block(m_raw_inode.i_block[EXT2_DIND_BLOCK], buffer, fs().block_size()); VERIFY(err >= 0); } } @@ -733,8 +733,6 @@ ssize_t Ext2FSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer& return nread; } - Locker fs_locker(fs().m_lock); - if (m_block_list.is_empty()) m_block_list = fs().block_list_for_inode(m_raw_inode); @@ -828,15 +826,15 @@ KResult Ext2FSInode::resize(u64 new_size) } } - auto result = fs().write_block_list_for_inode(index(), m_raw_inode, block_list); + m_block_list = move(block_list); + + auto result = flush_block_list(); if (result.is_error()) return result; m_raw_inode.i_size = new_size; set_metadata_dirty(true); - m_block_list = move(block_list); - if (new_size > old_size) { // If we're growing the inode, make sure we zero out all the new space. // FIXME: There are definitely more efficient ways to achieve this. @@ -862,7 +860,6 @@ ssize_t Ext2FSInode::write_bytes(off_t offset, ssize_t count, const UserOrKernel VERIFY(count >= 0); Locker inode_locker(m_lock); - Locker fs_locker(fs().m_lock); auto result = prepare_to_write_data(); if (result.is_error()) diff --git a/Kernel/FileSystem/Ext2FileSystem.h b/Kernel/FileSystem/Ext2FileSystem.h index 8a96195729..65a83afde3 100644 --- a/Kernel/FileSystem/Ext2FileSystem.h +++ b/Kernel/FileSystem/Ext2FileSystem.h @@ -76,12 +76,12 @@ private: virtual KResult chmod(mode_t) override; virtual KResult chown(uid_t, gid_t) override; virtual KResult truncate(u64) override; - virtual KResultOr<int> get_block_address(int) override; KResult write_directory(const Vector<Ext2FSDirectoryEntry>&); bool populate_lookup_cache() const; KResult resize(u64); + KResult flush_block_list(); Ext2FS& fs(); const Ext2FS& fs() const; @@ -147,7 +147,6 @@ private: Vector<BlockIndex> block_list_for_inode_impl(const ext2_inode&, bool include_block_list_blocks = false) const; Vector<BlockIndex> block_list_for_inode(const ext2_inode&, bool include_block_list_blocks = false) const; - KResult write_block_list_for_inode(InodeIndex, ext2_inode&, const Vector<BlockIndex>&); KResultOr<bool> get_inode_allocation_state(InodeIndex) const; KResult set_inode_allocation_state(InodeIndex, bool); |