Bläddra i källkod

Kernel: Use a FixedArray for a process's extra GIDs

There's not really enough of these to justify using a HashTable.
Andreas Kling 5 år sedan
förälder
incheckning
a7dbb3cf96
5 ändrade filer med 42 tillägg och 12 borttagningar
  1. 22 1
      AK/FixedArray.h
  2. 1 0
      Kernel/FileSystem/Inode.h
  3. 4 4
      Kernel/FileSystem/InodeMetadata.h
  4. 12 5
      Kernel/Process.cpp
  5. 3 2
      Kernel/Process.h

+ 22 - 1
AK/FixedArray.h

@@ -54,7 +54,13 @@ public:
             new (&m_elements[i]) T(other[i]);
     }
 
-    FixedArray& operator=(const FixedArray&) = delete;
+    FixedArray& operator=(const FixedArray& other)
+    {
+        FixedArray array(other);
+        swap(array);
+        return *this;
+    }
+
     FixedArray(FixedArray&&) = delete;
     FixedArray& operator=(FixedArray&&) = delete;
 
@@ -109,6 +115,21 @@ public:
         m_size = new_size;
     }
 
+    bool contains(const T& value) const
+    {
+        for (size_t i = 0; i < m_size; ++i) {
+            if (m_elements[i] == value)
+                return true;
+        }
+        return false;
+    }
+
+    void swap(FixedArray& other)
+    {
+        ::swap(m_elements, other.m_elements);
+        ::swap(m_size, other.m_size);
+    }
+
     using Iterator = VectorIterator<FixedArray, T>;
     Iterator begin() { return Iterator(*this, 0); }
     Iterator end() { return Iterator(*this, size()); }

+ 1 - 0
Kernel/FileSystem/Inode.h

@@ -27,6 +27,7 @@
 #pragma once
 
 #include <AK/Function.h>
+#include <AK/HashTable.h>
 #include <AK/InlineLinkedList.h>
 #include <AK/RefCounted.h>
 #include <AK/String.h>

+ 4 - 4
Kernel/FileSystem/InodeMetadata.h

@@ -26,7 +26,7 @@
 
 #pragma once
 
-#include <AK/HashTable.h>
+#include <AK/FixedArray.h>
 #include <Kernel/FileSystem/InodeIdentifier.h>
 #include <Kernel/KResult.h>
 #include <Kernel/UnixTypes.h>
@@ -58,7 +58,7 @@ struct InodeMetadata {
     bool may_write(const Process&) const;
     bool may_execute(const Process&) const;
 
-    bool may_read(uid_t u, gid_t g, const HashTable<gid_t>& eg) const
+    bool may_read(uid_t u, gid_t g, const FixedArray<gid_t>& eg) const
     {
         if (u == 0)
             return true;
@@ -69,7 +69,7 @@ struct InodeMetadata {
         return mode & 0004;
     }
 
-    bool may_write(uid_t u, gid_t g, const HashTable<gid_t>& eg) const
+    bool may_write(uid_t u, gid_t g, const FixedArray<gid_t>& eg) const
     {
         if (u == 0)
             return true;
@@ -80,7 +80,7 @@ struct InodeMetadata {
         return mode & 0002;
     }
 
-    bool may_execute(uid_t u, gid_t g, const HashTable<gid_t>& eg) const
+    bool may_execute(uid_t u, gid_t g, const FixedArray<gid_t>& eg) const
     {
         if (u == 0)
             return true;

+ 12 - 5
Kernel/Process.cpp

@@ -219,7 +219,7 @@ Region* Process::allocate_region_with_vmobject(const Range& range, NonnullRefPtr
 {
     ASSERT(range.is_valid());
     size_t end_in_vmobject = offset_in_vmobject + range.size();
-    if (end_in_vmobject < offset_in_vmobject) {
+    if (end_in_vmobject <= offset_in_vmobject) {
         dbgprintf("allocate_region_with_vmobject: Overflow (offset + size)\n");
         return nullptr;
     }
@@ -2663,11 +2663,18 @@ int Process::sys$setgroups(ssize_t count, const gid_t* user_gids)
     gids.resize(count);
     copy_from_user(gids.data(), user_gids, sizeof(gid_t) * count);
 
-    m_extra_gids.clear();
-    for (int i = 0; i < count; ++i) {
-        if (gids[i] == m_gid)
+    HashTable<gid_t> unique_extra_gids;
+    for (auto& gid : gids) {
+        if (gid != m_gid)
+            unique_extra_gids.set(gid);
+    }
+
+    m_extra_gids.resize(unique_extra_gids.size());
+    size_t i = 0;
+    for (auto& gid : unique_extra_gids) {
+        if (gid == m_gid)
             continue;
-        m_extra_gids.set(gids[i]);
+        m_extra_gids[i++] = gid;
     }
     return 0;
 }

+ 3 - 2
Kernel/Process.h

@@ -26,6 +26,7 @@
 
 #pragma once
 
+#include <AK/FixedArray.h>
 #include <AK/HashMap.h>
 #include <AK/InlineLinkedList.h>
 #include <AK/NonnullOwnPtrVector.h>
@@ -134,7 +135,7 @@ public:
     pid_t pgid() const { return m_pgid; }
     uid_t uid() const { return m_uid; }
     gid_t gid() const { return m_gid; }
-    const HashTable<gid_t>& extra_gids() const { return m_extra_gids; }
+    const FixedArray<gid_t>& extra_gids() const { return m_extra_gids; }
     uid_t euid() const { return m_euid; }
     gid_t egid() const { return m_egid; }
     pid_t ppid() const { return m_ppid; }
@@ -485,7 +486,7 @@ private:
     pid_t m_ppid { 0 };
     mode_t m_umask { 022 };
 
-    HashTable<gid_t> m_extra_gids;
+    FixedArray<gid_t> m_extra_gids;
 
     RefPtr<ProcessTracer> m_tracer;
     OwnPtr<ELFLoader> m_elf_loader;