summaryrefslogtreecommitdiff
path: root/Kernel/FileSystem/ProcFS.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/FileSystem/ProcFS.cpp')
-rw-r--r--Kernel/FileSystem/ProcFS.cpp345
1 files changed, 188 insertions, 157 deletions
diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp
index 4c457c3a21..1f1e648811 100644
--- a/Kernel/FileSystem/ProcFS.cpp
+++ b/Kernel/FileSystem/ProcFS.cpp
@@ -253,6 +253,10 @@ static inline bool is_persistent_inode(const InodeIdentifier& identifier)
return to_proc_parent_directory(identifier) == PDI_Root_sys;
}
+struct ProcFSInodeData : public FileDescriptionData {
+ RefPtr<KBufferImpl> buffer;
+};
+
NonnullRefPtr<ProcFS> ProcFS::create()
{
return adopt(*new ProcFS);
@@ -262,19 +266,18 @@ ProcFS::~ProcFS()
{
}
-static OwnPtr<KBuffer> procfs$pid_fds(InodeIdentifier identifier)
+static bool procfs$pid_fds(InodeIdentifier identifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
auto process = Process::from_pid(to_pid(identifier));
if (!process) {
array.finish();
- return builder.build();
+ return true;
}
if (process->number_of_open_file_descriptors() == 0) {
array.finish();
- return builder.build();
+ return true;
}
for (int i = 0; i < process->max_open_file_descriptors(); ++i) {
@@ -295,27 +298,27 @@ static OwnPtr<KBuffer> procfs$pid_fds(InodeIdentifier identifier)
description_object.add("can_write", description->can_write());
}
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$pid_fd_entry(InodeIdentifier identifier)
+static bool procfs$pid_fd_entry(InodeIdentifier identifier, KBufferBuilder& builder)
{
auto process = Process::from_pid(to_pid(identifier));
if (!process)
- return {};
+ return false;
int fd = to_fd(identifier);
auto description = process->file_description(fd);
if (!description)
- return {};
- return KBuffer::try_create_with_bytes(description->absolute_path().bytes());
+ return false;
+ builder.append_bytes(description->absolute_path().bytes());
+ return true;
}
-static OwnPtr<KBuffer> procfs$pid_vm(InodeIdentifier identifier)
+static bool procfs$pid_vm(InodeIdentifier identifier, KBufferBuilder& builder)
{
auto process = Process::from_pid(to_pid(identifier));
if (!process)
- return {};
- KBufferBuilder builder;
+ return false;
JsonArraySerializer array { builder };
{
ScopedSpinLock lock(process->get_lock());
@@ -357,12 +360,11 @@ static OwnPtr<KBuffer> procfs$pid_vm(InodeIdentifier identifier)
}
}
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$pci(InodeIdentifier)
+static bool procfs$pci(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
PCI::enumerate([&array](PCI::Address address, PCI::ID id) {
auto obj = array.add_object();
@@ -379,12 +381,11 @@ static OwnPtr<KBuffer> procfs$pci(InodeIdentifier)
obj.add("subsystem_vendor_id", PCI::get_subsystem_vendor_id(address));
});
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$interrupts(InodeIdentifier)
+static bool procfs$interrupts(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
InterruptManagement::the().enumerate_interrupt_handlers([&array](GenericInterruptHandler& handler) {
auto obj = array.add_object();
@@ -396,21 +397,19 @@ static OwnPtr<KBuffer> procfs$interrupts(InodeIdentifier)
obj.add("call_count", (unsigned)handler.get_invoking_count());
});
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$keymap(InodeIdentifier)
+static bool procfs$keymap(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonObjectSerializer<KBufferBuilder> json { builder };
json.add("keymap", KeyboardDevice::the().keymap_name());
json.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$devices(InodeIdentifier)
+static bool procfs$devices(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
Device::for_each([&array](auto& device) {
auto obj = array.add_object();
@@ -426,28 +425,25 @@ static OwnPtr<KBuffer> procfs$devices(InodeIdentifier)
ASSERT_NOT_REACHED();
});
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$uptime(InodeIdentifier)
+static bool procfs$uptime(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
builder.appendf("%llu\n", TimeManagement::the().uptime_ms() / 1000);
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$cmdline(InodeIdentifier)
+static bool procfs$cmdline(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
builder.append(kernel_command_line().string());
builder.append('\n');
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$modules(InodeIdentifier)
+static bool procfs$modules(InodeIdentifier, KBufferBuilder& builder)
{
extern HashMap<String, OwnPtr<Module>>* g_modules;
- KBufferBuilder builder;
JsonArraySerializer array { builder };
for (auto& it : *g_modules) {
auto obj = array.add_object();
@@ -461,13 +457,12 @@ static OwnPtr<KBuffer> procfs$modules(InodeIdentifier)
obj.add("size", size);
}
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$profile(InodeIdentifier)
+static bool procfs$profile(InodeIdentifier, KBufferBuilder& builder)
{
InterruptDisabler disabler;
- KBufferBuilder builder;
JsonObjectSerializer object(builder);
object.add("pid", Profiling::pid().value());
@@ -493,12 +488,11 @@ static OwnPtr<KBuffer> procfs$profile(InodeIdentifier)
});
array.finish();
object.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$net_adapters(InodeIdentifier)
+static bool procfs$net_adapters(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
NetworkAdapter::for_each([&array](auto& adapter) {
auto obj = array.add_object();
@@ -519,12 +513,11 @@ static OwnPtr<KBuffer> procfs$net_adapters(InodeIdentifier)
obj.add("mtu", adapter.mtu());
});
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$net_arp(InodeIdentifier)
+static bool procfs$net_arp(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
LOCKER(arp_table().lock(), Lock::Mode::Shared);
for (auto& it : arp_table().resource()) {
@@ -533,12 +526,11 @@ static OwnPtr<KBuffer> procfs$net_arp(InodeIdentifier)
obj.add("ip_address", it.key.to_string());
}
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$net_tcp(InodeIdentifier)
+static bool procfs$net_tcp(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
TCPSocket::for_each([&array](auto& socket) {
auto obj = array.add_object();
@@ -555,12 +547,11 @@ static OwnPtr<KBuffer> procfs$net_tcp(InodeIdentifier)
obj.add("bytes_out", socket.bytes_out());
});
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$net_udp(InodeIdentifier)
+static bool procfs$net_udp(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
UDPSocket::for_each([&array](auto& socket) {
auto obj = array.add_object();
@@ -570,12 +561,11 @@ static OwnPtr<KBuffer> procfs$net_udp(InodeIdentifier)
obj.add("peer_port", socket.peer_port());
});
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$net_local(InodeIdentifier)
+static bool procfs$net_local(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
LocalSocket::for_each([&array](auto& socket) {
auto obj = array.add_object();
@@ -588,15 +578,14 @@ static OwnPtr<KBuffer> procfs$net_local(InodeIdentifier)
obj.add("acceptor_gid", socket.acceptor_gid());
});
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$pid_vmobjects(InodeIdentifier identifier)
+static bool procfs$pid_vmobjects(InodeIdentifier identifier, KBufferBuilder& builder)
{
auto process = Process::from_pid(to_pid(identifier));
if (!process)
- return {};
- KBufferBuilder builder;
+ return false;
builder.appendf("BEGIN END SIZE NAME\n");
{
ScopedSpinLock lock(process->get_lock());
@@ -623,15 +612,14 @@ static OwnPtr<KBuffer> procfs$pid_vmobjects(InodeIdentifier identifier)
builder.appendf("\n");
}
}
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$pid_unveil(InodeIdentifier identifier)
+static bool procfs$pid_unveil(InodeIdentifier identifier, KBufferBuilder& builder)
{
auto process = Process::from_pid(to_pid(identifier));
if (!process)
- return {};
- KBufferBuilder builder;
+ return false;
JsonArraySerializer array { builder };
for (auto& unveiled_path : process->unveiled_paths()) {
if (!unveiled_path.was_explicitly_unveiled())
@@ -652,57 +640,57 @@ static OwnPtr<KBuffer> procfs$pid_unveil(InodeIdentifier identifier)
obj.add("permissions", permissions_builder.to_string());
}
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$tid_stack(InodeIdentifier identifier)
+static bool procfs$tid_stack(InodeIdentifier identifier, KBufferBuilder& builder)
{
auto thread = Thread::from_tid(to_tid(identifier));
if (!thread)
- return {};
- KBufferBuilder builder;
+ return false;
builder.appendf("Thread %d (%s):\n", thread->tid().value(), thread->name().characters());
builder.append(thread->backtrace());
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$pid_exe(InodeIdentifier identifier)
+static bool procfs$pid_exe(InodeIdentifier identifier, KBufferBuilder& builder)
{
auto process = Process::from_pid(to_pid(identifier));
if (!process)
- return {};
+ return false;
auto* custody = process->executable();
ASSERT(custody);
- return KBuffer::try_create_with_bytes(custody->absolute_path().bytes());
+ builder.append(custody->absolute_path().bytes());
+ return true;
}
-static OwnPtr<KBuffer> procfs$pid_cwd(InodeIdentifier identifier)
+static bool procfs$pid_cwd(InodeIdentifier identifier, KBufferBuilder& builder)
{
auto process = Process::from_pid(to_pid(identifier));
if (!process)
- return {};
- return KBuffer::try_create_with_bytes(process->current_directory().absolute_path().bytes());
+ return false;
+ builder.append_bytes(process->current_directory().absolute_path().bytes());
+ return true;
}
-static OwnPtr<KBuffer> procfs$pid_root(InodeIdentifier identifier)
+static bool procfs$pid_root(InodeIdentifier identifier, KBufferBuilder& builder)
{
auto process = Process::from_pid(to_pid(identifier));
if (!process)
- return {};
- return KBuffer::try_create_with_bytes(process->root_directory_relative_to_global_root().absolute_path().to_byte_buffer());
+ return false;
+ builder.append_bytes(process->root_directory_relative_to_global_root().absolute_path().to_byte_buffer());
+ return false;
}
-static OwnPtr<KBuffer> procfs$self(InodeIdentifier)
+static bool procfs$self(InodeIdentifier, KBufferBuilder& builder)
{
- char buffer[16];
- int written = snprintf(buffer, sizeof(buffer), "%d", Process::current()->pid().value());
- return KBuffer::try_create_with_bytes(ReadonlyBytes { buffer, static_cast<size_t>(written) });
+ builder.appendf("%d", Process::current()->pid().value());
+ return true;
}
-OwnPtr<KBuffer> procfs$mm(InodeIdentifier)
+static bool procfs$mm(InodeIdentifier, KBufferBuilder& builder)
{
InterruptDisabler disabler;
- KBufferBuilder builder;
u32 vmobject_count = 0;
MemoryManager::for_each_vmobject([&](auto& vmobject) {
++vmobject_count;
@@ -716,22 +704,20 @@ OwnPtr<KBuffer> procfs$mm(InodeIdentifier)
builder.appendf("VMO count: %u\n", vmobject_count);
builder.appendf("Free physical pages: %u\n", MM.user_physical_pages() - MM.user_physical_pages_used());
builder.appendf("Free supervisor physical pages: %u\n", MM.super_physical_pages() - MM.super_physical_pages_used());
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$dmesg(InodeIdentifier)
+static bool procfs$dmesg(InodeIdentifier, KBufferBuilder& builder)
{
InterruptDisabler disabler;
- KBufferBuilder builder;
for (char ch : Console::the().logbuffer())
builder.append(ch);
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$mounts(InodeIdentifier)
+static bool procfs$mounts(InodeIdentifier, KBufferBuilder& builder)
{
// FIXME: This is obviously racy against the VFS mounts changing.
- KBufferBuilder builder;
VFS::the().for_each_mount([&builder](auto& mount) {
auto& fs = mount.guest_fs();
builder.appendf("%s @ ", fs.class_name());
@@ -744,13 +730,12 @@ static OwnPtr<KBuffer> procfs$mounts(InodeIdentifier)
}
builder.append('\n');
});
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$df(InodeIdentifier)
+static bool procfs$df(InodeIdentifier, KBufferBuilder& builder)
{
// FIXME: This is obviously racy against the VFS mounts changing.
- KBufferBuilder builder;
JsonArraySerializer array { builder };
VFS::the().for_each_mount([&array](auto& mount) {
auto& fs = mount.guest_fs();
@@ -771,12 +756,11 @@ static OwnPtr<KBuffer> procfs$df(InodeIdentifier)
fs_object.add("source", "none");
});
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$cpuinfo(InodeIdentifier)
+static bool procfs$cpuinfo(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
Processor::for_each(
[&](Processor& proc) -> IterationDecision {
@@ -796,17 +780,16 @@ static OwnPtr<KBuffer> procfs$cpuinfo(InodeIdentifier)
return IterationDecision::Continue;
});
array.finish();
- return builder.build();
+ return true;
}
-OwnPtr<KBuffer> procfs$memstat(InodeIdentifier)
+static bool procfs$memstat(InodeIdentifier, KBufferBuilder& builder)
{
InterruptDisabler disabler;
kmalloc_stats stats;
get_kmalloc_stats(stats);
- KBufferBuilder builder;
JsonObjectSerializer<KBufferBuilder> json { builder };
json.add("kmalloc_allocated", stats.bytes_allocated);
json.add("kmalloc_available", stats.bytes_free);
@@ -823,12 +806,11 @@ OwnPtr<KBuffer> procfs$memstat(InodeIdentifier)
json.add(String::format("%s_num_free", prefix.characters()), num_free);
});
json.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$all(InodeIdentifier)
+static bool procfs$all(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
JsonArraySerializer array { builder };
// Keep this in sync with CProcessStatistics.
@@ -914,18 +896,17 @@ static OwnPtr<KBuffer> procfs$all(InodeIdentifier)
for (auto& process : processes)
build_process(process);
array.finish();
- return builder.build();
+ return true;
}
-static OwnPtr<KBuffer> procfs$inodes(InodeIdentifier)
+static bool procfs$inodes(InodeIdentifier, KBufferBuilder& builder)
{
- KBufferBuilder builder;
InterruptDisabler disabler;
ScopedSpinLock all_inodes_lock(Inode::all_inodes_lock());
for (auto& inode : Inode::all_with_lock()) {
builder.appendf("Inode{K%x} %02u:%08u (%u)\n", &inode, inode.fsid(), inode.index(), inode.ref_count());
}
- return builder.build();
+ return true;
}
struct SysVariable {
@@ -969,7 +950,7 @@ SysVariable& SysVariable::for_inode(InodeIdentifier id)
return variable;
}
-static OwnPtr<KBuffer> read_sys_bool(InodeIdentifier inode_id)
+static bool read_sys_bool(InodeIdentifier inode_id, KBufferBuilder& builder)
{
auto& variable = SysVariable::for_inode(inode_id);
ASSERT(variable.type == SysVariable::Type::Boolean);
@@ -981,7 +962,8 @@ static OwnPtr<KBuffer> read_sys_bool(InodeIdentifier inode_id)
buffer[0] = lockable_bool->resource() ? '1' : '0';
}
buffer[1] = '\n';
- return KBuffer::try_create_with_bytes(ReadonlyBytes { buffer, sizeof(buffer) });
+ builder.append_bytes(ReadonlyBytes { buffer, sizeof(buffer) });
+ return true;
}
static ssize_t write_sys_bool(InodeIdentifier inode_id, const UserOrKernelBuffer& buffer, size_t size)
@@ -1013,14 +995,15 @@ static ssize_t write_sys_bool(InodeIdentifier inode_id, const UserOrKernelBuffer
return (ssize_t)size;
}
-static OwnPtr<KBuffer> read_sys_string(InodeIdentifier inode_id)
+static bool read_sys_string(InodeIdentifier inode_id, KBufferBuilder& builder)
{
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 KBuffer::try_create_with_bytes(lockable_string->resource().bytes());
+ builder.append_bytes(lockable_string->resource().bytes());
+ return true;
}
static ssize_t write_sys_string(InodeIdentifier inode_id, const UserOrKernelBuffer& buffer, size_t size)
@@ -1130,6 +1113,83 @@ ProcFSInode::~ProcFSInode()
fs().m_inodes.remove(it);
}
+KResult ProcFSInode::refresh_data(FileDescription& description) const
+{
+ auto& cached_data = description.data();
+ auto* directory_entry = fs().get_directory_entry(identifier());
+
+ bool (*read_callback)(InodeIdentifier, KBufferBuilder&) = nullptr;
+ if (directory_entry) {
+ if (directory_entry->proc_file_type > (unsigned)FI_Root) {
+ read_callback = directory_entry->read_callback;
+ ASSERT(read_callback);
+ } else {
+ return KSuccess;
+ }
+ } else {
+ switch (to_proc_parent_directory(identifier())) {
+ case PDI_PID_fd:
+ read_callback = procfs$pid_fd_entry;
+ break;
+ case PDI_PID_stacks:
+ read_callback = procfs$tid_stack;
+ break;
+ case PDI_Root_sys:
+ switch (SysVariable::for_inode(identifier()).type) {
+ case SysVariable::Type::Invalid:
+ ASSERT_NOT_REACHED();
+ case SysVariable::Type::Boolean:
+ read_callback = read_sys_bool;
+ break;
+ case SysVariable::Type::String:
+ read_callback = read_sys_string;
+ break;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ ASSERT(read_callback);
+ }
+
+ if (!cached_data)
+ cached_data = new ProcFSInodeData;
+ auto& buffer = static_cast<ProcFSInodeData&>(*cached_data).buffer;
+ if (buffer) {
+ // If we're reusing the buffer, reset the size to 0 first. This
+ // ensures we don't accidentally leak previously written data.
+ buffer->set_size(0);
+ }
+ KBufferBuilder builder(buffer, true);
+ if (!read_callback(identifier(), builder))
+ return KResult(-ENOENT);
+ // We don't use builder.build() here, which would steal our buffer
+ // and turn it into an OwnPtr. Instead, just flush to the buffer so
+ // that we can read all the data that was written.
+ if (!builder.flush())
+ return KResult(-ENOMEM);
+ if (!buffer)
+ return KResult(-ENOMEM);
+ return KSuccess;
+}
+
+KResult ProcFSInode::attach(FileDescription& description)
+{
+ return refresh_data(description);
+}
+
+void ProcFSInode::did_seek(FileDescription& description, off_t new_offset)
+{
+ if (new_offset != 0)
+ return;
+ auto result = refresh_data(description);
+ if (result.is_error()) {
+ // Subsequent calls to read will return EIO!
+ dbg() << "ProcFS: Could not refresh contents: " << result.error();
+ }
+}
+
InodeMetadata ProcFSInode::metadata() const
{
#ifdef PROCFS_DEBUG
@@ -1215,68 +1275,29 @@ InodeMetadata ProcFSInode::metadata() const
ssize_t ProcFSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer& buffer, FileDescription* description) const
{
#ifdef PROCFS_DEBUG
- dbg() << "ProcFS: read_bytes " << index();
+ dbg() << "ProcFS: read_bytes offset: " << offset << " count: " << count;
#endif
ASSERT(offset >= 0);
ASSERT(buffer.user_or_kernel_ptr());
- auto* directory_entry = fs().get_directory_entry(identifier());
-
- OwnPtr<KBuffer> (*read_callback)(InodeIdentifier) = nullptr;
- if (directory_entry)
- read_callback = directory_entry->read_callback;
- else
- switch (to_proc_parent_directory(identifier())) {
- case PDI_PID_fd:
- read_callback = procfs$pid_fd_entry;
- break;
- case PDI_PID_stacks:
- read_callback = procfs$tid_stack;
- break;
- case PDI_Root_sys:
- switch (SysVariable::for_inode(identifier()).type) {
- case SysVariable::Type::Invalid:
- ASSERT_NOT_REACHED();
- case SysVariable::Type::Boolean:
- read_callback = read_sys_bool;
- break;
- case SysVariable::Type::String:
- read_callback = read_sys_string;
- break;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- ASSERT(read_callback);
-
- OwnPtr<KBuffer> descriptionless_generated_data;
- KBuffer* data = nullptr;
- if (!description) {
- descriptionless_generated_data = read_callback(identifier());
- data = descriptionless_generated_data.ptr();
- } else {
- if (!description->generator_cache())
- description->generator_cache() = (*read_callback)(identifier());
- data = description->generator_cache().ptr();
+ if (!description)
+ return -EIO;
+ if (!description->data()) {
+#ifdef PROCFS_DEBUG
+ dbg() << "ProcFS: Do not have cached data!";
+#endif
+ return -EIO;
}
- if (!data)
- return 0;
- if (data->is_null()) {
- dbg() << "ProcFS: Not enough memory!";
- return 0;
- }
+ // Be sure to keep a reference to data_buffer while we use it!
+ RefPtr<KBufferImpl> data_buffer = static_cast<ProcFSInodeData&>(*description->data()).buffer;
- if ((size_t)offset >= data->size())
+ if (!data_buffer || (size_t)offset >= data_buffer->size())
return 0;
- ssize_t nread = min(static_cast<off_t>(data->size() - offset), static_cast<off_t>(count));
- if (!buffer.write(data->data() + offset, nread))
+ ssize_t nread = min(static_cast<off_t>(data_buffer->size() - offset), static_cast<off_t>(count));
+ if (!buffer.write(data_buffer->data() + offset, nread))
return -EFAULT;
- if (nread == 0 && description && description->generator_cache())
- description->generator_cache().clear();
return nread;
}
@@ -1599,6 +1620,16 @@ ProcFSProxyInode::~ProcFSProxyInode()
{
}
+KResult ProcFSProxyInode::attach(FileDescription& fd)
+{
+ return m_fd->inode()->attach(fd);
+}
+
+void ProcFSProxyInode::did_seek(FileDescription& fd, off_t new_offset)
+{
+ return m_fd->inode()->did_seek(fd, new_offset);
+}
+
InodeMetadata ProcFSProxyInode::metadata() const
{
InodeMetadata metadata = m_fd->metadata();