From 7b3ab3252f9010590da1cc695919b70e09a3d5e8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 5 Sep 2017 22:25:03 -0400 Subject: [PATCH] crush: fix fast rule lookup when uniform Older clients will search for the first rule with a matching ruleset, type, and size. The has_uniform_rules bool is only set if we have rule ids and rulesets that line up, but we must also verify that the rest of the mask matches or else we can get a different CRUSH mapping result because the mask might not match and old clients will fail to find a rule and we will find one. We also can't just check the ruleset as the legacy clients find the *first* (of potentially many) matching rules; hence we only do the fast check if all rulesets == rule id. Signed-off-by: Sage Weil (cherry picked from commit f24095e0e9734531dbdbcd4bff1392c463188e8e) --- src/crush/CrushWrapper.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index 3737d5730023..384af2c44269 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -1258,14 +1258,15 @@ public: int find_rule(int ruleset, int type, int size) const { if (!crush) return -1; - if (!have_uniform_rules) { - return crush_find_rule(crush, ruleset, type, size); - } else { - if (ruleset < (int)crush->max_rules && - crush->rules[ruleset]) - return ruleset; - return -1; + if (have_uniform_rules && + ruleset < (int)crush->max_rules && + crush->rules[ruleset] && + crush->rules[ruleset]->mask.type == type && + crush->rules[ruleset]->mask.min_size <= size && + crush->rules[ruleset]->mask.max_size >= size) { + return ruleset; } + return crush_find_rule(crush, ruleset, type, size); } bool ruleset_exists(const int ruleset) const { -- 2.47.3