mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:07:35 +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 {};
|
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)
|
if (static_cast<u64>(m_raw_inode.i_size) == size)
|
||||||
return {};
|
return {};
|
||||||
TRY(resize(size));
|
TRY(resize(size));
|
||||||
|
|
|
@ -42,7 +42,7 @@ private:
|
||||||
virtual ErrorOr<void> decrement_link_count() override;
|
virtual ErrorOr<void> decrement_link_count() override;
|
||||||
virtual ErrorOr<void> chmod(mode_t) override;
|
virtual ErrorOr<void> chmod(mode_t) override;
|
||||||
virtual ErrorOr<void> chown(UserID, GroupID) 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;
|
virtual ErrorOr<int> get_block_address(int) override;
|
||||||
|
|
||||||
ErrorOr<void> write_directory(Vector<Ext2FSDirectoryEntry>&);
|
ErrorOr<void> write_directory(Vector<Ext2FSDirectoryEntry>&);
|
||||||
|
|
|
@ -140,7 +140,7 @@ ErrorOr<void> ISO9660Inode::chown(UserID, GroupID)
|
||||||
return EROFS;
|
return EROFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> ISO9660Inode::truncate(u64)
|
ErrorOr<void> ISO9660Inode::truncate_locked(u64)
|
||||||
{
|
{
|
||||||
return EROFS;
|
return EROFS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
||||||
virtual ErrorOr<void> chmod(mode_t) override;
|
virtual ErrorOr<void> chmod(mode_t) override;
|
||||||
virtual ErrorOr<void> chown(UserID, GroupID) 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> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -88,6 +88,12 @@ void Inode::will_be_destroyed()
|
||||||
(void)flush_metadata();
|
(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)
|
ErrorOr<size_t> Inode::write_bytes(off_t offset, size_t length, UserOrKernelBuffer const& target_buffer, OpenFileDescription* open_description)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
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> 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_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<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 ErrorOr<void> attach(OpenFileDescription&) { return {}; }
|
||||||
virtual void detach(OpenFileDescription&) { }
|
virtual void detach(OpenFileDescription&) { }
|
||||||
|
@ -70,7 +71,6 @@ public:
|
||||||
virtual ErrorOr<void> replace_child(StringView name, Inode&) = 0;
|
virtual ErrorOr<void> replace_child(StringView name, Inode&) = 0;
|
||||||
virtual ErrorOr<void> chmod(mode_t) = 0;
|
virtual ErrorOr<void> chmod(mode_t) = 0;
|
||||||
virtual ErrorOr<void> chown(UserID, GroupID) = 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;
|
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> 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<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const = 0;
|
||||||
|
virtual ErrorOr<void> truncate_locked(u64) { return {}; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ErrorOr<bool> try_apply_flock(Process const&, OpenFileDescription const&, flock const&);
|
ErrorOr<bool> try_apply_flock(Process const&, OpenFileDescription const&, flock const&);
|
||||||
|
|
|
@ -284,8 +284,9 @@ ErrorOr<void> Plan9FSInode::chown(UserID, GroupID)
|
||||||
return ENOTIMPL;
|
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) {
|
if (fs().m_remote_protocol_version >= Plan9FS::ProtocolVersion::v9P2000L) {
|
||||||
Plan9FSMessage message { fs(), Plan9FSMessage::Type::Tsetattr };
|
Plan9FSMessage message { fs(), Plan9FSMessage::Type::Tsetattr };
|
||||||
SetAttrMask valid = SetAttrMask::Size;
|
SetAttrMask valid = SetAttrMask::Size;
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
||||||
virtual ErrorOr<void> chmod(mode_t) override;
|
virtual ErrorOr<void> chmod(mode_t) override;
|
||||||
virtual ErrorOr<void> chown(UserID, GroupID) override;
|
virtual ErrorOr<void> chown(UserID, GroupID) override;
|
||||||
virtual ErrorOr<void> truncate(u64) override;
|
virtual ErrorOr<void> truncate_locked(u64) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// ^Inode
|
// ^Inode
|
||||||
|
|
|
@ -50,7 +50,7 @@ private:
|
||||||
virtual ErrorOr<void> chmod(mode_t) override { return EROFS; }
|
virtual ErrorOr<void> chmod(mode_t) override { return EROFS; }
|
||||||
virtual ErrorOr<void> chown(UserID, GroupID) 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<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)
|
// ^Inode (Silent ignore handling)
|
||||||
virtual ErrorOr<void> flush_metadata() override { return {}; }
|
virtual ErrorOr<void> flush_metadata() override { return {}; }
|
||||||
|
|
|
@ -361,9 +361,9 @@ ErrorOr<void> RAMFSInode::remove_child(StringView name)
|
||||||
return {};
|
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());
|
VERIFY(!is_directory());
|
||||||
|
|
||||||
u64 block_index = size / DataBlock::block_size + ((size % DataBlock::block_size == 0) ? 0 : 1);
|
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> replace_child(StringView name, Inode& child) override;
|
||||||
virtual ErrorOr<void> chmod(mode_t) override;
|
virtual ErrorOr<void> chmod(mode_t) override;
|
||||||
virtual ErrorOr<void> chown(UserID, GroupID) 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> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -105,8 +105,9 @@ ErrorOr<void> SysFSInode::chown(UserID, GroupID)
|
||||||
return EPERM;
|
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);
|
return m_associated_component->truncate(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ protected:
|
||||||
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
virtual ErrorOr<void> replace_child(StringView name, Inode& child) override;
|
||||||
virtual ErrorOr<void> chmod(mode_t) override;
|
virtual ErrorOr<void> chmod(mode_t) override;
|
||||||
virtual ErrorOr<void> chown(UserID, GroupID) 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> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) override;
|
||||||
|
|
||||||
virtual ErrorOr<void> attach(OpenFileDescription& description) override final;
|
virtual ErrorOr<void> attach(OpenFileDescription& description) override final;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue