コード例 #1
0
ファイル: hashtable.c プロジェクト: srimalik/nfs-ganesha
struct hash_table *
hashtable_init(struct hash_param *hparam)
{
	/* The hash table being constructed */
	struct hash_table *ht = NULL;
	/* The index for initializing each partition */
	uint32_t index = 0;
	/* Read-Write Lock attributes, to prevent write starvation under
	   GLIBC */
	pthread_rwlockattr_t rwlockattr;
	/* Hash partition */
	struct hash_partition *partition = NULL;
	/* The number of fully initialized partitions */
	uint32_t completed = 0;

	if (pthread_rwlockattr_init(&rwlockattr) != 0)
		return NULL;

	/* At some point factor this out into the OS directory.  it is
	   necessary to prevent writer starvation under GLIBC. */
#ifdef GLIBC
	if ((pthread_rwlockattr_setkind_np
	     (&rwlockattrs,
	      PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)) != 0) {
		LogCrit(COMPONENT_HASHTABLE,
			"Unable to set writer-preference on lock attribute.");
		goto deconstruct;
	}
#endif				/* GLIBC */

	ht = gsh_calloc(1, sizeof(struct hash_table) +
			(sizeof(struct hash_partition) *
			 hparam->index_size));

	/* Fixup entry size */
	if (hparam->flags & HT_FLAG_CACHE) {
		if (!hparam->cache_entry_count)
			/* works fine with a good hash algo */
			hparam->cache_entry_count = 32767;
	}

	/* We need to save copy of the parameters in the table. */
	ht->parameter = *hparam;
	for (index = 0; index < hparam->index_size; ++index) {
		partition = (&ht->partitions[index]);
		RBT_HEAD_INIT(&(partition->rbt));

		if (pthread_rwlock_init(&partition->lock, &rwlockattr) != 0) {
			LogCrit(COMPONENT_HASHTABLE,
				"Unable to initialize lock in hash table.");
			goto deconstruct;
		}

		/* Allocate a cache if requested */
		if (hparam->flags & HT_FLAG_CACHE)
			partition->cache = gsh_calloc(1, cache_page_size(ht));

		completed++;
	}

	ht->node_pool = pool_basic_init(NULL, sizeof(rbt_node_t));
	ht->data_pool = pool_basic_init(NULL, sizeof(struct hash_data));

	pthread_rwlockattr_destroy(&rwlockattr);
	return ht;

 deconstruct:

	while (completed != 0) {
		if (hparam->flags & HT_FLAG_CACHE)
			gsh_free(ht->partitions[completed - 1].cache);

		PTHREAD_RWLOCK_destroy(&(ht->partitions[completed - 1].lock));
		completed--;
	}
	if (ht->node_pool)
		pool_destroy(ht->node_pool);
	if (ht->data_pool)
		pool_destroy(ht->data_pool);

	gsh_free(ht);
	return ht = NULL;
}
コード例 #2
0
/**
 * Init handle mapping module.
 * Reloads the content of the mapping files it they exist,
 * else it creates them.
 * \return 0 if OK, a posix error code else.
 */
int HandleMap_Init(const handle_map_param_t *p_param)
{
	int rc;

	/* first check database count */

	rc = handlemap_db_count(p_param->databases_directory);

	if ((rc > 0) && (rc != p_param->database_count)) {
		LogCrit(COMPONENT_FSAL,
			"ERROR: The number of existing databases (%u) does not match the requested DB thread count (%u)",
			rc, p_param->database_count);

		return HANDLEMAP_INVALID_PARAM;
	} else if (rc < 0)
		return -rc;

	/* init database module */

	rc = handlemap_db_init(p_param->databases_directory,
			       p_param->temp_directory, p_param->database_count,
			       p_param->synchronous_insert);

	if (rc) {
		LogCrit(COMPONENT_FSAL, "ERROR %d initializing database access",
			rc);
		return rc;
	}

	/* initialize memory pool of digests and handles */

	digest_pool =
	    pool_basic_init("digest_pool", sizeof(digest_pool_entry_t));

	handle_pool =
	    pool_basic_init("handle_pool", sizeof(handle_pool_entry_t));

	/* create hash table */

	handle_hash_config.index_size = p_param->hashtable_size;

	handle_map_hash = hashtable_init(&handle_hash_config);

	if (!handle_map_hash) {
		LogCrit(COMPONENT_FSAL,
			"ERROR creating hash table for handle mapping");
		return HANDLEMAP_INTERNAL_ERROR;
	}

	/* reload previous data */

	rc = handlemap_db_reaload_all(handle_map_hash);

	if (rc) {
		LogCrit(COMPONENT_FSAL,
			"ERROR %d reloading handle mapping from database", rc);
		return rc;
	}

	return HANDLEMAP_SUCCESS;
}