Exemple #1
0
int
rtems_rfs_inode_open (rtems_rfs_file_system*  fs,
                      rtems_rfs_ino           ino,
                      rtems_rfs_inode_handle* handle,
                      bool                    load)
{
  int group;
  int gino;
  int index;
  int rc;

  if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_OPEN))
    printf ("rtems-rfs: inode-open: ino: %" PRIu32 "\n", ino);

  if (ino == RTEMS_RFS_EMPTY_INO)
    return EINVAL;

  if ((ino - RTEMS_RFS_ROOT_INO) > rtems_rfs_fs_inodes (fs))
    return EINVAL;

  handle->ino = ino;
  handle->node = NULL;
  handle->loads = 0;

  gino  = ino - RTEMS_RFS_ROOT_INO;
  group = gino / fs->group_inodes;
  gino  = gino % fs->group_inodes;
  index = (gino / fs->inodes_per_block) + RTEMS_RFS_GROUP_INODE_BLOCK;

  handle->offset = gino % fs->inodes_per_block;
  handle->block  = rtems_rfs_group_block (&fs->groups[group], index);

  rc = rtems_rfs_buffer_handle_open (fs, &handle->buffer);
  if ((rc == 0) && load)
    rc = rtems_rfs_inode_load (fs, handle);
  return rc;
}
Exemple #2
0
int
rtems_rfs_group_bitmap_alloc (rtems_rfs_file_system* fs,
                              rtems_rfs_bitmap_bit   goal,
                              bool                   inode,
                              rtems_rfs_bitmap_bit*  result)
{
  int                  group_start;
  size_t               size;
  rtems_rfs_bitmap_bit bit;
  int                  offset;
  bool                 updown;
  int                  direction;

  if (inode)
  {
    size = fs->group_inodes;
    goal -= RTEMS_RFS_ROOT_INO;
  }
  else
    size = fs->group_blocks;
    
  group_start = goal / size;
  bit = (rtems_rfs_bitmap_bit) (goal % size);
  offset = 0;
  updown = true;
  direction = 1;
      
  /*
   * Try the goal group first and if that group fails try the groups either
   * side until the whole file system has be tried.
   */
  while (true)
  {
    rtems_rfs_bitmap_control* bitmap;
    int                       group;
    bool                      allocated = false;
    int                       rc;

    /*
     * We can start at any location and we move out from that point in each
     * direction. The offset grows until we find a free bit or we hit an end.
     */
    group = group_start + (direction * offset);
    if (offset)
      bit = direction > 0 ? 0 : size - 1;
    
    /*
     * If we are still looking up and down and if the group is out of range we
     * have reached one end. Stopping looking up and down and just move in the
     * one direction one group at a time.
     */
    if ((group < 0) || (group >= fs->group_count))
    {
      if (!updown)
        break;
      direction = direction > 0 ? -1 : 1;
      updown = false;
      continue;
    }

   if (inode)
      bitmap = &fs->groups[group].inode_bitmap;
    else
      bitmap = &fs->groups[group].block_bitmap;
    
    rc = rtems_rfs_bitmap_map_alloc (bitmap, bit, &allocated, &bit);
    if (rc > 0)
      return rc;
    
    if (rtems_rfs_fs_release_bitmaps (fs))
      rtems_rfs_bitmap_release_buffer (fs, bitmap);
      
    if (allocated)
    {
      if (inode)
        *result = rtems_rfs_group_inode (fs, group, bit);
      else
        *result = rtems_rfs_group_block (&fs->groups[group], bit);
      if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS))
        printf ("rtems-rfs: group-bitmap-alloc: %s allocated: %" PRId32 "\n",
                inode ? "inode" : "block", *result);
      return 0;
    }

    if (updown)
      direction = direction > 0 ? -1 : 1;

    offset++;
  }
  
  if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS))
    printf ("rtems-rfs: group-bitmap-alloc: no blocks available\n");

  return ENOSPC;
}