Exemplo n.º 1
0
static bool
rtems_rfs_check_config (rtems_rfs_file_system*         fs,
                        const rtems_rfs_format_config* config)
{
  fs->block_size = config->block_size;
  if (!fs->block_size)
  {
    uint64_t total_size = rtems_rfs_fs_media_size (fs);

    if (total_size >= GIGS (1))
    {
      uint32_t gigs = (total_size + GIGS (1)) / GIGS (1);
      int      b;
      for (b = 31; b > 0; b--)
        if ((gigs & (1 << b)) != 0)
          break;
      fs->block_size = 1 << b;
    }

    if (fs->block_size < 512)
      fs->block_size = 512;
    
    if (fs->block_size > (4 * 1024))
      fs->block_size = (4 * 1024);
  }
  
  if ((fs->block_size % rtems_rfs_fs_media_block_size (fs)) != 0)
  {
    printf ("block size (%zd) is not a multiple of media block size (%" PRId32 ")\n",
            fs->block_size, rtems_rfs_fs_media_block_size (fs));
    return false;
  }

  fs->group_blocks = config->group_blocks;
  if (!fs->group_blocks)
  {
    /*
     * The number of blocks per group is defined by the number of bits in a
     * block.
     */
    fs->group_blocks = rtems_rfs_bitmap_numof_bits (fs->block_size);
  }

  if (fs->group_blocks > rtems_rfs_bitmap_numof_bits (fs->block_size))
  {
    printf ("group block count is higher than bits in block\n");
    return false;
  }
  
  fs->blocks = rtems_rfs_fs_media_size (fs) / fs->block_size;

  /*
   * The bits per block sets the upper limit for the number of blocks in a
   * group. The disk will be divided into groups which are the number of bits
   * per block.
   */  
  fs->group_count = rtems_rfs_rup_quotient (rtems_rfs_fs_blocks (fs),
                                            rtems_rfs_bits_per_block (fs));

  fs->group_inodes = config->group_inodes;
  if (!fs->group_inodes)
  {
    int inode_overhead = RTEMS_RFS_INODE_OVERHEAD_PERCENTAGE;
    
    /*
     * The number of inodes per group is set as a percentage.
     */
    if (config->inode_overhead)
      inode_overhead = config->inode_overhead;
      
    fs->group_inodes = rtems_rfs_inodes_from_percent (fs, inode_overhead);
  }

  /*
   * Round up to fill a block because the minimum allocation unit is a block.
   */
  fs->inodes_per_block = rtems_rfs_fs_block_size (fs) / RTEMS_RFS_INODE_SIZE;
  fs->group_inodes =
    rtems_rfs_rup_quotient (fs->group_inodes,
                            fs->inodes_per_block) * fs->inodes_per_block;
  
  if (fs->group_inodes > rtems_rfs_bitmap_numof_bits (fs->block_size))
    fs->group_inodes = rtems_rfs_bitmap_numof_bits (fs->block_size);

  fs->max_name_length = config->max_name_length;
  if (!fs->max_name_length)
  {
    fs->max_name_length = 512;
  }
  
  return true;
}
Exemplo n.º 2
0
static int
rtems_rfs_fs_read_superblock (rtems_rfs_file_system* fs)
{
  rtems_rfs_buffer_handle handle;
  uint8_t*                sb;
  int                     group;
  int                     rc;

  rc = rtems_rfs_buffer_handle_open (fs, &handle);
  if (rc > 0)
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: read-superblock: handle open failed: %d: %s\n",
              rc, strerror (rc));
    return rc;
  }

  rc = rtems_rfs_buffer_handle_request (fs, &handle, 0, true);
  if (rc > 0)
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: read-superblock: request failed%d: %s\n",
              rc, strerror (rc));
    return rc;
  }

  sb = rtems_rfs_buffer_data (&handle);

#define read_sb(_o) rtems_rfs_read_u32 (sb + (_o))

  if (read_sb (RTEMS_RFS_SB_OFFSET_MAGIC) != RTEMS_RFS_SB_MAGIC)
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: read-superblock: invalid superblock, bad magic\n");
    rtems_rfs_buffer_handle_close (fs, &handle);
    return EIO;
  }

  fs->blocks     = read_sb (RTEMS_RFS_SB_OFFSET_BLOCKS);
  fs->block_size = read_sb (RTEMS_RFS_SB_OFFSET_BLOCK_SIZE);

  if (rtems_rfs_fs_size(fs) > rtems_rfs_fs_media_size (fs))
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: read-superblock: invalid superblock block/size count\n");
    rtems_rfs_buffer_handle_close (fs, &handle);
    return EIO;
  }

  if ((read_sb (RTEMS_RFS_SB_OFFSET_VERSION) & RTEMS_RFS_VERSION_MASK) !=
      (RTEMS_RFS_VERSION * RTEMS_RFS_VERSION_MASK))
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: read-superblock: incompatible version: %08" PRIx32 " (%08" PRIx32 ")\n",
              read_sb (RTEMS_RFS_SB_OFFSET_VERSION), RTEMS_RFS_VERSION_MASK);
    rtems_rfs_buffer_handle_close (fs, &handle);
    return EIO;
  }

  if (read_sb (RTEMS_RFS_SB_OFFSET_INODE_SIZE) != RTEMS_RFS_INODE_SIZE)
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: read-superblock: inode size mismatch: fs:%" PRId32 " target:%" PRId32 "\n",
              read_sb (RTEMS_RFS_SB_OFFSET_VERSION), RTEMS_RFS_VERSION_MASK);
    rtems_rfs_buffer_handle_close (fs, &handle);
    return EIO;
  }

  fs->bad_blocks      = read_sb (RTEMS_RFS_SB_OFFSET_BAD_BLOCKS);
  fs->max_name_length = read_sb (RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH);
  fs->group_count     = read_sb (RTEMS_RFS_SB_OFFSET_GROUPS);
  fs->group_blocks    = read_sb (RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS);
  fs->group_inodes    = read_sb (RTEMS_RFS_SB_OFFSET_GROUP_INODES);

  fs->blocks_per_block =
    rtems_rfs_fs_block_size (fs) / sizeof (rtems_rfs_inode_block);

  fs->block_map_singly_blocks =
    fs->blocks_per_block * RTEMS_RFS_INODE_BLOCKS;
  fs->block_map_doubly_blocks =
    fs->blocks_per_block * fs->blocks_per_block * RTEMS_RFS_INODE_BLOCKS;

  fs->inodes = fs->group_count * fs->group_inodes;

  fs->inodes_per_block = fs->block_size / RTEMS_RFS_INODE_SIZE;

  if (fs->group_blocks >
      rtems_rfs_bitmap_numof_bits (rtems_rfs_fs_block_size (fs)))
  {
    rtems_rfs_buffer_handle_close (fs, &handle);
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: read-superblock: groups blocks larger than block bits\n");
    return EIO;
  }

  rtems_rfs_buffer_handle_close (fs, &handle);

  /*
   * Change the block size to the value in the superblock.
   */
  rc = rtems_rfs_buffer_setblksize (fs, rtems_rfs_fs_block_size (fs));
  if (rc > 0)
  {
    rtems_rfs_buffer_handle_close (fs, &handle);
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: read-superblock: invalid superblock block size%d: %s\n",
              rc, strerror (rc));
    return rc;
  }

  fs->groups = calloc (fs->group_count, sizeof (rtems_rfs_group));

  if (!fs->groups)
  {
    rtems_rfs_buffer_handle_close (fs, &handle);
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: read-superblock: no memory for group table\n");
    return ENOMEM;
  }

  /*
   * Perform each phase of group initialisation at the same time. This way we
   * know how far the initialisation has gone if an error occurs and we need to
   * close everything.
   */
  for (group = 0; group < fs->group_count; group++)
  {
    rc = rtems_rfs_group_open (fs,
                               rtems_rfs_fs_block (fs, group, 0),
                               fs->group_blocks,
                               fs->group_inodes,
                               &fs->groups[group]);
    if (rc > 0)
    {
      int g;
      for (g = 0; g < group; g++)
        rtems_rfs_group_close (fs, &fs->groups[g]);
      rtems_rfs_buffer_handle_close (fs, &handle);
      if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
        printf ("rtems-rfs: read-superblock: no memory for group table%d: %s\n",
                rc, strerror (rc));
      return rc;
    }
  }

  return 0;
}
Exemplo n.º 3
0
/**
 * Return the number of bits that fit in the block size.
 */
static int
rtems_rfs_bits_per_block (rtems_rfs_file_system* fs)
{
  return rtems_rfs_bitmap_numof_bits (rtems_rfs_fs_block_size (fs));
}