Преглед на файлове

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.
Liav A преди 3 години
родител
ревизия
fcc0e4d538

+ 1 - 4
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) {

+ 1 - 3
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();

+ 1 - 0
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();

+ 6 - 1
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);

+ 1 - 3
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)

+ 2 - 0
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 {};
 }