static void nfs4_acls_test() { int i = 0; fsal_acl_data_t acldata; fsal_ace_t *pace = NULL; fsal_acl_t *pacl = NULL; fsal_acl_status_t status; acldata.naces = 3; acldata.aces = nfs4_ace_alloc(3); LogDebug(COMPONENT_NFS_V4_ACL, "&acldata.aces = %p", &acldata.aces); pace = acldata.aces; for(i = 0; i < 3; i++) { pace->type = i; pace->perm = i; pace->flag = i; pace->who.uid = i; pace++; } pacl = nfs4_acl_new_entry(&acldata, &status); nfs4_acl_entry_inc_ref(pacl); P_r(&pacl->lock); LogDebug(COMPONENT_NFS_V4_ACL, "pacl = %p, ref = %u, status = %u", pacl, pacl->ref, status); V_r(&pacl->lock); pacl = nfs4_acl_new_entry(&acldata, &status); nfs4_acl_entry_inc_ref(pacl); P_r(&pacl->lock); LogDebug(COMPONENT_NFS_V4_ACL, "re-access: pacl = %p, ref = %u, status = %u", pacl, pacl->ref, status); V_r(&pacl->lock); nfs4_acl_release_entry(pacl, &status); P_r(&pacl->lock); LogDebug(COMPONENT_NFS_V4_ACL, "release: pacl = %p, ref = %u, status = %u", pacl, pacl->ref, status); V_r(&pacl->lock); nfs4_acl_release_entry(pacl, &status); }
fsal_acl_t *nfs4_acl_new_entry(fsal_acl_data_t *acldata, fsal_acl_status_t *status) { fsal_acl_t *acl = NULL; struct gsh_buffdesc key; struct gsh_buffdesc value; int rc; struct hash_latch latch; /* Set the return default to NFS_V4_ACL_SUCCESS */ *status = NFS_V4_ACL_SUCCESS; key.addr = acldata->aces; key.len = acldata->naces * sizeof(fsal_ace_t); /* Check if the entry already exists */ rc = hashtable_getlatch(fsal_acl_hash, &key, &value, true, &latch); if (rc == HASHTABLE_SUCCESS) { /* Entry is already in the cache, do not add it */ acl = value.addr; *status = NFS_V4_ACL_EXISTS; nfs4_ace_free(acldata->aces); nfs4_acl_entry_inc_ref(acl); hashtable_releaselatched(fsal_acl_hash, &latch); return acl; } /* Any other result other than no such key is an error */ if (rc != HASHTABLE_ERROR_NO_SUCH_KEY) { *status = NFS_V4_ACL_INIT_ENTRY_FAILED; nfs4_ace_free(acldata->aces); return NULL; } /* Adding the entry in the cache */ acl = nfs4_acl_alloc(); if (pthread_rwlock_init(&(acl->lock), NULL) != 0) { nfs4_acl_free(acl); LogCrit(COMPONENT_NFS_V4_ACL, "New ACL RW lock init returned %d (%s)", errno, strerror(errno)); *status = NFS_V4_ACL_INIT_ENTRY_FAILED; nfs4_ace_free(acldata->aces); hashtable_releaselatched(fsal_acl_hash, &latch); return NULL; } acl->naces = acldata->naces; acl->aces = acldata->aces; acl->ref = 1; /* We give out one reference */ /* Build the value */ value.addr = acl; value.len = sizeof(fsal_acl_t); rc = hashtable_setlatched(fsal_acl_hash, &key, &value, &latch, HASHTABLE_SET_HOW_SET_NO_OVERWRITE, NULL, NULL); if (rc != HASHTABLE_SUCCESS) { /* Put the entry back in its pool */ nfs4_acl_free(acl); LogWarn(COMPONENT_NFS_V4_ACL, "New ACL entry could not be added to hash, rc=%s", hash_table_err_to_str(rc)); *status = NFS_V4_ACL_HASH_SET_ERROR; return NULL; } return acl; }