summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-08-24 19:52:18 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-08-24 19:58:09 +0200
commit5978993f00290036a68dee4c4f76e37579703828 (patch)
treea4873c9adc71b9d9ebe3fdabf2d5b99a62e214e3
parentb018cd653fe18fb73a4518d7d28c4cf7614e4c85 (diff)
downloadserenity-5978993f00290036a68dee4c4f76e37579703828.zip
TmpFS: Fix two bugs that broke GCC inside Serenity
- TmpFSInode::write_bytes() needs to allow non-zero offsets - TmpFSInode::read_bytes() wasn't respecting the offset GCC puts the temporary files generated during compilation in /tmp, so this exposed some bugs in TmpFS.
-rw-r--r--Kernel/FileSystem/TmpFS.cpp44
1 files changed, 21 insertions, 23 deletions
diff --git a/Kernel/FileSystem/TmpFS.cpp b/Kernel/FileSystem/TmpFS.cpp
index 4b0281ecfb..65b48b608f 100644
--- a/Kernel/FileSystem/TmpFS.cpp
+++ b/Kernel/FileSystem/TmpFS.cpp
@@ -153,10 +153,10 @@ ssize_t TmpFSInode::read_bytes(off_t offset, ssize_t size, u8* buffer, FileDescr
if (!m_content.has_value())
return 0;
- if (static_cast<size_t>(size) > m_content.value().size() - offset)
- size = m_content.value().size() - offset;
- memcpy(buffer, m_content.value().data(), size);
+ if (static_cast<off_t>(size) > m_metadata.size - offset)
+ size = m_metadata.size - offset;
+ memcpy(buffer, m_content.value().data() + offset, size);
return size;
}
@@ -165,26 +165,26 @@ ssize_t TmpFSInode::write_bytes(off_t offset, ssize_t size, const u8* buffer, Fi
LOCKER(m_lock);
ASSERT(!is_directory());
- if (!m_content.has_value()) {
- ASSERT(offset == 0);
- m_content = KBuffer::copy(buffer, size);
- m_metadata.size = size;
- set_metadata_dirty(true);
- set_metadata_dirty(false);
- return size;
- }
-
- if (static_cast<size_t>(size) > m_content.value().size() - offset) {
- auto tmp = KBuffer::create_with_size(offset + size);
- memcpy(tmp.data(), m_content.value().data(), m_content.value().size());
- m_content = move(tmp);
- m_metadata.size = offset + size;
+ off_t old_size = m_metadata.size;
+ off_t new_size = m_metadata.size;
+ if ((offset + size) > new_size)
+ new_size = offset + size;
+
+ if (new_size > old_size) {
+ if (m_content.has_value() && m_content.value().capacity() >= (size_t)new_size) {
+ m_content.value().set_size(new_size);
+ } else {
+ auto tmp = KBuffer::create_with_size(new_size);
+ if (m_content.has_value())
+ memcpy(tmp.data(), m_content.value().data(), old_size);
+ m_content = move(tmp);
+ }
+ m_metadata.size = new_size;
set_metadata_dirty(true);
set_metadata_dirty(false);
}
memcpy(m_content.value().data() + offset, buffer, size);
-
return size;
}
@@ -283,24 +283,22 @@ KResult TmpFSInode::truncate(off_t size)
m_content.clear();
else if (!m_content.has_value()) {
m_content = KBuffer::create_with_size(size);
- memset(m_content.value().data(), 0, size);
} else if (static_cast<size_t>(size) < m_content.value().capacity()) {
- size_t prev_size = m_content.value().size();
+ size_t prev_size = m_metadata.size;
m_content.value().set_size(size);
if (prev_size < static_cast<size_t>(size))
memset(m_content.value().data() + prev_size, 0, size - prev_size);
} else {
- size_t prev_size = m_content.value().size();
+ size_t prev_size = m_metadata.size;
KBuffer tmp = KBuffer::create_with_size(size);
memcpy(tmp.data(), m_content.value().data(), prev_size);
- memset(tmp.data() + prev_size, 0, size - prev_size);
m_content = move(tmp);
}
+ size_t old_size = m_metadata.size;
m_metadata.size = size;
set_metadata_dirty(true);
set_metadata_dirty(false);
-
return KSuccess;
}