From: Tongliang Deng Date: Fri, 31 Dec 2021 06:02:25 +0000 (+0800) Subject: mon/OSDMonitor: fix integer underflow of check_pg_num X-Git-Tag: v18.0.0~1548^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=bd9813f5e1a3addca1a57360d58b50b120e0e5f3;p=ceph.git mon/OSDMonitor: fix integer underflow of check_pg_num Underflow of the `uint64_t projected` variable occurs when the sum of current acting pg num and new pg num we specified is less than the pg num calculated from pg info. Signed-off-by: Tongliang Deng --- diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index a35d0137862e..1550af6b6480 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -7823,13 +7823,12 @@ int OSDMonitor::check_pg_num(int64_t pool, int pg_num, int size, int crush_rule, } osd_num += osd_ids.size() - out_osd; } - if (pool >= 0) { - // update an existing pool's pg num - const auto& pg_info = osdmap.get_pools().at(pool); - // already counted the pgs of this `pool` by iterating crush map, so + if (pool >= 0) { + // update an existing pool's pg num. + // already counted the pgs of this `pool` by iterating crush map, so // remove them using adding the specified pg num projected += pg_num * size; - projected -= pg_info.get_pg_num_target() * pg_info.get_size(); + projected -= mapping.get_num_acting_pgs(pool); } num_osds = std::max(osd_num, 3u); // assume min cluster size 3 } else { diff --git a/src/osd/OSDMapMapping.h b/src/osd/OSDMapMapping.h index 216c30446a95..0019eebf0838 100644 --- a/src/osd/OSDMapMapping.h +++ b/src/osd/OSDMapMapping.h @@ -247,6 +247,16 @@ private: row[4 + size + i] = up[i]; } } + + uint64_t get_num_acting_pgs() const { + uint64_t num_acting_pgs = 0; + const size_t row_size = this->row_size(); + for (size_t ps = 0; ps < pg_num; ++ps) { + const int32_t *row = &table[row_size * ps]; + num_acting_pgs += row[2]; + } + return num_acting_pgs; + } }; mempool::osdmap_mapping::map pools; @@ -330,6 +340,12 @@ public: return acting_rmap[osd]; } + uint64_t get_num_acting_pgs(int64_t pool) const { + auto p = pools.find(pool); + ceph_assert(p != pools.end()); + return p->second.get_num_acting_pgs(); + } + void update(const OSDMap& map, pg_t pgid); std::unique_ptr start_update(