static ssize_t IMFS_fifo_write( rtems_libio_t *iop, const void *buffer, size_t count ) { IMFS_jnode_t *jnode = iop->pathinfo.node_access; int err = pipe_write(JNODE2PIPE(jnode), buffer, count, iop); if (err > 0) { IMFS_mtime_ctime_update(jnode); } IMFS_FIFO_RETURN(err); }
ssize_t IMFS_fifo_write( epos_libio_t *iop, const void *buffer, size_t count ) { IMFS_jnode_t *jnode = iop->file_info; int err = pipe_write(JNODE2PIPE(jnode), buffer, count, iop); if (err > 0) { IMFS_mtime_ctime_update(jnode); } IMFS_FIFO_RETURN(err); }
/* * IMFS_memfile_write * * This routine writes the specified data buffer into the in memory * file pointed to by memfile. The file is extended as needed. */ ssize_t IMFS_memfile_write( IMFS_memfile_t *memfile, off_t start, const unsigned char *source, unsigned int length ) { block_p *block_ptr; unsigned int block; int status; unsigned int my_length; unsigned int to_copy = 0; unsigned int last_byte; unsigned int start_offset; int copied; const unsigned char *src; src = source; /* * Perform internal consistency checks */ IMFS_assert( source ); IMFS_assert( memfile ); my_length = length; /* * If the last byte we are supposed to write is past the end of this * in memory file, then extend the length. */ last_byte = start + my_length; if ( last_byte > memfile->File.size ) { bool zero_fill = start > memfile->File.size; status = IMFS_memfile_extend( memfile, zero_fill, last_byte ); if ( status ) return status; } copied = 0; /* * Three phases to the write: * + possibly the last part of one block * + all of zero of more blocks * + possibly the first part of one block */ /* * Phase 1: possibly the last part of one block */ start_offset = start % IMFS_MEMFILE_BYTES_PER_BLOCK; block = start / IMFS_MEMFILE_BYTES_PER_BLOCK; if ( start_offset ) { to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK - start_offset; if ( to_copy > my_length ) to_copy = my_length; block_ptr = IMFS_memfile_get_block_pointer( memfile, block, 0 ); if ( !block_ptr ) return copied; #if 0 fprintf( stderr, "write %d at %d in %d: %*s\n", to_copy, start_offset, block, to_copy, src ); #endif memcpy( &(*block_ptr)[ start_offset ], src, to_copy ); src += to_copy; block++; my_length -= to_copy; copied += to_copy; } /* * Phase 2: all of zero of more blocks */ to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK; while ( my_length >= IMFS_MEMFILE_BYTES_PER_BLOCK ) { block_ptr = IMFS_memfile_get_block_pointer( memfile, block, 0 ); if ( !block_ptr ) return copied; #if 0 fprintf(stdout, "write %d in %d: %*s\n", to_copy, block, to_copy, src ); #endif memcpy( &(*block_ptr)[ 0 ], src, to_copy ); src += to_copy; block++; my_length -= to_copy; copied += to_copy; } /* * Phase 3: possibly the first part of one block */ IMFS_assert( my_length < IMFS_MEMFILE_BYTES_PER_BLOCK ); to_copy = my_length; if ( my_length ) { block_ptr = IMFS_memfile_get_block_pointer( memfile, block, 0 ); if ( !block_ptr ) return copied; #if 0 fprintf(stdout, "write %d in %d: %*s\n", to_copy, block, to_copy, src ); #endif memcpy( &(*block_ptr)[ 0 ], src, my_length ); my_length = 0; copied += to_copy; } IMFS_mtime_ctime_update( &memfile->File.Node ); return copied; }
/* * 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; }
int IMFS_make_generic_node( const char *path, mode_t mode, const IMFS_node_control *node_control, void *context ) { int rv = 0; mode &= ~rtems_filesystem_umask; switch (mode & S_IFMT) { case S_IFBLK: case S_IFCHR: case S_IFIFO: case S_IFREG: case S_IFSOCK: break; default: errno = EINVAL; rv = -1; break; } if ( rv == 0 ) { if ( node_control->imfs_type == IMFS_GENERIC ) { rtems_filesystem_eval_path_context_t ctx; int eval_flags = RTEMS_FS_FOLLOW_LINK | RTEMS_FS_MAKE | RTEMS_FS_EXCLUSIVE; const rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_start( &ctx, path, eval_flags ); if ( IMFS_is_imfs_instance( currentloc ) ) { IMFS_types_union info; IMFS_jnode_t *new_node; info.generic.context = context; new_node = IMFS_create_node_with_control( currentloc, node_control, rtems_filesystem_eval_path_get_token( &ctx ), rtems_filesystem_eval_path_get_tokenlen( &ctx ), mode, &info ); if ( new_node != NULL ) { IMFS_jnode_t *parent = currentloc->node_access; IMFS_mtime_ctime_update( parent ); } else { rv = -1; } } else { rtems_filesystem_eval_path_error( &ctx, ENOTSUP ); rv = -1; } rtems_filesystem_eval_path_cleanup( &ctx ); } else { errno = EINVAL; rv = -1; } } return rv; }
MEMFILE_STATIC ssize_t IMFS_memfile_write( IMFS_jnode_t *the_jnode, off_t start, const unsigned char *source, unsigned int length ) { block_p *block_ptr; unsigned int block; int status; unsigned int my_length; unsigned int to_copy = 0; unsigned int last_byte; unsigned int start_offset; int copied; const unsigned char *src; src = source; /* * Perform internal consistency checks */ assert( the_jnode ); if ( !the_jnode ) rtems_set_errno_and_return_minus_one( EIO ); assert( the_jnode->type == IMFS_MEMORY_FILE ); if ( the_jnode->type != IMFS_MEMORY_FILE ) rtems_set_errno_and_return_minus_one( EIO ); /* * Error check arguments */ assert( source ); if ( !source ) rtems_set_errno_and_return_minus_one( EINVAL ); /* * If there is nothing to write, then quick exit. */ my_length = length; if ( !my_length ) rtems_set_errno_and_return_minus_one( EINVAL ); /* * If the last byte we are supposed to write is past the end of this * in memory file, then extend the length. */ last_byte = start + length; if ( last_byte > the_jnode->info.file.size ) { status = IMFS_memfile_extend( the_jnode, last_byte ); if ( status ) rtems_set_errno_and_return_minus_one( ENOSPC ); } copied = 0; /* * Three phases to the write: * + possibly the last part of one block * + all of zero of more blocks * + possibly the first part of one block */ /* * Phase 1: possibly the last part of one block */ start_offset = start % IMFS_MEMFILE_BYTES_PER_BLOCK; block = start / IMFS_MEMFILE_BYTES_PER_BLOCK; if ( start_offset ) { to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK - start_offset; if ( to_copy > my_length ) to_copy = my_length; block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 ); assert( block_ptr ); if ( !block_ptr ) return copied; #if 0 fprintf(stdout, "write %d at %d in %d: %*s\n", to_copy, start_offset, block, to_copy, src ); #endif memcpy( &(*block_ptr)[ start_offset ], src, to_copy ); src += to_copy; block++; my_length -= to_copy; copied += to_copy; } /* * Phase 2: all of zero of more blocks */ to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK; while ( my_length >= IMFS_MEMFILE_BYTES_PER_BLOCK ) { block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 ); assert( block_ptr ); if ( !block_ptr ) return copied; #if 0 fprintf(stdout, "write %d in %d: %*s\n", to_copy, block, to_copy, src ); #endif memcpy( &(*block_ptr)[ 0 ], src, to_copy ); src += to_copy; block++; my_length -= to_copy; copied += to_copy; } /* * Phase 3: possibly the first part of one block */ assert( my_length < IMFS_MEMFILE_BYTES_PER_BLOCK ); to_copy = my_length; if ( my_length ) { block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 ); assert( block_ptr ); if ( !block_ptr ) return copied; #if 0 fprintf(stdout, "write %d in %d: %*s\n", to_copy, block, to_copy, src ); #endif memcpy( &(*block_ptr)[ 0 ], src, my_length ); my_length = 0; copied += to_copy; } IMFS_mtime_ctime_update( the_jnode ); return copied; }