Beispiel #1
0
int do_invalidate(LRU_list_t * plru, int key)
{
  LRU_entry_t *pentry = NULL;

  pentry = tabentry[key];

  return LRU_invalidate(plru, pentry);
}
cache_inode_status_t cache_inode_kill_entry( cache_entry_t          * pentry,
                                             cache_inode_lock_how_t   lock_how,  
                                             hash_table_t           * ht,
                                             cache_inode_client_t   * pclient,
                                             cache_inode_status_t   * pstatus )
{
  fsal_handle_t *pfsal_handle = NULL;
  cache_inode_fsal_data_t fsaldata;
  cache_inode_parent_entry_t *parent_iter = NULL;
  cache_inode_parent_entry_t *parent_iter_next = NULL;
  hash_buffer_t key, old_key;
  hash_buffer_t old_value;
  int rc;
  fsal_status_t fsal_status;

  memset( (char *)&fsaldata, 0, sizeof( fsaldata ) ) ;

  LogInfo(COMPONENT_CACHE_INODE,
          "Using cache_inode_kill_entry for entry %p", pentry);

  /* Invalidation is not for junctions or special files */
  if( ( pentry->internal_md.type == FS_JUNCTION )    ||
      ( pentry->internal_md.type == SOCKET_FILE )    ||
      ( pentry->internal_md.type == FIFO_FILE )      ||
      ( pentry->internal_md.type == CHARACTER_FILE ) ||
      ( pentry->internal_md.type == BLOCK_FILE ) )
   {
     free_lock( pentry, lock_how ) ; 

     *pstatus = CACHE_INODE_SUCCESS;
     return *pstatus;
   }

#if 0
  /** @todo: BUGAZOMEU : directory invalidation seems quite tricky, temporarily avoid it */
  if( pentry->internal_md.type == DIRECTORY )
   {
     free_lock( pentry, lock_how ) ; 

     *pstatus = CACHE_INODE_SUCCESS;
     return *pstatus;
   }

  /** @todo: BUGAZOMEU : file invalidation seems quite tricky, temporarily avoid it */
  /* We need to know how to manage how to deal with "files with states"  */
  if( pentry->internal_md.type == REGULAR_FILE )
   {
     free_lock( pentry, lock_how ) ; 

     *pstatus = CACHE_INODE_SUCCESS;
     return *pstatus;
   }
#endif

  if(pstatus == NULL)
    return CACHE_INODE_INVALID_ARGUMENT;

  if(pentry == NULL || pclient == NULL || ht == NULL)
    {
      free_lock( pentry, lock_how ) ; 

      *pstatus = CACHE_INODE_INVALID_ARGUMENT;
      return *pstatus;
    }

  /* Get the FSAL handle */
  if((pfsal_handle = cache_inode_get_fsal_handle(pentry, pstatus)) == NULL)
    {
      free_lock( pentry, lock_how ) ; 

      LogCrit(COMPONENT_CACHE_INODE,
              "cache_inode_kill_entry: unable to retrieve pentry's specific filesystem info");
      return *pstatus;
    }

  /* Invalidate the related LRU gc entry (no more required) */
  if(pentry->gc_lru_entry != NULL)
    {
      if(LRU_invalidate(pentry->gc_lru, pentry->gc_lru_entry) != LRU_LIST_SUCCESS)
        {
          free_lock( pentry, lock_how ) ; 

          *pstatus = CACHE_INODE_LRU_ERROR;
          return *pstatus;
        }
    }

  fsaldata.handle = *pfsal_handle;
  fsaldata.cookie = DIR_START;

  /* Use the handle to build the key */
  if(cache_inode_fsaldata_2_key(&key, &fsaldata, pclient))
    {
      free_lock( pentry, lock_how ) ; 

      LogCrit(COMPONENT_CACHE_INODE,
              "cache_inode_kill_entry: could not build hashtable key");

      cache_inode_release_fsaldata_key(&key, pclient);
      *pstatus = CACHE_INODE_NOT_FOUND;
      return *pstatus;
    }

  /* use the key to delete the entry */
  if((rc = HashTable_Del(ht, &key, &old_key, &old_value)) != HASHTABLE_SUCCESS)
    {
      if( rc != HASHTABLE_ERROR_NO_SUCH_KEY) /* rc=3 => Entry was previously removed */
        LogCrit( COMPONENT_CACHE_INODE,
                 "cache_inode_kill_entry: entry could not be deleted, status = %d",
                 rc);

      cache_inode_release_fsaldata_key(&key, pclient);

      *pstatus = CACHE_INODE_NOT_FOUND;
      return *pstatus;
    }

  /* Release the hash key data */
  cache_inode_release_fsaldata_key(&old_key, pclient);

  /* Clean up the associated ressources in the FSAL */
  if(FSAL_IS_ERROR(fsal_status = FSAL_CleanObjectResources(pfsal_handle)))
    {
      LogCrit(COMPONENT_CACHE_INODE,
              "cache_inode_kill_entry: Couldn't free FSAL ressources fsal_status.major=%u",
              fsal_status.major);
    }

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

  /* Release the current key */
  cache_inode_release_fsaldata_key(&key, pclient);

  /* Recover the parent list entries */
  parent_iter = pentry->parent_list;
  while(parent_iter != NULL)
    {
      parent_iter_next = parent_iter->next_parent;

      ReleaseToPool(parent_iter, &pclient->pool_parent);

      parent_iter = parent_iter_next;
    }

  /* If entry is datacached, remove it from the cache */
  if(pentry->internal_md.type == REGULAR_FILE)
    {
      cache_content_status_t cache_content_status;

      if(pentry->object.file.pentry_content != NULL)
        if(cache_content_release_entry
           ((cache_content_entry_t *) pentry->object.file.pentry_content,
            (cache_content_client_t *) pclient->pcontent_client,
            &cache_content_status) != CACHE_CONTENT_SUCCESS)
          LogCrit(COMPONENT_CACHE_INODE,
                  "Could not removed datacached entry for pentry %p", pentry);
    }

  /* If entry is a DIRECTORY, invalidate dirents */
  if(pentry->internal_md.type == DIRECTORY)
    {
	cache_inode_invalidate_related_dirents(pentry, pclient);
    }

  // free_lock( pentry, lock_how ) ; /* Really needed ? The pentry is unaccessible now and will be destroyed */

  /* Destroy the mutex associated with the pentry */
  cache_inode_mutex_destroy(pentry);

  /* Put the pentry back to the pool */
  ReleaseToPool(pentry, &pclient->pool_entry);

  *pstatus = CACHE_INODE_SUCCESS;
  return *pstatus;
}                               /* cache_inode_kill_entry */
/**
 * cache_inode_clean_internal: remove a pentry from cache and all LRUs,
 *                             and release related resources.
 *
 * @param pentry [IN] entry to be deleted from cache
 * @param hash_table_t [IN] The cache hash table
 * @param pclient [INOUT] ressource allocated by the client for the nfs management.
 */
cache_inode_status_t cache_inode_clean_internal(cache_entry_t * to_remove_entry,
                                                hash_table_t * ht,
                                                cache_inode_client_t * pclient)
{
  fsal_handle_t *pfsal_handle_remove;
  cache_inode_parent_entry_t *parent_iter = NULL;
  cache_inode_parent_entry_t *parent_iter_next = NULL;
  cache_inode_fsal_data_t fsaldata;
  cache_inode_status_t status;
  hash_buffer_t key, old_key, old_value;
  int rc;
 
  memset( (char *)&fsaldata, 0, sizeof( fsaldata ) ) ;

  if((pfsal_handle_remove =
      cache_inode_get_fsal_handle(to_remove_entry, &status)) == NULL)
    {
      return status;
    }

  /* Invalidate the related LRU gc entry (no more required) */
  if(to_remove_entry->gc_lru_entry != NULL)
    {
      if(LRU_invalidate(to_remove_entry->gc_lru, to_remove_entry->gc_lru_entry)
         != LRU_LIST_SUCCESS)
        {
          return CACHE_INODE_LRU_ERROR;
        }
    }

  /* delete the entry from the cache */
  fsaldata.handle = *pfsal_handle_remove;

  /* XXX always DIR_START */
  fsaldata.cookie = DIR_START;

  if(cache_inode_fsaldata_2_key(&key, &fsaldata, pclient))
    {
      return CACHE_INODE_INCONSISTENT_ENTRY;
    }

  /* use the key to delete the entry */
  rc = HashTable_Del(ht, &key, &old_key, &old_value);

  if(rc)
    LogCrit(COMPONENT_CACHE_INODE,
            "HashTable_Del error %d in cache_inode_clean_internal", rc);

  if((rc != HASHTABLE_SUCCESS) && (rc != HASHTABLE_ERROR_NO_SUCH_KEY))
    {
      cache_inode_release_fsaldata_key(&key, pclient);
      return CACHE_INODE_INCONSISTENT_ENTRY;
    }

  /* release the key that was stored in hash table */
  if(rc != HASHTABLE_ERROR_NO_SUCH_KEY)
    {
      cache_inode_release_fsaldata_key(&old_key, pclient);

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

  /* release the key used for hash query */
  cache_inode_release_fsaldata_key(&key, pclient);

  /* Free the parent list entries */

  parent_iter = to_remove_entry->parent_list;
  while(parent_iter != NULL)
    {
      parent_iter_next = parent_iter->next_parent;

      ReleaseToPool(parent_iter, &pclient->pool_parent);

      parent_iter = parent_iter_next;
    }

  return CACHE_INODE_SUCCESS;
}                               /* cache_inode_clean_internal */
Beispiel #4
0
int main(int argc, char *argv[])
{
  SetDefaultLogging("TEST");
  SetNamePgm("test_lru");

  LRU_list_t *plru;
  LRU_parameter_t param;
  LRU_entry_t *entry = NULL;
  LRU_entry_t *kept_entry = NULL;
  LRU_status_t status = 0;
  int i = 0;
  char strtab[MAXTEST][10];

  param.nb_entry_prealloc = PREALLOC;
  param.entry_to_str = print_entry;
  param.clean_entry = clean_entry;
  param.lp_name = "Test";

  BuddyInit(NULL);

  if((plru = LRU_Init(param, &status)) == NULL)
    {
      LogTest("Test FAILED: Bad Init");
      exit(1);
    }

  for(i = 0; i < MAXTEST; i++)
    {
      LogTest("Added entry %d", i);
      sprintf(strtab[i], "%d", i);
      if((entry = LRU_new_entry(plru, &status)) == NULL)
        {

          LogTest("Test FAILED: bad entry add, status = %d", status);
          exit(1);
        }

      entry->buffdata.pdata = strtab[i];
      entry->buffdata.len = strlen(strtab[i]);

      if(i == KEPT_ENTRY)
        kept_entry = entry;
    }

  /* printing the table */
  LRU_Print(plru);

  LRU_invalidate(plru, kept_entry);

  if(isFullDebug(COMPONENT_LRU))
    LRU_Print(plru);

  if(LRU_gc_invalid(plru, NULL) != LRU_LIST_SUCCESS)
    {
      LogTest("Test FAILED: bad gc");
      exit(1);
    }
  LRU_Print(plru);

  /* Tous les tests sont ok */
  LogTest("\n-----------------------------------------");
  LogTest("Test succeeded: all tests pass successfully");

  exit(0);
}                               /* main */