]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
fsmap: switch to using iterator based loop 48269/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:37:14 +0000 (13:07 +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)

 Conflicts:
src/mds/FSMap.h

Conflict due to use of std::string_view vs string_view.

src/mds/FSMap.h

index 9cb2dce45b2b994f85f57aea875889ebc32a5c2c..f6c24e4d45eda94e4d8f15d54cbfe46250bae630 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) {
-      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) {
-      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)