소스 검색

FileSystem: Don't create a temporary FileDescriptor every time we stat().

Instead, move the stat buffer population into InodeMetadata so we can call
it directly from VFS::stat() once we have an Inode.
Andreas Kling 6 년 전
부모
커밋
00de8b9fc4
4개의 변경된 파일30개의 추가작업 그리고 29개의 파일을 삭제
  1. 1 19
      Kernel/FileSystem/FileDescriptor.cpp
  2. 28 2
      Kernel/FileSystem/InodeMetadata.h
  3. 1 1
      Kernel/FileSystem/VirtualFileSystem.cpp
  4. 0 7
      Kernel/FileSystem/VirtualFileSystem.h

+ 1 - 19
Kernel/FileSystem/FileDescriptor.cpp

@@ -81,25 +81,7 @@ KResult FileDescriptor::fstat(stat& buffer)
     ASSERT(!is_fifo());
     if (!m_inode)
         return KResult(-EBADF);
-
-    auto metadata = this->metadata();
-    if (!metadata.is_valid())
-        return KResult(-EIO);
-
-    buffer.st_rdev = encoded_device(metadata.major_device, metadata.minor_device);
-    buffer.st_ino = metadata.inode.index();
-    buffer.st_mode = metadata.mode;
-    buffer.st_nlink = metadata.link_count;
-    buffer.st_uid = metadata.uid;
-    buffer.st_gid = metadata.gid;
-    buffer.st_dev = 0; // FIXME
-    buffer.st_size = metadata.size;
-    buffer.st_blksize = metadata.block_size;
-    buffer.st_blocks = metadata.block_count;
-    buffer.st_atime = metadata.atime;
-    buffer.st_mtime = metadata.mtime;
-    buffer.st_ctime = metadata.ctime;
-    return KSuccess;
+    return metadata().stat(buffer);
 }
 
 KResult FileDescriptor::fchmod(mode_t mode)

+ 28 - 2
Kernel/FileSystem/InodeMetadata.h

@@ -1,11 +1,17 @@
 #pragma once
 
-#include "InodeIdentifier.h"
-#include "UnixTypes.h"
 #include <AK/HashTable.h>
+#include <Kernel/FileSystem/InodeIdentifier.h>
+#include <Kernel/KResult.h>
+#include <Kernel/UnixTypes.h>
 
 class Process;
 
+inline constexpr dword encoded_device(unsigned major, unsigned minor)
+{
+    return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
+}
+
 inline bool is_directory(mode_t mode) { return (mode & 0170000) == 0040000; }
 inline bool is_character_device(mode_t mode) { return (mode & 0170000) == 0020000; }
 inline bool is_block_device(mode_t mode) { return (mode & 0170000) == 0060000; }
@@ -69,6 +75,26 @@ struct InodeMetadata {
     bool is_setuid() const { return ::is_setuid(mode); }
     bool is_setgid() const { return ::is_setgid(mode); }
 
+    KResult stat(stat& buffer) const
+    {
+        if (!is_valid())
+            return KResult(-EIO);
+        buffer.st_rdev = encoded_device(major_device, minor_device);
+        buffer.st_ino = inode.index();
+        buffer.st_mode = mode;
+        buffer.st_nlink = link_count;
+        buffer.st_uid = uid;
+        buffer.st_gid = gid;
+        buffer.st_dev = 0; // FIXME
+        buffer.st_size = size;
+        buffer.st_blksize = block_size;
+        buffer.st_blocks = block_count;
+        buffer.st_atime = atime;
+        buffer.st_mtime = mtime;
+        buffer.st_ctime = ctime;
+        return KSuccess;
+    }
+
     InodeIdentifier inode;
     off_t size { 0 };
     mode_t mode { 0 };

+ 1 - 1
Kernel/FileSystem/VirtualFileSystem.cpp

@@ -146,7 +146,7 @@ KResult VFS::stat(StringView path, int options, Custody& base, struct stat& stat
     auto custody_or_error = resolve_path(path, base, nullptr, options);
     if (custody_or_error.is_error())
         return custody_or_error.error();
-    return FileDescriptor::create(custody_or_error.value().ptr())->fstat(statbuf);
+    return custody_or_error.value()->inode().metadata().stat(statbuf);
 }
 
 KResultOr<Retained<FileDescriptor>> VFS::open(StringView path, int options, mode_t mode, Custody& base)

+ 0 - 7
Kernel/FileSystem/VirtualFileSystem.h

@@ -30,13 +30,6 @@ class Custody;
 class Device;
 class FileDescriptor;
 
-inline constexpr dword encoded_device(unsigned major, unsigned minor)
-{
-    return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
-}
-
-class VFS;
-
 class VFS {
     AK_MAKE_ETERNAL
 public: