mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 06:48: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:
parent
4f4717e351
commit
c88cc8557f
20 changed files with 87 additions and 72 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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&);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue