int compare_nsm_client(state_nsm_client_t *pclient1, state_nsm_client_t *pclient2) { if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE)) { char str1[HASHTABLE_DISPLAY_STRLEN]; char str2[HASHTABLE_DISPLAY_STRLEN]; display_nsm_client(pclient1, str1); display_nsm_client(pclient2, str2); LogFullDebug(COMPONENT_STATE, "{%s} vs {%s}", str1, str2); } if(pclient1 == NULL || pclient2 == NULL) return 1; if(pclient1 == pclient2) return 0; if(!nfs_param.core_param.nsm_use_caller_name) { if(cmp_sockaddr(&pclient1->ssc_client_addr, &pclient2->ssc_client_addr, IGNORE_PORT) == 0) return 1; return 0; } if(pclient1->ssc_nlm_caller_name_len != pclient2->ssc_nlm_caller_name_len) return 1; return memcmp(pclient1->ssc_nlm_caller_name, pclient2->ssc_nlm_caller_name, pclient1->ssc_nlm_caller_name_len); }
/** * @brief Compare NSM clients * * @param[in] client1 A client * @param[in] client2 Another client * * @retval 0 on equality. * @retval 1 on inequality. */ int compare_nsm_client(state_nsm_client_t *client1, state_nsm_client_t *client2) { if (isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE)) { char str1[LOG_BUFF_LEN / 2]; char str2[LOG_BUFF_LEN / 2]; struct display_buffer dspbuf1 = {sizeof(str1), str1, str1}; struct display_buffer dspbuf2 = {sizeof(str2), str2, str2}; display_nsm_client(&dspbuf1, client1); display_nsm_client(&dspbuf2, client2); LogFullDebug(COMPONENT_STATE, "{%s} vs {%s}", str1, str2); } if (client1 == NULL || client2 == NULL) return 1; if (client1 == client2) return 0; if (!nfs_param.core_param.nsm_use_caller_name) { if (client1->ssc_client != client2->ssc_client) return 1; return 0; } if (client1->ssc_nlm_caller_name_len != client2->ssc_nlm_caller_name_len) return 1; return memcmp(client1->ssc_nlm_caller_name, client2->ssc_nlm_caller_name, client1->ssc_nlm_caller_name_len); }
static int Hash_dec_nsm_client_ref(hash_buffer_t *buffval) { int rc; state_nsm_client_t *pclient = (state_nsm_client_t *)(buffval->pdata); P(pclient->ssc_mutex); pclient->ssc_refcount--; if(isFullDebug(COMPONENT_STATE)) { char str[HASHTABLE_DISPLAY_STRLEN]; display_nsm_client(pclient, str); LogFullDebug(COMPONENT_STATE, "Decrement refcount NSM Client {%s}", str); } rc = pclient->ssc_refcount; V(pclient->ssc_mutex); return rc; }
/** * @brief Display an NLM client * * @param[in/out] dspbuf display_buffer describing output string * @param[in] key The NLM client * * @return the bytes remaining in the buffer. */ int display_nlm_client(struct display_buffer *dspbuf, state_nlm_client_t *key) { int b_left; if (key == NULL) return display_printf(dspbuf, "NLM Client <NULL>"); b_left = display_printf(dspbuf, "NLM Client %p: {", key); if (b_left <= 0) return b_left; b_left = display_nsm_client(dspbuf, key->slc_nsm_client); if (b_left <= 0) return b_left; b_left = display_printf(dspbuf, "} caller_name="); if (b_left <= 0) return b_left; b_left = display_len_cat(dspbuf, key->slc_nlm_caller_name, key->slc_nlm_caller_name_len); if (b_left <= 0) return b_left; return display_printf(dspbuf, " type=%s refcount=%d", xprt_type_to_str(key->slc_client_type), atomic_fetch_int32_t(&key->slc_refcount)); }
/** * @brief Display an NSM client in the hash table * * @param[in] buff The value * @param[out] str Output buffer * * @return Length of output string. */ int display_nsm_client_val(struct gsh_buffdesc *buff, char *str) { struct display_buffer dspbuf = {HASHTABLE_DISPLAY_STRLEN, str, str}; display_nsm_client(&dspbuf, buff->addr); return display_buffer_len(&dspbuf); }
void dec_nsm_client_ref_locked(state_nsm_client_t *pclient) { bool_t remove = FALSE; char str[HASHTABLE_DISPLAY_STRLEN]; if(isFullDebug(COMPONENT_STATE)) display_nsm_client(pclient, str); if(pclient->ssc_refcount > 1) { pclient->ssc_refcount--; LogFullDebug(COMPONENT_STATE, "Decrement refcount NSM Client {%s}", str); } else remove = TRUE; V(pclient->ssc_mutex); if(remove) { hash_buffer_t buffkey, old_key, old_value; buffkey.pdata = (caddr_t) pclient; buffkey.len = sizeof(*pclient); switch(HashTable_DelRef(ht_nsm_client, &buffkey, &old_key, &old_value, Hash_dec_nsm_client_ref)) { case HASHTABLE_SUCCESS: LogFullDebug(COMPONENT_STATE, "Free NSM Client {%s} size %llx", str, (unsigned long long) old_value.len); nsm_unmonitor((state_nsm_client_t *) old_value.pdata); free_nsm_client((state_nsm_client_t *) old_key.pdata); free_nsm_client((state_nsm_client_t *) old_value.pdata); break; case HASHTABLE_NOT_DELETED: /* ref count didn't end up at 0, don't free. */ LogDebug(COMPONENT_STATE, "HashTable_DelRef didn't reduce refcount to 0 for NSM Client {%s}", str); break; default: /* some problem occurred */ LogDebug(COMPONENT_STATE, "HashTable_DelRef failed for NSM Client {%s}", str); break; } } }
void inc_nsm_client_ref_locked(state_nsm_client_t *pclient) { pclient->ssc_refcount++; if(isFullDebug(COMPONENT_STATE)) { char str[HASHTABLE_DISPLAY_STRLEN]; display_nsm_client(pclient, str); LogFullDebug(COMPONENT_STATE, "Increment refcount NSM Client {%s}", str); } V(pclient->ssc_mutex); }
int display_nlm_client(state_nlm_client_t *pkey, char *str) { char *strtmp = str; if(pkey == NULL) return sprintf(str, "<NULL>"); strtmp += sprintf(strtmp, "%p: NSM Client {", pkey); strtmp += display_nsm_client(pkey->slc_nsm_client, strtmp); strtmp += sprintf(strtmp, "} caller_name="); strncpy(strtmp, pkey->slc_nlm_caller_name, pkey->slc_nlm_caller_name_len); strtmp += pkey->slc_nlm_caller_name_len; strtmp += sprintf(strtmp, " type=%s", xprt_type_to_str(pkey->slc_client_type)); strtmp += sprintf(strtmp, " refcount=%d", pkey->slc_refcount); return strtmp - str; }
int display_nlm_client(state_nlm_client_t *pkey, char *str) { char *strtmp = str; if(pkey == NULL) return sprintf(str, "NLM Client <NULL>"); strtmp += sprintf(strtmp, "NLM Client %p: {", pkey); strtmp += display_nsm_client(pkey->slc_nsm_client, strtmp); strtmp += sprintf(strtmp, "} caller_name="); memcpy(strtmp, pkey->slc_nlm_caller_name, pkey->slc_nlm_caller_name_len); strtmp += pkey->slc_nlm_caller_name_len; strtmp += sprintf(strtmp, " type=%s", xprt_type_to_str(pkey->slc_client_type)); strtmp += sprintf(strtmp, " refcount=%d", atomic_fetch_int32_t(&pkey->slc_refcount)); return strtmp - str; }
static void Hash_inc_nsm_client_ref(hash_buffer_t *buffval) { state_nsm_client_t *pclient = (state_nsm_client_t *)(buffval->pdata); P(pclient->ssc_mutex); pclient->ssc_refcount++; if(isFullDebug(COMPONENT_STATE)) { char str[HASHTABLE_DISPLAY_STRLEN]; display_nsm_client(pclient, str); LogFullDebug(COMPONENT_STATE, "Increment refcount NSM Client {%s}", str); } V(pclient->ssc_mutex); }
int display_nsm_client_val(hash_buffer_t * pbuff, char *str) { return display_nsm_client((state_nsm_client_t *)pbuff->pdata, str); }
state_nsm_client_t *get_nsm_client(care_t care, SVCXPRT * xprt, char * caller_name) { state_nsm_client_t key; state_nsm_client_t * pclient; char sock_name[SOCK_NAME_MAX]; char str[HASHTABLE_DISPLAY_STRLEN]; struct hash_latch latch; hash_error_t rc; hash_buffer_t buffkey; hash_buffer_t buffval; if(caller_name == NULL) return NULL; memset(&key, 0, sizeof(key)); if(nfs_param.core_param.nsm_use_caller_name) { key.ssc_nlm_caller_name_len = strlen(caller_name); if(key.ssc_nlm_caller_name_len > LM_MAXSTRLEN) { return NULL; } key.ssc_nlm_caller_name = caller_name; } else if(xprt == NULL) { int rc = ipstring_to_sockaddr(caller_name, &key.ssc_client_addr); if(rc != 0) { LogEvent(COMPONENT_STATE, "Error %s, converting caller_name %s to an ipaddress", gai_strerror(rc), caller_name); return NULL; } key.ssc_nlm_caller_name_len = strlen(caller_name); if(key.ssc_nlm_caller_name_len > LM_MAXSTRLEN) { return NULL; } key.ssc_nlm_caller_name = caller_name; } else { key.ssc_nlm_caller_name = sock_name; if(copy_xprt_addr(&key.ssc_client_addr, xprt) == 0) { LogCrit(COMPONENT_STATE, "Error converting caller_name %s to an ipaddress", caller_name); return NULL; } if(sprint_sockip(&key.ssc_client_addr, key.ssc_nlm_caller_name, sizeof(sock_name)) == 0) { LogCrit(COMPONENT_STATE, "Error converting caller_name %s to an ipaddress", caller_name); return NULL; } key.ssc_nlm_caller_name_len = strlen(key.ssc_nlm_caller_name); } if(isFullDebug(COMPONENT_STATE)) { display_nsm_client(&key, str); LogFullDebug(COMPONENT_STATE, "Find {%s}", str); } buffkey.pdata = &key; buffkey.len = sizeof(key); rc = HashTable_GetLatch(ht_nsm_client, &buffkey, &buffval, TRUE, &latch); /* If we found it, return it */ if(rc == HASHTABLE_SUCCESS) { pclient = buffval.pdata; /* Return the found NSM Client */ if(isFullDebug(COMPONENT_STATE)) { display_nsm_client(pclient, str); LogFullDebug(COMPONENT_STATE, "Found {%s}", str); } /* Increment refcount under hash latch. * This prevents dec ref from removing this entry from hash if a race * occurs. */ inc_nsm_client_ref(pclient); HashTable_ReleaseLatched(ht_nsm_client, &latch); if(care == CARE_MONITOR && !nsm_monitor(pclient)) { dec_nsm_client_ref(pclient); pclient = NULL; } return pclient; } /* An error occurred, return NULL */ if(rc != HASHTABLE_ERROR_NO_SUCH_KEY) { display_nsm_client(&key, str); LogCrit(COMPONENT_STATE, "Error %s, could not find {%s}", hash_table_err_to_str(rc), str); return NULL; } /* Not found, but we don't care, return NULL */ if(care == CARE_NOT) { /* Return the found NSM Client */ if(isFullDebug(COMPONENT_STATE)) { display_nsm_client(&key, str); LogFullDebug(COMPONENT_STATE, "Ignoring {%s}", str); } HashTable_ReleaseLatched(ht_nsm_client, &latch); return NULL; } pclient = gsh_malloc(sizeof(*pclient)); if(pclient == NULL) { display_nsm_client(&key, str); LogCrit(COMPONENT_STATE, "No memory for {%s}", str); return NULL; } /* Copy everything over */ memcpy(pclient, &key, sizeof(key)); if(pthread_mutex_init(&pclient->ssc_mutex, NULL) == -1) { /* Mutex initialization failed, free the created client */ display_nsm_client(&key, str); LogCrit(COMPONENT_STATE, "Could not init mutex for {%s}", str); gsh_free(pclient); return NULL; } pclient->ssc_nlm_caller_name = gsh_strdup(key.ssc_nlm_caller_name); if(pclient->ssc_nlm_caller_name == NULL) { /* Discard the created client */ free_nsm_client(pclient); return NULL; } init_glist(&pclient->ssc_lock_list); init_glist(&pclient->ssc_share_list); pclient->ssc_refcount = 1; if(isFullDebug(COMPONENT_STATE)) { display_nsm_client(pclient, str); LogFullDebug(COMPONENT_STATE, "New {%s}", str); } buffkey.pdata = pclient; buffkey.len = sizeof(*pclient); buffval.pdata = pclient; buffval.len = sizeof(*pclient); rc = HashTable_SetLatched(ht_nsm_client, &buffval, &buffval, &latch, FALSE, NULL, NULL); /* An error occurred, return NULL */ if(rc != HASHTABLE_SUCCESS) { display_nsm_client(pclient, str); LogCrit(COMPONENT_STATE, "Error %s, inserting {%s}", hash_table_err_to_str(rc), str); free_nsm_client(pclient); return NULL; } if(care != CARE_MONITOR || nsm_monitor(pclient)) return pclient; /* Failed to monitor, release client reference * and almost certainly remove it from the hash table. */ dec_nsm_client_ref(pclient); return NULL; }
void dec_nsm_client_ref(state_nsm_client_t *pclient) { char str[HASHTABLE_DISPLAY_STRLEN]; struct hash_latch latch; hash_error_t rc; hash_buffer_t buffkey; hash_buffer_t old_value; hash_buffer_t old_key; int32_t refcount; if(isDebug(COMPONENT_STATE)) display_nsm_client(pclient, str); refcount = atomic_dec_int32_t(&pclient->ssc_refcount); if(refcount > 0) { LogFullDebug(COMPONENT_STATE, "Decrement refcount now=%"PRId32" {%s}", refcount, str); return; } LogFullDebug(COMPONENT_STATE, "Try to remove {%s}", str); buffkey.pdata = pclient; buffkey.len = sizeof(*pclient); /* Get the hash table entry and hold latch */ rc = HashTable_GetLatch(ht_nsm_client, &buffkey, &old_value, TRUE, &latch); if(rc != HASHTABLE_SUCCESS) { if(rc == HASHTABLE_ERROR_NO_SUCH_KEY) HashTable_ReleaseLatched(ht_nsm_client, &latch); display_nsm_client(pclient, str); LogCrit(COMPONENT_STATE, "Error %s, could not find {%s}", hash_table_err_to_str(rc), str); return; } refcount = atomic_fetch_int32_t(&pclient->ssc_refcount); if(refcount > 0) { LogDebug(COMPONENT_STATE, "Did not release refcount now=%"PRId32" {%s}", refcount, str); HashTable_ReleaseLatched(ht_nsm_client, &latch); return; } /* use the key to delete the entry */ rc = HashTable_DeleteLatched(ht_nsm_client, &buffkey, &latch, &old_key, &old_value); if(rc != HASHTABLE_SUCCESS) { if(rc == HASHTABLE_ERROR_NO_SUCH_KEY) HashTable_ReleaseLatched(ht_nsm_client, &latch); display_nsm_client(pclient, str); LogCrit(COMPONENT_STATE, "Error %s, could not remove {%s}", hash_table_err_to_str(rc), str); return; } LogFullDebug(COMPONENT_STATE, "Free {%s}", str); nsm_unmonitor(old_value.pdata); free_nsm_client(old_value.pdata); }
state_nsm_client_t *get_nsm_client(care_t care, SVCXPRT * xprt, const char * caller_name) { state_nsm_client_t *pkey, *pclient; if(caller_name == NULL) return NULL; pkey = (state_nsm_client_t *)Mem_Alloc(sizeof(*pkey)); if(pkey == NULL) return NULL; memset(pkey, 0, sizeof(*pkey)); pkey->ssc_refcount = 1; if(nfs_param.core_param.nsm_use_caller_name) { pkey->ssc_nlm_caller_name_len = strlen(caller_name); if(pkey->ssc_nlm_caller_name_len > LM_MAXSTRLEN) { /* Discard the key we created */ free_nsm_client(pkey); return NULL; } pkey->ssc_nlm_caller_name = Mem_Alloc(pkey->ssc_nlm_caller_name_len + 1); if(pkey->ssc_nlm_caller_name == NULL) { /* Discard the key we created */ free_nsm_client(pkey); return NULL; } memcpy(pkey->ssc_nlm_caller_name, caller_name, pkey->ssc_nlm_caller_name_len); pkey->ssc_nlm_caller_name[pkey->ssc_nlm_caller_name_len] = '\0'; } else { pkey->ssc_nlm_caller_name_len = SOCK_NAME_MAX; pkey->ssc_nlm_caller_name = Mem_Alloc(SOCK_NAME_MAX); if(pkey->ssc_nlm_caller_name == NULL) { /* Discard the key we created */ free_nsm_client(pkey); return NULL; } if(copy_xprt_addr(&pkey->ssc_client_addr, xprt) == 0) { /* Discard the key we created */ free_nsm_client(pkey); return NULL; } if(sprint_sockip(&pkey->ssc_client_addr, pkey->ssc_nlm_caller_name, SOCK_NAME_MAX) == 0) { /* Discard the key we created */ free_nsm_client(pkey); return NULL; } pkey->ssc_nlm_caller_name_len = strlen(pkey->ssc_nlm_caller_name); } if(isFullDebug(COMPONENT_STATE)) { char str[HASHTABLE_DISPLAY_STRLEN]; display_nsm_client(pkey, str); LogFullDebug(COMPONENT_STATE, "Find NSM Client pkey {%s}", str); } /* If we found it, return it, if we don't care, return NULL */ if(nsm_client_Get_Pointer(pkey, &pclient) == 1 || care == CARE_NOT) { /* Discard the key we created and return the found NSM Client */ free_nsm_client(pkey); if(isFullDebug(COMPONENT_STATE)) { char str[HASHTABLE_DISPLAY_STRLEN]; display_nsm_client(pclient, str); LogFullDebug(COMPONENT_STATE, "Found NSM Client {%s}", str); } if(care == CARE_MONITOR) if(!nsm_monitor(pclient)) { dec_nsm_client_ref(pclient); return NULL; } return pclient; } pclient = (state_nsm_client_t *)Mem_Alloc(sizeof(*pkey)); if(pclient == NULL) { free_nsm_client(pkey); return NULL; } /* Copy everything over */ *pclient = *pkey; pclient->ssc_nlm_caller_name = Mem_Alloc(pkey->ssc_nlm_caller_name_len + 1); if(pclient->ssc_nlm_caller_name == NULL) { /* Discard the key and created client */ free_nsm_client(pkey); free_nsm_client(pclient); return NULL; } memcpy(pclient->ssc_nlm_caller_name, pkey->ssc_nlm_caller_name, pclient->ssc_nlm_caller_name_len); pclient->ssc_nlm_caller_name[pclient->ssc_nlm_caller_name_len] = '\0'; init_glist(&pclient->ssc_lock_list); if(isFullDebug(COMPONENT_STATE)) { char str[HASHTABLE_DISPLAY_STRLEN]; display_nsm_client(pclient, str); LogFullDebug(COMPONENT_STATE, "New NSM Client {%s}", str); } if(pthread_mutex_init(&pclient->ssc_mutex, NULL) == -1) { /* Mutex initialization failed, free the key and created client */ free_nsm_client(pkey); free_nsm_client(pclient); return NULL; } if(nsm_client_Set(pkey, pclient) == 1) { if(isFullDebug(COMPONENT_STATE)) { char str[HASHTABLE_DISPLAY_STRLEN]; display_nsm_client(pclient, str); LogFullDebug(COMPONENT_STATE, "Set NSM Client {%s}", str); } if(care != CARE_MONITOR || nsm_monitor(pclient)) return pclient; dec_nsm_client_ref(pclient); return NULL; } free_nsm_client(pkey); free_nsm_client(pclient); return NULL; }
/** * @brief Get an NSM client * * @param[in] care Care status * @param[in] xprt RPC transport * @param[in] caller_name Caller name * * @return NSM client or NULL. */ state_nsm_client_t *get_nsm_client(care_t care, SVCXPRT *xprt, char *caller_name) { state_nsm_client_t key; state_nsm_client_t *pclient; char str[LOG_BUFF_LEN]; struct display_buffer dspbuf = {sizeof(str), str, str}; struct hash_latch latch; hash_error_t rc; struct gsh_buffdesc buffkey; struct gsh_buffdesc buffval; if (caller_name == NULL) return NULL; memset(&key, 0, sizeof(key)); if (nfs_param.core_param.nsm_use_caller_name) { key.ssc_nlm_caller_name_len = strlen(caller_name); if (key.ssc_nlm_caller_name_len > LM_MAXSTRLEN) return NULL; key.ssc_nlm_caller_name = caller_name; } else if (op_ctx->client == NULL) { LogCrit(COMPONENT_STATE, "No gsh_client for caller_name %s", caller_name); return NULL; } else { key.ssc_nlm_caller_name = op_ctx->client->hostaddr_str; key.ssc_nlm_caller_name_len = strlen(key.ssc_nlm_caller_name); key.ssc_client = op_ctx->client; } if (isFullDebug(COMPONENT_STATE)) { display_nsm_client(&dspbuf, &key); LogFullDebug(COMPONENT_STATE, "Find {%s}", str); } buffkey.addr = &key; buffkey.len = sizeof(key); rc = hashtable_getlatch(ht_nsm_client, &buffkey, &buffval, true, &latch); /* If we found it, return it */ if (rc == HASHTABLE_SUCCESS) { pclient = buffval.addr; /* Return the found NSM Client */ if (isFullDebug(COMPONENT_STATE)) { display_nsm_client(&dspbuf, pclient); LogFullDebug(COMPONENT_STATE, "Found {%s}", str); } /* Increment refcount under hash latch. * This prevents dec ref from removing this entry from hash * if a race occurs. */ inc_nsm_client_ref(pclient); hashtable_releaselatched(ht_nsm_client, &latch); if (care == CARE_MONITOR && !nsm_monitor(pclient)) { dec_nsm_client_ref(pclient); pclient = NULL; } return pclient; } /* An error occurred, return NULL */ if (rc != HASHTABLE_ERROR_NO_SUCH_KEY) { display_nsm_client(&dspbuf, &key); LogCrit(COMPONENT_STATE, "Error %s, could not find {%s}", hash_table_err_to_str(rc), str); return NULL; } /* Not found, but we don't care, return NULL */ if (care == CARE_NOT) { /* Return the found NSM Client */ if (isFullDebug(COMPONENT_STATE)) { display_nsm_client(&dspbuf, &key); LogFullDebug(COMPONENT_STATE, "Ignoring {%s}", str); } hashtable_releaselatched(ht_nsm_client, &latch); return NULL; } pclient = gsh_malloc(sizeof(*pclient)); if (pclient == NULL) { display_nsm_client(&dspbuf, &key); LogCrit(COMPONENT_STATE, "No memory for {%s}", str); return NULL; } /* Copy everything over */ memcpy(pclient, &key, sizeof(key)); PTHREAD_MUTEX_init(&pclient->ssc_mutex, NULL); pclient->ssc_nlm_caller_name = gsh_strdup(key.ssc_nlm_caller_name); if (pclient->ssc_nlm_caller_name == NULL) { /* Discard the created client */ PTHREAD_MUTEX_destroy(&pclient->ssc_mutex); free_nsm_client(pclient); return NULL; } glist_init(&pclient->ssc_lock_list); glist_init(&pclient->ssc_share_list); pclient->ssc_refcount = 1; if (op_ctx->client != NULL) { pclient->ssc_client = op_ctx->client; inc_gsh_client_refcount(op_ctx->client); } if (isFullDebug(COMPONENT_STATE)) { display_nsm_client(&dspbuf, pclient); LogFullDebug(COMPONENT_STATE, "New {%s}", str); } buffkey.addr = pclient; buffkey.len = sizeof(*pclient); buffval.addr = pclient; buffval.len = sizeof(*pclient); rc = hashtable_setlatched(ht_nsm_client, &buffval, &buffval, &latch, false, NULL, NULL); /* An error occurred, return NULL */ if (rc != HASHTABLE_SUCCESS) { display_nsm_client(&dspbuf, pclient); LogCrit(COMPONENT_STATE, "Error %s, inserting {%s}", hash_table_err_to_str(rc), str); PTHREAD_MUTEX_destroy(&pclient->ssc_mutex); free_nsm_client(pclient); return NULL; } if (care != CARE_MONITOR || nsm_monitor(pclient)) return pclient; /* Failed to monitor, release client reference * and almost certainly remove it from the hash table. */ dec_nsm_client_ref(pclient); return NULL; }
/** * @brief Relinquish a reference on an NSM client * * @param[in] client The client to release */ void dec_nsm_client_ref(state_nsm_client_t *client) { char str[LOG_BUFF_LEN]; struct display_buffer dspbuf = {sizeof(str), str, str}; bool str_valid = false; struct hash_latch latch; hash_error_t rc; struct gsh_buffdesc buffkey; struct gsh_buffdesc old_value; struct gsh_buffdesc old_key; int32_t refcount; if (isDebug(COMPONENT_STATE)) { display_nsm_client(&dspbuf, client); str_valid = true; } refcount = atomic_dec_int32_t(&client->ssc_refcount); if (refcount > 0) { if (str_valid) LogFullDebug(COMPONENT_STATE, "Decrement refcount now=%" PRId32 " {%s}", refcount, str); return; } if (str_valid) LogFullDebug(COMPONENT_STATE, "Try to remove {%s}", str); buffkey.addr = client; buffkey.len = sizeof(*client); /* Get the hash table entry and hold latch */ rc = hashtable_getlatch(ht_nsm_client, &buffkey, &old_value, true, &latch); if (rc != HASHTABLE_SUCCESS) { if (rc == HASHTABLE_ERROR_NO_SUCH_KEY) hashtable_releaselatched(ht_nsm_client, &latch); if (!str_valid) display_nsm_client(&dspbuf, client); LogCrit(COMPONENT_STATE, "Error %s, could not find {%s}", hash_table_err_to_str(rc), str); return; } refcount = atomic_fetch_int32_t(&client->ssc_refcount); if (refcount > 0) { if (str_valid) LogDebug(COMPONENT_STATE, "Did not release refcount now=%"PRId32" {%s}", refcount, str); hashtable_releaselatched(ht_nsm_client, &latch); return; } /* use the key to delete the entry */ rc = hashtable_deletelatched(ht_nsm_client, &buffkey, &latch, &old_key, &old_value); if (rc != HASHTABLE_SUCCESS) { if (rc == HASHTABLE_ERROR_NO_SUCH_KEY) hashtable_releaselatched(ht_nsm_client, &latch); if (!str_valid) display_nsm_client(&dspbuf, client); LogCrit(COMPONENT_STATE, "Error %s, could not remove {%s}", hash_table_err_to_str(rc), str); return; } LogFullDebug(COMPONENT_STATE, "Free {%s}", str); nsm_unmonitor(old_value.addr); free_nsm_client(old_value.addr); }