]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
fsmap: switch to using iterator based loop 48268/head
authorAliaksei Makarau <aliaksei.makarau@ibm.com>
Mon, 20 Jun 2022 08:25:54 +0000 (10:25 +0200)
committerVenky Shankar <vshankar@redhat.com>
Tue, 27 Sep 2022 07:39:02 +0000 (13:09 +0530)
Segfault was triggered by the fs/mirror test.
The problem is in potential undefined behaviour
after erasing element and iterator invalidation in
FSMap::filter().
Fixed by explicit iterator increment.

Fixes: https://tracker.ceph.com/issues/55134
Signed-off-by: Aliaksei Makarau <aliaksei.makarau@ibm.com>
(cherry picked from commit 093331425d1737ea4c3345d46f599be485e55860)

src/mds/FSMap.h

index 099c1337ceb864b1da9e30a71bab8d550e60284a..5bf2f6b267f1d2ab75c5aa2c478f4fc1a4013461 100644 (file)
 #include "common/Formatter.h"
 #include "mds/mdstypes.h"
 
+#if __cplusplus <= 201703L
+template<class Key, class T, class Compare, class Alloc, class Pred>
+typename std::map<Key, T, Compare, Alloc>::size_type
+erase_if(std::map<Key, T, Compare, Alloc>& c, Pred pred) {
+  auto old_size = c.size();
+  for (auto i = c.begin(), last = c.end(); i != last; ) {
+    if (pred(*i)) {
+      i = c.erase(i);
+    } else {
+      ++i;
+    }
+  }
+  return old_size - c.size();
+}
+#endif
+
 class health_check_map_t;
 
 struct ClusterInfo {
@@ -259,19 +275,13 @@ public:
       return;
     }
 
-    for (auto &f : filesystems) {
-      std::string_view fs_name = f.second->mds_map.get_fs_name();
-      if (std::find(allowed.begin(), allowed.end(), fs_name) == allowed.end()) {
-       filesystems.erase(f.first);
-      }
-    }
+    erase_if(filesystems, [&](const auto& f) {
+      return std::find(allowed.begin(), allowed.end(), f.second->mds_map.get_fs_name()) == allowed.end();
+    });
 
-    for (auto r : mds_roles) {
-      std::string_view fs_name = fs_name_from_gid(r.first);
-      if (std::find(allowed.begin(), allowed.end(), fs_name) == allowed.end()) {
-       mds_roles.erase(r.first);
-      }
-    }
+    erase_if(mds_roles, [&](const auto& r) {
+      return std::find(allowed.begin(), allowed.end(), fs_name_from_gid(r.first)) == allowed.end();
+    });
   }
 
   void set_enable_multiple(const bool v)