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.
This commit is contained in:
Andreas Kling 2020-12-18 14:10:10 +01:00
parent d936d86332
commit 8e79bde2b7
18 changed files with 121 additions and 100 deletions

View file

@ -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()) {

View file

@ -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());

View file

@ -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 };

View file

@ -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);
}

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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))
{
}

View file

@ -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 };
};

View file

@ -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());
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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; }

View file

@ -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());

View file

@ -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;

View file

@ -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();