1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 08:08:12 +00:00

Kernel/FileSystem: Make Inode::{write,read}_bytes methods non-virtual

We make these methods non-virtual because we want to ensure we properly
enforce locking of the m_inode_lock mutex. Also, for write operations,
we want to call prepare_to_write_data before the actual write. The
previous design required us to ensure the callers do that at various
places which lead to hard-to-find bugs. By moving everything to a place
where we call prepare_to_write_data only once, we eliminate a possibilty
of forgeting to call it on some code path in the kernel.
This commit is contained in:
Liav A 2022-08-06 04:22:20 +03:00 committed by Idan Horowitz
parent 4f4717e351
commit c88cc8557f
20 changed files with 87 additions and 72 deletions

View file

@ -78,12 +78,12 @@ DevPtsFSInode::DevPtsFSInode(DevPtsFS& fs, InodeIndex index, SlavePTY* pty)
DevPtsFSInode::~DevPtsFSInode() = default;
ErrorOr<size_t> DevPtsFSInode::read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const
ErrorOr<size_t> DevPtsFSInode::read_bytes_locked(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const
{
VERIFY_NOT_REACHED();
}
ErrorOr<size_t> DevPtsFSInode::write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*)
ErrorOr<size_t> DevPtsFSInode::write_bytes_locked(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*)
{
VERIFY_NOT_REACHED();
}

View file

@ -47,12 +47,12 @@ private:
DevPtsFSInode(DevPtsFS&, InodeIndex, SlavePTY*);
// ^Inode
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
virtual ErrorOr<void> add_child(Inode&, StringView name, mode_t) override;
virtual ErrorOr<void> remove_child(StringView name) override;

View file

@ -51,7 +51,7 @@ DevTmpFSInode::DevTmpFSInode(DevTmpFS& fs, MajorNumber major_number, MinorNumber
{
}
ErrorOr<size_t> DevTmpFSInode::read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const
ErrorOr<size_t> DevTmpFSInode::read_bytes_locked(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const
{
VERIFY_NOT_REACHED();
}
@ -71,7 +71,7 @@ ErrorOr<void> DevTmpFSInode::flush_metadata()
return {};
}
ErrorOr<size_t> DevTmpFSInode::write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*)
ErrorOr<size_t> DevTmpFSInode::write_bytes_locked(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*)
{
VERIFY_NOT_REACHED();
}
@ -171,20 +171,19 @@ DevTmpFSLinkInode::DevTmpFSLinkInode(DevTmpFS& fs, NonnullOwnPtr<KString> name)
{
}
ErrorOr<size_t> DevTmpFSLinkInode::read_bytes(off_t offset, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const
ErrorOr<size_t> DevTmpFSLinkInode::read_bytes_locked(off_t offset, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const
{
MutexLocker locker(m_inode_lock);
VERIFY(m_inode_lock.is_locked());
VERIFY(offset == 0);
VERIFY(m_link);
TRY(buffer.write(m_link->characters() + offset, m_link->length()));
return m_link->length();
}
ErrorOr<size_t> DevTmpFSLinkInode::write_bytes(off_t offset, size_t count, UserOrKernelBuffer const& buffer, OpenFileDescription*)
ErrorOr<size_t> DevTmpFSLinkInode::write_bytes_locked(off_t offset, size_t count, UserOrKernelBuffer const& buffer, OpenFileDescription*)
{
VERIFY(m_inode_lock.is_locked());
auto new_string = TRY(buffer.try_copy_into_kstring(count));
MutexLocker locker(m_inode_lock);
VERIFY(offset == 0);
VERIFY(buffer.is_kernel_buffer());
m_link = move(new_string);
@ -303,9 +302,9 @@ StringView DevTmpFSDeviceInode::name() const
return m_name->view();
}
ErrorOr<size_t> DevTmpFSDeviceInode::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const
ErrorOr<size_t> DevTmpFSDeviceInode::read_bytes_locked(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const
{
MutexLocker locker(m_inode_lock);
VERIFY(m_inode_lock.is_locked());
VERIFY(!!description);
LockRefPtr<Device> device = DeviceManagement::the().get_device(m_major_number, m_minor_number);
if (!device)
@ -318,9 +317,9 @@ ErrorOr<size_t> DevTmpFSDeviceInode::read_bytes(off_t offset, size_t count, User
return result.value();
}
ErrorOr<size_t> DevTmpFSDeviceInode::write_bytes(off_t offset, size_t count, UserOrKernelBuffer const& buffer, OpenFileDescription* description)
ErrorOr<size_t> DevTmpFSDeviceInode::write_bytes_locked(off_t offset, size_t count, UserOrKernelBuffer const& buffer, OpenFileDescription* description)
{
MutexLocker locker(m_inode_lock);
VERIFY(m_inode_lock.is_locked());
VERIFY(!!description);
LockRefPtr<Device> device = DeviceManagement::the().get_device(m_major_number, m_minor_number);
if (!device)

View file

@ -48,12 +48,12 @@ public:
protected:
explicit DevTmpFSInode(DevTmpFS&);
DevTmpFSInode(DevTmpFS&, MajorNumber, MinorNumber);
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override;
virtual InodeMetadata metadata() const override final;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
virtual ErrorOr<void> add_child(Inode&, StringView name, mode_t) override;
virtual ErrorOr<void> remove_child(StringView name) override;
@ -95,8 +95,8 @@ private:
virtual Type node_type() const override { return m_block_device ? Type::BlockDevice : Type::CharacterDevice; }
// ^Inode
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
NonnullOwnPtr<KString> m_name;
bool const m_block_device;
@ -116,8 +116,8 @@ protected:
virtual Type node_type() const override { return Type::Link; }
// ^Inode
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
NonnullOwnPtr<KString> m_name;
OwnPtr<KString> m_link;

View file

@ -811,9 +811,9 @@ ErrorOr<void> Ext2FSInode::compute_block_list_with_exclusive_locking()
return {};
}
ErrorOr<size_t> Ext2FSInode::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const
ErrorOr<size_t> Ext2FSInode::read_bytes_locked(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const
{
MutexLocker inode_locker(m_inode_lock);
VERIFY(m_inode_lock.is_locked());
VERIFY(offset >= 0);
if (m_raw_inode.i_size == 0)
return 0;
@ -952,7 +952,7 @@ ErrorOr<void> Ext2FSInode::resize(u64 new_size)
return {};
}
ErrorOr<size_t> Ext2FSInode::write_bytes(off_t offset, size_t count, UserOrKernelBuffer const& data, OpenFileDescription* description)
ErrorOr<size_t> Ext2FSInode::write_bytes_locked(off_t offset, size_t count, UserOrKernelBuffer const& data, OpenFileDescription* description)
{
VERIFY(m_inode_lock.is_locked());
VERIFY(offset >= 0);
@ -963,7 +963,7 @@ ErrorOr<size_t> Ext2FSInode::write_bytes(off_t offset, size_t count, UserOrKerne
if (is_symlink()) {
VERIFY(offset == 0);
if (max((size_t)(offset + count), (size_t)m_raw_inode.i_size) < max_inline_symlink_length) {
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::write_bytes(): Poking into i_block array for inline symlink ({} bytes)", identifier(), count);
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::write_bytes_locked(): Poking into i_block array for inline symlink ({} bytes)", identifier(), count);
TRY(data.read(((u8*)m_raw_inode.i_block) + offset, count));
if ((size_t)(offset + count) > (size_t)m_raw_inode.i_size)
m_raw_inode.i_size = offset + count;
@ -997,14 +997,14 @@ ErrorOr<size_t> Ext2FSInode::write_bytes(off_t offset, size_t count, UserOrKerne
size_t nwritten = 0;
auto remaining_count = min((off_t)count, (off_t)new_size - offset);
dbgln_if(EXT2_VERY_DEBUG, "Ext2FSInode[{}]::write_bytes(): Writing {} bytes, {} bytes into inode from {}", identifier(), count, offset, data.user_or_kernel_ptr());
dbgln_if(EXT2_VERY_DEBUG, "Ext2FSInode[{}]::write_bytes_locked(): Writing {} bytes, {} bytes into inode from {}", identifier(), count, offset, data.user_or_kernel_ptr());
for (auto bi = first_block_logical_index; remaining_count && bi <= last_block_logical_index; bi = bi.value() + 1) {
size_t offset_into_block = (bi == first_block_logical_index) ? offset_into_first_block : 0;
size_t num_bytes_to_copy = min((size_t)block_size - offset_into_block, (size_t)remaining_count);
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::write_bytes(): Writing block {} (offset_into_block: {})", identifier(), m_block_list[bi.value()], offset_into_block);
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::write_bytes_locked(): Writing block {} (offset_into_block: {})", identifier(), m_block_list[bi.value()], offset_into_block);
if (auto result = fs().write_block(m_block_list[bi.value()], data.offset(nwritten), num_bytes_to_copy, offset_into_block, allow_cache); result.is_error()) {
dbgln("Ext2FSInode[{}]::write_bytes(): Failed to write block {} (index {})", identifier(), m_block_list[bi.value()], bi);
dbgln("Ext2FSInode[{}]::write_bytes_locked(): Failed to write block {} (index {})", identifier(), m_block_list[bi.value()], bi);
return result.release_error();
}
remaining_count -= num_bytes_to_copy;
@ -1013,7 +1013,7 @@ ErrorOr<size_t> Ext2FSInode::write_bytes(off_t offset, size_t count, UserOrKerne
did_modify_contents();
dbgln_if(EXT2_VERY_DEBUG, "Ext2FSInode[{}]::write_bytes(): After write, i_size={}, i_blocks={} ({} blocks in list)", identifier(), size(), m_raw_inode.i_blocks, m_block_list.size());
dbgln_if(EXT2_VERY_DEBUG, "Ext2FSInode[{}]::write_bytes_locked(): After write, i_size={}, i_blocks={} ({} blocks in list)", identifier(), size(), m_raw_inode.i_blocks, m_block_list.size());
return nwritten;
}

View file

@ -35,12 +35,12 @@ public:
private:
// ^Inode
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& data, OpenFileDescription*) override;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& data, OpenFileDescription*) override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
virtual ErrorOr<void> add_child(Inode& child, StringView name, mode_t) override;
virtual ErrorOr<void> remove_child(StringView name) override;

View file

@ -398,9 +398,9 @@ u32 ISO9660FS::calculate_directory_entry_cache_key(ISO::DirectoryRecordHeader co
return LittleEndian { record.extent_location.little };
}
ErrorOr<size_t> ISO9660Inode::read_bytes(off_t offset, size_t size, UserOrKernelBuffer& buffer, OpenFileDescription*) const
ErrorOr<size_t> ISO9660Inode::read_bytes_locked(off_t offset, size_t size, UserOrKernelBuffer& buffer, OpenFileDescription*) const
{
MutexLocker inode_locker(m_inode_lock);
VERIFY(m_inode_lock.is_locked());
u32 data_length = LittleEndian { m_record.data_length.little };
u32 extent_location = LittleEndian { m_record.extent_location.little };
@ -493,7 +493,7 @@ ErrorOr<void> ISO9660Inode::flush_metadata()
return {};
}
ErrorOr<size_t> ISO9660Inode::write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*)
ErrorOr<size_t> ISO9660Inode::write_bytes_locked(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*)
{
return EROFS;
}

View file

@ -347,12 +347,10 @@ public:
ISO9660FS const& fs() const { return static_cast<ISO9660FS const&>(Inode::fs()); }
// ^Inode
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
virtual ErrorOr<void> add_child(Inode&, StringView name, mode_t) override;
virtual ErrorOr<void> remove_child(StringView name) override;
@ -367,6 +365,10 @@ private:
// without any problems, so let's allow it anyway.
static constexpr size_t max_file_identifier_length = 256 - sizeof(ISO::DirectoryRecordHeader);
// ^Inode
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
ISO9660Inode(ISO9660FS&, ISO::DirectoryRecordHeader const& record, StringView name);
static ErrorOr<NonnullLockRefPtr<ISO9660Inode>> try_create_from_directory_record(ISO9660FS&, ISO::DirectoryRecordHeader const& record, StringView name);

View file

@ -106,6 +106,19 @@ void Inode::will_be_destroyed()
(void)flush_metadata();
}
ErrorOr<size_t> Inode::write_bytes(off_t offset, size_t length, UserOrKernelBuffer const& target_buffer, OpenFileDescription* open_description)
{
MutexLocker locker(m_inode_lock);
TRY(prepare_to_write_data());
return write_bytes_locked(offset, length, target_buffer, open_description);
}
ErrorOr<size_t> Inode::read_bytes(off_t offset, size_t length, UserOrKernelBuffer& buffer, OpenFileDescription* open_description) const
{
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
return read_bytes_locked(offset, length, buffer, open_description);
}
ErrorOr<void> Inode::update_timestamps([[maybe_unused]] Optional<time_t> atime, [[maybe_unused]] Optional<time_t> ctime, [[maybe_unused]] Optional<time_t> mtime)
{
return ENOTIMPL;

View file

@ -56,13 +56,14 @@ public:
ErrorOr<NonnullOwnPtr<KBuffer>> read_entire(OpenFileDescription* = nullptr) const;
ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& data, OpenFileDescription*);
ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const;
virtual ErrorOr<void> attach(OpenFileDescription&) { return {}; }
virtual void detach(OpenFileDescription&) { }
virtual void did_seek(OpenFileDescription&, off_t) { }
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const = 0;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const = 0;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) = 0;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& data, OpenFileDescription*) = 0;
virtual ErrorOr<NonnullLockRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) = 0;
virtual ErrorOr<void> add_child(Inode&, StringView name, mode_t) = 0;
virtual ErrorOr<void> remove_child(StringView name) = 0;
@ -119,6 +120,9 @@ protected:
mutable Mutex m_inode_lock { "Inode"sv };
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& data, OpenFileDescription*) = 0;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const = 0;
private:
ErrorOr<bool> try_apply_flock(Process const&, OpenFileDescription const&, flock const&);

View file

@ -42,12 +42,7 @@ ErrorOr<size_t> InodeFile::write(OpenFileDescription& description, u64 offset, U
if (Checked<off_t>::addition_would_overflow(offset, count))
return EOVERFLOW;
size_t nwritten = 0;
{
MutexLocker locker(m_inode->m_inode_lock);
TRY(m_inode->prepare_to_write_data());
nwritten = TRY(m_inode->write_bytes(offset, count, data, &description));
}
size_t nwritten = TRY(m_inode->write_bytes(offset, count, data, &description));
if (nwritten > 0) {
auto mtime_result = m_inode->update_timestamps({}, {}, kgettimeofday().to_truncated_seconds());
Thread::current()->did_file_write(nwritten);

View file

@ -718,7 +718,7 @@ ErrorOr<void> Plan9FSInode::ensure_open_for_mode(int mode)
return fs().post_message_and_wait_for_a_reply(message);
}
ErrorOr<size_t> Plan9FSInode::read_bytes(off_t offset, size_t size, UserOrKernelBuffer& buffer, OpenFileDescription*) const
ErrorOr<size_t> Plan9FSInode::read_bytes_locked(off_t offset, size_t size, UserOrKernelBuffer& buffer, OpenFileDescription*) const
{
TRY(const_cast<Plan9FSInode&>(*this).ensure_open_for_mode(O_RDONLY));
@ -750,7 +750,7 @@ ErrorOr<size_t> Plan9FSInode::read_bytes(off_t offset, size_t size, UserOrKernel
return nread;
}
ErrorOr<size_t> Plan9FSInode::write_bytes(off_t offset, size_t size, UserOrKernelBuffer const& data, OpenFileDescription*)
ErrorOr<size_t> Plan9FSInode::write_bytes_locked(off_t offset, size_t size, UserOrKernelBuffer const& data, OpenFileDescription*)
{
TRY(ensure_open_for_mode(O_WRONLY));
size = fs().adjust_buffer_size(size);

View file

@ -156,8 +156,6 @@ public:
// ^Inode
virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& data, OpenFileDescription*) override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
@ -168,6 +166,10 @@ public:
virtual ErrorOr<void> truncate(u64) override;
private:
// ^Inode
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& data, OpenFileDescription*) override;
Plan9FSInode(Plan9FS&, u32 fid);
static ErrorOr<NonnullLockRefPtr<Plan9FSInode>> try_create(Plan9FS&, u32 fid);

View file

@ -120,7 +120,7 @@ ErrorOr<void> ProcFSGlobalInode::attach(OpenFileDescription& description)
return m_associated_component->refresh_data(description);
}
ErrorOr<size_t> ProcFSGlobalInode::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* fd) const
ErrorOr<size_t> ProcFSGlobalInode::read_bytes_locked(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* fd) const
{
return m_associated_component->read_bytes(offset, count, buffer, fd);
}
@ -163,7 +163,7 @@ InodeMetadata ProcFSGlobalInode::metadata() const
return metadata;
}
ErrorOr<size_t> ProcFSGlobalInode::write_bytes(off_t offset, size_t count, UserOrKernelBuffer const& buffer, OpenFileDescription* fd)
ErrorOr<size_t> ProcFSGlobalInode::write_bytes_locked(off_t offset, size_t count, UserOrKernelBuffer const& buffer, OpenFileDescription* fd)
{
return m_associated_component->write_bytes(offset, count, buffer, fd);
}
@ -233,7 +233,7 @@ ProcFSProcessAssociatedInode::ProcFSProcessAssociatedInode(ProcFS const& fs, Pro
{
}
ErrorOr<size_t> ProcFSProcessAssociatedInode::write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*)
ErrorOr<size_t> ProcFSProcessAssociatedInode::write_bytes_locked(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*)
{
return ENOTSUP;
}
@ -271,7 +271,7 @@ InodeMetadata ProcFSProcessDirectoryInode::metadata() const
return metadata;
}
ErrorOr<size_t> ProcFSProcessDirectoryInode::read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const
ErrorOr<size_t> ProcFSProcessDirectoryInode::read_bytes_locked(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const
{
VERIFY_NOT_REACHED();
}
@ -327,7 +327,7 @@ ProcFSProcessSubDirectoryInode::ProcFSProcessSubDirectoryInode(ProcFS const& pro
{
}
ErrorOr<size_t> ProcFSProcessSubDirectoryInode::read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const
ErrorOr<size_t> ProcFSProcessSubDirectoryInode::read_bytes_locked(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const
{
VERIFY_NOT_REACHED();
}
@ -490,9 +490,9 @@ ErrorOr<void> ProcFSProcessPropertyInode::traverse_as_directory(Function<ErrorOr
{
VERIFY_NOT_REACHED();
}
ErrorOr<size_t> ProcFSProcessPropertyInode::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const
ErrorOr<size_t> ProcFSProcessPropertyInode::read_bytes_locked(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const
{
dbgln_if(PROCFS_DEBUG, "ProcFS ProcessInformation: read_bytes offset: {} count: {}", offset, count);
dbgln_if(PROCFS_DEBUG, "ProcFS ProcessInformation: read_bytes_locked offset: {} count: {}", offset, count);
VERIFY(offset >= 0);
VERIFY(buffer.user_or_kernel_ptr());

View file

@ -77,8 +77,8 @@ protected:
// ^Inode
virtual ErrorOr<void> attach(OpenFileDescription& description) override final;
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override final;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override final;
virtual void did_seek(OpenFileDescription&, off_t) override final;
virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
@ -123,7 +123,7 @@ protected:
ProcessID associated_pid() const { return m_pid; }
// ^Inode
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override final;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override final;
private:
const ProcessID m_pid;
@ -142,7 +142,7 @@ private:
virtual void did_seek(OpenFileDescription&, off_t) override { }
virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) override;
};
@ -159,7 +159,7 @@ private:
virtual void did_seek(OpenFileDescription&, off_t) override;
virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) override;
const SegmentedProcFSIndex::ProcessSubDirectory m_sub_directory_type;
@ -185,7 +185,7 @@ private:
virtual void did_seek(OpenFileDescription&, off_t) override;
virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override final;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) override final;
ErrorOr<void> refresh_data(OpenFileDescription& description);

View file

@ -58,7 +58,7 @@ ErrorOr<void> SysFSInode::attach(OpenFileDescription& description)
return m_associated_component->refresh_data(description);
}
ErrorOr<size_t> SysFSInode::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* fd) const
ErrorOr<size_t> SysFSInode::read_bytes_locked(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* fd) const
{
return m_associated_component->read_bytes(offset, count, buffer, fd);
}
@ -91,7 +91,7 @@ ErrorOr<void> SysFSInode::flush_metadata()
return {};
}
ErrorOr<size_t> SysFSInode::write_bytes(off_t offset, size_t count, UserOrKernelBuffer const& buffer, OpenFileDescription* fd)
ErrorOr<size_t> SysFSInode::write_bytes_locked(off_t offset, size_t count, UserOrKernelBuffer const& buffer, OpenFileDescription* fd)
{
return m_associated_component->write_bytes(offset, count, buffer, fd);
}

View file

@ -42,12 +42,12 @@ public:
protected:
SysFSInode(SysFS const&, SysFSComponent const&);
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override;
virtual InodeMetadata metadata() const override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) override;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
virtual ErrorOr<void> add_child(Inode&, StringView name, mode_t) override;
virtual ErrorOr<void> remove_child(StringView name) override;

View file

@ -87,9 +87,9 @@ ErrorOr<void> TmpFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSyste
return {};
}
ErrorOr<size_t> TmpFSInode::read_bytes(off_t offset, size_t size, UserOrKernelBuffer& buffer, OpenFileDescription*) const
ErrorOr<size_t> TmpFSInode::read_bytes_locked(off_t offset, size_t size, UserOrKernelBuffer& buffer, OpenFileDescription*) const
{
MutexLocker locker(m_inode_lock, Mutex::Mode::Shared);
VERIFY(m_inode_lock.is_locked());
VERIFY(!is_directory());
VERIFY(offset >= 0);
@ -106,7 +106,7 @@ ErrorOr<size_t> TmpFSInode::read_bytes(off_t offset, size_t size, UserOrKernelBu
return size;
}
ErrorOr<size_t> TmpFSInode::write_bytes(off_t offset, size_t size, UserOrKernelBuffer const& buffer, OpenFileDescription*)
ErrorOr<size_t> TmpFSInode::write_bytes_locked(off_t offset, size_t size, UserOrKernelBuffer const& buffer, OpenFileDescription*)
{
VERIFY(m_inode_lock.is_locked());
VERIFY(!is_directory());

View file

@ -47,12 +47,10 @@ public:
TmpFS const& fs() const { return static_cast<TmpFS const&>(Inode::fs()); }
// ^Inode
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual InodeMetadata metadata() const override;
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView name) override;
virtual ErrorOr<void> flush_metadata() override;
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
virtual ErrorOr<void> add_child(Inode&, StringView name, mode_t) override;
virtual ErrorOr<void> remove_child(StringView name) override;
@ -66,6 +64,10 @@ private:
static ErrorOr<NonnullLockRefPtr<TmpFSInode>> try_create(TmpFS&, InodeMetadata const& metadata, LockWeakPtr<TmpFSInode> parent);
static ErrorOr<NonnullLockRefPtr<TmpFSInode>> try_create_root(TmpFS&);
// ^Inode
virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override;
struct Child {
NonnullOwnPtr<KString> name;
NonnullLockRefPtr<TmpFSInode> inode;

View file

@ -703,8 +703,6 @@ ErrorOr<void> VirtualFileSystem::symlink(Credentials const& credentials, StringV
auto inode = TRY(parent_inode.create_child(basename, S_IFLNK | 0644, 0, credentials.euid(), credentials.egid()));
auto target_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>((u8 const*)target.characters_without_null_termination()));
MutexLocker locker(inode->m_inode_lock);
TRY(inode->prepare_to_write_data());
TRY(inode->write_bytes(0, target.length(), target_buffer, nullptr));
return {};
}