Ejemplo n.º 1
0
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 */