4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 #ifndef __LIBCFS_LINUX_HASH_H__
24 #define __LIBCFS_LINUX_HASH_H__
26 #include <linux/dcache.h>
27 #include <linux/rhashtable.h>
29 u64 cfs_hashlen_string(const void *salt, const char *name);
32 #define hashlen_hash(hashlen) ((u32)(hashlen))
35 #ifndef HAVE_STRINGHASH
36 #ifndef hashlen_create
37 #define hashlen_create(hash, len) ((u64)(len)<<32 | (u32)(hash))
39 #endif /* !HAVE_STRINGHASH */
41 #ifdef HAVE_BROKEN_HASH_64
43 #define GOLDEN_RATIO_32 0x61C88647
44 #define GOLDEN_RATIO_64 0x61C8864680B583EBull
46 static inline u32 cfs_hash_32(u32 val, unsigned int bits)
48 /* High bits are more random, so use them. */
49 return (val * GOLDEN_RATIO_32) >> (32 - bits);
52 static __always_inline u32 cfs_hash_64(u64 val, unsigned int bits)
54 #if BITS_PER_LONG == 64
55 /* 64x64-bit multiply is efficient on all 64-bit processors */
56 return val * GOLDEN_RATIO_64 >> (64 - bits);
58 /* Hash 64 bits using only 32x32-bit multiply. */
59 return cfs_hash_32(((u32)val ^ ((val >> 32) * GOLDEN_RATIO_32)), bits);
64 #define cfs_hash_32 hash_32
65 #define cfs_hash_64 hash_64
67 #endif /* HAVE_BROKEN_HASH_64 */
71 struct rhash_head rhead;
72 struct rhlist_head __rcu *next;
79 #define rhl_for_each_entry_rcu(tpos, pos, list, member) \
80 for (pos = list; pos && rht_entry(tpos, pos, member); \
81 pos = rcu_dereference_raw(pos->next))
83 static inline int rhltable_init(struct rhltable *hlt,
84 const struct rhashtable_params *params)
86 return rhashtable_init(&hlt->ht, params);
89 static inline struct rhlist_head *rhltable_lookup(
90 struct rhltable *hlt, const void *key,
91 const struct rhashtable_params params)
93 struct rhashtable *ht = &hlt->ht;
94 struct rhashtable_compare_arg arg = {
98 struct bucket_table *tbl;
99 struct rhash_head *he;
102 tbl = rht_dereference_rcu(ht->tbl, ht);
104 hash = rht_key_hashfn(ht, tbl, key, params);
105 rht_for_each_rcu(he, tbl, hash) {
106 if (params.obj_cmpfn ?
107 params.obj_cmpfn(&arg, rht_obj(ht, he)) :
108 rhashtable_compare(&arg, rht_obj(ht, he)))
110 return he ? container_of(he, struct rhlist_head, rhead) : NULL;
113 /* Ensure we see any new tables. */
116 tbl = rht_dereference_rcu(tbl->future_tbl, ht);
123 static inline int rhltable_insert_key(
124 struct rhltable *hlt, const void *key, struct rhlist_head *list,
125 const struct rhashtable_params params)
127 #ifdef HAVE_HASHTABLE_INSERT_FAST_RETURN_INT
128 return __rhashtable_insert_fast(&hlt->ht, key, &list->rhead,
131 return PTR_ERR(__rhashtable_insert_fast(&hlt->ht, key, &list->rhead,
136 static inline int rhltable_remove(
137 struct rhltable *hlt, struct rhlist_head *list,
138 const struct rhashtable_params params)
140 return rhashtable_remove_fast(&hlt->ht, &list->rhead, params);
143 static inline void rhltable_free_and_destroy(struct rhltable *hlt,
144 void (*free_fn)(void *ptr,
148 rhashtable_free_and_destroy(&hlt->ht, free_fn, arg);
151 static inline void rhltable_destroy(struct rhltable *hlt)
153 rhltable_free_and_destroy(hlt, NULL, NULL);
156 static inline void rhltable_walk_enter(struct rhltable *hlt,
157 struct rhashtable_iter *iter)
159 rhashtable_walk_init(&hlt->ht, iter);
161 #endif /* !HAVE_RHLTABLE */
163 #ifndef HAVE_RHASHTABLE_LOOKUP_GET_INSERT_FAST
165 * rhashtable_lookup_get_insert_fast - lookup and insert object into hash table
167 * @obj: pointer to hash head inside object
168 * @params: hash table parameters
170 * Just like rhashtable_lookup_insert_fast(), but this function returns the
171 * object if it exists, NULL if it did not and the insertion was successful,
172 * and an ERR_PTR otherwise.
174 static inline void *rhashtable_lookup_get_insert_fast(
175 struct rhashtable *ht, struct rhash_head *obj,
176 const struct rhashtable_params params)
182 rc = rhashtable_lookup_insert_fast(ht, obj, params);
185 key = rht_obj(ht, obj);
186 ret = rhashtable_lookup_fast(ht, key, params);
197 #endif /* !HAVE_RHASHTABLE_LOOKUP_GET_INSERT_FAST */
199 #ifndef HAVE_RHASHTABLE_LOOKUP
201 * The function rhashtable_lookup() and rhashtable_lookup_fast()
202 * are almost the same except rhashtable_lookup() doesn't
203 * take the RCU read lock. Since this is the case and only
204 * SLES12 SP3 lacks rhashtable_lookup() just duplicate the
205 * SLES12 SP3 rhashtable_lookup_fast() minus the RCU read lock.
207 static inline void *rhashtable_lookup(
208 struct rhashtable *ht, const void *key,
209 const struct rhashtable_params params)
211 struct rhashtable_compare_arg arg = {
215 const struct bucket_table *tbl;
216 struct rhash_head *he;
219 tbl = rht_dereference_rcu(ht->tbl, ht);
221 hash = rht_key_hashfn(ht, tbl, key, params);
222 rht_for_each_rcu(he, tbl, hash) {
223 if (params.obj_cmpfn ?
224 params.obj_cmpfn(&arg, rht_obj(ht, he)) :
225 rhashtable_compare(&arg, rht_obj(ht, he)))
227 return rht_obj(ht, he);
230 /* Ensure we see any new tables. */
233 tbl = rht_dereference_rcu(tbl->future_tbl, ht);
239 #endif /* !HAVE_RHASHTABLE_LOOKUP */
241 #endif /* __LIBCFS_LINUX_HASH_H__ */