From 093331425d1737ea4c3345d46f599be485e55860 Mon Sep 17 00:00:00 2001 From: Aliaksei Makarau Date: Mon, 20 Jun 2022 10:25:54 +0200 Subject: [PATCH] fsmap: switch to using iterator based loop 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 --- src/mds/FSMap.h | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/mds/FSMap.h b/src/mds/FSMap.h index 099c1337ceb..5bf2f6b267f 100644 --- a/src/mds/FSMap.h +++ b/src/mds/FSMap.h @@ -34,6 +34,22 @@ #include "common/Formatter.h" #include "mds/mdstypes.h" +#if __cplusplus <= 201703L +template +typename std::map::size_type +erase_if(std::map& 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) -- 2.47.3