/* * IMFS_memfile_destroy * * This routine frees all memory associated with an in memory file. * * NOTE: This is an exceptionally conservative implementation. * It will check EVERY pointer which is non-NULL and insure * any child non-NULL pointers are freed. Optimistically, all that * is necessary is to scan until a NULL pointer is found. There * should be no allocated data past that point. * * In experimentation on the powerpc simulator, it was noted * that using blocks which held 128 slots versus 16 slots made * a significant difference in the performance of this routine. * * Regardless until the IMFS implementation is proven, it * is better to stick to simple, easy to understand algorithms. */ static void IMFS_memfile_destroy( IMFS_jnode_t *the_jnode ) { IMFS_memfile_t *memfile; int i; int j; unsigned int to_free; block_p *p; memfile = (IMFS_memfile_t *) the_jnode; /* * Perform internal consistency checks */ IMFS_assert( memfile ); /* * Eventually this could be set smarter at each call to * memfile_free_blocks_in_table to greatly speed this up. */ to_free = IMFS_MEMFILE_BLOCK_SLOTS; /* * Now start freeing blocks in this order: * + indirect * + doubly indirect * + triply indirect */ if ( memfile->indirect ) { memfile_free_blocks_in_table( &memfile->indirect, to_free ); } if ( memfile->doubly_indirect ) { for ( i=0 ; i<IMFS_MEMFILE_BLOCK_SLOTS ; i++ ) { if ( memfile->doubly_indirect[i] ) { memfile_free_blocks_in_table( (block_p **)&memfile->doubly_indirect[i], to_free ); } } memfile_free_blocks_in_table( &memfile->doubly_indirect, to_free ); } if ( memfile->triply_indirect ) { for ( i=0 ; i<IMFS_MEMFILE_BLOCK_SLOTS ; i++ ) { p = (block_p *) memfile->triply_indirect[i]; if ( !p ) /* ensure we have a valid pointer */ break; for ( j=0 ; j<IMFS_MEMFILE_BLOCK_SLOTS ; j++ ) { if ( p[j] ) { memfile_free_blocks_in_table( (block_p **)&p[j], to_free); } } memfile_free_blocks_in_table( (block_p **)&memfile->triply_indirect[i], to_free ); } memfile_free_blocks_in_table( (block_p **)&memfile->triply_indirect, to_free ); } IMFS_node_destroy_default( the_jnode ); }
/* * IMFS_memfile_remove * * This routine frees all memory associated with an in memory file. * * NOTE: This is an exceptionally conservative implementation. * It will check EVERY pointer which is non-NULL and insure * any child non-NULL pointers are freed. Optimistically, all that * is necessary is to scan until a NULL pointer is found. There * should be no allocated data past that point. * * In experimentation on the powerpc simulator, it was noted * that using blocks which held 128 slots versus 16 slots made * a significant difference in the performance of this routine. * * Regardless until the IMFS implementation is proven, it * is better to stick to simple, easy to understand algorithms. */ IMFS_jnode_t *IMFS_memfile_remove( IMFS_jnode_t *the_jnode ) { IMFS_memfile_t *info; int i; int j; unsigned int to_free; block_p *p; /* * Perform internal consistency checks */ IMFS_assert( the_jnode ); IMFS_assert( IMFS_type( the_jnode ) == IMFS_MEMORY_FILE ); /* * Eventually this could be set smarter at each call to * memfile_free_blocks_in_table to greatly speed this up. */ to_free = IMFS_MEMFILE_BLOCK_SLOTS; /* * Now start freeing blocks in this order: * + indirect * + doubly indirect * + triply indirect */ info = &the_jnode->info.file; if ( info->indirect ) { memfile_free_blocks_in_table( &info->indirect, to_free ); } if ( info->doubly_indirect ) { for ( i=0 ; i<IMFS_MEMFILE_BLOCK_SLOTS ; i++ ) { if ( info->doubly_indirect[i] ) { memfile_free_blocks_in_table( (block_p **)&info->doubly_indirect[i], to_free ); } } memfile_free_blocks_in_table( &info->doubly_indirect, to_free ); } if ( info->triply_indirect ) { for ( i=0 ; i<IMFS_MEMFILE_BLOCK_SLOTS ; i++ ) { p = (block_p *) info->triply_indirect[i]; if ( !p ) /* ensure we have a valid pointer */ break; for ( j=0 ; j<IMFS_MEMFILE_BLOCK_SLOTS ; j++ ) { if ( p[j] ) { memfile_free_blocks_in_table( (block_p **)&p[j], to_free); } } memfile_free_blocks_in_table( (block_p **)&info->triply_indirect[i], to_free ); } memfile_free_blocks_in_table( (block_p **)&info->triply_indirect, to_free ); } return the_jnode; }