summaryrefslogtreecommitdiff
path: root/Kernel/FileSystem
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-07-27 21:42:16 +0300
committerLinus Groh <mail@linusgroh.de>2022-07-30 23:31:08 +0200
commitfcc0e4d538ce1583d285bf28c171002e8d79dbb9 (patch)
treec99399dab8fb4578ddd338ea7120fdcf9b3bfee0 /Kernel/FileSystem
parent38bf7863d0bcaa0ee77a17bd9c1460e909d8b0d7 (diff)
downloadserenity-fcc0e4d538ce1583d285bf28c171002e8d79dbb9.zip
Kernel/FileSystem: Funnel calls to Inode::prepare_to_write_data method
Instead of requiring each FileSystem implementation to call this method when trying to write data, do the calls at 2 points to avoid further calls (or lack of them due to not remembering to use it) at other files and locations in the codebase.
Diffstat (limited to 'Kernel/FileSystem')
-rw-r--r--Kernel/FileSystem/Ext2FileSystem.cpp5
-rw-r--r--Kernel/FileSystem/Inode.cpp4
-rw-r--r--Kernel/FileSystem/Inode.h1
-rw-r--r--Kernel/FileSystem/InodeFile.cpp7
-rw-r--r--Kernel/FileSystem/TmpFS.cpp4
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.cpp2
6 files changed, 12 insertions, 11 deletions
diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp
index 08c77aa3a0..1d66841459 100644
--- a/Kernel/FileSystem/Ext2FileSystem.cpp
+++ b/Kernel/FileSystem/Ext2FileSystem.cpp
@@ -937,15 +937,12 @@ ErrorOr<void> Ext2FSInode::resize(u64 new_size)
ErrorOr<size_t> Ext2FSInode::write_bytes(off_t offset, size_t count, UserOrKernelBuffer const& data, OpenFileDescription* description)
{
+ VERIFY(m_inode_lock.is_locked());
VERIFY(offset >= 0);
if (count == 0)
return 0;
- MutexLocker inode_locker(m_inode_lock);
-
- TRY(prepare_to_write_data());
-
if (is_symlink()) {
VERIFY(offset == 0);
if (max((size_t)(offset + count), (size_t)m_raw_inode.i_size) < max_inline_symlink_length) {
diff --git a/Kernel/FileSystem/Inode.cpp b/Kernel/FileSystem/Inode.cpp
index 69f495d101..62f37aa7a7 100644
--- a/Kernel/FileSystem/Inode.cpp
+++ b/Kernel/FileSystem/Inode.cpp
@@ -253,9 +253,7 @@ void Inode::did_delete_self()
ErrorOr<void> Inode::prepare_to_write_data()
{
- // FIXME: It's a poor design that filesystems are expected to call this before writing out data.
- // We should funnel everything through an interface at the VirtualFileSystem layer so this can happen from a single place.
- MutexLocker locker(m_inode_lock);
+ VERIFY(m_inode_lock.is_locked());
if (fs().is_readonly())
return EROFS;
auto metadata = this->metadata();
diff --git a/Kernel/FileSystem/Inode.h b/Kernel/FileSystem/Inode.h
index 479c86167c..3974d96350 100644
--- a/Kernel/FileSystem/Inode.h
+++ b/Kernel/FileSystem/Inode.h
@@ -31,6 +31,7 @@ class Inode : public ListedRefCounted<Inode, LockType::Spinlock>
, public Weakable<Inode> {
friend class VirtualFileSystem;
friend class FileSystem;
+ friend class InodeFile;
public:
virtual ~Inode();
diff --git a/Kernel/FileSystem/InodeFile.cpp b/Kernel/FileSystem/InodeFile.cpp
index bbc030908e..04056e6e88 100644
--- a/Kernel/FileSystem/InodeFile.cpp
+++ b/Kernel/FileSystem/InodeFile.cpp
@@ -42,7 +42,12 @@ ErrorOr<size_t> InodeFile::write(OpenFileDescription& description, u64 offset, U
if (Checked<off_t>::addition_would_overflow(offset, count))
return EOVERFLOW;
- auto nwritten = TRY(m_inode->write_bytes(offset, count, data, &description));
+ 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));
+ }
if (nwritten > 0) {
auto mtime_result = m_inode->set_mtime(kgettimeofday().to_truncated_seconds());
Thread::current()->did_file_write(nwritten);
diff --git a/Kernel/FileSystem/TmpFS.cpp b/Kernel/FileSystem/TmpFS.cpp
index 2c4ba99891..a0dbf463f3 100644
--- a/Kernel/FileSystem/TmpFS.cpp
+++ b/Kernel/FileSystem/TmpFS.cpp
@@ -108,12 +108,10 @@ ErrorOr<size_t> TmpFSInode::read_bytes(off_t offset, size_t size, UserOrKernelBu
ErrorOr<size_t> TmpFSInode::write_bytes(off_t offset, size_t size, UserOrKernelBuffer const& buffer, OpenFileDescription*)
{
- MutexLocker locker(m_inode_lock);
+ VERIFY(m_inode_lock.is_locked());
VERIFY(!is_directory());
VERIFY(offset >= 0);
- TRY(prepare_to_write_data());
-
off_t old_size = m_metadata.size;
off_t new_size = m_metadata.size;
if (static_cast<off_t>(offset + size) > new_size)
diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp
index d17530e344..ac9eb700bc 100644
--- a/Kernel/FileSystem/VirtualFileSystem.cpp
+++ b/Kernel/FileSystem/VirtualFileSystem.cpp
@@ -693,6 +693,8 @@ ErrorOr<void> VirtualFileSystem::symlink(StringView target, StringView linkpath,
auto inode = TRY(parent_inode.create_child(basename, S_IFLNK | 0644, 0, current_process.euid(), current_process.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 {};
}