From: xie xingguo Date: Tue, 5 Jul 2016 03:04:31 +0000 (+0800) Subject: os/bluestore: fix potential access past eof during debugging prefill X-Git-Tag: ses5-milestone5~470^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c48c19957c07428e66e3fa0f5be66822d4f7fcdd;p=ceph.git os/bluestore: fix potential access past eof during debugging prefill 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 --- diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 09a13f328d4..9132233075e 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -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; }