Beispiel #1
0
int
rtems_rfs_buffer_open (const char* name, rtems_rfs_file_system* fs)
{
  struct stat st;
#if RTEMS_RFS_USE_LIBBLOCK
  int rv;
#endif

  if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_SYNC))
    printf ("rtems-rfs: buffer-open: opening: %s\n", name);

  fs->device = open (name, O_RDWR);
  if (fs->device < 0)
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN))
      printf ("rtems-rfs: buffer-open: cannot open file\n");
    return ENXIO;
  }

  if (fstat (fs->device, &st) < 0)
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN))
      printf ("rtems-rfs: buffer-open: stat '%s' failed: %s\n",
              name, strerror (errno));
    return ENXIO;
  }

#if RTEMS_RFS_USE_LIBBLOCK
  /*
   * Is the device a block device ?
   */
  if (!S_ISBLK (st.st_mode))
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN))
      printf ("rtems-rfs: buffer-open: '%s' is not a block device\n", name);
    return ENXIO;
  }

  /*
   * Check that device is registred as a block device and lock it.
   */
  rv = rtems_disk_fd_get_disk_device (fs->device, &fs->disk);
  if (rv != 0)
  {
    if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN))
      printf ("rtems-rfs: buffer-open: cannot obtain the disk\n");
    return ENXIO;
  }
#else
  fs->media_size = st.st_size;
  strcat (fs->name, name);
#endif

  if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_SYNC))
    printf ("rtems-rfs: buffer-open: blks=%" PRId32 ", blk-size=%" PRId32 "\n",
            rtems_rfs_fs_media_blocks (fs),
            rtems_rfs_fs_media_block_size (fs));

  return 0;
}
Beispiel #2
0
/*
 * Black box test the disk parameters of a sparse disk
 */
static void test_disk_params(
  const int               file_descriptor,
  const uint32_t          block_size,
  const uint32_t          media_block_size,
  const rtems_blkdev_bnum block_number )
{
  int                rv;
  uint32_t           value       = 0;
  rtems_disk_device *fd_dd       = NULL;
  rtems_blkdev_bnum  block_count = 0;


  rv = rtems_disk_fd_get_media_block_size( file_descriptor, &value );
  rtems_test_assert( 0 == rv );
  rtems_test_assert( media_block_size == value );

  value = 0;
  rv    = rtems_disk_fd_get_block_size( file_descriptor, &value );
  rtems_test_assert( 0 == rv );
  rtems_test_assert( block_size == value );

  block_count = 0;
  rv          = rtems_disk_fd_get_block_count( file_descriptor, &block_count );
  rtems_test_assert( 0 == rv );
  rtems_test_assert( block_number == block_count );

  rv = rtems_disk_fd_get_disk_device( file_descriptor, &fd_dd );
  rtems_test_assert( 0 == rv );
  rtems_test_assert( NULL != fd_dd );
}
Beispiel #3
0
static void test_logical_disks(const char *const *rdax, bool exists)
{
  size_t i = 0;

  for (i = 0; i < PARTITION_COUNT; ++i) {
    int fd = open(rdax [i], O_RDONLY);

    if (exists) {
      rtems_disk_device *dd = NULL;
      int rv = 0;

      rtems_test_assert(fd >= 0);

      rv = rtems_disk_fd_get_disk_device(fd, &dd);
      rtems_test_assert(rv == 0);

      rtems_test_assert(dd->start == starts [i]);
      rtems_test_assert(dd->size == 63);

      rv = close(fd);
      rtems_test_assert(rv == 0);
    } else {
      rtems_test_assert(fd == -1);
    }
  }
}
Beispiel #4
0
static void test_block_io_control_api(dev_t dev, ramdisk *rd)
{
    rtems_status_code sc = RTEMS_SUCCESSFUL;
    rtems_disk_device *dd = NULL;
    const rtems_disk_device *fd_dd = NULL;
    int fd = -1;
    int rv = -1;
    uint32_t value = 0;
    rtems_blkdev_bnum block_count = 0;

    sc = rtems_disk_create_phys(dev, BLOCK_SIZE, BLOCK_COUNT, ramdisk_ioctl, rd, "/dev/rda");
    ASSERT_SC(sc);

    dd = rtems_disk_obtain(dev);
    rtems_test_assert(dd != NULL);

    fd = open("/dev/rda", O_RDWR);
    rtems_test_assert(fd >= 0);

    value = 0;
    rv = rtems_disk_fd_get_media_block_size(fd, &value);
    rtems_test_assert(rv == 0);
    rtems_test_assert(value == BLOCK_SIZE);

    value = 0;
    rv = rtems_disk_fd_get_block_size(fd, &value);
    rtems_test_assert(rv == 0);
    rtems_test_assert(value == BLOCK_SIZE);

    value = 1024;
    rv = rtems_disk_fd_set_block_size(fd, value);
    rtems_test_assert(rv == 0);

    value = 0;
    rv = rtems_disk_fd_get_block_size(fd, &value);
    rtems_test_assert(rv == 0);
    rtems_test_assert(value == 1024);

    block_count = 0;
    rv = rtems_disk_fd_get_block_count(fd, &block_count);
    rtems_test_assert(rv == 0);
    rtems_test_assert(block_count == BLOCK_COUNT);

    rv = rtems_disk_fd_get_disk_device(fd, &fd_dd);
    rtems_test_assert(rv == 0);
    rtems_test_assert(fd_dd == dd);

    rv = rtems_disk_fd_sync(fd);
    rtems_test_assert(rv == 0);

    rv = close(fd);
    rtems_test_assert(rv == 0);

    sc = rtems_disk_release(dd);
    ASSERT_SC(sc);

    sc = rtems_disk_delete(dev);
    ASSERT_SC(sc);
}
Beispiel #5
0
/*
 * FIXME: This code should the deviceio interface and not the bdbug interface.
 */
rtems_status_code rtems_bdpart_get_disk_data(
  const char *disk_name,
  int *fd_ptr,
  rtems_disk_device **dd_ptr,
  rtems_blkdev_bnum *disk_end
)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;
  int rv = 0;
  int fd = -1;
  rtems_disk_device *dd = NULL;
  rtems_blkdev_bnum disk_begin = 0;
  rtems_blkdev_bnum block_size = 0;

  /* Open device file */
  fd = open( disk_name, O_RDWR);
  if (fd < 0) {
    sc = RTEMS_INVALID_NAME;
    goto error;
  }

  /* Get disk handle */
  rv = rtems_disk_fd_get_disk_device( fd, &dd);
  if (rv != 0) {
    sc = RTEMS_INVALID_NAME;
    goto error;
  }

  /* Get disk begin, end and block size */
  disk_begin = dd->start;
  *disk_end = dd->size;
  block_size = dd->block_size;

  /* Check block size */
  if (block_size < RTEMS_BDPART_BLOCK_SIZE) {
    sc = RTEMS_IO_ERROR;
    goto error;
  }

  /* Check that we have do not have a logical disk */
  if (disk_begin != 0) {
    sc = RTEMS_IO_ERROR;
    goto error;
  }

error:

  if (sc == RTEMS_SUCCESSFUL && fd_ptr != NULL && dd_ptr != NULL) {
    *fd_ptr = fd;
    *dd_ptr = dd;
  } else {
    close( fd);
  }

  return sc;
}
Beispiel #6
0
static void test_blkdev_imfs_parameters(void)
{
  rtems_status_code sc;
  int rv;
  ramdisk *rd;
  int fd;
  rtems_disk_device *dd;
  struct stat st;

  rd = ramdisk_allocate(NULL, BLOCK_SIZE, BLOCK_COUNT, false);
  rtems_test_assert(rd != NULL);

  ramdisk_enable_free_at_delete_request(rd);

  sc = rtems_blkdev_create(
    rda,
    BLOCK_SIZE,
    BLOCK_COUNT,
    ramdisk_ioctl,
    rd
  );
  ASSERT_SC(sc);

  sc = rtems_blkdev_create_partition(
    rda1,
    rda,
    1,
    BLOCK_COUNT - 1
  );
  ASSERT_SC(sc);

  fd = open(rda, O_RDWR);
  rtems_test_assert(fd >= 0);

  rv = fstat(fd, &st);
  rtems_test_assert(rv == 0);

  rv = rtems_disk_fd_get_disk_device(fd, &dd);
  rtems_test_assert(rv == 0);

  rtems_test_assert(rtems_disk_get_driver_data(dd) == rd);
  rtems_test_assert(rtems_disk_get_device_identifier(dd) == st.st_rdev);
  rtems_test_assert(rtems_disk_get_media_block_size(dd) == BLOCK_SIZE);
  rtems_test_assert(rtems_disk_get_block_size(dd) == BLOCK_SIZE);
  rtems_test_assert(rtems_disk_get_block_begin(dd) == 0);
  rtems_test_assert(rtems_disk_get_block_count(dd) == BLOCK_COUNT);

  rv = close(fd);
  rtems_test_assert(rv == 0);

  fd = open(rda1, O_RDWR);
  rtems_test_assert(fd >= 0);

  rv = fstat(fd, &st);
  rtems_test_assert(rv == 0);

  rv = rtems_disk_fd_get_disk_device(fd, &dd);
  rtems_test_assert(rv == 0);

  rtems_test_assert(rtems_disk_get_driver_data(dd) == rd);
  rtems_test_assert(rtems_disk_get_device_identifier(dd) == st.st_rdev);
  rtems_test_assert(rtems_disk_get_media_block_size(dd) == BLOCK_SIZE);
  rtems_test_assert(rtems_disk_get_block_size(dd) == BLOCK_SIZE);
  rtems_test_assert(rtems_disk_get_block_begin(dd) == 1);
  rtems_test_assert(rtems_disk_get_block_count(dd) == BLOCK_COUNT - 1);

  rv = close(fd);
  rtems_test_assert(rv == 0);

  rv = unlink(rda1);
  rtems_test_assert(rv == 0);

  rv = unlink(rda);
  rtems_test_assert(rv == 0);
}
Beispiel #7
0
rtems_status_code rtems_blkdev_create_partition(
  const char *partition,
  const char *parent_block_device,
  rtems_blkdev_bnum media_block_begin,
  rtems_blkdev_bnum media_block_count
)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;
  int fd = open(parent_block_device, O_RDWR);

  if (fd >= 0) {
    int rv;
    struct stat st;

    rv = fstat(fd, &st);
    if (rv == 0 && S_ISBLK(st.st_mode)) {
      rtems_disk_device *phys_dd;

      rv = rtems_disk_fd_get_disk_device(fd, &phys_dd);
      if (rv == 0) {
        rtems_blkdev_imfs_context *ctx = malloc(sizeof(*ctx));

        if (ctx != NULL) {
          sc = rtems_disk_init_log(
            &ctx->dd,
            phys_dd,
            media_block_begin,
            media_block_count
          );

          if (sc == RTEMS_SUCCESSFUL) {
            ctx->fd = fd;

            rv = IMFS_make_generic_node(
              partition,
              S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO,
              &rtems_blkdev_imfs_control,
              ctx
            );

            if (rv != 0) {
              free(ctx);
              sc = RTEMS_UNSATISFIED;
            }
          } else {
            free(ctx);
          }
        } else {
          sc = RTEMS_NO_MEMORY;
        }
      } else {
        sc = RTEMS_NOT_IMPLEMENTED;
      }
    } else {
      sc = RTEMS_INVALID_NODE;
    }

    if (sc != RTEMS_SUCCESSFUL) {
      close(fd);
    }
  } else {
    sc = RTEMS_INVALID_ID;
  }

  return sc;
}
Beispiel #8
0
/* 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;
}