Esempio n. 1
0
/*
 *  IMFS_memfile_addblock
 *
 *  This routine adds a single block to the specified in-memory file.
 */
static int IMFS_memfile_addblock(
   IMFS_memfile_t *memfile,
   unsigned int    block
)
{
  block_p  memory;
  block_p *block_entry_ptr;

  IMFS_assert( memfile );

  /*
   * Obtain the pointer for the specified block number
   */
  block_entry_ptr = IMFS_memfile_get_block_pointer( memfile, block, 1 );
  if ( !block_entry_ptr )
    return 1;

  if ( *block_entry_ptr )
    return 0;

  /*
   *  There is no memory for this block number so allocate it.
   */
  memory = memfile_alloc_block();
  if ( !memory )
    return 1;

  *block_entry_ptr = memory;
  return 0;
}
Esempio n. 2
0
/*
 *  IMFS_memfile_addblock
 *
 *  This routine adds a single block to the specified in-memory file.
 */
MEMFILE_STATIC int IMFS_memfile_addblock(
   IMFS_jnode_t  *the_jnode,
   unsigned int   block
)
{
  block_p  memory;
  block_p *block_entry_ptr;

  IMFS_assert( the_jnode );
  IMFS_assert( IMFS_type( the_jnode ) == IMFS_MEMORY_FILE );

  /*
   * Obtain the pointer for the specified block number
   */
  block_entry_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 1 );
  if ( !block_entry_ptr )
    return 1;

  if ( *block_entry_ptr )
    return 0;

  /*
   *  There is no memory for this block number so allocate it.
   */
  memory = memfile_alloc_block();
  if ( !memory )
    return 1;

  *block_entry_ptr = memory;
  return 0;
}
Esempio n. 3
0
MEMFILE_STATIC int IMFS_memfile_addblock(
   IMFS_jnode_t  *the_jnode,
   unsigned int   block
)
{
  block_p  memory;
  block_p *block_entry_ptr;

  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 );

  block_entry_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 1 );
  if ( *block_entry_ptr )
    return 0;

#if 0
  fprintf(stdout, "%d %p", block, block_entry_ptr );
    fflush(stdout);
#endif

  memory = memfile_alloc_block();
  if ( !memory )
    return 1;
  *block_entry_ptr = memory;

  return 0;
}
Esempio n. 4
0
/*
 *  IMFS_memfile_remove_block
 *
 *  This routine removes the specified block from the in-memory file.
 *
 *  NOTE:  This is a support routine and is called only to remove
 *         the last block or set of blocks in a file.  Removing a
 *         block from the middle of a file would be exceptionally
 *         dangerous and the results unpredictable.
 */
static void IMFS_memfile_remove_block(
   IMFS_memfile_t *memfile,
   unsigned int    block
)
{
  block_p *block_ptr;
  block_p  ptr;

  block_ptr = IMFS_memfile_get_block_pointer( memfile, block, 0 );
  if ( block_ptr ) {
    ptr = *block_ptr;
    *block_ptr = 0;
    memfile_free_block( ptr );
  }
}
Esempio n. 5
0
/*
 *  IMFS_memfile_remove_block
 *
 *  This routine removes the specified block from the in-memory file.
 *
 *  NOTE:  This is a support routine and is called only to remove
 *         the last block or set of blocks in a file.  Removing a
 *         block from the middle of a file would be exceptionally
 *         dangerous and the results unpredictable.
 */
MEMFILE_STATIC void IMFS_memfile_remove_block(
   IMFS_jnode_t  *the_jnode,
   unsigned int   block
)
{
  block_p *block_ptr;
  block_p  ptr;

  block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
  if ( block_ptr ) {
    ptr = *block_ptr;
    *block_ptr = 0;
    memfile_free_block( ptr );
  }
}
Esempio n. 6
0
/*
 *  IMFS_memfile_remove_block
 *
 *  This routine removes the specified block from the in-memory file.
 *
 *  NOTE:  This is a support routine and is called only to remove
 *         the last block or set of blocks in a file.  Removing a
 *         block from the middle of a file would be exceptionally
 *         dangerous and the results unpredictable.
 */
MEMFILE_STATIC int IMFS_memfile_remove_block(
   IMFS_jnode_t  *the_jnode,
   unsigned int   block
)
{
  block_p *block_ptr;
  block_p  ptr;

  block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
  IMFS_assert( block_ptr );

  ptr = *block_ptr;
  *block_ptr = 0;
  memfile_free_block( ptr );

  return 1;
}
Esempio n. 7
0
/*
 *  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;
}
Esempio n. 8
0
/*
 *  IMFS_memfile_read
 *
 *  This routine read from memory file pointed to by the_jnode into
 *  the specified data buffer specified by destination.  The file
 *  is NOT extended.  An offset greater than the length of the file
 *  is considered an error.  Read from an offset for more bytes than
 *  are between the offset and the end of the file will result in
 *  reading the data between offset and the end of the file (truncated
 *  read).
 */
static ssize_t IMFS_memfile_read(
   IMFS_file_t     *file,
   off_t            start,
   unsigned char   *destination,
   unsigned int     length
)
{
  block_p             *block_ptr;
  unsigned int         block;
  unsigned int         my_length;
  unsigned int         to_copy = 0;
  unsigned int         last_byte;
  unsigned int         copied;
  unsigned int         start_offset;
  unsigned char       *dest;

  dest = destination;

  /*
   *  Perform internal consistency checks
   */
  IMFS_assert( file );
  IMFS_assert( dest );

  /*
   *  Linear files (as created from a tar file are easier to handle
   *  than block files).
   */
  my_length = length;

  /*
   *  If the last byte we are supposed to read is past the end of this
   *  in memory file, then shorten the length to read.
   */
  last_byte = start + length;
  if ( last_byte > file->Memfile.File.size )
    my_length = file->Memfile.File.size - start;

  copied = 0;

  /*
   *  Three phases to the read:
   *    + 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( &file->Memfile, block, 0 );
    if ( !block_ptr )
      return copied;
    memcpy( dest, &(*block_ptr)[ start_offset ], to_copy );
    dest += 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( &file->Memfile, block, 0 );
    if ( !block_ptr )
      return copied;
    memcpy( dest, &(*block_ptr)[ 0 ], to_copy );
    dest += 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 );

  if ( my_length ) {
    block_ptr = IMFS_memfile_get_block_pointer( &file->Memfile, block, 0 );
    if ( !block_ptr )
      return copied;
    memcpy( dest, &(*block_ptr)[ 0 ], my_length );
    copied += my_length;
  }

  IMFS_update_atime( &file->Node );

  return copied;
}
Esempio n. 9
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
MEMFILE_STATIC ssize_t IMFS_memfile_read(
   IMFS_jnode_t    *the_jnode,
   off_t            start,
   unsigned char   *destination,
   unsigned int     length
)
{
  block_p             *block_ptr;
  unsigned int         block;
  unsigned int         my_length;
  unsigned int         to_copy = 0;
  unsigned int         last_byte;
  unsigned int         copied;
  unsigned int         start_offset;
  unsigned char       *dest;

  dest = destination;

  /*
   *  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 ||
          the_jnode->type == IMFS_LINEAR_FILE );
  if ( the_jnode->type != IMFS_MEMORY_FILE &&
       the_jnode->type != IMFS_LINEAR_FILE )
    rtems_set_errno_and_return_minus_one( EIO );

  /*
   *  Error checks on arguments
   */

  assert( dest );
  if ( !dest )
    rtems_set_errno_and_return_minus_one( EINVAL );

  /*
   *  If there is nothing to read, then quick exit.
   */

  my_length = length;
  if ( !my_length )
    rtems_set_errno_and_return_minus_one( EINVAL );

  /*
   *  Linear files (as created from a tar file are easier to handle
   *  than block files).
   */
  if (the_jnode->type == IMFS_LINEAR_FILE) {
    unsigned char  *file_ptr;

    file_ptr = (unsigned char *)the_jnode->info.linearfile.direct;

    if (my_length > (the_jnode->info.linearfile.size - start))
      my_length = the_jnode->info.linearfile.size - start;

    memcpy(dest, &file_ptr[start], my_length);

    IMFS_update_atime( the_jnode );

    return my_length;
  }

  /*
   *  If the last byte we are supposed to read is past the end of this
   *  in memory file, then shorten the length to read.
   */

  last_byte = start + length;
  if ( last_byte > the_jnode->info.file.size )
    my_length = the_jnode->info.file.size - start;

  copied = 0;

  /*
   *  Three phases to the read:
   *    + 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;
    memcpy( dest, &(*block_ptr)[ start_offset ], to_copy );
    dest += 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;
    memcpy( dest, &(*block_ptr)[ 0 ], to_copy );
    dest += 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 );

  if ( my_length ) {
    block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
    assert( block_ptr );
    if ( !block_ptr )
      return copied;
    memcpy( dest, &(*block_ptr)[ 0 ], my_length );
    copied += my_length;
  }

  IMFS_update_atime( the_jnode );

  return copied;
}