Пример #1
0
/**
 * This routine processes the read() system call.
 *
 * @param iop
 * @param buffer
 * @param count
 * @return int
 */
static ssize_t
rtems_rfs_rtems_file_read (rtems_libio_t* iop,
                           void*          buffer,
                           size_t         count)
{
  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
  rtems_rfs_pos          pos;
  uint8_t*               data = buffer;
  ssize_t                read = 0;
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_READ))
    printf("rtems-rfs: file-read: handle:%p count:%zd\n", file, count);

  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));

  pos = iop->offset;
  
  if (pos < rtems_rfs_file_size (file))
  {
    while (count)
    {
      size_t size;

      rc = rtems_rfs_file_io_start (file, &size, true);
      if (rc > 0)
      {
        read = rtems_rfs_rtems_error ("file-read: read: io-start", rc);
        break;
      }

      if (size == 0)
        break;
    
      if (size > count)
        size = count;
    
      memcpy (data, rtems_rfs_file_data (file), size);

      data  += size;
      count -= size;
      read  += size;

      rc = rtems_rfs_file_io_end (file, size, true);
      if (rc > 0)
      {
        read = rtems_rfs_rtems_error ("file-read: read: io-end", rc);
        break;
      }
    }
  }
  
  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
  
  return read;
}
Пример #2
0
/**
 * This handler maps an open() operation onto rtems_io_open().
 *
 * @param iop
 * @param pathname
 * @param flag
 * @param mode
 * @return int
 */
static int
rtems_rfs_rtems_device_open ( rtems_libio_t *iop,
                              const char    *pathname,
                              int            oflag,
                              mode_t         mode)
{
    rtems_rfs_file_system*        fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
    rtems_rfs_ino                 ino = rtems_rfs_rtems_get_iop_ino (iop);
    rtems_rfs_inode_handle        inode;
    rtems_device_major_number     major;
    rtems_device_minor_number     minor;
    int                           rc;

    rtems_rfs_rtems_lock (fs);

    rc = rtems_rfs_inode_open (fs, ino, &inode, true);
    if (rc > 0)
    {
        rtems_rfs_rtems_unlock (fs);
        return rtems_rfs_rtems_error ("device_open: opening inode", rc);
    }

    major = rtems_rfs_inode_get_block (&inode, 0);
    minor = rtems_rfs_inode_get_block (&inode, 1);

    rc = rtems_rfs_inode_close (fs, &inode);
    if (rc > 0)
    {
        rtems_rfs_rtems_unlock (fs);
        return rtems_rfs_rtems_error ("device_open: closing inode", rc);
    }

    rtems_rfs_rtems_unlock (fs);

    iop->data0 = major;
    iop->data1 = (void *) (uintptr_t) minor;

    return rtems_deviceio_open (iop, pathname, oflag, mode, minor, major);
}
Пример #3
0
static int
rtems_rfs_rtems_file_open (rtems_libio_t* iop,
                           const char*    pathname,
                           int            oflag,
                           mode_t         mode)
{
  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
  rtems_rfs_ino          ino;
  rtems_rfs_file_handle* file;
  int                    flags;
  int                    rc;

  flags = 0;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_OPEN))
    printf("rtems-rfs: file-open: path:%s ino:%" PRId32 " flags:%04i mode:%04" PRIu32 "\n",
           pathname, ino, flags, mode);

  rtems_rfs_rtems_lock (fs);

  ino = rtems_rfs_rtems_get_iop_ino (iop);

  rc = rtems_rfs_file_open (fs, ino, flags, &file);
  if (rc > 0)
  {
    rtems_rfs_rtems_unlock (fs);
    return rtems_rfs_rtems_error ("file-open: open", rc);
  }

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_OPEN))
    printf("rtems-rfs: file-open: handle:%p\n", file);

  iop->size = rtems_rfs_file_size (file);
  rtems_rfs_rtems_set_iop_file_handle (iop, file);

  rtems_rfs_rtems_unlock (fs);
  return 0;
}
Пример #4
0
/**
 * This routine processes the close() system call.  Note that there is nothing
 * to flush at this point.
 *
 * @param iop
 * @return int
 */
static int
rtems_rfs_rtems_file_close (rtems_libio_t* iop)
{
  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
  rtems_rfs_file_system* fs = rtems_rfs_file_fs (file);
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_CLOSE))
    printf("rtems-rfs: file-close: handle:%p\n", file);

  rtems_rfs_rtems_lock (fs);

  rc = rtems_rfs_file_close (fs, file);
  if (rc > 0)
    rc = rtems_rfs_rtems_error ("file-close: file close", rc);

  rtems_rfs_rtems_unlock (fs);
  return rc;
}
Пример #5
0
/**
 * This routine processes the ftruncate() system call.
 *
 * @param iop
 * @param length
 * @return int
 */
static int
rtems_rfs_rtems_file_ftruncate (rtems_libio_t* iop,
                                off_t          length)
{
  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_FTRUNC))
    printf("rtems-rfs: file-ftrunc: handle:%p length:%" PRIdoff_t "\n", file, length);

  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));

  rc = rtems_rfs_file_set_size (file, length);
  if (rc)
    rc = rtems_rfs_rtems_error ("file_ftruncate: set size", rc);

  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));

  return rc;
}
Пример #6
0
/**
 * This routine processes the write() system call.
 *
 * @param iop
 * @param buffer
 * @param count
 * @return ssize_t
 */
static ssize_t
rtems_rfs_rtems_file_write (rtems_libio_t* iop,
                            const void*    buffer,
                            size_t         count)
{
  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
  rtems_rfs_pos          pos;
  rtems_rfs_pos          file_size;
  const uint8_t*         data = buffer;
  ssize_t                write = 0;
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_WRITE))
    printf("rtems-rfs: file-write: handle:%p count:%zd\n", file, count);

  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));

  pos = iop->offset;
  file_size = rtems_rfs_file_size (file);
  if (pos > file_size)
  {
    /*
     * If the iop position is past the physical end of the file we need to set
     * the file size to the new length before writing.  The
     * rtems_rfs_file_io_end() will grow the file subsequently.
     */
    rc = rtems_rfs_file_set_size (file, pos);
    if (rc)
    {
      rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
      return rtems_rfs_rtems_error ("file-write: write extend", rc);
    }

    rtems_rfs_file_set_bpos (file, pos);
  }
  else if (pos < file_size && rtems_libio_iop_is_append(iop))
  {
    pos = file_size;
    rc = rtems_rfs_file_seek (file, pos, &pos);
    if (rc)
    {
      rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
      return rtems_rfs_rtems_error ("file-write: write append seek", rc);
    }
  }

  while (count)
  {
    size_t size = count;

    rc = rtems_rfs_file_io_start (file, &size, false);
    if (rc)
    {
      /*
       * If we have run out of space and have written some data return that
       * amount first as the inode will have accounted for it. This means
       * there was no error and the return code from can be ignored.
       */
      if (!write)
        write = rtems_rfs_rtems_error ("file-write: write open", rc);
      break;
    }

    if (size > count)
      size = count;

    memcpy (rtems_rfs_file_data (file), data, size);

    data  += size;
    count -= size;
    write  += size;

    rc = rtems_rfs_file_io_end (file, size, false);
    if (rc)
    {
      write = rtems_rfs_rtems_error ("file-write: write close", rc);
      break;
    }
  }

  if (write >= 0)
    iop->offset = pos + write;

  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));

  return write;
}
Пример #7
0
int
rtems_rfs_rtems_initialise (rtems_filesystem_mount_table_entry_t* mt_entry,
                            const void*                           data)
{
  rtems_rfs_rtems_private* rtems;
  rtems_rfs_file_system*   fs;
  uint32_t                 flags = 0;
  uint32_t                 max_held_buffers = RTEMS_RFS_FS_MAX_HELD_BUFFERS;
  const char*              options = data;
  int                      rc;

  /*
   * Parse the options the user specifiies.
   */
  while (options)
  {
    printf ("options=%s\n", options);
    if (strncmp (options, "hold-bitmaps",
                 sizeof ("hold-bitmaps") - 1) == 0)
      flags |= RTEMS_RFS_FS_BITMAPS_HOLD;
    else if (strncmp (options, "no-local-cache",
                      sizeof ("no-local-cache") - 1) == 0)
      flags |= RTEMS_RFS_FS_NO_LOCAL_CACHE;
    else if (strncmp (options, "max-held-bufs",
                      sizeof ("max-held-bufs") - 1) == 0)
    {
      max_held_buffers = strtoul (options + sizeof ("max-held-bufs"), 0, 0);
    }
    else
      return rtems_rfs_rtems_error ("initialise: invalid option", EINVAL);

    options = strchr (options, ',');
    if (options)
    {
      ++options;
      if (*options == '\0')
        options = NULL;
    }
  }

  rtems = malloc (sizeof (rtems_rfs_rtems_private));
  if (!rtems)
    return rtems_rfs_rtems_error ("initialise: local data", ENOMEM);

  memset (rtems, 0, sizeof (rtems_rfs_rtems_private));

  rc = rtems_rfs_mutex_create (&rtems->access);
  if (rc > 0)
  {
    free (rtems);
    return rtems_rfs_rtems_error ("initialise: cannot create mutex", rc);
  }

  rc = rtems_rfs_mutex_lock (&rtems->access);
  if (rc > 0)
  {
    rtems_rfs_mutex_destroy (&rtems->access);
    free (rtems);
    return rtems_rfs_rtems_error ("initialise: cannot lock access  mutex", rc);
  }

  rc = rtems_rfs_fs_open (mt_entry->dev, rtems, flags, max_held_buffers, &fs);
  if (rc)
  {
    free (rtems);
    return rtems_rfs_rtems_error ("initialise: open", rc);
  }

  mt_entry->fs_info                          = fs;
  mt_entry->ops                              = &rtems_rfs_ops;
  mt_entry->mt_fs_root->location.node_access = (void*) RTEMS_RFS_ROOT_INO;
  mt_entry->mt_fs_root->location.handlers    = &rtems_rfs_rtems_dir_handlers;

  rtems_rfs_rtems_unlock (fs);

  return 0;
}
Пример #8
0
/**
 * This routine processes the write() system call.
 *
 * @param iop
 * @param buffer
 * @param count
 * @return ssize_t
 */
static ssize_t
rtems_rfs_rtems_file_write (rtems_libio_t* iop,
                            const void*    buffer,
                            size_t         count)
{
  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
  rtems_rfs_pos          pos;
  const uint8_t*         data = buffer;
  ssize_t                write = 0;
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_WRITE))
    printf("rtems-rfs: file-write: handle:%p count:%zd\n", file, count);

  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));

  pos = iop->offset;

  /*
   * If the iop position is past the physical end of the file we need to set
   * the file size to the new length before writing. If the position equals the
   * size of file we are still past the end of the file as positions number
   * from 0. For a specific position we need a file that has a length of one
   * more.
   */

  if (pos >= rtems_rfs_file_size (file))
  {
    rc = rtems_rfs_file_set_size (file, pos + 1);
    if (rc)
    {
      rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
      return rtems_rfs_rtems_error ("file-write: write extend", rc);
    }
  }

  rtems_rfs_file_set_bpos (file, pos);

  while (count)
  {
    size_t size = count;

    rc = rtems_rfs_file_io_start (file, &size, false);
    if (rc)
    {
      write = rtems_rfs_rtems_error ("file-write: write open", rc);
      break;
    }

    if (size > count)
      size = count;

    memcpy (rtems_rfs_file_data (file), data, size);

    data  += size;
    count -= size;
    write  += size;

    rc = rtems_rfs_file_io_end (file, size, false);
    if (rc)
    {
      write = rtems_rfs_rtems_error ("file-write: write close", rc);
      break;
    }
  }

  iop->size = rtems_rfs_file_size (file);

  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));

  return write;
}