]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/OSDMonitor: fix integer underflow of check_pg_num 44430/head
authorTongliang Deng <dengtongliang@gmail.com>
Fri, 31 Dec 2021 06:02:25 +0000 (14:02 +0800)
committerTongliang Deng <dengtongliang@gmail.com>
Sat, 8 Jan 2022 12:49:16 +0000 (20:49 +0800)
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>
src/mon/OSDMonitor.cc
src/osd/OSDMapMapping.h

index a35d0137862e0c8889ee777763a13bf2ca3255ff..1550af6b6480acadd8014cc2bdea2ba362782d52 100644 (file)
@@ -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 {
index 216c30446a95a216230681f94feb73cf3f7db3bd..0019eebf08389bac392deeb4d41b99b2892d116f 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(