*/
void lustre_hash_add(lustre_hash_t *lh, void *key,
struct hlist_node *hnode);
-int lustre_hash_add_unique(lustre_hash_t *lh, void *key,
- struct hlist_node *hnode);
+int lustre_hash_add_unique(lustre_hash_t *lh, void *key,
+ struct hlist_node *hnode);
void *lustre_hash_findadd_unique(lustre_hash_t *lh, void *key,
struct hlist_node *hnode);
{
LASSERT(min < max);
lh->lh_min_theta = min;
- lh->lh_min_theta = max;
+ lh->lh_max_theta = max;
}
/*
export->exp_connection = ptlrpc_connection_get(req->rq_peer,
req->rq_self,
&remote_uuid);
-
- spin_lock(&target->obd_dev_lock);
-
- /* Export might be hashed already, e.g. if this is reconnect */
- if (hlist_unhashed(&export->exp_nid_hash))
- lustre_hash_add(export->exp_obd->obd_nid_hash,
- &export->exp_connection->c_peer.nid,
- &export->exp_nid_hash);
-
- spin_unlock(&target->obd_dev_lock);
+ if (hlist_unhashed(&export->exp_nid_hash)) {
+ lustre_hash_add_unique(export->exp_obd->obd_nid_hash,
+ &export->exp_connection->c_peer.nid,
+ &export->exp_nid_hash);
+ }
spin_lock_bh(&target->obd_processing_task_lock);
if (target->obd_recovering && !export->exp_in_recovery) {
GOTO(out_err, rc);
}
- spin_lock(&obd->obd_dev_lock);
- /* check if pool already exists */
- if (lustre_hash_lookup(lov->lov_pools_hash_body, poolname) != NULL) {
- spin_unlock(&obd->obd_dev_lock);
+ INIT_HLIST_NODE(&new_pool->pool_hash);
+ rc = lustre_hash_add_unique(lov->lov_pools_hash_body, poolname,
+ &new_pool->pool_hash);
+ if (rc) {
lov_ost_pool_free(&new_pool->pool_rr.lqr_pool);
lov_ost_pool_free(&new_pool->pool_obds);
GOTO(out_err, rc = -EEXIST);
}
- INIT_HLIST_NODE(&new_pool->pool_hash);
- lustre_hash_add_unique(lov->lov_pools_hash_body, poolname,
- &new_pool->pool_hash);
+ spin_lock(&obd->obd_dev_lock);
list_add_tail(&new_pool->pool_list, &lov->lov_pool_list);
lov->lov_pool_count++;
spin_unlock(&obd->obd_dev_lock);
lh->lh_cur_size = cur_size;
lh->lh_min_size = cur_size;
lh->lh_max_size = max_size;
- lh->lh_min_theta = 500; /* theta * 1000 */
- lh->lh_max_theta = 2000; /* theta * 1000 */
lh->lh_ops = ops;
lh->lh_flags = flags;
+ /* theta * 1000 */
+ __lustre_hash_set_theta(lh, 500, 2000);
+
OBD_VMALLOC(lh->lh_buckets, sizeof(*lh->lh_buckets) * lh->lh_cur_size);
if (!lh->lh_buckets) {
OBD_FREE_PTR(lh);
static inline unsigned int lustre_hash_rehash_size(lustre_hash_t *lh)
{
+ int size;
+
if (!(lh->lh_flags & LH_REHASH))
return 0;
if ((lh->lh_cur_size < lh->lh_max_size) &&
(__lustre_hash_theta(lh) > lh->lh_max_theta))
- return MIN(lh->lh_cur_size * 2, lh->lh_max_size);
-
- if ((lh->lh_cur_size > lh->lh_min_size) &&
+ size = min(lh->lh_cur_size * 2, lh->lh_max_size);
+ else if ((lh->lh_cur_size > lh->lh_min_size) &&
(__lustre_hash_theta(lh) < lh->lh_min_theta))
- return MAX(lh->lh_cur_size / 2, lh->lh_min_size);
+ size = max(lh->lh_cur_size / 2, lh->lh_min_size);
+ else
+ size = 0;
- return 0;
+ if (lh->lh_cur_size == size)
+ size = 0;
+
+ return size;
}
/**
lustre_hash_findadd_unique_hnode(lustre_hash_t *lh, void *key,
struct hlist_node *hnode)
{
+ int size = 0;
struct hlist_node *ehnode;
lustre_hash_bucket_t *lhb;
- int size;
unsigned i;
ENTRY;
} else {
__lustre_hash_bucket_add(lh, lhb, hnode);
ehnode = hnode;
+ size = lustre_hash_rehash_size(lh);
}
write_unlock(&lhb->lhb_rwlock);
-
- size = lustre_hash_rehash_size(lh);
read_unlock(&lh->lh_rwlock);
if (size)
lustre_hash_rehash(lh, size);
ENTRY;
ehnode = lustre_hash_findadd_unique_hnode(lh, key, hnode);
- if (ehnode != hnode)
+ if (ehnode != hnode) {
+ lh_put(lh, ehnode);
RETURN(-EALREADY);
+ }
RETURN(0);
}
lustre_hash_del(lustre_hash_t *lh, void *key, struct hlist_node *hnode)
{
lustre_hash_bucket_t *lhb;
- int size;
unsigned i;
void *obj;
ENTRY;
write_lock(&lhb->lhb_rwlock);
obj = __lustre_hash_bucket_del(lh, lhb, hnode);
write_unlock(&lhb->lhb_rwlock);
-
- size = lustre_hash_rehash_size(lh);
read_unlock(&lh->lh_rwlock);
- if (size)
- lustre_hash_rehash(lh, size);
RETURN(obj);
}
{
struct hlist_node *hnode;
lustre_hash_bucket_t *lhb;
- int size;
unsigned i;
void *obj = NULL;
ENTRY;
obj = __lustre_hash_bucket_del(lh, lhb, hnode);
write_unlock(&lhb->lhb_rwlock);
-
- size = lustre_hash_rehash_size(lh);
read_unlock(&lh->lh_rwlock);
- if (size)
- lustre_hash_rehash(lh, size);
RETURN(obj);
}
}
EXPORT_SYMBOL(lustre_hash_for_each_empty);
- /*
+/**
* For each item in the lustre hash @lh which matches the @key call
* the passed callback @func and pass to it as an argument each hash
* item and the private @data. Before each callback ops->lh_get will
ENTRY;
LASSERT(size > 0);
+ LASSERT(!in_interrupt());
OBD_VMALLOC(rehash_buckets, sizeof(*rehash_buckets) * size);
if (!rehash_buckets)