+void lustre_hash_bucket_iterate(struct lustre_class_hash_body *hash_body,
+ void *key, hash_item_iterate_cb func, void *data)
+{
+ int hashent, find = 0;
+ struct lustre_hash_bucket *bucket = NULL;
+ struct hlist_node *hash_item_node = NULL;
+ struct lustre_hash_operations *hop = hash_body->lchb_hash_operations;
+ struct obd_export *tmp = NULL;
+
+ ENTRY;
+
+ hashent = hop->lustre_hashfn(hash_body, key);
+ bucket = &hash_body->lchb_hash_tables[hashent];
+
+ spin_lock(&bucket->lhb_lock);
+ hlist_for_each(hash_item_node, &(bucket->lhb_head)) {
+ find = hop->lustre_hash_key_compare(key, hash_item_node);
+ if (find) {
+ tmp = hop->lustre_hash_object_refcount_get(hash_item_node);
+ func(tmp, data);
+ hop->lustre_hash_object_refcount_put(hash_item_node);
+ }
+ }
+ spin_unlock(&bucket->lhb_lock);
+}
+EXPORT_SYMBOL(lustre_hash_bucket_iterate);
+
+void lustre_hash_iterate_all(struct lustre_class_hash_body *hash_body,
+ hash_item_iterate_cb func, void *data)
+{
+ int i;
+ struct lustre_hash_operations *hop = hash_body->lchb_hash_operations;
+ ENTRY;
+
+ for( i = 0; i < hash_body->lchb_hash_max_size; i++ ) {
+ struct lustre_hash_bucket * bucket;
+ struct hlist_node * actual_hnode, *pos;
+ void *obj;
+
+ bucket = &hash_body->lchb_hash_tables[i];
+#ifdef LUSTRE_HASH_DEBUG
+ CDEBUG(D_INFO, "idx %d - bucket %p\n", i, bucket);
+#endif
+ spin_lock(&bucket->lhb_lock); /* lock the bucket */
+ hlist_for_each_safe(actual_hnode, pos, &(bucket->lhb_head)) {
+ obj = hop->lustre_hash_object_refcount_get(actual_hnode);
+ func(obj, data);
+ hop->lustre_hash_object_refcount_put(actual_hnode);
+ }
+ spin_unlock(&bucket->lhb_lock);
+ }
+ EXIT;
+}
+EXPORT_SYMBOL(lustre_hash_iterate_all);
+
+