瀏覽代碼

Kernel: Move KBufferBuilder to the fallible KBuffer API

KBufferBuilder::build() now returns an OwnPtr<KBuffer> and can fail.
Clients of the API have been updated to handle that situation.
Andreas Kling 4 年之前
父節點
當前提交
8e79bde2b7

+ 1 - 1
Kernel/FileSystem/Ext2FileSystem.cpp

@@ -928,7 +928,7 @@ KResult Ext2FSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
     if (buffer_or.is_error())
         return buffer_or.error();
 
-    auto buffer = buffer_or.value();
+    auto& buffer = *buffer_or.value();
     auto* entry = reinterpret_cast<ext2_dir_entry_2*>(buffer.data());
 
     while (entry < buffer.end_pointer()) {

+ 1 - 1
Kernel/FileSystem/FileDescription.cpp

@@ -179,7 +179,7 @@ bool FileDescription::can_read() const
     return m_file->can_read(*this, offset());
 }
 
-KResultOr<KBuffer> FileDescription::read_entire_file()
+KResultOr<NonnullOwnPtr<KBuffer>> FileDescription::read_entire_file()
 {
     // HACK ALERT: (This entire function)
     ASSERT(m_file->is_inode());

+ 3 - 3
Kernel/FileSystem/FileDescription.h

@@ -73,7 +73,7 @@ public:
 
     ssize_t get_dir_entries(UserOrKernelBuffer& buffer, ssize_t);
 
-    KResultOr<KBuffer> read_entire_file();
+    KResultOr<NonnullOwnPtr<KBuffer>> read_entire_file();
 
     String absolute_path() const;
 
@@ -122,7 +122,7 @@ public:
     FIFO::Direction fifo_direction() { return m_fifo_direction; }
     void set_fifo_direction(Badge<FIFO>, FIFO::Direction direction) { m_fifo_direction = direction; }
 
-    Optional<KBuffer>& generator_cache() { return m_generator_cache; }
+    OwnPtr<KBuffer>& generator_cache() { return m_generator_cache; }
 
     void set_original_inode(Badge<VFS>, NonnullRefPtr<Inode>&& inode) { m_inode = move(inode); }
 
@@ -150,7 +150,7 @@ private:
 
     off_t m_current_offset { 0 };
 
-    Optional<KBuffer> m_generator_cache;
+    OwnPtr<KBuffer> m_generator_cache;
 
     u32 m_file_flags { 0 };
 

+ 6 - 3
Kernel/FileSystem/Inode.cpp

@@ -71,7 +71,7 @@ void Inode::sync()
     }
 }
 
-KResultOr<KBuffer> Inode::read_entire(FileDescription* descriptor) const
+KResultOr<NonnullOwnPtr<KBuffer>> Inode::read_entire(FileDescription* descriptor) const
 {
     KBufferBuilder builder;
 
@@ -96,7 +96,10 @@ KResultOr<KBuffer> Inode::read_entire(FileDescription* descriptor) const
         return KResult(nread);
     }
 
-    return builder.build();
+    auto entire_file = builder.build();
+    if (!entire_file)
+        return KResult(-ENOMEM);
+    return entire_file.release_nonnull();
 }
 
 KResultOr<NonnullRefPtr<Custody>> Inode::resolve_as_link(Custody& base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level) const
@@ -109,7 +112,7 @@ KResultOr<NonnullRefPtr<Custody>> Inode::resolve_as_link(Custody& base, RefPtr<C
         return contents_or.error();
 
     auto& contents = contents_or.value();
-    auto path = StringView(contents.data(), contents.size());
+    auto path = StringView(contents->data(), contents->size());
     return VFS::the().resolve_path(path, base, out_parent, options, symlink_recursion_level);
 }
 

+ 1 - 1
Kernel/FileSystem/Inode.h

@@ -67,7 +67,7 @@ public:
     InodeIdentifier identifier() const { return { fsid(), index() }; }
     virtual InodeMetadata metadata() const = 0;
 
-    KResultOr<KBuffer> read_entire(FileDescription* = nullptr) const;
+    KResultOr<NonnullOwnPtr<KBuffer>> read_entire(FileDescription* = nullptr) const;
 
     virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const = 0;
     virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const = 0;

+ 21 - 16
Kernel/FileSystem/Plan9FileSystem.cpp

@@ -185,7 +185,7 @@ public:
     u16 tag() const { return m_tag; }
 
     Message(Plan9FS&, Type);
-    Message(KBuffer&&);
+    Message(NonnullOwnPtr<KBuffer>&&);
     ~Message();
     Message& operator=(Message&&);
 
@@ -205,7 +205,7 @@ private:
     union {
         KBufferBuilder m_builder;
         struct {
-            KBuffer buffer;
+            NonnullOwnPtr<KBuffer> buffer;
             Decoder decoder;
         } m_built;
     };
@@ -356,8 +356,8 @@ Plan9FS::Message::Message(Plan9FS& fs, Type type)
     *this << size_placeholder << (u8)type << m_tag;
 }
 
-Plan9FS::Message::Message(KBuffer&& buffer)
-    : m_built { buffer, Decoder({ buffer.data(), buffer.size() }) }
+Plan9FS::Message::Message(NonnullOwnPtr<KBuffer>&& buffer)
+    : m_built { move(buffer), Decoder({ buffer->data(), buffer->size() }) }
     , m_have_been_built(true)
 {
     u32 size;
@@ -369,7 +369,7 @@ Plan9FS::Message::Message(KBuffer&& buffer)
 Plan9FS::Message::~Message()
 {
     if (m_have_been_built) {
-        m_built.buffer.~KBuffer();
+        m_built.buffer.~NonnullOwnPtr<KBuffer>();
         m_built.decoder.~Decoder();
     } else {
         m_builder.~KBufferBuilder();
@@ -382,7 +382,7 @@ Plan9FS::Message& Plan9FS::Message::operator=(Message&& message)
     m_type = message.m_type;
 
     if (m_have_been_built) {
-        m_built.buffer.~KBuffer();
+        m_built.buffer.~NonnullOwnPtr<KBuffer>();
         m_built.decoder.~Decoder();
     } else {
         m_builder.~KBufferBuilder();
@@ -390,7 +390,7 @@ Plan9FS::Message& Plan9FS::Message::operator=(Message&& message)
 
     m_have_been_built = message.m_have_been_built;
     if (m_have_been_built) {
-        new (&m_built.buffer) KBuffer(move(message.m_built.buffer));
+        new (&m_built.buffer) NonnullOwnPtr<KBuffer>(move(message.m_built.buffer));
         new (&m_built.decoder) Decoder(move(message.m_built.decoder));
     } else {
         new (&m_builder) KBufferBuilder(move(message.m_builder));
@@ -405,14 +405,17 @@ const KBuffer& Plan9FS::Message::build()
 
     auto tmp_buffer = m_builder.build();
 
+    // FIXME: We should not assume success here.
+    ASSERT(tmp_buffer);
+
     m_have_been_built = true;
     m_builder.~KBufferBuilder();
 
-    new (&m_built.buffer) KBuffer(move(tmp_buffer));
-    new (&m_built.decoder) Decoder({ m_built.buffer.data(), m_built.buffer.size() });
-    u32* size = reinterpret_cast<u32*>(m_built.buffer.data());
-    *size = m_built.buffer.size();
-    return m_built.buffer;
+    new (&m_built.buffer) NonnullOwnPtr<KBuffer>(tmp_buffer.release_nonnull());
+    new (&m_built.decoder) Decoder({ m_built.buffer->data(), m_built.buffer->size() });
+    u32* size = reinterpret_cast<u32*>(m_built.buffer->data());
+    *size = m_built.buffer->size();
+    return *m_built.buffer;
 }
 
 Plan9FS::ReceiveCompletion::ReceiveCompletion(u16 tag)
@@ -578,10 +581,12 @@ KResult Plan9FS::read_and_dispatch_one_message()
     if (result.is_error())
         return result;
 
-    auto buffer = KBuffer::create_with_size(header.size, Region::Access::Read | Region::Access::Write);
+    auto buffer = KBuffer::try_create_with_size(header.size, Region::Access::Read | Region::Access::Write);
+    if (!buffer)
+        return KResult(-ENOMEM);
     // Copy the already read header into the buffer.
-    memcpy(buffer.data(), &header, sizeof(header));
-    result = do_read(buffer.data() + sizeof(header), header.size - sizeof(header));
+    memcpy(buffer->data(), &header, sizeof(header));
+    result = do_read(buffer->data() + sizeof(header), header.size - sizeof(header));
     if (result.is_error())
         return result;
 
@@ -592,7 +597,7 @@ KResult Plan9FS::read_and_dispatch_one_message()
         auto completion = optional_completion.value();
         ScopedSpinLock lock(completion->lock);
         completion->result = KSuccess;
-        completion->message = new Message { move(buffer) };
+        completion->message = new Message { buffer.release_nonnull() };
         completion->completed = true;
 
         m_completions.remove(header.tag);

+ 53 - 52
Kernel/FileSystem/ProcFS.cpp

@@ -262,7 +262,7 @@ ProcFS::~ProcFS()
 {
 }
 
-static Optional<KBuffer> procfs$pid_fds(InodeIdentifier identifier)
+static OwnPtr<KBuffer> procfs$pid_fds(InodeIdentifier identifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -298,7 +298,7 @@ static Optional<KBuffer> procfs$pid_fds(InodeIdentifier identifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$pid_fd_entry(InodeIdentifier identifier)
+static OwnPtr<KBuffer> procfs$pid_fd_entry(InodeIdentifier identifier)
 {
     auto process = Process::from_pid(to_pid(identifier));
     if (!process)
@@ -307,10 +307,10 @@ static Optional<KBuffer> procfs$pid_fd_entry(InodeIdentifier identifier)
     auto description = process->file_description(fd);
     if (!description)
         return {};
-    return description->absolute_path().to_byte_buffer();
+    return KBuffer::try_create_with_bytes(description->absolute_path().bytes());
 }
 
-static Optional<KBuffer> procfs$pid_vm(InodeIdentifier identifier)
+static OwnPtr<KBuffer> procfs$pid_vm(InodeIdentifier identifier)
 {
     auto process = Process::from_pid(to_pid(identifier));
     if (!process)
@@ -359,7 +359,7 @@ static Optional<KBuffer> procfs$pid_vm(InodeIdentifier identifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$pci(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$pci(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -381,7 +381,7 @@ static Optional<KBuffer> procfs$pci(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$interrupts(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$interrupts(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -398,7 +398,7 @@ static Optional<KBuffer> procfs$interrupts(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$keymap(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$keymap(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonObjectSerializer<KBufferBuilder> json { builder };
@@ -407,7 +407,7 @@ static Optional<KBuffer> procfs$keymap(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$devices(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$devices(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -428,14 +428,14 @@ static Optional<KBuffer> procfs$devices(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$uptime(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$uptime(InodeIdentifier)
 {
     KBufferBuilder builder;
     builder.appendf("%llu\n", TimeManagement::the().uptime_ms() / 1000);
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$cmdline(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$cmdline(InodeIdentifier)
 {
     KBufferBuilder builder;
     builder.append(kernel_command_line().string());
@@ -443,7 +443,7 @@ static Optional<KBuffer> procfs$cmdline(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$modules(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$modules(InodeIdentifier)
 {
     extern HashMap<String, OwnPtr<Module>>* g_modules;
     KBufferBuilder builder;
@@ -463,7 +463,7 @@ static Optional<KBuffer> procfs$modules(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$profile(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$profile(InodeIdentifier)
 {
     InterruptDisabler disabler;
     KBufferBuilder builder;
@@ -495,7 +495,7 @@ static Optional<KBuffer> procfs$profile(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$net_adapters(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$net_adapters(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -521,7 +521,7 @@ static Optional<KBuffer> procfs$net_adapters(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$net_arp(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$net_arp(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -535,7 +535,7 @@ static Optional<KBuffer> procfs$net_arp(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$net_tcp(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$net_tcp(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -557,7 +557,7 @@ static Optional<KBuffer> procfs$net_tcp(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$net_udp(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$net_udp(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -572,7 +572,7 @@ static Optional<KBuffer> procfs$net_udp(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$net_local(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$net_local(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -590,7 +590,7 @@ static Optional<KBuffer> procfs$net_local(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$pid_vmobjects(InodeIdentifier identifier)
+static OwnPtr<KBuffer> procfs$pid_vmobjects(InodeIdentifier identifier)
 {
     auto process = Process::from_pid(to_pid(identifier));
     if (!process)
@@ -625,7 +625,7 @@ static Optional<KBuffer> procfs$pid_vmobjects(InodeIdentifier identifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$pid_unveil(InodeIdentifier identifier)
+static OwnPtr<KBuffer> procfs$pid_unveil(InodeIdentifier identifier)
 {
     auto process = Process::from_pid(to_pid(identifier));
     if (!process)
@@ -652,7 +652,7 @@ static Optional<KBuffer> procfs$pid_unveil(InodeIdentifier identifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$tid_stack(InodeIdentifier identifier)
+static OwnPtr<KBuffer> procfs$tid_stack(InodeIdentifier identifier)
 {
     auto thread = Thread::from_tid(to_tid(identifier));
     if (!thread)
@@ -663,40 +663,40 @@ static Optional<KBuffer> procfs$tid_stack(InodeIdentifier identifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$pid_exe(InodeIdentifier identifier)
+static OwnPtr<KBuffer> procfs$pid_exe(InodeIdentifier identifier)
 {
     auto process = Process::from_pid(to_pid(identifier));
     if (!process)
         return {};
     auto* custody = process->executable();
     ASSERT(custody);
-    return custody->absolute_path().to_byte_buffer();
+    return KBuffer::try_create_with_bytes(custody->absolute_path().bytes());
 }
 
-static Optional<KBuffer> procfs$pid_cwd(InodeIdentifier identifier)
+static OwnPtr<KBuffer> procfs$pid_cwd(InodeIdentifier identifier)
 {
     auto process = Process::from_pid(to_pid(identifier));
     if (!process)
         return {};
-    return process->current_directory().absolute_path().to_byte_buffer();
+    return KBuffer::try_create_with_bytes(process->current_directory().absolute_path().bytes());
 }
 
-static Optional<KBuffer> procfs$pid_root(InodeIdentifier identifier)
+static OwnPtr<KBuffer> procfs$pid_root(InodeIdentifier identifier)
 {
     auto process = Process::from_pid(to_pid(identifier));
     if (!process)
         return {};
-    return process->root_directory_relative_to_global_root().absolute_path().to_byte_buffer();
+    return KBuffer::try_create_with_bytes(process->root_directory_relative_to_global_root().absolute_path().to_byte_buffer());
 }
 
-static Optional<KBuffer> procfs$self(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$self(InodeIdentifier)
 {
     char buffer[16];
     int written = snprintf(buffer, sizeof(buffer), "%d", Process::current()->pid().value());
-    return KBuffer::copy((const u8*)buffer, static_cast<size_t>(written));
+    return KBuffer::try_create_with_bytes(ReadonlyBytes { buffer, static_cast<size_t>(written) });
 }
 
-Optional<KBuffer> procfs$mm(InodeIdentifier)
+OwnPtr<KBuffer> procfs$mm(InodeIdentifier)
 {
     InterruptDisabler disabler;
     KBufferBuilder builder;
@@ -716,7 +716,7 @@ Optional<KBuffer> procfs$mm(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$dmesg(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$dmesg(InodeIdentifier)
 {
     InterruptDisabler disabler;
     KBufferBuilder builder;
@@ -725,7 +725,7 @@ static Optional<KBuffer> procfs$dmesg(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$mounts(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$mounts(InodeIdentifier)
 {
     // FIXME: This is obviously racy against the VFS mounts changing.
     KBufferBuilder builder;
@@ -744,7 +744,7 @@ static Optional<KBuffer> procfs$mounts(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$df(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$df(InodeIdentifier)
 {
     // FIXME: This is obviously racy against the VFS mounts changing.
     KBufferBuilder builder;
@@ -771,7 +771,7 @@ static Optional<KBuffer> procfs$df(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$cpuinfo(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$cpuinfo(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -796,7 +796,7 @@ static Optional<KBuffer> procfs$cpuinfo(InodeIdentifier)
     return builder.build();
 }
 
-Optional<KBuffer> procfs$memstat(InodeIdentifier)
+OwnPtr<KBuffer> procfs$memstat(InodeIdentifier)
 {
     InterruptDisabler disabler;
 
@@ -823,7 +823,7 @@ Optional<KBuffer> procfs$memstat(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$all(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$all(InodeIdentifier)
 {
     KBufferBuilder builder;
     JsonArraySerializer array { builder };
@@ -912,7 +912,7 @@ static Optional<KBuffer> procfs$all(InodeIdentifier)
     return builder.build();
 }
 
-static Optional<KBuffer> procfs$inodes(InodeIdentifier)
+static OwnPtr<KBuffer> procfs$inodes(InodeIdentifier)
 {
     KBufferBuilder builder;
     InterruptDisabler disabler;
@@ -964,19 +964,19 @@ SysVariable& SysVariable::for_inode(InodeIdentifier id)
     return variable;
 }
 
-static Optional<KBuffer> read_sys_bool(InodeIdentifier inode_id)
+static OwnPtr<KBuffer> read_sys_bool(InodeIdentifier inode_id)
 {
     auto& variable = SysVariable::for_inode(inode_id);
     ASSERT(variable.type == SysVariable::Type::Boolean);
 
-    auto buffer = ByteBuffer::create_uninitialized(2);
+    u8 buffer[2];
     auto* lockable_bool = reinterpret_cast<Lockable<bool>*>(variable.address);
     {
         LOCKER(lockable_bool->lock(), Lock::Mode::Shared);
         buffer[0] = lockable_bool->resource() ? '1' : '0';
     }
     buffer[1] = '\n';
-    return buffer;
+    return KBuffer::try_create_with_bytes(ReadonlyBytes { buffer, sizeof(buffer) });
 }
 
 static ssize_t write_sys_bool(InodeIdentifier inode_id, const UserOrKernelBuffer& buffer, size_t size)
@@ -1008,14 +1008,14 @@ static ssize_t write_sys_bool(InodeIdentifier inode_id, const UserOrKernelBuffer
     return (ssize_t)size;
 }
 
-static Optional<KBuffer> read_sys_string(InodeIdentifier inode_id)
+static OwnPtr<KBuffer> read_sys_string(InodeIdentifier inode_id)
 {
     auto& variable = SysVariable::for_inode(inode_id);
     ASSERT(variable.type == SysVariable::Type::String);
 
     auto* lockable_string = reinterpret_cast<Lockable<String>*>(variable.address);
     LOCKER(lockable_string->lock(), Lock::Mode::Shared);
-    return lockable_string->resource().to_byte_buffer();
+    return KBuffer::try_create_with_bytes(lockable_string->resource().bytes());
 }
 
 static ssize_t write_sys_string(InodeIdentifier inode_id, const UserOrKernelBuffer& buffer, size_t size)
@@ -1209,7 +1209,7 @@ ssize_t ProcFSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer&
 
     auto* directory_entry = fs().get_directory_entry(identifier());
 
-    Optional<KBuffer> (*read_callback)(InodeIdentifier) = nullptr;
+    OwnPtr<KBuffer> (*read_callback)(InodeIdentifier) = nullptr;
     if (directory_entry)
         read_callback = directory_entry->read_callback;
     else
@@ -1238,26 +1238,27 @@ ssize_t ProcFSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer&
 
     ASSERT(read_callback);
 
-    Optional<KBuffer> generated_data;
+    OwnPtr<KBuffer> descriptionless_generated_data;
+    KBuffer* data = nullptr;
     if (!description) {
-        generated_data = read_callback(identifier());
+        descriptionless_generated_data = read_callback(identifier());
+        data = descriptionless_generated_data.ptr();
     } else {
-        if (!description->generator_cache().has_value())
+        if (!description->generator_cache())
             description->generator_cache() = (*read_callback)(identifier());
-        generated_data = description->generator_cache();
+        data = description->generator_cache().ptr();
     }
 
-    auto& data = generated_data;
-    if (!data.has_value())
+    if (!data)
         return 0;
 
-    if ((size_t)offset >= data.value().size())
+    if ((size_t)offset >= data->size())
         return 0;
 
-    ssize_t nread = min(static_cast<off_t>(data.value().size() - offset), static_cast<off_t>(count));
-    if (!buffer.write(data.value().data() + offset, nread))
+    ssize_t nread = min(static_cast<off_t>(data->size() - offset), static_cast<off_t>(count));
+    if (!buffer.write(data->data() + offset, nread))
         return -EFAULT;
-    if (nread == 0 && description && description->generator_cache().has_value())
+    if (nread == 0 && description && description->generator_cache())
         description->generator_cache().clear();
 
     return nread;

+ 2 - 2
Kernel/FileSystem/ProcFS.h

@@ -59,7 +59,7 @@ private:
 
     struct ProcFSDirectoryEntry {
         ProcFSDirectoryEntry() { }
-        ProcFSDirectoryEntry(const char* a_name, unsigned a_proc_file_type, bool a_supervisor_only, Optional<KBuffer> (*read_callback)(InodeIdentifier) = nullptr, ssize_t (*write_callback)(InodeIdentifier, const UserOrKernelBuffer&, size_t) = nullptr, RefPtr<ProcFSInode>&& a_inode = nullptr)
+        ProcFSDirectoryEntry(const char* a_name, unsigned a_proc_file_type, bool a_supervisor_only, OwnPtr<KBuffer> (*read_callback)(InodeIdentifier) = nullptr, ssize_t (*write_callback)(InodeIdentifier, const UserOrKernelBuffer&, size_t) = nullptr, RefPtr<ProcFSInode>&& a_inode = nullptr)
             : name(a_name)
             , proc_file_type(a_proc_file_type)
             , supervisor_only(a_supervisor_only)
@@ -72,7 +72,7 @@ private:
         const char* name { nullptr };
         unsigned proc_file_type { 0 };
         bool supervisor_only { false };
-        Optional<KBuffer> (*read_callback)(InodeIdentifier);
+        OwnPtr<KBuffer> (*read_callback)(InodeIdentifier);
         ssize_t (*write_callback)(InodeIdentifier, const UserOrKernelBuffer&, size_t);
         RefPtr<ProcFSInode> inode;
         InodeIdentifier identifier(unsigned fsid) const;

+ 7 - 5
Kernel/KBufferBuilder.cpp

@@ -33,19 +33,21 @@ namespace Kernel {
 
 inline bool KBufferBuilder::can_append(size_t size) const
 {
-    bool has_space = ((m_size + size) < m_buffer.size());
+    if (!m_buffer)
+        return false;
+    bool has_space = ((m_size + size) < m_buffer->size());
     ASSERT(has_space);
     return has_space;
 }
 
-KBuffer KBufferBuilder::build()
+OwnPtr<KBuffer> KBufferBuilder::build()
 {
-    m_buffer.set_size(m_size);
-    return m_buffer;
+    m_buffer->set_size(m_size);
+    return m_buffer.release_nonnull();
 }
 
 KBufferBuilder::KBufferBuilder()
-    : m_buffer(KBuffer::create_with_size(4 * MiB, Region::Access::Read | Region::Access::Write))
+    : m_buffer(KBuffer::try_create_with_size(4 * MiB, Region::Access::Read | Region::Access::Write))
 {
 }
 

+ 9 - 3
Kernel/KBufferBuilder.h

@@ -37,6 +37,7 @@ public:
     using OutputType = KBuffer;
 
     explicit KBufferBuilder();
+    KBufferBuilder(KBufferBuilder&&) = default;
     ~KBufferBuilder() { }
 
     void append(const StringView&);
@@ -55,13 +56,18 @@ public:
         append(String::formatted(fmtstr, parameters...));
     }
 
-    KBuffer build();
+    OwnPtr<KBuffer> build();
 
 private:
     bool can_append(size_t) const;
-    u8* insertion_ptr() { return m_buffer.data() + m_size; }
+    u8* insertion_ptr()
+    {
+        if (!m_buffer)
+            return nullptr;
+        return m_buffer->data() + m_size;
+    }
 
-    KBuffer m_buffer;
+    OwnPtr<KBuffer> m_buffer;
     size_t m_size { 0 };
 };
 

+ 1 - 1
Kernel/KSyms.cpp

@@ -205,7 +205,7 @@ void load_kernel_symbol_table()
     auto description = result.value();
     auto buffer = description->read_entire_file();
     ASSERT(!buffer.is_error());
-    load_kernel_sybols_from_data(buffer.value());
+    load_kernel_sybols_from_data(*buffer.value());
 }
 
 }

+ 1 - 1
Kernel/PerformanceEventBuffer.cpp

@@ -93,7 +93,7 @@ PerformanceEvent& PerformanceEventBuffer::at(size_t index)
     return events[index];
 }
 
-KBuffer PerformanceEventBuffer::to_json(ProcessID pid, const String& executable_path) const
+OwnPtr<KBuffer> PerformanceEventBuffer::to_json(ProcessID pid, const String& executable_path) const
 {
     KBufferBuilder builder;
 

+ 1 - 1
Kernel/PerformanceEventBuffer.h

@@ -68,7 +68,7 @@ public:
         return const_cast<PerformanceEventBuffer&>(*this).at(index);
     }
 
-    KBuffer to_json(ProcessID, const String& executable_path) const;
+    OwnPtr<KBuffer> to_json(ProcessID, const String& executable_path) const;
 
 private:
     PerformanceEvent& at(size_t index);

+ 9 - 5
Kernel/Process.cpp

@@ -612,10 +612,14 @@ void Process::finalize()
         if (!description_or_error.is_error()) {
             auto& description = description_or_error.value();
             auto json = m_perf_event_buffer->to_json(m_pid, m_executable ? m_executable->absolute_path() : "");
-            auto json_buffer = UserOrKernelBuffer::for_kernel_buffer(json.data());
-            auto result = description->write(json_buffer, json.size());
-            if (result.is_error()) {
-                dbgln("Error while writing perfcore file: {}", result.error().error());
+            if (!json) {
+                dbgln("Error generating perfcore JSON");
+            } else {
+                auto json_buffer = UserOrKernelBuffer::for_kernel_buffer(json->data());
+                auto result = description->write(json_buffer, json->size());
+                if (result.is_error()) {
+                    dbgln("Error while writing perfcore file: {}", result.error().error());
+                }
             }
         }
     }
@@ -840,7 +844,7 @@ void Process::FileDescriptionAndFlags::set(NonnullRefPtr<FileDescription>&& desc
     m_flags = flags;
 }
 
-KBuffer Process::backtrace() const
+OwnPtr<KBuffer> Process::backtrace() const
 {
     KBufferBuilder builder;
     for_each_thread([&](Thread& thread) {

+ 1 - 1
Kernel/Process.h

@@ -166,7 +166,7 @@ public:
     bool should_core_dump() const { return m_should_dump_core; }
     void set_dump_core(bool dump_core) { m_should_dump_core = dump_core; }
 
-    KBuffer backtrace() const;
+    OwnPtr<KBuffer> backtrace() const;
 
     bool is_dead() const { return m_dead; }
 

+ 1 - 1
Kernel/Syscalls/module.cpp

@@ -53,7 +53,7 @@ int Process::sys$module_load(Userspace<const char*> user_path, size_t path_lengt
     if (payload_or_error.is_error())
         return payload_or_error.error();
 
-    auto payload = payload_or_error.value();
+    auto& payload = *payload_or_error.value();
     auto storage = KBuffer::create_with_size(payload.size());
     memcpy(storage.data(), payload.data(), payload.size());
 

+ 1 - 1
Kernel/Syscalls/readlink.cpp

@@ -55,7 +55,7 @@ int Process::sys$readlink(Userspace<const Syscall::SC_readlink_params*> user_par
     if (contents.is_error())
         return contents.error();
 
-    auto& link_target = contents.value();
+    auto& link_target = *contents.value();
     auto size_to_copy = min(link_target.size(), params.buffer.size);
     if (!copy_to_user(params.buffer.data, link_target.data(), size_to_copy))
         return -EFAULT;

+ 2 - 2
Kernel/VM/MemoryManager.h

@@ -84,8 +84,8 @@ class MemoryManager {
     friend class PhysicalRegion;
     friend class Region;
     friend class VMObject;
-    friend Optional<KBuffer> procfs$mm(InodeIdentifier);
-    friend Optional<KBuffer> procfs$memstat(InodeIdentifier);
+    friend OwnPtr<KBuffer> procfs$mm(InodeIdentifier);
+    friend OwnPtr<KBuffer> procfs$memstat(InodeIdentifier);
 
 public:
     static MemoryManager& the();