1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 23:37:43 +00:00

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.
This commit is contained in:
Andreas Kling 2019-08-24 19:52:18 +02:00
parent b018cd653f
commit 5978993f00

View file

@ -153,10 +153,10 @@ ssize_t TmpFSInode::read_bytes(off_t offset, ssize_t size, u8* buffer, FileDescr
if (!m_content.has_value()) if (!m_content.has_value())
return 0; return 0;
if (static_cast<size_t>(size) > m_content.value().size() - offset) if (static_cast<off_t>(size) > m_metadata.size - offset)
size = m_content.value().size() - offset; size = m_metadata.size - offset;
memcpy(buffer, m_content.value().data(), size);
memcpy(buffer, m_content.value().data() + offset, size);
return 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); LOCKER(m_lock);
ASSERT(!is_directory()); ASSERT(!is_directory());
if (!m_content.has_value()) { off_t old_size = m_metadata.size;
ASSERT(offset == 0); off_t new_size = m_metadata.size;
m_content = KBuffer::copy(buffer, size); if ((offset + size) > new_size)
m_metadata.size = size; new_size = offset + size;
set_metadata_dirty(true);
set_metadata_dirty(false);
return size;
}
if (static_cast<size_t>(size) > m_content.value().size() - offset) { if (new_size > old_size) {
auto tmp = KBuffer::create_with_size(offset + size); if (m_content.has_value() && m_content.value().capacity() >= (size_t)new_size) {
memcpy(tmp.data(), m_content.value().data(), m_content.value().size()); m_content.value().set_size(new_size);
m_content = move(tmp); } else {
m_metadata.size = offset + size; 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(true);
set_metadata_dirty(false); set_metadata_dirty(false);
} }
memcpy(m_content.value().data() + offset, buffer, size); memcpy(m_content.value().data() + offset, buffer, size);
return size; return size;
} }
@ -283,24 +283,22 @@ KResult TmpFSInode::truncate(off_t size)
m_content.clear(); m_content.clear();
else if (!m_content.has_value()) { else if (!m_content.has_value()) {
m_content = KBuffer::create_with_size(size); 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()) { } 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); m_content.value().set_size(size);
if (prev_size < static_cast<size_t>(size)) if (prev_size < static_cast<size_t>(size))
memset(m_content.value().data() + prev_size, 0, size - prev_size); memset(m_content.value().data() + prev_size, 0, size - prev_size);
} else { } else {
size_t prev_size = m_content.value().size(); size_t prev_size = m_metadata.size;
KBuffer tmp = KBuffer::create_with_size(size); KBuffer tmp = KBuffer::create_with_size(size);
memcpy(tmp.data(), m_content.value().data(), prev_size); memcpy(tmp.data(), m_content.value().data(), prev_size);
memset(tmp.data() + prev_size, 0, size - prev_size);
m_content = move(tmp); m_content = move(tmp);
} }
size_t old_size = m_metadata.size;
m_metadata.size = size; m_metadata.size = size;
set_metadata_dirty(true); set_metadata_dirty(true);
set_metadata_dirty(false); set_metadata_dirty(false);
return KSuccess; return KSuccess;
} }