예제 #1
0
int
rtems_rfs_block_map_open (rtems_rfs_file_system*  fs,
                          rtems_rfs_inode_handle* inode,
                          rtems_rfs_block_map*    map)
{
  int b;
  int rc;

  /*
   * Set the count to 0 so at least find fails, then open the handle and make
   * sure the inode has been loaded into memory. If we did not load the inode
   * do not unload it. The caller may assume it is still loaded when we return.
   */

  map->dirty = false;
  map->inode = NULL;
  rtems_rfs_block_set_size_zero (&map->size);
  rtems_rfs_block_set_bpos_zero (&map->bpos);

  rc = rtems_rfs_buffer_handle_open (fs, &map->singly_buffer);
  if (rc > 0)
    return rc;
  rc = rtems_rfs_buffer_handle_open (fs, &map->doubly_buffer);
  if (rc > 0)
    return rc;

  rc = rtems_rfs_inode_load (fs, inode);
  if (rc > 0)
  {
    rtems_rfs_buffer_handle_close (fs, &map->singly_buffer);
    rtems_rfs_buffer_handle_close (fs, &map->doubly_buffer);
    return rc;
  }

  /*
   * Extract the block and block count data from the inode into the targets
   * byte order.
   */
  map->inode = inode;
  for (b = 0; b < RTEMS_RFS_INODE_BLOCKS; b++)
    map->blocks[b] = rtems_rfs_inode_get_block (inode, b);
  map->size.count = rtems_rfs_inode_get_block_count (inode);
  map->size.offset = rtems_rfs_inode_get_block_offset (inode);
  map->last_map_block = rtems_rfs_inode_get_last_map_block (inode);
  map->last_data_block = rtems_rfs_inode_get_last_data_block (inode);

  rc = rtems_rfs_inode_unload (fs, inode, false);

  return rc;
}
예제 #2
0
int
rtems_rfs_block_map_close (rtems_rfs_file_system* fs,
                           rtems_rfs_block_map*   map)
{
  int rc = 0;
  int brc;

  if (map->dirty && map->inode)
  {
    brc = rtems_rfs_inode_load (fs, map->inode);
    if (brc > 0)
      rc = brc;

    if (rc == 0)
    {
      int b;

      for (b = 0; b < RTEMS_RFS_INODE_BLOCKS; b++)
        rtems_rfs_inode_set_block (map->inode, b, map->blocks[b]);
      rtems_rfs_inode_set_block_count (map->inode, map->size.count);
      rtems_rfs_inode_set_block_offset (map->inode, map->size.offset);
      rtems_rfs_inode_set_last_map_block (map->inode, map->last_map_block);
      rtems_rfs_inode_set_last_data_block (map->inode, map->last_data_block);

      brc = rtems_rfs_inode_unload (fs, map->inode, true);
      if (brc > 0)
        rc = brc;

      map->dirty = false;
    }
  }

  map->inode = NULL;

  brc = rtems_rfs_buffer_handle_close (fs, &map->singly_buffer);
  if ((brc > 0) && (rc == 0))
    rc = brc;
  brc = rtems_rfs_buffer_handle_close (fs, &map->doubly_buffer);
  if ((brc > 0) && (rc == 0))
    rc = brc;
  return rc;
}
예제 #3
0
int
rtems_rfs_inode_close (rtems_rfs_file_system*  fs,
                       rtems_rfs_inode_handle* handle)
{
  int rc;

  if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_CLOSE))
    printf ("rtems-rfs: inode-close: ino: %" PRIu32 "\n", handle->ino);

  rc = rtems_rfs_inode_unload (fs, handle, true);

  if ((rc == 0) && (handle->loads > 0))
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_CLOSE))
      printf ("rtems-rfs: inode-close: bad loads number: %d\n",
              handle->loads);
    rc = EIO;
  }

  handle->ino = 0;
  return rc;
}
int
rtems_rfs_file_open (rtems_rfs_file_system*  fs,
                     rtems_rfs_ino           ino,
                     uint32_t                flags,
                     rtems_rfs_file_handle** file)
{
  rtems_rfs_file_handle* handle;
  rtems_rfs_file_shared* shared;
  int                    rc;

  if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN))
    printf ("rtems-rfs: file-open: ino=%" PRId32 "\n", ino);
            
  *file = NULL;

  /*
   * Allocate a new handle and initialise it. Do this before we deal with the
   * shared node data so we do not have to be concerned with reference
   * counting.
   */
  handle = malloc (sizeof (rtems_rfs_file_handle));
  if (!handle)
    return ENOMEM;

  memset (handle, 0, sizeof (rtems_rfs_file_handle));

  rc = rtems_rfs_buffer_handle_open (fs, &handle->buffer);
  if (rc > 0)
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN))
      printf ("rtems-rfs: file-open: buffer handle open failed: %d: %s\n",
              rc, strerror (rc));
    free (handle);
    return rc;
  }
  
  /*
   * Scan the file system data list of open files for this ino. If found up
   * the reference count and return the pointer to the data.
   */
  shared = rtems_rfs_file_get_shared (fs, ino);
  if (shared)
  {
    shared->references++;
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN))
      printf ("rtems-rfs: file-open: ino=%" PRId32 " shared\n", ino);
  }
  else
  {
    /*
     * None exists so create. Copy in the shared parts of the inode we hold in
     * memory.
     */
    shared = malloc (sizeof (rtems_rfs_file_shared));
    if (!shared)
    {
      rtems_rfs_buffer_handle_close (fs, &handle->buffer);
      free (handle);
      return ENOMEM;
    }

    memset (shared, 0, sizeof (rtems_rfs_file_shared));
    
    rc = rtems_rfs_inode_open (fs, ino, &shared->inode, true);
    if (rc > 0)
    {
      if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN))
        printf ("rtems-rfs: file-open: inode open failed: %d: %s\n",
                rc, strerror (rc));
      free (shared);
      rtems_rfs_buffer_handle_close (fs, &handle->buffer);
      free (handle);
      return rc;
    }

    rc = rtems_rfs_block_map_open (fs, &shared->inode, &shared->map);
    if (rc > 0)
    {
      if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN))
        printf ("rtems-rfs: file-open: block map open failed: %d: %s\n",
                rc, strerror (rc));
      rtems_rfs_inode_close (fs, &shared->inode);
      free (shared);
      rtems_rfs_buffer_handle_close (fs, &handle->buffer);
      free (handle);
      return rc;
    }

    shared->references = 1;
    shared->size.count = rtems_rfs_inode_get_block_count (&shared->inode);
    shared->size.offset = rtems_rfs_inode_get_block_offset (&shared->inode);
    shared->atime = rtems_rfs_inode_get_atime (&shared->inode);
    shared->mtime = rtems_rfs_inode_get_mtime (&shared->inode);
    shared->ctime = rtems_rfs_inode_get_ctime (&shared->inode);
    shared->fs = fs;

    rtems_chain_append (&fs->file_shares, &shared->link);

    rtems_rfs_inode_unload (fs, &shared->inode, false);

    if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_OPEN))
      printf ("rtems-rfs: file-open: ino=%" PRId32 " share created\n", ino);
  }

  handle->flags  = flags;
  handle->shared = shared;
  
  *file = handle;
  
  return 0;
}