mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 06:24:58 +00:00
Kernel/FileSystem: Enforce locking of m_inode_lock when truncating Inode
Such operation is almost equivalent to writing on an Inode, so lock the Inode m_inode_lock exclusively. All FileSystem Inode implementations then override a new method called truncate_locked which should implement the actual truncating.
This commit is contained in:
parent
53dd04e219
commit
b63a1dda63
13 changed files with 23 additions and 14 deletions
|
@ -1071,9 +1071,9 @@ ErrorOr<void> Ext2FSInode::chown(UserID uid, GroupID gid)
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> Ext2FSInode::truncate(u64 size)
|
||||
ErrorOr<void> Ext2FSInode::truncate_locked(u64 size)
|
||||
{
|
||||
MutexLocker locker(m_inode_lock);
|
||||
VERIFY(m_inode_lock.is_locked());
|
||||
if (static_cast<u64>(m_raw_inode.i_size) == size)
|
||||
return {};
|
||||
TRY(resize(size));
|
||||
|
|
|
@ -42,7 +42,7 @@ private:
|
|||
virtual ErrorOr<void> decrement_link_count() override;
|
||||
virtual ErrorOr<void> chmod(mode_t) override;
|
||||
virtual ErrorOr<void> chown(UserID, GroupID) override;
|
||||
virtual ErrorOr<void> truncate(u64) override;
|
||||
virtual ErrorOr<void> truncate_locked(u64) override;
|
||||
virtual ErrorOr<int> get_block_address(int) override;
|
||||
|
||||
ErrorOr<void> write_directory(Vector<Ext2FSDirectoryEntry>&);
|
||||
|
|
|
@ -140,7 +140,7 @@ ErrorOr<void> ISO9660Inode::chown(UserID, GroupID)
|
|||
return EROFS;
|
||||
}
|
||||
|
||||
ErrorOr<void> ISO9660Inode::truncate(u64)
|
||||
ErrorOr<void> ISO9660Inode::truncate_locked(u64)
|
||||
{
|
||||
return EROFS;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
||||
virtual ErrorOr<void> chmod(mode_t) override;
|
||||
virtual ErrorOr<void> chown(UserID, GroupID) override;
|
||||
virtual ErrorOr<void> truncate(u64) override;
|
||||
virtual ErrorOr<void> truncate_locked(u64) override;
|
||||
virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -88,6 +88,12 @@ void Inode::will_be_destroyed()
|
|||
(void)flush_metadata();
|
||||
}
|
||||
|
||||
ErrorOr<void> Inode::truncate(u64 size)
|
||||
{
|
||||
MutexLocker locker(m_inode_lock);
|
||||
return truncate_locked(size);
|
||||
}
|
||||
|
||||
ErrorOr<size_t> Inode::write_bytes(off_t offset, size_t length, UserOrKernelBuffer const& target_buffer, OpenFileDescription* open_description)
|
||||
{
|
||||
MutexLocker locker(m_inode_lock);
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
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;
|
||||
ErrorOr<size_t> read_until_filled_or_end(off_t, size_t, UserOrKernelBuffer buffer, OpenFileDescription*) const;
|
||||
ErrorOr<void> truncate(u64);
|
||||
|
||||
virtual ErrorOr<void> attach(OpenFileDescription&) { return {}; }
|
||||
virtual void detach(OpenFileDescription&) { }
|
||||
|
@ -70,7 +71,6 @@ public:
|
|||
virtual ErrorOr<void> replace_child(StringView name, Inode&) = 0;
|
||||
virtual ErrorOr<void> chmod(mode_t) = 0;
|
||||
virtual ErrorOr<void> chown(UserID, GroupID) = 0;
|
||||
virtual ErrorOr<void> truncate(u64) { return {}; }
|
||||
|
||||
ErrorOr<NonnullRefPtr<Custody>> resolve_as_link(Credentials const&, Custody& base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level) const;
|
||||
|
||||
|
@ -123,6 +123,7 @@ protected:
|
|||
|
||||
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;
|
||||
virtual ErrorOr<void> truncate_locked(u64) { return {}; }
|
||||
|
||||
private:
|
||||
ErrorOr<bool> try_apply_flock(Process const&, OpenFileDescription const&, flock const&);
|
||||
|
|
|
@ -284,8 +284,9 @@ ErrorOr<void> Plan9FSInode::chown(UserID, GroupID)
|
|||
return ENOTIMPL;
|
||||
}
|
||||
|
||||
ErrorOr<void> Plan9FSInode::truncate(u64 new_size)
|
||||
ErrorOr<void> Plan9FSInode::truncate_locked(u64 new_size)
|
||||
{
|
||||
VERIFY(m_inode_lock.is_locked());
|
||||
if (fs().m_remote_protocol_version >= Plan9FS::ProtocolVersion::v9P2000L) {
|
||||
Plan9FSMessage message { fs(), Plan9FSMessage::Type::Tsetattr };
|
||||
SetAttrMask valid = SetAttrMask::Size;
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
||||
virtual ErrorOr<void> chmod(mode_t) override;
|
||||
virtual ErrorOr<void> chown(UserID, GroupID) override;
|
||||
virtual ErrorOr<void> truncate(u64) override;
|
||||
virtual ErrorOr<void> truncate_locked(u64) override;
|
||||
|
||||
private:
|
||||
// ^Inode
|
||||
|
|
|
@ -50,7 +50,7 @@ private:
|
|||
virtual ErrorOr<void> chmod(mode_t) override { return EROFS; }
|
||||
virtual ErrorOr<void> chown(UserID, GroupID) override { return EROFS; }
|
||||
virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) override { return EROFS; }
|
||||
virtual ErrorOr<void> truncate(u64) override { return EROFS; }
|
||||
virtual ErrorOr<void> truncate_locked(u64) override { return EROFS; }
|
||||
|
||||
// ^Inode (Silent ignore handling)
|
||||
virtual ErrorOr<void> flush_metadata() override { return {}; }
|
||||
|
|
|
@ -361,9 +361,9 @@ ErrorOr<void> RAMFSInode::remove_child(StringView name)
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> RAMFSInode::truncate(u64 size)
|
||||
ErrorOr<void> RAMFSInode::truncate_locked(u64 size)
|
||||
{
|
||||
MutexLocker locker(m_inode_lock);
|
||||
VERIFY(m_inode_lock.is_locked());
|
||||
VERIFY(!is_directory());
|
||||
|
||||
u64 block_index = size / DataBlock::block_size + ((size % DataBlock::block_size == 0) ? 0 : 1);
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
||||
virtual ErrorOr<void> chmod(mode_t) override;
|
||||
virtual ErrorOr<void> chown(UserID, GroupID) override;
|
||||
virtual ErrorOr<void> truncate(u64) override;
|
||||
virtual ErrorOr<void> truncate_locked(u64) override;
|
||||
virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -105,8 +105,9 @@ ErrorOr<void> SysFSInode::chown(UserID, GroupID)
|
|||
return EPERM;
|
||||
}
|
||||
|
||||
ErrorOr<void> SysFSInode::truncate(u64 size)
|
||||
ErrorOr<void> SysFSInode::truncate_locked(u64 size)
|
||||
{
|
||||
VERIFY(m_inode_lock.is_locked());
|
||||
return m_associated_component->truncate(size);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ protected:
|
|||
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
||||
virtual ErrorOr<void> chmod(mode_t) override;
|
||||
virtual ErrorOr<void> chown(UserID, GroupID) override;
|
||||
virtual ErrorOr<void> truncate(u64) override;
|
||||
virtual ErrorOr<void> truncate_locked(u64) override;
|
||||
virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) override;
|
||||
|
||||
virtual ErrorOr<void> attach(OpenFileDescription& description) override final;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue