static int nhash_find_insert(int *set, int setsize) { int j, found, *currlist; struct nhash_list *tableptr; unsigned int hashval; hashval = hashf(set, setsize); if ((table+hashval)->size == 0) { return(nhash_insert(hashval, set, setsize)); } else { for (tableptr=(table+hashval); tableptr != NULL; tableptr = tableptr->next) { if ((tableptr)->size != setsize) { continue; } else { /* Compare the list at hashval position */ /* to the current set by looking at etable */ /* entries */ for (j=0, found = 1, currlist= set_table+tableptr->set_offset; j < setsize; j++) { if (*(e_table+(*(currlist+j))) != (mainloop-1)) { found = 0; break; } } if (op == SUBSET_TEST_STAR_FREE && found == 1) { for (j=0, currlist= set_table+tableptr->set_offset; j < setsize; j++) { if (*(set+j) != *(currlist+j)) { /* Set mark */ star_free_mark = 1; } } } if (found == 1) { return(tableptr->setnum); } } } if (nhash_load / NHASH_LOAD_LIMIT > nhash_tablesize) { nhash_rebuild_table(); hashval = hashf(set, setsize); } return(nhash_insert(hashval, set, setsize)); } }
int ns_stat_add_namespace(const int nth, const int state, const char *ns_uuid, const uint64_t cache_pin_max_obj_bytes, const uint64_t cache_pin_resv_bytes, const int cache_pin_enabled, const ns_tier_entry_t *ssd, const ns_tier_entry_t *sas, const ns_tier_entry_t *sata, const int lock_flag) { ns_stat_entry_t *ns; int64_t old_index, orig_old_index = -1; uint32_t keyhash; const AO_t tmp_one = 1, tmp_zero = 0; int not_found = 1; int num_entries = 0; keyhash = n_str_hash(ns_uuid); NS_HASH_WLOCK(lock_flag); ns = nhash_lookup(s_ns_stat_hash, keyhash, (void *)ns_uuid /*key*/); if (ns) { /* This is the case where cache-inherit is done from multiple namespaces * to a single deleted namespace or for an active namespace. */ ns->num_dup_ns++; NS_HASH_WUNLOCK(lock_flag); DBG_LOG(SEVERE, MOD_NAMESPACE, "Stat add called for existing" " Namespace (%s)", ns_uuid); return 0; } while (not_found) { /* By putting this first, we can atomically hand out indices */ old_index = (int64_t)AO_fetch_and_add1(&g_ns_index); if (old_index == NS_NUM_STAT_ENTRIES) { // size of array AO_store(&g_ns_index, tmp_zero); continue; } if (num_entries >= NKN_MAX_NAMESPACES) {// # of supported namespaces NS_HASH_WUNLOCK(lock_flag); // Ran out of valid namespace slots glob_ns_stat_add_too_many_err++; return ENOMEM; } if (orig_old_index == -1) orig_old_index = old_index; else if (orig_old_index == old_index) { /* No free slots */ NS_HASH_WUNLOCK(lock_flag); NKN_ASSERT(0); // should never happen glob_ns_stat_add_no_free_slot_err++; return ENOMEM; } if (ns_slot_info[old_index] == NULL) { ns = nkn_calloc_type(1, sizeof(ns_stat_entry_t), mod_ns_stat_entry_t); if (ns == NULL) { NS_HASH_WUNLOCK(lock_flag); glob_ns_stat_add_nomem_err++; return ENOMEM; } ns_slot_info[old_index] = ns; AO_fetch_and_add1(&ns_num_namespaces); glob_ns_stat_add_new_slot_cnt++; break; } if (ns_slot_info[old_index]->state == NS_STATE_DELETED) { ns = ns_slot_info[old_index]; AO_fetch_and_add1(&ns_num_namespaces); glob_ns_stat_add_reuse_slot_cnt++; break; } num_entries++; } NS_HASH_WUNLOCK(lock_flag); DBG_LOG(MSG1, MOD_NAMESPACE, "Namespace (%s) stat added (index %lu) " "(num_ns %lu) (state %d)", ns_uuid, old_index, ns_num_namespaces, state); ns->index = old_index; ns->token_curr_gen = 1; ns->rp_index = nth; // MGMT promises that value never changes ns->state = state; strncpy(ns->ns_key, ns_uuid, NKN_MAX_UID_LENGTH-1); ns->ns_key[NKN_MAX_UID_LENGTH] = '\0'; /* If ns_key stored is truncated, it would cause * issue during stat_delete. Added assert at the source of the issue. */ if (strlen(ns->ns_key) != strlen(ns_uuid)) { DBG_LOG(SEVERE, MOD_NAMESPACE, "Namespace uid is longer than MAX_UID_LENGTH: %s", ns_uuid); NKN_ASSERT(0); } ns->cache_pin_max_obj_bytes = cache_pin_max_obj_bytes; ns->cache_pin_resv_bytes = cache_pin_resv_bytes; ns->cache_pin_enabled = cache_pin_enabled; ns->ssd.read_size = ssd->read_size; ns->ssd.block_free_threshold = ssd->block_free_threshold; ns->ssd.group_read = ssd->group_read; ns->ssd.max_disk_usage = ssd->max_disk_usage * 1024 * 1024; ns->sas.read_size = sas->read_size; ns->sas.block_free_threshold = sas->block_free_threshold; ns->sas.group_read = sas->group_read; ns->sas.max_disk_usage = sas->max_disk_usage * 1024 *1024; ns->sata.read_size = sata->read_size; ns->sata.block_free_threshold = sata->block_free_threshold; ns->sata.group_read = sata->group_read; ns->sata.max_disk_usage = sata->max_disk_usage * 1024 *1024; /* insert into hash table with key "namespace:uuid" */ NS_HASH_WLOCK(lock_flag); nhash_insert(s_ns_stat_hash, keyhash, ns->ns_key, ns /* value */); NS_HASH_WUNLOCK(lock_flag); AO_store(&ns_token_gen[ns->index], tmp_one); AO_store(&ns_stats[ns->index][NS_CACHE_PIN_SPACE_ENABLED], ns->cache_pin_enabled); AO_store(&ns_stats[ns->index][NS_CACHE_PIN_SPACE_RESV_TOTAL], ns->cache_pin_resv_bytes); AO_store(&ns_stats[ns->index][NS_CACHE_PIN_SPACE_OBJ_LIMIT], ns->cache_pin_max_obj_bytes); AO_store(&ns_stats[ns->index][NS_SSD_MAX_USAGE], ns->ssd.max_disk_usage); AO_store(&ns_stats[ns->index][NS_SAS_MAX_USAGE], ns->sas.max_disk_usage); AO_store(&ns_stats[ns->index][NS_SATA_MAX_USAGE], ns->sata.max_disk_usage); ns_stat_add_counters(ns->ns_key, ns->index); glob_ns_num_namespaces = AO_load(&ns_num_namespaces); return 0; } /* ns_stat_add_namespace */