From f24095e0e9734531dbdbcd4bff1392c463188e8e 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 --- 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 cefcd8fee17f3..a8c017c29c5bb 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -1261,14 +1261,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.39.5