]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fix potential access past eof during debugging prefill
authorxie xingguo <xie.xingguo@zte.com.cn>
Tue, 5 Jul 2016 03:04:31 +0000 (11:04 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Tue, 5 Jul 2016 03:10:32 +0000 (11:10 +0800)
1. pre-calculate r, so we don't have to do the division each loop, which
   is expensive.

2. make sure the extent to be allocated is within the block device size.

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
src/os/bluestore/BlueStore.cc

index 09a13f328d45fef0c6f54e44307e7339448593ba..9132233075e241e26cc2a035c8b4aef6ad19f9a8 100644 (file)
@@ -1746,18 +1746,38 @@ int BlueStore::_open_fm(bool create)
       dout(1) << __func__ << " pre-fragmenting freespace, using "
              << g_conf->bluestore_debug_prefill << " with max free extent "
              << g_conf->bluestore_debug_prefragment_max << dendl;
-      uint64_t start = ROUND_UP_TO(reserved, min_alloc_size);
+      uint64_t start = P2ROUNDUP(reserved, min_alloc_size);
       uint64_t max_b = g_conf->bluestore_debug_prefragment_max / min_alloc_size;
       float r = g_conf->bluestore_debug_prefill;
-      while (start < end) {
+      r /= 1.0 - r;
+      bool stop = false;
+
+      while (!stop && start < end) {
        uint64_t l = (rand() % max_b + 1) * min_alloc_size;
-       if (start + l > end)
+       if (start + l > end) {
          l = end - start;
-       l = ROUND_UP_TO(l, min_alloc_size);
-       uint64_t u = 1 + (uint64_t)(r * (double)l / (1.0 - r));
-       u = ROUND_UP_TO(u, min_alloc_size);
+          l = P2ALIGN(l, min_alloc_size);
+        }
+        assert(start + l <= end);
+
+       uint64_t u = 1 + (uint64_t)(r * (double)l);
+       u = P2ROUNDUP(u, min_alloc_size);
+        if (start + l + u > end) {
+          u = end - (start + l);
+          // trim to align so we don't overflow again
+          u = P2ALIGN(u, min_alloc_size);
+          stop = true;
+        }
+        assert(start + l + u <= end);
+
        dout(20) << "  free 0x" << std::hex << start << "~" << l
                 << " use 0x" << u << std::dec << dendl;
+
+        if (u == 0) {
+          // break if u has been trimmed to nothing
+          break;
+        }
+
        fm->allocate(start + l, u, t);
        start += l + u;
       }