/* * IMFS_memfile_extend * * This routine insures that the in-memory file is of the length * specified. If necessary, it will allocate memory blocks to * extend the file. */ MEMFILE_STATIC int IMFS_memfile_extend( IMFS_jnode_t *the_jnode, off_t new_length ) { unsigned int block; unsigned int new_blocks; unsigned int old_blocks; /* * Perform internal consistency checks */ IMFS_assert( the_jnode ); IMFS_assert( IMFS_type( the_jnode ) == IMFS_MEMORY_FILE ); /* * Verify new file size is supported */ if ( new_length >= IMFS_MEMFILE_MAXIMUM_SIZE ) rtems_set_errno_and_return_minus_one( EINVAL ); /* * Verify new file size is actually larger than current size */ if ( new_length <= the_jnode->info.file.size ) return 0; /* * Calculate the number of range of blocks to allocate */ new_blocks = new_length / IMFS_MEMFILE_BYTES_PER_BLOCK; old_blocks = the_jnode->info.file.size / IMFS_MEMFILE_BYTES_PER_BLOCK; /* * Now allocate each of those blocks. */ for ( block=old_blocks ; block<=new_blocks ; block++ ) { if ( IMFS_memfile_addblock( the_jnode, block ) ) { for ( ; block>=old_blocks ; block-- ) { IMFS_memfile_remove_block( the_jnode, block ); } rtems_set_errno_and_return_minus_one( ENOSPC ); } } /* * Set the new length of the file. */ the_jnode->info.file.size = new_length; IMFS_update_ctime(the_jnode); IMFS_update_mtime(the_jnode); return 0; }
/* * IMFS_memfile_extend * * This routine insures that the in-memory file is of the length * specified. If necessary, it will allocate memory blocks to * extend the file. */ static int IMFS_memfile_extend( IMFS_memfile_t *memfile, bool zero_fill, off_t new_length ) { unsigned int block; unsigned int new_blocks; unsigned int old_blocks; unsigned int offset; /* * Perform internal consistency checks */ IMFS_assert( memfile ); /* * Verify new file size is supported */ if ( new_length >= IMFS_MEMFILE_MAXIMUM_SIZE ) rtems_set_errno_and_return_minus_one( EFBIG ); /* * Verify new file size is actually larger than current size */ if ( new_length <= memfile->File.size ) return 0; /* * Calculate the number of range of blocks to allocate */ new_blocks = new_length / IMFS_MEMFILE_BYTES_PER_BLOCK; old_blocks = memfile->File.size / IMFS_MEMFILE_BYTES_PER_BLOCK; offset = memfile->File.size - old_blocks * IMFS_MEMFILE_BYTES_PER_BLOCK; /* * Now allocate each of those blocks. */ for ( block=old_blocks ; block<=new_blocks ; block++ ) { if ( !IMFS_memfile_addblock( memfile, block ) ) { if ( zero_fill ) { size_t count = IMFS_MEMFILE_BYTES_PER_BLOCK - offset; block_p *block_ptr = IMFS_memfile_get_block_pointer( memfile, block, 0 ); memset( &(*block_ptr) [offset], 0, count); offset = 0; } } else { for ( ; block>=old_blocks ; block-- ) { IMFS_memfile_remove_block( memfile, block ); } rtems_set_errno_and_return_minus_one( ENOSPC ); } } /* * Set the new length of the file. */ memfile->File.size = new_length; IMFS_mtime_ctime_update( &memfile->File.Node ); return 0; }