From cf89f2f4c94498878e528e975e17231205a73536 Mon Sep 17 00:00:00 2001 From: yury Date: Fri, 19 Sep 2008 19:01:45 +0000 Subject: [PATCH] b=16777 16776 r=shadow, adilger, vitaly, robert - new clas_hash and using it for connections, held locks on server, etc --- lustre/obdclass/obd_config.c | 236 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 212 insertions(+), 24 deletions(-) diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 2811635..aafe553 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -54,8 +54,9 @@ #include #include -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 *********/ @@ -297,26 +298,28 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) /* 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 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-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 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)) @@ -344,9 +347,9 @@ 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); @@ -480,13 +483,13 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) 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 stage 1, we must make sure all exports (other than the self-export) get destroyed. */ @@ -1330,3 +1333,188 @@ out: 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, +}; -- 1.8.3.1