diff options
-rw-r--r-- | lib/rhashtable.c | 41 |
1 files changed, 18 insertions, 23 deletions
diff --git a/lib/rhashtable.c b/lib/rhashtable.c index cbad192d3b3d..f2fdd7a7cb16 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c | |||
@@ -612,6 +612,19 @@ restart: | |||
612 | } | 612 | } |
613 | EXPORT_SYMBOL_GPL(rhashtable_remove); | 613 | EXPORT_SYMBOL_GPL(rhashtable_remove); |
614 | 614 | ||
615 | struct rhashtable_compare_arg { | ||
616 | struct rhashtable *ht; | ||
617 | const void *key; | ||
618 | }; | ||
619 | |||
620 | static bool rhashtable_compare(void *ptr, void *arg) | ||
621 | { | ||
622 | struct rhashtable_compare_arg *x = arg; | ||
623 | struct rhashtable *ht = x->ht; | ||
624 | |||
625 | return !memcmp(ptr + ht->p.key_offset, x->key, ht->p.key_len); | ||
626 | } | ||
627 | |||
615 | /** | 628 | /** |
616 | * rhashtable_lookup - lookup key in hash table | 629 | * rhashtable_lookup - lookup key in hash table |
617 | * @ht: hash table | 630 | * @ht: hash table |
@@ -627,32 +640,14 @@ EXPORT_SYMBOL_GPL(rhashtable_remove); | |||
627 | */ | 640 | */ |
628 | void *rhashtable_lookup(struct rhashtable *ht, const void *key) | 641 | void *rhashtable_lookup(struct rhashtable *ht, const void *key) |
629 | { | 642 | { |
630 | const struct bucket_table *tbl, *old_tbl; | 643 | struct rhashtable_compare_arg arg = { |
631 | struct rhash_head *he; | 644 | .ht = ht, |
632 | u32 hash; | 645 | .key = key, |
646 | }; | ||
633 | 647 | ||
634 | BUG_ON(!ht->p.key_len); | 648 | BUG_ON(!ht->p.key_len); |
635 | 649 | ||
636 | rcu_read_lock(); | 650 | return rhashtable_lookup_compare(ht, key, &rhashtable_compare, &arg); |
637 | old_tbl = rht_dereference_rcu(ht->tbl, ht); | ||
638 | tbl = rht_dereference_rcu(ht->future_tbl, ht); | ||
639 | hash = key_hashfn(ht, key, ht->p.key_len); | ||
640 | restart: | ||
641 | rht_for_each_rcu(he, tbl, rht_bucket_index(tbl, hash)) { | ||
642 | if (memcmp(rht_obj(ht, he) + ht->p.key_offset, key, | ||
643 | ht->p.key_len)) | ||
644 | continue; | ||
645 | rcu_read_unlock(); | ||
646 | return rht_obj(ht, he); | ||
647 | } | ||
648 | |||
649 | if (unlikely(tbl != old_tbl)) { | ||
650 | tbl = old_tbl; | ||
651 | goto restart; | ||
652 | } | ||
653 | |||
654 | rcu_read_unlock(); | ||
655 | return NULL; | ||
656 | } | 651 | } |
657 | EXPORT_SYMBOL_GPL(rhashtable_lookup); | 652 | EXPORT_SYMBOL_GPL(rhashtable_lookup); |
658 | 653 | ||