1
0
mirror of https://github.com/ceph/ceph synced 2025-03-30 23:40:09 +00:00

crush/mapper: fix divide-by-0 in straw2

If the item weight is 0 we don't want to divide; instead draw a minimal
value.

Fixes: 
Reported-by: Yann Dupont <yd@objoo.org>
Tested-by: Yann Dupont <yd@objoo.org>
Signed-off-by: Sage Weil <sage@redhat.com>
This commit is contained in:
Sage Weil 2015-04-09 14:42:34 -07:00
parent e61c4f093f
commit 64d1e900ec

View File

@ -307,28 +307,38 @@ static int bucket_straw2_choose(struct crush_bucket_straw2 *bucket,
{
unsigned i, high = 0;
unsigned u;
unsigned w;
__s64 ln, draw, high_draw = 0;
for (i = 0; i < bucket->h.size; i++) {
u = crush_hash32_3(bucket->h.hash, x, bucket->h.items[i], r);
u &= 0xffff;
w = bucket->item_weights[i];
if (w) {
u = crush_hash32_3(bucket->h.hash, x,
bucket->h.items[i], r);
u &= 0xffff;
/*
* for some reason slightly less than 0x10000 produces
* a slightly more accurate distribution... probably a
* rounding effect.
*
* the natural log lookup table maps [0,0xffff]
* (corresponding to real numbers [1/0x10000, 1] to
* [0, 0xffffffffffff] (corresponding to real numbers
* [-11.090355,0]).
*/
ln = crush_ln(u) - 0x1000000000000ll;
/*
* for some reason slightly less than 0x10000 produces
* a slightly more accurate distribution... probably a
* rounding effect.
*
* the natural log lookup table maps [0,0xffff]
* (corresponding to real numbers [1/0x10000, 1] to
* [0, 0xffffffffffff] (corresponding to real numbers
* [-11.090355,0]).
*/
ln = crush_ln(u) - 0x1000000000000ll;
/*
* divide by 16.16 fixed-point weight
*/
draw = ln / bucket->item_weights[i];
/*
* divide by 16.16 fixed-point weight. note
* that the ln value is negative, so a larger
* weight means a larger (less negative) value
* for draw.
*/
draw = ln / w;
} else {
draw = INT64_MIN;
}
if (i == 0 || draw > high_draw) {
high = i;