Преглед изворни кода

Kernel: Closing a file descriptor should not always close the file

When there is more than one file descriptor for a file closing
one of them should not close the underlying file.

Previously this relied on the file's ref_count() but at least
for sockets this didn't work reliably.
Gunnar Beutner пре 4 година
родитељ
комит
7a1d09ef1a
3 измењених фајлова са 17 додато и 3 уклоњено
  1. 11 0
      Kernel/FileSystem/File.cpp
  2. 5 2
      Kernel/FileSystem/File.h
  3. 1 1
      Kernel/FileSystem/FileDescription.cpp

+ 11 - 0
Kernel/FileSystem/File.cpp

@@ -43,4 +43,15 @@ KResultOr<Region*> File::mmap(Process&, FileDescription&, const Range&, u64, int
     return ENODEV;
 }
 
+KResult File::attach(FileDescription&)
+{
+    m_attach_count++;
+    return KSuccess;
+}
+
+void File::detach(FileDescription&)
+{
+    m_attach_count--;
+}
+
 }

+ 5 - 2
Kernel/FileSystem/File.h

@@ -82,8 +82,8 @@ public:
     virtual bool can_read(const FileDescription&, size_t) const = 0;
     virtual bool can_write(const FileDescription&, size_t) const = 0;
 
-    virtual KResult attach(FileDescription&) { return KSuccess; }
-    virtual void detach(FileDescription&) { }
+    virtual KResult attach(FileDescription&);
+    virtual void detach(FileDescription&);
     virtual void did_seek(FileDescription&, off_t) { }
     virtual KResultOr<size_t> read(FileDescription&, u64, UserOrKernelBuffer&, size_t) = 0;
     virtual KResultOr<size_t> write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) = 0;
@@ -112,6 +112,8 @@ public:
 
     virtual FileBlockCondition& block_condition() { return m_block_condition; }
 
+    size_t attach_count() const { return m_attach_count; }
+
 protected:
     File();
 
@@ -138,6 +140,7 @@ private:
     }
 
     FileBlockCondition m_block_condition;
+    size_t m_attach_count { 0 };
 };
 
 }

+ 1 - 1
Kernel/FileSystem/FileDescription.cpp

@@ -288,7 +288,7 @@ MasterPTY* FileDescription::master_pty()
 
 KResult FileDescription::close()
 {
-    if (m_file->ref_count() > 1)
+    if (m_file->attach_count() > 0)
         return KSuccess;
     return m_file->close();
 }