コード例 #1
0
ファイル: nfs4_acls.c プロジェクト: manusfreedom/nfs-ganesha
void nfs4_acl_release_entry(fsal_acl_t *acl, fsal_acl_status_t *status)
{
    struct gsh_buffdesc key, old_key;
    struct gsh_buffdesc old_value;
    int rc;
    struct hash_latch latch;

    /* Set the return default to NFS_V4_ACL_SUCCESS */
    *status = NFS_V4_ACL_SUCCESS;

    if (!acl)
        return;

    PTHREAD_RWLOCK_wrlock(&acl->lock);
    if (acl->ref > 1) {
        nfs4_acl_entry_dec_ref(acl);
        PTHREAD_RWLOCK_unlock(&acl->lock);
        return;
    } else
        LogDebug(COMPONENT_NFS_V4_ACL, "Free ACL %p", acl);

    key.addr = acl->aces;
    key.len = acl->naces * sizeof(fsal_ace_t);

    PTHREAD_RWLOCK_unlock(&acl->lock);

    /* Get the hash table entry and hold latch */
    rc = hashtable_getlatch(fsal_acl_hash, &key, &old_value, true, &latch);

    switch (rc) {
    case HASHTABLE_ERROR_NO_SUCH_KEY:
        hashtable_releaselatched(fsal_acl_hash, &latch);
        return;

    case HASHTABLE_SUCCESS:
        PTHREAD_RWLOCK_wrlock(&acl->lock);
        nfs4_acl_entry_dec_ref(acl);
        if (acl->ref != 0) {
            /* Did not actually release last reference */
            hashtable_releaselatched(fsal_acl_hash, &latch);
            PTHREAD_RWLOCK_unlock(&acl->lock);
            return;
        }

        /* use the key to delete the entry */
        hashtable_deletelatched(fsal_acl_hash, &key, &latch,
                                &old_key, &old_value);

        /* Release the latch */
        hashtable_releaselatched(fsal_acl_hash, &latch);
        break;

    default:
        LogCrit(COMPONENT_NFS_V4_ACL,
                "ACL entry could not be deleted, status=%s",
                hash_table_err_to_str(rc));
        return;
    }

    /* Sanity check: old_value.addr is expected to be equal to acl,
     * and is released later in this function */
    assert(old_value.addr == acl);

    PTHREAD_RWLOCK_unlock(&acl->lock);

    /* Release acl */
    nfs4_acl_free(acl);
}
コード例 #2
0
ファイル: nlm_owner.c プロジェクト: JevonQ/nfs-ganesha
/**
 * @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);
}