diff --git a/Kernel/FileSystem/BlockBasedFileSystem.cpp b/Kernel/FileSystem/BlockBasedFileSystem.cpp index b6608d88360..8bd2e70d004 100644 --- a/Kernel/FileSystem/BlockBasedFileSystem.cpp +++ b/Kernel/FileSystem/BlockBasedFileSystem.cpp @@ -144,7 +144,9 @@ KResult BlockBasedFS::write_block(BlockIndex index, const UserOrKernelBuffer& da if (!allow_cache) { flush_specific_block_if_needed(index); u32 base_offset = index.value() * block_size() + offset; - file_description().seek(base_offset, SEEK_SET); + auto seek_result = file_description().seek(base_offset, SEEK_SET); + if (seek_result.is_error()) + return seek_result.error(); auto nwritten = file_description().write(data, count); if (nwritten.is_error()) return nwritten.error(); @@ -171,7 +173,8 @@ bool BlockBasedFS::raw_read(BlockIndex index, UserOrKernelBuffer& buffer) { LOCKER(m_lock); u32 base_offset = index.value() * m_logical_block_size; - file_description().seek(base_offset, SEEK_SET); + auto seek_result = file_description().seek(base_offset, SEEK_SET); + VERIFY(!seek_result.is_error()); auto nread = file_description().read(buffer, m_logical_block_size); VERIFY(!nread.is_error()); VERIFY(nread.value() == m_logical_block_size); @@ -182,7 +185,8 @@ bool BlockBasedFS::raw_write(BlockIndex index, const UserOrKernelBuffer& buffer) { LOCKER(m_lock); size_t base_offset = index.value() * m_logical_block_size; - file_description().seek(base_offset, SEEK_SET); + auto seek_result = file_description().seek(base_offset, SEEK_SET); + VERIFY(!seek_result.is_error()); auto nwritten = file_description().write(buffer, m_logical_block_size); VERIFY(!nwritten.is_error()); VERIFY(nwritten.value() == m_logical_block_size); @@ -236,7 +240,9 @@ KResult BlockBasedFS::read_block(BlockIndex index, UserOrKernelBuffer* buffer, s if (!allow_cache) { const_cast(this)->flush_specific_block_if_needed(index); auto base_offset = index.value() * block_size() + offset; - file_description().seek(base_offset, SEEK_SET); + auto seek_result = file_description().seek(base_offset, SEEK_SET); + if (seek_result.is_error()) + return seek_result.error(); auto nread = file_description().read(*buffer, count); if (nread.is_error()) return nread.error(); @@ -247,7 +253,9 @@ KResult BlockBasedFS::read_block(BlockIndex index, UserOrKernelBuffer* buffer, s auto& entry = cache().get(index); if (!entry.has_data) { auto base_offset = index.value() * block_size(); - file_description().seek(base_offset, SEEK_SET); + auto seek_result = file_description().seek(base_offset, SEEK_SET); + if (seek_result.is_error()) + return seek_result.error(); auto entry_data_buffer = UserOrKernelBuffer::for_kernel_buffer(entry.data); auto nread = file_description().read(entry_data_buffer, block_size()); if (nread.is_error()) @@ -288,7 +296,8 @@ void BlockBasedFS::flush_specific_block_if_needed(BlockIndex index) cache().for_each_dirty_entry([&](CacheEntry& entry) { if (entry.block_index != index) { size_t base_offset = entry.block_index.value() * block_size(); - file_description().seek(base_offset, SEEK_SET); + auto seek_result = file_description().seek(base_offset, SEEK_SET); + VERIFY(!seek_result.is_error()); // FIXME: Should this error path be surfaced somehow? auto entry_data_buffer = UserOrKernelBuffer::for_kernel_buffer(entry.data); [[maybe_unused]] auto rc = file_description().write(entry_data_buffer, block_size()); @@ -309,7 +318,8 @@ void BlockBasedFS::flush_writes_impl() u32 count = 0; cache().for_each_dirty_entry([&](CacheEntry& entry) { u32 base_offset = entry.block_index.value() * block_size(); - file_description().seek(base_offset, SEEK_SET); + auto seek_result = file_description().seek(base_offset, SEEK_SET); + VERIFY(!seek_result.is_error()); // FIXME: Should this error path be surfaced somehow? auto entry_data_buffer = UserOrKernelBuffer::for_kernel_buffer(entry.data); [[maybe_unused]] auto rc = file_description().write(entry_data_buffer, block_size()); diff --git a/Kernel/FileSystem/FileDescription.cpp b/Kernel/FileSystem/FileDescription.cpp index c499b0daa79..1c53f3007ba 100644 --- a/Kernel/FileSystem/FileDescription.cpp +++ b/Kernel/FileSystem/FileDescription.cpp @@ -126,11 +126,11 @@ KResult FileDescription::stat(::stat& buffer) return m_file->stat(buffer); } -off_t FileDescription::seek(off_t offset, int whence) +KResultOr FileDescription::seek(off_t offset, int whence) { LOCKER(m_lock); if (!m_file->is_seekable()) - return -ESPIPE; + return ESPIPE; off_t new_offset; @@ -140,21 +140,21 @@ off_t FileDescription::seek(off_t offset, int whence) break; case SEEK_CUR: if (Checked::addition_would_overflow(m_current_offset, offset)) - return -EOVERFLOW; + return EOVERFLOW; new_offset = m_current_offset + offset; break; case SEEK_END: if (!metadata().is_valid()) - return -EIO; + return EIO; new_offset = metadata().size; break; default: - return -EINVAL; + return EINVAL; } if (new_offset < 0) - return -EINVAL; - // FIXME: Return -EINVAL if attempting to seek past the end of a seekable device. + return EINVAL; + // FIXME: Return EINVAL if attempting to seek past the end of a seekable device. m_current_offset = new_offset; diff --git a/Kernel/FileSystem/FileDescription.h b/Kernel/FileSystem/FileDescription.h index df9fda57a7c..6133c4a0012 100644 --- a/Kernel/FileSystem/FileDescription.h +++ b/Kernel/FileSystem/FileDescription.h @@ -66,7 +66,7 @@ public: KResult close(); - off_t seek(off_t, int whence); + KResultOr seek(off_t, int whence); KResultOr read(UserOrKernelBuffer&, size_t); KResultOr write(const UserOrKernelBuffer& data, size_t); KResult stat(::stat&); diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 2d6cc61e8e7..2f797d0d5e3 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -559,7 +559,8 @@ KResult Process::do_exec(NonnullRefPtr main_program_description if (interpreter_description) { main_program_fd = alloc_fd(); VERIFY(main_program_fd >= 0); - main_program_description->seek(0, SEEK_SET); + auto seek_result = main_program_description->seek(0, SEEK_SET); + VERIFY(!seek_result.is_error()); main_program_description->set_readable(true); m_fds[main_program_fd].set(move(main_program_description), FD_CLOEXEC); } diff --git a/Kernel/Syscalls/lseek.cpp b/Kernel/Syscalls/lseek.cpp index 015c490c508..a00f30d35e1 100644 --- a/Kernel/Syscalls/lseek.cpp +++ b/Kernel/Syscalls/lseek.cpp @@ -38,13 +38,12 @@ KResultOr Process::sys$lseek(int fd, Userspace userspace_offset, in off_t offset; if (!copy_from_user(&offset, userspace_offset)) return EFAULT; - offset = description->seek(offset, whence); - if (!copy_to_user(userspace_offset, &offset)) + auto seek_result = description->seek(offset, whence); + if (seek_result.is_error()) + return seek_result.error(); + if (!copy_to_user(userspace_offset, &seek_result.value())) return EFAULT; - if (offset < 0) - return offset; - else - return 0; + return KSuccess; } } diff --git a/Kernel/Syscalls/write.cpp b/Kernel/Syscalls/write.cpp index c279592d7e7..25435576383 100644 --- a/Kernel/Syscalls/write.cpp +++ b/Kernel/Syscalls/write.cpp @@ -84,8 +84,11 @@ KResultOr Process::do_write(FileDescription& description, const UserOrK return EAGAIN; } - if (description.should_append()) - description.seek(0, SEEK_END); + if (description.should_append()) { + auto seek_result = description.seek(0, SEEK_END); + if (seek_result.is_error()) + return seek_result.error(); + } while ((size_t)total_nwritten < data_size) { if (!description.can_write()) {