]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/OSDMonitor: fix integer underflow of check_pg_num
authorTongliang Deng <dengtongliang@gmail.com>
Fri, 31 Dec 2021 06:02:25 +0000 (14:02 +0800)
committerMatan Breizman <mbreizma@redhat.com>
Thu, 9 Mar 2023 09:33:17 +0000 (09:33 +0000)
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 <dengtongliang@gmail.com>
Note: This commit is cherry-picked as a dependency
      for later commits in this backport.
(cherry picked from commit bd9813f5e1a3addca1a57360d58b50b120e0e5f3)

src/mon/OSDMonitor.cc
src/osd/OSDMapMapping.h

index 5d76862e0a8346a593879f0f69b55870a04fc912..b64da5fb6c9849fa4969ff4a6725088b28ebe12c 100644 (file)
@@ -7932,13 +7932,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 {
index 8f779c41e6698a39a390feab47ff4e941ec32e43..eeeb7a8bc7f3a9cb7d392edfa34f495c08995822 100644 (file)
@@ -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<int64_t,PoolMapping> 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<MappingJob> start_update(