#include <lustre_param.h>
#include <class_hash.h>
-extern struct lustre_hash_operations uuid_hash_operations;
-extern struct lustre_hash_operations nid_hash_operations;
+static lustre_hash_ops_t uuid_hash_ops;
+static lustre_hash_ops_t nid_hash_ops;
+static lustre_hash_ops_t nid_stat_hash_ops;
/*********** string parsing utils *********/
/* just leave this on forever. I can't use obd_set_up here because
other fns check that status, and we're not actually set up yet. */
obd->obd_starting = 1;
+ obd->obd_uuid_hash = NULL;
+ obd->obd_nid_hash = NULL;
+ obd->obd_nid_stats_hash = NULL;
spin_unlock(&obd->obd_dev_lock);
- /* create an uuid-export hash body */
- err = lustre_hash_init(&obd->obd_uuid_hash_body, "UUID_HASH",
- 128, &uuid_hash_operations);
- if (err)
- GOTO(err_hash, err);
-
- /* create a nid-export hash body */
- err = lustre_hash_init(&obd->obd_nid_hash_body, "NID_HASH",
- 128, &nid_hash_operations);
- if (err)
- GOTO(err_hash, err);
-
- /* create a nid-stats hash body */
- err = lustre_hash_init(&obd->obd_nid_stats_hash_body, "NID_STATS",
- 128, &nid_stat_hash_operations);
- if (err)
- GOTO(err_hash, err);
+ /* create an uuid-export lustre hash */
+ obd->obd_uuid_hash = lustre_hash_init("UUID_HASH", 128, 128,
+ &uuid_hash_ops, 0);
+ if (!obd->obd_uuid_hash)
+ GOTO(err_hash, -ENOMEM);
+
+ /* create a nid-export lustre hash */
+ obd->obd_nid_hash = lustre_hash_init("NID_HASH", 128, 128,
+ &nid_hash_ops, 0);
+ if (!obd->obd_nid_hash)
+ GOTO(err_hash, -ENOMEM);
+
+ /* create a nid-stats lustre hash */
+ obd->obd_nid_stats_hash = lustre_hash_init("NID_STATS", 128, 128,
+ &nid_stat_hash_ops, 0);
+ if (!obd->obd_nid_stats_hash)
+ GOTO(err_hash, -ENOMEM);
exp = class_new_export(obd, &obd->obd_uuid);
if (IS_ERR(exp))
class_unlink_export(obd->obd_self_export);
obd->obd_self_export = NULL;
err_hash:
- lustre_hash_exit(&obd->obd_uuid_hash_body);
- lustre_hash_exit(&obd->obd_nid_hash_body);
- lustre_hash_exit(&obd->obd_nid_stats_hash_body);
+ lustre_hash_exit(obd->obd_uuid_hash);
+ lustre_hash_exit(obd->obd_nid_hash);
+ lustre_hash_exit(obd->obd_nid_stats_hash);
obd->obd_starting = 0;
CERROR("setup %s failed (%d)\n", obd->obd_name, err);
RETURN(err);
LASSERT(obd->obd_self_export);
/* destroy an uuid-export hash body */
- lustre_hash_exit(&obd->obd_uuid_hash_body);
+ lustre_hash_exit(obd->obd_uuid_hash);
/* destroy a nid-export hash body */
- lustre_hash_exit(&obd->obd_nid_hash_body);
+ lustre_hash_exit(obd->obd_nid_hash);
/* destroy a nid-stats hash body */
- lustre_hash_exit(&obd->obd_nid_stats_hash_body);
+ lustre_hash_exit(obd->obd_nid_stats_hash);
/* Precleanup, we must make sure all exports get destroyed. */
err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
lustre_cfg_free(lcfg);
RETURN(rc);
}
+
+/*
+ * uuid<->export lustre hash operations
+ */
+
+static unsigned
+uuid_hash(lustre_hash_t *lh, void *key, unsigned mask)
+{
+ return lh_djb2_hash(((struct obd_uuid *)key)->uuid,
+ sizeof(((struct obd_uuid *)key)->uuid), mask);
+}
+
+static void *
+uuid_key(struct hlist_node *hnode)
+{
+ struct obd_export *exp;
+
+ exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
+
+ RETURN(&exp->exp_client_uuid);
+}
+
+/*
+ * NOTE: It is impossible to find an export that is in failed
+ * state with this function
+ */
+static int
+uuid_compare(void *key, struct hlist_node *hnode)
+{
+ struct obd_export *exp;
+
+ LASSERT(key);
+ exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
+
+ RETURN(obd_uuid_equals((struct obd_uuid *)key,&exp->exp_client_uuid) &&
+ !exp->exp_failed);
+}
+
+static void *
+uuid_export_get(struct hlist_node *hnode)
+{
+ struct obd_export *exp;
+
+ exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
+ class_export_get(exp);
+
+ RETURN(exp);
+}
+
+static void *
+uuid_export_put(struct hlist_node *hnode)
+{
+ struct obd_export *exp;
+
+ exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
+ class_export_put(exp);
+
+ RETURN(exp);
+}
+
+static lustre_hash_ops_t uuid_hash_ops = {
+ .lh_hash = uuid_hash,
+ .lh_key = uuid_key,
+ .lh_compare = uuid_compare,
+ .lh_get = uuid_export_get,
+ .lh_put = uuid_export_put,
+};
+
+
+/*
+ * nid<->export hash operations
+ */
+
+static unsigned
+nid_hash(lustre_hash_t *lh, void *key, unsigned mask)
+{
+ return lh_djb2_hash(key, sizeof(lnet_nid_t), mask);
+}
+
+static void *
+nid_key(struct hlist_node *hnode)
+{
+ struct obd_export *exp;
+
+ exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
+
+ RETURN(&exp->exp_connection->c_peer.nid);
+}
+
+/*
+ * NOTE: It is impossible to find an export that is in failed
+ * state with this function
+ */
+static int
+nid_compare(void *key, struct hlist_node *hnode)
+{
+ struct obd_export *exp;
+
+ LASSERT(key);
+ exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
+
+ RETURN(exp->exp_connection->c_peer.nid == *(lnet_nid_t *)key &&
+ !exp->exp_failed);
+}
+
+static void *
+nid_export_get(struct hlist_node *hnode)
+{
+ struct obd_export *exp;
+
+ exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
+ class_export_get(exp);
+
+ RETURN(exp);
+}
+
+static void *
+nid_export_put(struct hlist_node *hnode)
+{
+ struct obd_export *exp;
+
+ exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
+ class_export_put(exp);
+
+ RETURN(exp);
+}
+
+static lustre_hash_ops_t nid_hash_ops = {
+ .lh_hash = nid_hash,
+ .lh_key = nid_key,
+ .lh_compare = nid_compare,
+ .lh_get = nid_export_get,
+ .lh_put = nid_export_put,
+};
+
+
+/*
+ * nid<->nidstats hash operations
+ */
+
+static void *
+nidstats_key(struct hlist_node *hnode)
+{
+ struct nid_stat *ns;
+
+ ns = hlist_entry(hnode, struct nid_stat, nid_hash);
+
+ RETURN(&ns->nid);
+}
+
+static int
+nidstats_compare(void *key, struct hlist_node *hnode)
+{
+ RETURN(*(lnet_nid_t *)nidstats_key(hnode) == *(lnet_nid_t *)key);
+}
+
+static void *
+nidstats_get(struct hlist_node *hnode)
+{
+ struct nid_stat *ns;
+
+ ns = hlist_entry(hnode, struct nid_stat, nid_hash);
+ ns->nid_exp_ref_count++;
+
+ RETURN(ns);
+}
+
+static void *
+nidstats_put(struct hlist_node *hnode)
+{
+ struct nid_stat *ns;
+
+ ns = hlist_entry(hnode, struct nid_stat, nid_hash);
+ ns->nid_exp_ref_count--;
+
+ RETURN(ns);
+}
+
+static lustre_hash_ops_t nid_stat_hash_ops = {
+ .lh_hash = nid_hash,
+ .lh_key = nidstats_key,
+ .lh_compare = nidstats_compare,
+ .lh_get = nidstats_get,
+ .lh_put = nidstats_put,
+};