summaryrefslogtreecommitdiff
path: root/Kernel/FileSystem
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-01-09 22:05:05 +0100
committerAndreas Kling <kling@serenityos.org>2021-01-09 22:08:53 +0100
commit77656aed8e7b0b79e50f8e4f79a4b18be59e0563 (patch)
tree639a339083d99d80d89cec4b59c63bde75f6cb86 /Kernel/FileSystem
parentf0093e5d59a28e3a3493407bd38f9f8aaae87dc2 (diff)
downloadserenity-77656aed8e7b0b79e50f8e4f79a4b18be59e0563.zip
Ext2FS: Zero out new space when growing an inode
Before this change, truncating an Ext2FS inode to a larger size than it was before would give you uninitialized on-disk data. Fix this by zeroing out all the new space when doing an inode resize. This is pretty naively implemented via Inode::write_bytes() and there's lots of room for cleverness here in the future.
Diffstat (limited to 'Kernel/FileSystem')
-rw-r--r--Kernel/FileSystem/Ext2FileSystem.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp
index 429c42d720..2037c75313 100644
--- a/Kernel/FileSystem/Ext2FileSystem.cpp
+++ b/Kernel/FileSystem/Ext2FileSystem.cpp
@@ -804,6 +804,24 @@ KResult Ext2FSInode::resize(u64 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.
+ size_t bytes_to_clear = new_size - old_size;
+ size_t clear_from = old_size;
+ u8 zero_buffer[PAGE_SIZE];
+ memset(zero_buffer, 0, sizeof(zero_buffer));
+ while (bytes_to_clear) {
+ auto nwritten = write_bytes(clear_from, min(sizeof(zero_buffer), bytes_to_clear), UserOrKernelBuffer::for_kernel_buffer(zero_buffer), nullptr);
+ if (nwritten < 0)
+ return KResult(-nwritten);
+ ASSERT(nwritten != 0);
+ bytes_to_clear -= nwritten;
+ clear_from += nwritten;
+ }
+ }
+
return KSuccess;
}