Bladeren bron

Kernel: Make Inode::register_watcher() OOM-fallible

Idan Horowitz 3 jaren geleden
bovenliggende
commit
a9cd8ca841
3 gewijzigde bestanden met toevoegingen van 14 en 7 verwijderingen
  1. 3 2
      Kernel/FileSystem/Inode.cpp
  2. 1 1
      Kernel/FileSystem/Inode.h
  3. 10 4
      Kernel/FileSystem/InodeWatcher.cpp

+ 3 - 2
Kernel/FileSystem/Inode.cpp

@@ -154,11 +154,12 @@ bool Inode::unbind_socket()
     return true;
 }
 
-void Inode::register_watcher(Badge<InodeWatcher>, InodeWatcher& watcher)
+ErrorOr<void> Inode::register_watcher(Badge<InodeWatcher>, InodeWatcher& watcher)
 {
     MutexLocker locker(m_inode_lock);
     VERIFY(!m_watchers.contains(&watcher));
-    m_watchers.set(&watcher);
+    TRY(m_watchers.try_set(&watcher));
+    return {};
 }
 
 void Inode::unregister_watcher(Badge<InodeWatcher>, InodeWatcher& watcher)

+ 1 - 1
Kernel/FileSystem/Inode.h

@@ -91,7 +91,7 @@ public:
 
     bool has_watchers() const { return !m_watchers.is_empty(); }
 
-    void register_watcher(Badge<InodeWatcher>, InodeWatcher&);
+    ErrorOr<void> register_watcher(Badge<InodeWatcher>, InodeWatcher&);
     void unregister_watcher(Badge<InodeWatcher>, InodeWatcher&);
 
     ErrorOr<NonnullRefPtr<FIFO>> fifo();

+ 10 - 4
Kernel/FileSystem/InodeWatcher.cpp

@@ -124,13 +124,19 @@ ErrorOr<int> InodeWatcher::register_inode(Inode& inode, unsigned event_mask)
     auto description = TRY(WatchDescription::create(wd, inode, event_mask));
 
     TRY(m_inode_to_watches.try_set(inode.identifier(), description.ptr()));
-    auto result = m_wd_to_watches.try_set(wd, move(description));
-    if (result.is_error()) {
+    auto set_result = m_wd_to_watches.try_set(wd, move(description));
+    if (set_result.is_error()) {
         m_inode_to_watches.remove(inode.identifier());
-        return result.release_error();
+        return set_result.release_error();
+    }
+
+    auto register_result = inode.register_watcher({}, *this);
+    if (register_result.is_error()) {
+        m_inode_to_watches.remove(inode.identifier());
+        m_wd_to_watches.remove(wd);
+        return register_result.release_error();
     }
 
-    inode.register_watcher({}, *this);
     return wd;
 }