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 */
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 */