Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
void nfs4_acl_release_entry(fsal_acl_t *pacl, fsal_acl_status_t *pstatus)
{
  fsal_acl_data_t acldata;
  hash_buffer_t key, old_key;
  hash_buffer_t old_value;
  int rc;

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

  P_w(&pacl->lock);
  nfs4_acl_entry_dec_ref(pacl);
  if(pacl->ref)
    {
      V_w(&pacl->lock);
      return;
    }
  else
      LogDebug(COMPONENT_NFS_V4_ACL, "nfs4_acl_release_entry: free acl %p", pacl);

  /* Turn the input to a hash key */
  acldata.naces = pacl->naces;
  acldata.aces = pacl->aces;

  if(nfs4_acldata_2_key(&key, &acldata))
  {
    *pstatus = NFS_V4_ACL_UNAPPROPRIATED_KEY;

    nfs4_release_acldata_key(&key);

    V_w(&pacl->lock);

    return;
  }

  /* use the key to delete the entry */
  if((rc = HashTable_Del(fsal_acl_hash, &key, &old_key, &old_value)) != HASHTABLE_SUCCESS)
    {
      LogCrit(COMPONENT_NFS_V4_ACL,
              "nfs4_acl_release_entry: entry could not be deleted, status = %d",
              rc);

      nfs4_release_acldata_key(&key);

      *pstatus = NFS_V4_ACL_NOT_FOUND;

      V_w(&pacl->lock);

      return;
    }

  /* Release the hash key data */
  nfs4_release_acldata_key(&old_key);

  /* Sanity check: old_value.pdata is expected to be equal to pacl,
   * and is released later in this function */
  if((fsal_acl_t *) old_value.pdata != pacl)
    {
      LogCrit(COMPONENT_NFS_V4_ACL,
              "nfs4_acl_release_entry: unexpected pdata %p from hash table (pacl=%p)",
              old_value.pdata, pacl);
    }

  /* Release the current key */
  nfs4_release_acldata_key(&key);

  V_w(&pacl->lock);

  /* Release acl */
  nfs4_acl_free(pacl);
}