Example #1
0
/**
 * Get the blocks 0 -> 4 and hold them. Wake the master to tell it was have the
 * buffers then wait for the master to tell us to release a single buffer.
 * Task 1 will be block waiting for each buffer. It is a higher priority.
 */
static void
bdbuf_tests_task_0_test_2 (bdbuf_task_control* tc)
{
  rtems_status_code   sc;
  bool                passed;
  int                 i;
  rtems_bdbuf_buffer* bd;
  rtems_chain_control buffers;

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  /*
   * Get the blocks 0 -> 4 and hold them.
   */
  rtems_chain_initialize_empty (&buffers);

  for (i = 0; (i < 5) && passed; i++)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_get[%d]: ", tc->name, i);
    sc = rtems_bdbuf_get (tc->dd, i, &bd);
    if (!bdbuf_test_print_sc (sc, true))
      passed = false;

    rtems_chain_append (&buffers, &bd->link);
  }

  /*
   * Wake the master to tell it we have the buffers.
   */
  bdbuf_send_wait_event (tc->name, "wake master", tc->master);

  if (passed)
  {
    /*
     * For each buffer we hold wait until the master wakes us
     * and then return it. Task 2 will block waiting for this
     * buffer. It is a higher priority task.
     */
    for (i = 0; (i < 5) && passed; i++)
    {
      sc = bdbuf_wait (tc->name, BDBUF_SECONDS (5));
      if (sc != RTEMS_SUCCESSFUL)
      {
        bdbuf_test_printf ("%s: wait failed: ", tc->name);
        bdbuf_test_print_sc (sc, true);
        passed = false;
        break;
      }
      else
      {
        bdbuf_test_printf ("%s: rtems_bdbuf_release[%d]: unblocks task 1\n",
                           tc->name, i);
        bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
        sc = rtems_bdbuf_release (bd);
        bdbuf_test_printf ("%s: rtems_bdbuf_release[%d]: ", tc->name, i);
        if (!bdbuf_test_print_sc (sc, true))
        {
          passed = false;
          break;
        }
      }
    }
  }

  tc->passed = passed;
  tc->test = 0;
}
Example #2
0
static void test_chain_with_notification(void)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;
  rtems_chain_control chain;
  rtems_chain_node a;
  rtems_chain_node b;
  rtems_chain_node *p = (rtems_chain_node *) 1;
  rtems_event_set out = 0;

  puts( "INIT - Verify rtems_chain_append_with_notification" );
  rtems_chain_initialize_empty( &chain );
  sc = rtems_chain_append_with_notification(
    &chain,
    &a,
    rtems_task_self(),
    EVENT
  );
  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
  sc = rtems_chain_get_with_wait( &chain, EVENT, TIMEOUT, &p );
  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
  rtems_test_assert( p == &a );

  rtems_chain_initialize_empty( &chain );

  rtems_chain_append( &chain, &b );
  sc = rtems_chain_append_with_notification(
    &chain,
    &a,
    rtems_task_self(),
    EVENT
  );
  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
  rtems_test_assert( p == &a );

  puts( "INIT - Verify rtems_chain_prepend_with_notification" );
  rtems_chain_initialize_empty( &chain );
  sc = rtems_chain_prepend_with_notification(
    &chain,
    &a,
    rtems_task_self(),
    EVENT
  );
  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
  sc = rtems_chain_get_with_wait( &chain, EVENT, TIMEOUT, &p );
  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
  rtems_test_assert( p == &a );

  rtems_chain_prepend( &chain, &b );
  sc = rtems_chain_prepend_with_notification(
    &chain,
    &a,
    rtems_task_self(),
    EVENT
  );
  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
  rtems_test_assert( p == &a );

  puts( "INIT - Verify rtems_chain_prepend_with_notification" );
  puts( "INIT - Verify rtems_chain_get_with_notification" );
  rtems_chain_initialize_empty( &chain );

  rtems_chain_append( &chain, &b );
  rtems_chain_append( &chain, &a );

  sc = rtems_chain_get_with_notification(&chain, rtems_task_self(), EVENT, &p);
  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
  rtems_test_assert( p == &b );

  sc = rtems_chain_get_with_notification(&chain, rtems_task_self(), EVENT, &p);
  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
  rtems_test_assert( p == &a );
  sc = rtems_event_receive(
    EVENT,
    RTEMS_EVENT_ALL | RTEMS_WAIT,
    TIMEOUT,
    &out
  );
  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
  rtems_test_assert( out == EVENT );
}
Example #3
0
static void
bdbuf_tests_task_0_test_8 (bdbuf_task_control* tc)
{
  rtems_status_code   sc;
  bool                passed;
  int                 i;
  rtems_bdbuf_buffer* bd;
  rtems_chain_control buffers;
  rtems_chain_node*   node;
  rtems_chain_node*   pnode;

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  /*
   * Clear any disk settings.
   */
  bdbuf_clear_disk_driver_watch (tc);
  bdbuf_set_disk_driver_action (tc, BDBUF_DISK_NOOP);

  /*
   * Get the blocks 0 -> 4 and hold them.
   */
  rtems_chain_initialize_empty (&buffers);

  for (i = 0; (i < 5) && passed; i++)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_read[%d]: ", tc->name, i);
    sc = rtems_bdbuf_get (tc->dd, i, &bd);
    if (!bdbuf_test_print_sc (sc, true))
      passed = false;

    rtems_chain_append (&buffers, &bd->link);
  }

  node = rtems_chain_tail (&buffers);
  node = node->previous;

  bd = (rtems_bdbuf_buffer*) node;
  pnode = node->previous;
  rtems_chain_extract (node);
  node = pnode;
  bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[4]: ", tc->name);
  passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true);

  bd = (rtems_bdbuf_buffer*) node;
  pnode = node->previous;
  rtems_chain_extract (node);
  node = pnode;
  bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[3]: ", tc->name);
  passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true);

  for (i = 0; (i < 3) && passed; i++)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: ",
                       tc->name, i);
    bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
    passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd),
                                  true);
  }

  if (passed)
  {
    /*
     * Check the block order.
     */
    bdbuf_set_disk_driver_action (tc, BDBUF_DISK_BLOCKS_INORDER);

    bdbuf_test_printf ("%s: rtems_bdbuf_syncdev[%d:%d]: checking order\n",
                       tc->name, i,
                       tc->major,
                       tc->minor);
    sc = rtems_bdbuf_syncdev (tc->dd);
    bdbuf_test_printf ("%s: rtems_bdbuf_syncdev[%d:%d]: ",
                       tc->name, i,
                       tc->major,
                       tc->minor);
    passed = bdbuf_test_print_sc (sc, true);
  }

  tc->passed = passed;
  tc->test = 0;
}
/*
 *  Create an IMFS filesystem node of an arbitrary type that is NOT
 *  the root directory node.
 */
IMFS_jnode_t *IMFS_create_node(
  rtems_filesystem_location_info_t *parent_loc,
  IMFS_jnode_types_t                type,
  const char                       *name,
  mode_t                            mode,
  const IMFS_types_union           *info
)
{
  IMFS_jnode_t        *node;
  IMFS_jnode_t        *parent;
  IMFS_fs_info_t      *fs_info;

  /*
   *  MUST have a parent node to call this routine.
   */
  if ( parent_loc == NULL )
    return NULL;

  /*
   *  Allocate filesystem node and fill in basic information
   */
  node  = IMFS_allocate_node( type, name, mode & ~rtems_filesystem_umask );
  if ( !node )
    return NULL;

  /*
   *  Set the type specific information
   */
  switch (type) {
    case IMFS_DIRECTORY:
      rtems_chain_initialize_empty(&node->info.directory.Entries);
      break;

    case IMFS_HARD_LINK:
      node->info.hard_link.link_node = info->hard_link.link_node;
      break;

    case IMFS_SYM_LINK:
      node->info.sym_link.name = info->sym_link.name;
      break;

    case IMFS_DEVICE:
      node->info.device.major = info->device.major;
      node->info.device.minor = info->device.minor;
      break;

    case IMFS_LINEAR_FILE:
      node->info.linearfile.size      = 0;
      node->info.linearfile.direct    = 0;

    case IMFS_MEMORY_FILE:
      node->info.file.size            = 0;
      node->info.file.indirect        = 0;
      node->info.file.doubly_indirect = 0;
      node->info.file.triply_indirect = 0;
      break;

    case IMFS_FIFO:
      node->info.fifo.pipe = NULL;
      break;

    default:
      assert(0);
      break;
  }

  /*
   *  This node MUST have a parent, so put it in that directory list.
   */
  parent       = parent_loc->node_access;
  fs_info      = parent_loc->mt_entry->fs_info;

  node->Parent = parent;
  node->st_ino = ++fs_info->ino_count;

  rtems_chain_append( &parent->info.directory.Entries, &node->Node );

  return node;
}
Example #5
0
int
rtems_rfs_fs_open (const char*             name,
                   void*                   user,
                   uint32_t                flags,
                   rtems_rfs_file_system** fs)
{
  rtems_rfs_group*       group;
  size_t                 group_base;
  rtems_rfs_inode_handle inode;
  uint16_t               mode;
  int                    rc;
  
  if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
    printf ("rtems-rfs: open: %s\n", name);
  
  *fs = malloc (sizeof (rtems_rfs_file_system));
  if (!*fs)
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: open: no memory for file system data\n");
    errno = ENOMEM;
    return -1;
  }

  memset (*fs, 0, sizeof (rtems_rfs_file_system));

  (*fs)->user = user;
  rtems_chain_initialize_empty (&(*fs)->buffers);
  rtems_chain_initialize_empty (&(*fs)->release);
  rtems_chain_initialize_empty (&(*fs)->release_modified);
  rtems_chain_initialize_empty (&(*fs)->file_shares);

  (*fs)->max_held_buffers = RTEMS_RFS_FS_MAX_HELD_BUFFERS;
  (*fs)->buffers_count = 0;
  (*fs)->release_count = 0;
  (*fs)->release_modified_count = 0;
  (*fs)->flags = flags;

  group = &(*fs)->groups[0];
  group_base = 0;

  /*
   * Open the buffer interface.
   */
  rc = rtems_rfs_buffer_open (name, *fs);
  if (rc > 0)
  {
    free (*fs);
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: open: buffer open failed: %d: %s\n",
              rc, strerror (rc));
    errno = rc;
    return -1;
  }

  rc = rtems_rfs_fs_read_superblock (*fs);
  if (rc > 0)
  {
    rtems_rfs_buffer_close (*fs);
    free (*fs);
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: open: reading superblock: %d: %s\n",
              rc, strerror (rc));
    errno = rc;
    return -1;
  }

  rc = rtems_rfs_inode_open (*fs, RTEMS_RFS_ROOT_INO, &inode, true);
  if (rc > 0)
  {
    rtems_rfs_buffer_close (*fs);
    free (*fs);
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: open: reading root inode: %d: %s\n",
              rc, strerror (rc));
    errno = rc;
    return -1;
  }

  if (((*fs)->flags & RTEMS_RFS_FS_FORCE_OPEN) == 0)
  {
    mode = rtems_rfs_inode_get_mode (&inode);

    if ((mode == 0xffff) || !RTEMS_RFS_S_ISDIR (mode))
    {
      rtems_rfs_inode_close (*fs, &inode);
      rtems_rfs_buffer_close (*fs);
      free (*fs);
      if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
        printf ("rtems-rfs: open: invalid root inode mode\n");
      errno = EIO;
      return -1;
    }
  }
  
  rc = rtems_rfs_inode_close (*fs, &inode);
  if (rc > 0)
  {
    rtems_rfs_buffer_close (*fs);
    free (*fs);
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
      printf ("rtems-rfs: open: closing root inode: %d: %s\n", rc, strerror (rc));
    errno = rc;
    return -1;
  }
    
  errno = 0;
  return 0;
}
Example #6
0
/**
 * Get all the blocks in the pool and hold them. Wake the master to tell it was
 * have the buffers then wait for the master to tell us to release them.
 */
static void
bdbuf_tests_task_0_test_4 (bdbuf_task_control* tc)
{
  rtems_status_code   sc;
  bool                passed;
  size_t              i;
  rtems_bdbuf_buffer* bd;
  rtems_chain_control buffers;
  size_t              num = bdbuf_test_buffer_count ();

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  /*
   * Clear any disk settings.
   */
  bdbuf_clear_disk_driver_watch (tc);
  bdbuf_set_disk_driver_action (tc, BDBUF_DISK_NOOP);

  /*
   * Get the blocks 0 -> 4 and hold them.
   */
  rtems_chain_initialize_empty (&buffers);

  for (i = 0; (i < num) && passed; i++)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_read[%d]: ", tc->name, i);
    sc = rtems_bdbuf_read (tc->dd, i, &bd);
    if (!bdbuf_test_print_sc (sc, true))
      passed = false;

    rtems_chain_append (&buffers, &bd->link);
  }

  /*
   * Wake the master to tell it we have the buffers.
   */
  bdbuf_send_wait_event (tc->name, "wake master", tc->master);

  if (passed)
  {
    bdbuf_sleep (250);

    bdbuf_set_disk_driver_watch (tc, num / 2);

    /*
     * Release half the buffers, wait 500msecs then release the
     * remainder. This tests the swap out timer on each buffer.
     */
    bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[0]: unblocks task 1\n",
                       tc->name);
    bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
    sc = rtems_bdbuf_release_modified (bd);
    bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[0]: ", tc->name);
    passed = bdbuf_test_print_sc (sc, true);
    if (passed)
    {
      for (i = 1; (i < (num / 2)) && passed; i++)
      {
        bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: " \
                           "unblocks task 1\n", tc->name, i);
        bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
        sc = rtems_bdbuf_release_modified (bd);
        bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: ",
                           tc->name, i);
        passed = bdbuf_test_print_sc (sc, true);
        if (!passed)
          break;
      }

      if (passed)
      {
        passed = bdbuf_disk_driver_watch_wait (tc, BDBUF_SECONDS (5));

        if (passed)
        {
          bdbuf_sleep (500);

          bdbuf_set_disk_driver_watch (tc, num / 2);

          for (i = 0; (i < (num / 2)) && passed; i++)
          {
            bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: ",
                               tc->name, i + (num / 2));
            bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
            passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd),
                                          true);
            if (!passed)
              break;
          }

          passed = bdbuf_disk_driver_watch_wait (tc, BDBUF_SECONDS (5));

          if (passed)
          {
            if (!rtems_chain_is_empty (&buffers))
            {
              passed = false;
              bdbuf_test_printf ("%s: buffer chain not empty\n", tc->name);
            }
          }
        }
      }
    }
  }

  tc->passed = passed;
  tc->test = 0;
}
Example #7
0
File: fat.c Project: kptran/rtems
/* fat_init_volume_info --
 *     Get inforamtion about volume on which filesystem is mounted on
 *
 * PARAMETERS:
 *     mt_entry - mount table entry
 *
 * RETURNS:
 *     RC_OK on success, or -1 if error occured
 *     and errno set appropriately
 */
int
fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
{
    rtems_status_code   sc = RTEMS_SUCCESSFUL;
    int                 rc = RC_OK;
    fat_fs_info_t      *fs_info = mt_entry->fs_info;
    register fat_vol_t *vol = &fs_info->vol;
    uint32_t            data_secs = 0;
    char                boot_rec[FAT_MAX_BPB_SIZE];
    char                fs_info_sector[FAT_USEFUL_INFO_SIZE];
    ssize_t             ret = 0;
    struct stat         stat_buf;
    int                 i = 0;
    rtems_bdbuf_buffer *block = NULL;

    vol->fd = open(mt_entry->dev, O_RDWR);
    if (vol->fd < 0)
    {
        rtems_set_errno_and_return_minus_one(ENXIO);
    }

    rc = fstat(vol->fd, &stat_buf);
    if (rc != 0)
    {
        close(vol->fd);
        rtems_set_errno_and_return_minus_one(ENXIO);
    }

    /* Must be a block device. */
    if (!S_ISBLK(stat_buf.st_mode))
    {
        close(vol->fd);
        rtems_set_errno_and_return_minus_one(ENXIO);
    }

    /* check that device is registred as block device and lock it */
    rc = rtems_disk_fd_get_disk_device(vol->fd, &vol->dd);
    if (rc != 0) {
        close(vol->fd);
        rtems_set_errno_and_return_minus_one(ENXIO);
    }

    /* Read boot record */
    /* FIXME: Asserts FAT_MAX_BPB_SIZE < bdbuf block size */
    sc = rtems_bdbuf_read( vol->dd, 0, &block);
    if (sc != RTEMS_SUCCESSFUL)
    {
        close(vol->fd);
        rtems_set_errno_and_return_minus_one( EIO);
    }

    memcpy( boot_rec, block->buffer, FAT_MAX_BPB_SIZE);

    sc = rtems_bdbuf_release( block);
    if (sc != RTEMS_SUCCESSFUL)
    {
        close(vol->fd);
        rtems_set_errno_and_return_minus_one( EIO );
    }

    /* Evaluate boot record */
    vol->bps = FAT_GET_BR_BYTES_PER_SECTOR(boot_rec);

    if ( (vol->bps != 512)  &&
         (vol->bps != 1024) &&
         (vol->bps != 2048) &&
         (vol->bps != 4096))
    {
        close(vol->fd);
        rtems_set_errno_and_return_minus_one( EINVAL );
    }

    for (vol->sec_mul = 0, i = (vol->bps >> FAT_SECTOR512_BITS); (i & 1) == 0;
         i >>= 1, vol->sec_mul++);
    for (vol->sec_log2 = 0, i = vol->bps; (i & 1) == 0;
         i >>= 1, vol->sec_log2++);

    vol->spc = FAT_GET_BR_SECTORS_PER_CLUSTER(boot_rec);
    /*
     * "sectors per cluster" of zero is invalid
     * (and would hang the following loop)
     */
    if (vol->spc == 0)
    {
        close(vol->fd);
        rtems_set_errno_and_return_minus_one(EINVAL);
    }

    for (vol->spc_log2 = 0, i = vol->spc; (i & 1) == 0;
         i >>= 1, vol->spc_log2++);

    /*
     * "bytes per cluster" value greater than 32K is invalid
     */
    if ((vol->bpc = vol->bps << vol->spc_log2) > MS_BYTES_PER_CLUSTER_LIMIT)
    {
        close(vol->fd);
        rtems_set_errno_and_return_minus_one(EINVAL);
    }

    for (vol->bpc_log2 = 0, i = vol->bpc; (i & 1) == 0;
         i >>= 1, vol->bpc_log2++);

    vol->fats = FAT_GET_BR_FAT_NUM(boot_rec);
    vol->fat_loc = FAT_GET_BR_RESERVED_SECTORS_NUM(boot_rec);

    vol->rdir_entrs = FAT_GET_BR_FILES_PER_ROOT_DIR(boot_rec);

    /* calculate the count of sectors occupied by the root directory */
    vol->rdir_secs = ((vol->rdir_entrs * FAT_DIRENTRY_SIZE) + (vol->bps - 1)) /
                     vol->bps;

    vol->rdir_size = vol->rdir_secs << vol->sec_log2;

    if ( (FAT_GET_BR_SECTORS_PER_FAT(boot_rec)) != 0)
        vol->fat_length = FAT_GET_BR_SECTORS_PER_FAT(boot_rec);
    else
        vol->fat_length = FAT_GET_BR_SECTORS_PER_FAT32(boot_rec);

    vol->data_fsec = vol->fat_loc + vol->fats * vol->fat_length +
                     vol->rdir_secs;

    /* for  FAT12/16 root dir starts at(sector) */
    vol->rdir_loc = vol->fat_loc + vol->fats * vol->fat_length;

    if ( (FAT_GET_BR_TOTAL_SECTORS_NUM16(boot_rec)) != 0)
        vol->tot_secs = FAT_GET_BR_TOTAL_SECTORS_NUM16(boot_rec);
    else
        vol->tot_secs = FAT_GET_BR_TOTAL_SECTORS_NUM32(boot_rec);

    data_secs = vol->tot_secs - vol->data_fsec;

    vol->data_cls = data_secs / vol->spc;

    /* determine FAT type at least */
    if ( vol->data_cls < FAT_FAT12_MAX_CLN)
    {
        vol->type = FAT_FAT12;
        vol->mask = FAT_FAT12_MASK;
        vol->eoc_val = FAT_FAT12_EOC;
    }
    else
    {
        if ( vol->data_cls < FAT_FAT16_MAX_CLN)
        {
            vol->type = FAT_FAT16;
            vol->mask = FAT_FAT16_MASK;
            vol->eoc_val = FAT_FAT16_EOC;
        }
        else
        {
            vol->type = FAT_FAT32;
            vol->mask = FAT_FAT32_MASK;
            vol->eoc_val = FAT_FAT32_EOC;
        }
    }

    if (vol->type == FAT_FAT32)
    {
        vol->rdir_cl = FAT_GET_BR_FAT32_ROOT_CLUSTER(boot_rec);

        vol->mirror = FAT_GET_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_MIRROR;
        if (vol->mirror)
            vol->afat = FAT_GET_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_FAT_NUM;
        else
            vol->afat = 0;

        vol->info_sec = FAT_GET_BR_FAT32_FS_INFO_SECTOR(boot_rec);
        if( vol->info_sec == 0 )
        {
            close(vol->fd);
            rtems_set_errno_and_return_minus_one( EINVAL );
        }
        else
        {
            ret = _fat_block_read(mt_entry, vol->info_sec , 0,
                                  FAT_FSI_LEADSIG_SIZE, fs_info_sector);
            if ( ret < 0 )
            {
                close(vol->fd);
                return -1;
            }

            if (FAT_GET_FSINFO_LEAD_SIGNATURE(fs_info_sector) !=
                FAT_FSINFO_LEAD_SIGNATURE_VALUE)
            {
                _fat_block_release(mt_entry);
                close(vol->fd);
                rtems_set_errno_and_return_minus_one( EINVAL );
            }
            else
            {
                ret = _fat_block_read(mt_entry, vol->info_sec , FAT_FSI_INFO,
                                      FAT_USEFUL_INFO_SIZE, fs_info_sector);
                if ( ret < 0 )
                {
                    _fat_block_release(mt_entry);
                    close(vol->fd);
                    return -1;
                }

                vol->free_cls = FAT_GET_FSINFO_FREE_CLUSTER_COUNT(fs_info_sector);
                vol->next_cl = FAT_GET_FSINFO_NEXT_FREE_CLUSTER(fs_info_sector);
                rc = fat_fat32_update_fsinfo_sector(mt_entry, 0xFFFFFFFF,
                                                    0xFFFFFFFF);
                if ( rc != RC_OK )
                {
                    _fat_block_release(mt_entry);
                    close(vol->fd);
                    return rc;
                }
            }
        }
    }
    else
    {
        vol->rdir_cl = 0;
        vol->mirror = 0;
        vol->afat = 0;
        vol->free_cls = 0xFFFFFFFF;
        vol->next_cl = 0xFFFFFFFF;
    }

    _fat_block_release(mt_entry);

    vol->afat_loc = vol->fat_loc + vol->fat_length * vol->afat;

    /* set up collection of fat-files fd */
    fs_info->vhash = calloc(FAT_HASH_SIZE, sizeof(rtems_chain_control));
    if ( fs_info->vhash == NULL )
    {
        close(vol->fd);
        rtems_set_errno_and_return_minus_one( ENOMEM );
    }

    for (i = 0; i < FAT_HASH_SIZE; i++)
        rtems_chain_initialize_empty(fs_info->vhash + i);

    fs_info->rhash = calloc(FAT_HASH_SIZE, sizeof(rtems_chain_control));
    if ( fs_info->rhash == NULL )
    {
        close(vol->fd);
        free(fs_info->vhash);
        rtems_set_errno_and_return_minus_one( ENOMEM );
    }
    for (i = 0; i < FAT_HASH_SIZE; i++)
        rtems_chain_initialize_empty(fs_info->rhash + i);

    fs_info->uino_pool_size = FAT_UINO_POOL_INIT_SIZE;
    fs_info->uino_base = (vol->tot_secs << vol->sec_mul) << 4;
    fs_info->index = 0;
    fs_info->uino = (char *)calloc(fs_info->uino_pool_size, sizeof(char));
    if ( fs_info->uino == NULL )
    {
        close(vol->fd);
        free(fs_info->vhash);
        free(fs_info->rhash);
        rtems_set_errno_and_return_minus_one( ENOMEM );
    }
    fs_info->sec_buf = (uint8_t *)calloc(vol->bps, sizeof(uint8_t));
    if (fs_info->sec_buf == NULL)
    {
        close(vol->fd);
        free(fs_info->vhash);
        free(fs_info->rhash);
        free(fs_info->uino);
        rtems_set_errno_and_return_minus_one( ENOMEM );
    }

    return RC_OK;
}
Example #8
0
int
rtems_rfs_format (const char* name, const rtems_rfs_format_config* config)
{
  rtems_rfs_file_system fs;
  int                   group;
  int                   rc;

  if (config->verbose)
    printf ("rtems-rfs: format: %s\n", name);
  
  memset (&fs, 0, sizeof (rtems_rfs_file_system));

  rtems_chain_initialize_empty (&fs.buffers);
  rtems_chain_initialize_empty (&fs.release);
  rtems_chain_initialize_empty (&fs.release_modified);
  rtems_chain_initialize_empty (&fs.file_shares);

  fs.max_held_buffers = RTEMS_RFS_FS_MAX_HELD_BUFFERS;

  fs.release_count = 0;
  fs.release_modified_count = 0;

  fs.flags = RTEMS_RFS_FS_NO_LOCAL_CACHE;
  
  /*
   * Open the buffer interface.
   */
  rc = rtems_rfs_buffer_open (name, &fs);
  if (rc > 0)
  {
    printf ("rtems-rfs: format: buffer open failed: %d: %s\n",
            rc, strerror (rc));
    return -1;
  }

  /*
   * Check the media.
   */
  if (rtems_rfs_fs_media_block_size (&fs) == 0)
  {
    printf ("rtems-rfs: media block is invalid: %" PRIu32 "\n",
            rtems_rfs_fs_media_block_size (&fs));
    return -1;
  }
  
  /*
   * Check the configuration data.
   */
  if (!rtems_rfs_check_config (&fs, config))
    return -1;

  if (config->verbose)
  {
    printf ("rtems-rfs: format: media size = %" PRIu64 "\n",
            rtems_rfs_fs_media_size (&fs));
    printf ("rtems-rfs: format: media blocks = %" PRIu32 "\n",
            rtems_rfs_fs_media_blocks (&fs));
    printf ("rtems-rfs: format: media block size = %" PRIu32 "\n",
            rtems_rfs_fs_media_block_size (&fs));
    printf ("rtems-rfs: format: size = %" PRIu64 "\n",
            rtems_rfs_fs_size (&fs));
    printf ("rtems-rfs: format: blocks = %zu\n",
            rtems_rfs_fs_blocks (&fs));
    printf ("rtems-rfs: format: block size = %zu\n",
            rtems_rfs_fs_block_size (&fs));
    printf ("rtems-rfs: format: bits per block = %u\n",
            rtems_rfs_bits_per_block (&fs));
    printf ("rtems-rfs: format: inode size = %zu\n", RTEMS_RFS_INODE_SIZE);
    printf ("rtems-rfs: format: inodes = %zu (%d.%d%%)\n",
            fs.group_inodes * fs.group_count,
            rtems_rfs_inode_overhead (&fs) / 10,
            rtems_rfs_inode_overhead (&fs) % 10);
    printf ("rtems-rfs: format: groups = %u\n", fs.group_count);
    printf ("rtems-rfs: format: group blocks = %zu\n", fs.group_blocks);
    printf ("rtems-rfs: format: group inodes = %zu\n", fs.group_inodes);
  }

  rc = rtems_rfs_buffer_setblksize (&fs, rtems_rfs_fs_block_size (&fs));
  if (rc > 0)
  {
    printf ("rtems-rfs: format: setting block size failed: %d: %s\n",
            rc, strerror (rc));
    return -1;
  }
  
  if (!rtems_rfs_write_superblock (&fs))
  {
    printf ("rtems-rfs: format: superblock write failed\n");
    return -1;
  }

  for (group = 0; group < fs.group_count; group++)
    if (!rtems_rfs_write_group (&fs, group,
                                config->initialise_inodes, config->verbose))
      return -1;

  if (config->verbose)
    printf ("\n");
  
  rc = rtems_rfs_buffer_close (&fs);
  if (rc > 0)
  {
    printf ("rtems-rfs: format: buffer close failed: %d: %s\n",
            rc, strerror (rc));
    return -1;
  }

  rc = rtems_rfs_write_root_dir (name);
  if (rc > 0)
  {
    printf ("rtems-rfs: format: writing root dir failed: %d: %s\n",
            rc, strerror (rc));
    return -1;
  }
  
  return 0;
}