⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memfile.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
          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;}/* *  IMFS_memfile_write * *  This routine writes the specified data buffer into the in memory *  file pointed to by the_jnode.  The file is extended as needed. */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 0printf( "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 0printf( "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 0printf( "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_atime_mtime_update( the_jnode );  return copied;}/* *  IMFS_memfile_get_block_pointer * *  This routine looks up the block pointer associated with the given block *  number.  If that block has not been allocated and "malloc_it" is *  TRUE, then the block is allocated.  Otherwise, it is an error. */#if 0block_p *IMFS_memfile_get_block_pointer_DEBUG(   IMFS_jnode_t   *the_jnode,   unsigned int    block,   int             malloc_it);block_p *IMFS_memfile_get_block_pointer(   IMFS_jnode_t   *the_jnode,   unsigned int    block,   int             malloc_it){  block_p *p;  p = IMFS_memfile_get_block_pointer_DEBUG( the_jnode, block, malloc_it );  printf( "(%d -> %p) ", block, p );  return p;}block_p *IMFS_memfile_get_block_pointer_DEBUG(#elseblock_p *IMFS_memfile_get_block_pointer(#endif   IMFS_jnode_t   *the_jnode,   unsigned int    block,   int             malloc_it){  unsigned int    my_block;  IMFS_memfile_t *info;  unsigned int    singly;  unsigned int    doubly;  unsigned int    triply;  block_p        *p;  block_p        *p1;  block_p        *p2;  /*   *  Perform internal consistency checks   */  assert( the_jnode );  if ( !the_jnode )    return NULL;  assert( the_jnode->type == IMFS_MEMORY_FILE );  if ( the_jnode->type != IMFS_MEMORY_FILE )    return NULL;  info = &the_jnode->info.file;  my_block = block;  /*   *  Is the block number in the simple indirect portion?   */  if ( my_block <= LAST_INDIRECT ) {#if 0printf( "(s %d) ", block );fflush(stdout);#endif    p = info->indirect;    if ( malloc_it ) {      if ( !p ) {        p = memfile_alloc_block();        if ( !p )           return 0;        info->indirect = p;      }      return &info->indirect[ my_block ];    }    if ( !p )      return 0;    return &info->indirect[ my_block ];  }  /*   *  Is the block number in the doubly indirect portion?   */  if ( my_block <= LAST_DOUBLY_INDIRECT ) {#if 0printf( "(d %d) ", block );fflush(stdout);#endif    my_block -= FIRST_DOUBLY_INDIRECT;    singly = my_block % IMFS_MEMFILE_BLOCK_SLOTS;    doubly = my_block / IMFS_MEMFILE_BLOCK_SLOTS;    p = info->doubly_indirect;    if ( malloc_it ) {      if ( !p ) {        p = memfile_alloc_block();        if ( !p )           return 0;        info->doubly_indirect = p;      }      p1 = (block_p *)p[ doubly ];      if ( !p1 ) {        p1 = memfile_alloc_block();        if ( !p1 )           return 0;        p[ doubly ] = (block_p) p1;      }      return (block_p *)&p1[ singly ];    }    if ( !p )      return 0;    p = (block_p *)p[ doubly ];    if ( !p )       return 0;#if 0printf( "(d %d %d %d %d %p %p) ", block, my_block, doubly,                                       singly, p, &p[singly] );fflush(stdout);#endif    return (block_p *)&p[ singly ];  }#if 0printf( "(t %d) ", block );fflush(stdout);#endif  /*   *  Is the block number in the triply indirect portion?   */  if ( my_block <= LAST_TRIPLY_INDIRECT ) {    my_block -= FIRST_TRIPLY_INDIRECT;    singly = my_block % IMFS_MEMFILE_BLOCK_SLOTS;    doubly = my_block / IMFS_MEMFILE_BLOCK_SLOTS;    triply = doubly / IMFS_MEMFILE_BLOCK_SLOTS;    doubly %= IMFS_MEMFILE_BLOCK_SLOTS;    p = info->triply_indirect;    if ( malloc_it ) {      if ( !p ) {        p = memfile_alloc_block();        if ( !p )           return 0;        info->triply_indirect = p;      }      p1 = (block_p *) p[ triply ];      if ( !p1 ) {        p1 = memfile_alloc_block();        if ( !p1 )           return 0;        p[ triply ] = (block_p) p1;      }      p2 = (block_p *)p1[ doubly ];      if ( !p2 ) {        p2 = memfile_alloc_block();        if ( !p2 )           return 0;        p1[ doubly ] = (block_p) p2;      }      return (block_p *)&p2[ singly ];    }    if ( !p )      return 0;#if 0printf( "(t %d %d %d %d %d) ", block, my_block, triply, doubly, singly );fflush(stdout);#endif    p1 = (block_p *) p[ triply ];    if ( !p1 )      return 0;    p2 = (block_p *)p1[ doubly ];    if ( !p )      return 0;    return (block_p *)&p2[ singly ];  }  /*   *  This means the requested block number is out of range.   */  return 0;}/* *  memfile_alloc_block * *  Allocate a block for an in-memory file. */int memfile_blocks_allocated = 0;void *memfile_alloc_block(void){  void *memory;  memory = (void *)calloc(1, IMFS_MEMFILE_BYTES_PER_BLOCK);  if ( memory )    memfile_blocks_allocated++;  return memory;}/* *  memfile_free_block * *  Free a block from an in-memory file. */void memfile_free_block(  void *memory){#if 0printf( "(d %p) ", memory );fflush(stdout);#endif  free(memory);  memfile_blocks_allocated--;}/* *  memfile_rmnod * *  This routine is available from the optable to remove a node  *  from the IMFS file system. */int memfile_rmnod(  rtems_filesystem_location_info_t      *pathloc       /* IN */){  IMFS_jnode_t *the_jnode;    the_jnode = (IMFS_jnode_t *) pathloc->node_access;  /*    * Take the node out of the parent's chain that contains this node    */  if ( the_jnode->Parent != NULL ) {    Chain_Extract( (Chain_Node *) the_jnode );    the_jnode->Parent = NULL;  }  /*   * Decrement the link counter and see if we can free the space.   */  the_jnode->st_nlink--;  IMFS_update_ctime( the_jnode );  return memfile_check_rmnod( the_jnode );}int  memfile_check_rmnod( IMFS_jnode_t *the_jnode ){  /*   * The file cannot be open and the link must be less than 1 to free.   */  if ( !rtems_libio_is_file_open( the_jnode ) && (the_jnode->st_nlink < 1) ) {    /*      * Is the rtems_filesystem_current is this node?     */    if ( rtems_filesystem_current.node_access == the_jnode )       rtems_filesystem_current.node_access = NULL;    /*     * Free memory associated with a memory file.     */    if (the_jnode->type != IMFS_LINEAR_FILE)      IMFS_memfile_remove( the_jnode );    free( the_jnode );  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -