+struct cdt_agent_record_loc {
+ struct hlist_node carl_hnode;
+ atomic_t carl_refcount;
+ u64 carl_cookie;
+ u32 carl_cat_idx;
+ u32 carl_rec_idx;
+};
+
+static inline void cdt_agent_record_loc_get(struct cdt_agent_record_loc *carl)
+{
+ LASSERT(atomic_read(&carl->carl_refcount) > 0);
+ atomic_inc(&carl->carl_refcount);
+}
+
+static inline void cdt_agent_record_loc_put(struct cdt_agent_record_loc *carl)
+{
+ LASSERT(atomic_read(&carl->carl_refcount) > 0);
+ if (atomic_dec_and_test(&carl->carl_refcount))
+ OBD_FREE_PTR(carl);
+}
+
+static unsigned int
+cdt_agent_record_hash(struct cfs_hash *hs, const void *key, unsigned int mask)
+{
+ return cfs_hash_djb2_hash(key, sizeof(u64), mask);
+}
+
+static void *cdt_agent_record_object(struct hlist_node *hnode)
+{
+ return hlist_entry(hnode, struct cdt_agent_record_loc, carl_hnode);
+}
+
+static void *cdt_agent_record_key(struct hlist_node *hnode)
+{
+ struct cdt_agent_record_loc *carl = cdt_agent_record_object(hnode);
+
+ return &carl->carl_cookie;
+}
+
+static int cdt_agent_record_keycmp(const void *key, struct hlist_node *hnode)
+{
+ const u64 *cookie2 = cdt_agent_record_key(hnode);
+
+ return *(const u64 *)key == *cookie2;
+}
+
+static void cdt_agent_record_get(struct cfs_hash *hs, struct hlist_node *hnode)
+{
+ struct cdt_agent_record_loc *carl = cdt_agent_record_object(hnode);
+
+ cdt_agent_record_loc_get(carl);
+}
+
+static void cdt_agent_record_put(struct cfs_hash *hs, struct hlist_node *hnode)
+{
+ struct cdt_agent_record_loc *carl = cdt_agent_record_object(hnode);
+
+ cdt_agent_record_loc_put(carl);
+}
+
+struct cfs_hash_ops cdt_agent_record_hash_ops = {
+ .hs_hash = cdt_agent_record_hash,
+ .hs_key = cdt_agent_record_key,
+ .hs_keycmp = cdt_agent_record_keycmp,
+ .hs_object = cdt_agent_record_object,
+ .hs_get = cdt_agent_record_get,
+ .hs_put_locked = cdt_agent_record_put,
+};
+
+void cdt_agent_record_hash_add(struct coordinator *cdt, u64 cookie, u32 cat_idx,
+ u32 rec_idx)
+{
+ struct cdt_agent_record_loc *carl0;
+ struct cdt_agent_record_loc *carl1;
+
+ OBD_ALLOC_PTR(carl1);
+ if (carl1 == NULL)
+ return;
+
+ INIT_HLIST_NODE(&carl1->carl_hnode);
+ atomic_set(&carl1->carl_refcount, 1);
+ carl1->carl_cookie = cookie;
+ carl1->carl_cat_idx = cat_idx;
+ carl1->carl_rec_idx = rec_idx;
+
+ carl0 = cfs_hash_findadd_unique(cdt->cdt_agent_record_hash,
+ &carl1->carl_cookie,
+ &carl1->carl_hnode);
+
+ LASSERT(carl0->carl_cookie == carl1->carl_cookie);
+ LASSERT(carl0->carl_cat_idx == carl1->carl_cat_idx);
+ LASSERT(carl0->carl_rec_idx == carl1->carl_rec_idx);
+
+ if (carl0 != carl1)
+ cdt_agent_record_loc_put(carl0);
+
+ cdt_agent_record_loc_put(carl1);
+}
+
+void cdt_agent_record_hash_lookup(struct coordinator *cdt, u64 cookie,
+ u32 *cat_idx, u32 *rec_idx)
+{
+ struct cdt_agent_record_loc *carl;
+
+ carl = cfs_hash_lookup(cdt->cdt_agent_record_hash, &cookie);
+ if (carl != NULL) {
+ LASSERT(carl->carl_cookie == cookie);
+ *cat_idx = carl->carl_cat_idx;
+ *rec_idx = carl->carl_rec_idx;
+ cdt_agent_record_loc_put(carl);
+ } else {
+ *cat_idx = 0;
+ *rec_idx = 0;
+ }
+}
+
+void cdt_agent_record_hash_del(struct coordinator *cdt, u64 cookie)
+{
+ cfs_hash_del_key(cdt->cdt_agent_record_hash, &cookie);
+}
+