Example #1
0
static void
rtems_rfs_rtems_eval_path (rtems_filesystem_eval_path_context_t *ctx)
{
  rtems_filesystem_location_info_t *currentloc =
    rtems_filesystem_eval_path_get_currentloc (ctx);
  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc);
  rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (currentloc);
  rtems_rfs_inode_handle inode;
  int rc;

  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
  if (rc == 0) {
    rtems_filesystem_eval_path_generic (
      ctx,
      &inode,
      &rtems_rfs_rtems_eval_config
    );
    rc = rtems_rfs_inode_close (fs, &inode);
    if (rc != 0) {
      rtems_filesystem_eval_path_error (
        ctx,
        rtems_rfs_rtems_error ("eval_path: closing inode", rc)
      );
    }
  } else {
    rtems_filesystem_eval_path_error (
      ctx,
      rtems_rfs_rtems_error ("eval_path: opening inode", rc)
    );
  }
}
Example #2
0
static int
rtems_rfs_rtems_dir_rmnod (rtems_filesystem_location_info_t* parent_pathloc,
                           rtems_filesystem_location_info_t* pathloc)
{
  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
  rtems_rfs_ino          parent = rtems_rfs_rtems_get_pathloc_ino (parent_pathloc);
  rtems_rfs_ino          ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
  uint32_t               doff = rtems_rfs_rtems_get_pathloc_doff (pathloc);
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_DIR_RMNOD))
    printf ("rtems-rfs: dir-rmnod: parent:%" PRId32 " doff:%" PRIu32 ", ino:%" PRId32 "\n",
            parent, doff, ino);

  if (ino == RTEMS_RFS_ROOT_INO)
    return rtems_rfs_rtems_error ("dir_rmnod: root inode", EBUSY);

  rtems_rfs_rtems_lock (fs);
  
  rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_if_empty);
  if (rc)
  {
    rtems_rfs_rtems_unlock (fs);
    return rtems_rfs_rtems_error ("dir_rmnod: unlinking", rc);
  }

  rtems_rfs_rtems_unlock (fs);
  return 0;
}
Example #3
0
static int
rtems_rfs_rtems_utime(const rtems_filesystem_location_info_t* pathloc,
                      time_t                                  atime,
                      time_t                                  mtime)
{
  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
  rtems_rfs_ino          ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
  rtems_rfs_inode_handle inode;
  int                    rc;

  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
  if (rc)
  {
    return rtems_rfs_rtems_error ("utime: read inode", rc);
  }

  rtems_rfs_inode_set_atime (&inode, atime);
  rtems_rfs_inode_set_mtime (&inode, mtime);

  rc = rtems_rfs_inode_close (fs, &inode);
  if (rc)
  {
    return rtems_rfs_rtems_error ("utime: closing inode", rc);
  }

  return 0;
}
Example #4
0
static int
rtems_rfs_rtems_fchmod (const rtems_filesystem_location_info_t* pathloc,
                        mode_t                                  mode)
{
  rtems_rfs_file_system*  fs = rtems_rfs_rtems_pathloc_dev (pathloc);
  rtems_rfs_ino           ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
  rtems_rfs_inode_handle  inode;
  int                     rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FCHMOD))
    printf ("rtems-rfs-rtems: fchmod: in: ino:%" PRId32 " mode:%06" PRIomode_t "\n",
            ino, mode);

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

  rtems_rfs_inode_set_mode (&inode, mode);

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

  return 0;
}
Example #5
0
static rtems_filesystem_node_types_t
rtems_rfs_rtems_node_type (const rtems_filesystem_location_info_t* pathloc)
{
  rtems_rfs_file_system*        fs = rtems_rfs_rtems_pathloc_dev (pathloc);
  rtems_rfs_ino                 ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
  rtems_filesystem_node_types_t type;
  rtems_rfs_inode_handle        inode;
  int                           rc;

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

  type = rtems_rfs_rtems_node_type_by_inode (&inode);

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

  return type;
}
Example #6
0
/**
 * This rountine will verify that the node being opened as a directory is in
 * fact a directory node. If it is then the offset into the directory will be
 * set to 0 to position to the first directory entry.
 */
static int
rtems_rfs_rtems_dir_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;
  int                    rc;

  rtems_rfs_rtems_lock (fs);

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

  if (!RTEMS_RFS_S_ISDIR (rtems_rfs_inode_get_mode (&inode)))
  {
    rtems_rfs_inode_close (fs, &inode);
    rtems_rfs_rtems_unlock (fs);
    return rtems_rfs_rtems_error ("dir_open: not dir", ENOTDIR);
  }

  iop->offset = 0;

  rtems_rfs_inode_close (fs, &inode);
  rtems_rfs_rtems_unlock (fs);
  return 0;
}
Example #7
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;
      }
    }
  }

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

  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));

  return read;
}
Example #8
0
static int
rtems_rfs_rtems_mknod (const rtems_filesystem_location_info_t *parentloc,
                       const char                             *name,
                       size_t                                  namelen,
                       mode_t                                  mode,
                       dev_t                                   dev)
{
  rtems_rfs_file_system*  fs = rtems_rfs_rtems_pathloc_dev (parentloc);
  rtems_rfs_ino           parent = rtems_rfs_rtems_get_pathloc_ino (parentloc);
  rtems_rfs_ino           ino;
  rtems_rfs_inode_handle  inode;
  uid_t                   uid;
  gid_t                   gid;
  int                     rc;

  uid = geteuid ();
  gid = getegid ();

  rc = rtems_rfs_inode_create (fs, parent, name, namelen,
                               rtems_rfs_rtems_imode (mode),
                               1, uid, gid, &ino);
  if (rc > 0)
  {
    return rtems_rfs_rtems_error ("mknod: inode create", rc);
  }

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

  if (S_ISDIR(mode) || S_ISREG(mode))
  {
  }
  else if (S_ISCHR (mode) || S_ISBLK (mode))
  {
    int major;
    int minor;
    rtems_filesystem_split_dev_t (dev, major, minor);
    rtems_rfs_inode_set_block (&inode, 0, major);
    rtems_rfs_inode_set_block (&inode, 1, minor);
  }
  else
  {
    rtems_rfs_inode_close (fs, &inode);
    return rtems_rfs_rtems_error ("mknod: bad mode", EINVAL);
  }

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

  return 0;
}
Example #9
0
static int
rtems_rfs_rtems_fchmod (const rtems_filesystem_location_info_t* pathloc,
                        mode_t                                  mode)
{
  rtems_rfs_file_system*  fs = rtems_rfs_rtems_pathloc_dev (pathloc);
  rtems_rfs_ino           ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
  rtems_rfs_inode_handle  inode;
  uint16_t                imode;
#if defined (RTEMS_POSIX_API)
  uid_t                   uid;
#endif
  int                     rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FCHMOD))
    printf ("rtems-rfs-rtems: fchmod: in: ino:%" PRId32 " mode:%06" PRIomode_t "\n",
            ino, mode);

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

  imode = rtems_rfs_inode_get_mode (&inode);

  /*
   *  Verify I am the owner of the node or the super user.
   */
#if defined (RTEMS_POSIX_API)
  uid = geteuid();

  if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0))
  {
    rtems_rfs_inode_close (fs, &inode);
    return rtems_rfs_rtems_error ("fchmod: checking uid", EPERM);
  }
#endif

  imode &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
  imode |= mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);

  rtems_rfs_inode_set_mode (&inode, imode);

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

  return 0;
}
Example #10
0
/**
 * This routine will read the next directory entry based on the directory
 * offset. The offset should be equal to -n- time the size of an individual
 * dirent structure. If n is not an integer multiple of the sizeof a dirent
 * structure, an integer division will be performed to determine directory
 * entry that will be returned in the buffer. Count should reflect -m- times
 * the sizeof dirent bytes to be placed in the buffer.  If there are not -m-
 * dirent elements from the current directory position to the end of the
 * exisiting file, the remaining entries will be placed in the buffer and the
 * returned value will be equal to -m actual- times the size of a directory
 * entry.
 */
static ssize_t
rtems_rfs_rtems_dir_read (rtems_libio_t* iop,
                          void*          buffer,
                          size_t         count)
{
  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;
  struct dirent*         dirent;
  ssize_t                bytes_transferred;
  int                    d;
  int                    rc;

  count  = count / sizeof (struct dirent);
  dirent = buffer;

  rtems_rfs_rtems_lock (fs);

  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
  if (rc)
  {
    rtems_rfs_rtems_unlock (fs);
    return rtems_rfs_rtems_error ("dir_read: read inode", rc);
  }

  bytes_transferred = 0;

  for (d = 0; d < count; d++, dirent++)
  {
    size_t size;
    rc = rtems_rfs_dir_read (fs, &inode, iop->offset, dirent, &size);
    if (rc == ENOENT)
    {
      rc = 0;
      break;
    }
    if (rc > 0)
    {
      bytes_transferred = rtems_rfs_rtems_error ("dir_read: dir read", rc);
      break;
    }
    iop->offset += size;
    bytes_transferred += sizeof (struct dirent);
  }

  rtems_rfs_inode_close (fs, &inode);
  rtems_rfs_rtems_unlock (fs);

  return bytes_transferred;
}
/**
 * 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,
                              uint32_t       flag,
                              uint32_t       mode)
{
  rtems_libio_open_close_args_t args;
  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;
  int                           major;
  int                           minor;
  rtems_status_code             status;
  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*)((intptr_t) minor);
  
  args.iop   = iop;
  args.flags = iop->flags;
  args.mode  = mode;

  status = rtems_io_open (major, minor, (void *) &args);
  if (status)
    return rtems_deviceio_errno(status);

  return 0;
}
/**
 * This routine processes the lseek() system call.
 *
 * @param iop
 * @param offset
 * @param whence
 * @return off_t
 */
static off_t
rtems_rfs_rtems_file_lseek (rtems_libio_t* iop,
                            off_t          offset,
                            int            whence)
{
  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
  rtems_rfs_pos          pos;
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_LSEEK))
    printf("rtems-rfs: file-lseek: handle:%p offset:%" PRIdoff_t "\n", file, offset);

  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));

  pos = iop->offset;

  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_lseek: lseek", rc);
  }

  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));

  return iop->offset;
}
Example #13
0
/**
 * This routine processes the lseek() system call.
 *
 * @param iop
 * @param offset
 * @param whence
 * @return off_t
 */
static off_t
rtems_rfs_rtems_file_lseek (rtems_libio_t* iop,
                            off_t          offset,
                            int            whence)
{
  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
  off_t                  old_offset;
  off_t                  new_offset;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_LSEEK))
    printf("rtems-rfs: file-lseek: handle:%p offset:%" PRIdoff_t "\n", file, offset);

  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));

  old_offset = iop->offset;
  new_offset = rtems_filesystem_default_lseek_file (iop, offset, whence);
  if (new_offset != -1)
  {
    rtems_rfs_pos pos = iop->offset;
    int           rc = rtems_rfs_file_seek (file, pos, &pos);

    if (rc)
    {
      rtems_rfs_rtems_error ("file_lseek: lseek", rc);
      iop->offset = old_offset;
      new_offset = -1;
    }
  }

  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));

  return new_offset;
}
Example #14
0
static int
rtems_rfs_rtems_chown (const rtems_filesystem_location_info_t *pathloc,
                       uid_t                                   owner,
                       gid_t                                   group)
{
  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
  rtems_rfs_ino          ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
  rtems_rfs_inode_handle inode;
#if defined (RTEMS_POSIX_API)
  uid_t                  uid;
#endif
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_CHOWN))
    printf ("rtems-rfs-rtems: chown: in: ino:%" PRId32 " uid:%d gid:%d\n",
            ino, owner, group);

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

  /*
   *  Verify I am the owner of the node or the super user.
   */

#if defined (RTEMS_POSIX_API)
  uid = geteuid();

  if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0))
  {
    rtems_rfs_inode_close (fs, &inode);
    return rtems_rfs_rtems_error ("chown: not able", EPERM);
  }
#endif

  rtems_rfs_inode_set_uid_gid (&inode, owner, group);

  rc = rtems_rfs_inode_close (fs, &inode);
  if (rc)
  {
    return rtems_rfs_rtems_error ("chown: closing inode", rc);
  }

  return 0;
}
Example #15
0
/**
 * Rename the node.
 */
static int
rtems_rfs_rtems_rename(const rtems_filesystem_location_info_t* old_parent_loc,
                       const rtems_filesystem_location_info_t* old_loc,
                       const rtems_filesystem_location_info_t* new_parent_loc,
                       const char*                             new_name,
                       size_t                                  new_name_len)
{
  rtems_rfs_file_system*  fs = rtems_rfs_rtems_pathloc_dev (old_loc);
  rtems_rfs_ino           old_parent;
  rtems_rfs_ino           new_parent;
  rtems_rfs_ino           ino;
  uint32_t                doff;
  int                     rc;

  old_parent = rtems_rfs_rtems_get_pathloc_ino (old_parent_loc);
  new_parent = rtems_rfs_rtems_get_pathloc_ino (new_parent_loc);

  ino  = rtems_rfs_rtems_get_pathloc_ino (old_loc);
  doff = rtems_rfs_rtems_get_pathloc_doff (old_loc);

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_RENAME))
    printf ("rtems-rfs: rename: ino:%" PRId32 " doff:%" PRIu32 ", new parent:%" PRId32 "\n",
            ino, doff, new_parent);

  /*
   * Link to the inode before unlinking so the inode is not erased when
   * unlinked.
   */
  rc = rtems_rfs_link (fs, new_name, new_name_len, new_parent, ino, true);
  if (rc)
  {
    return rtems_rfs_rtems_error ("rename: linking", rc);
  }

  /*
   * Unlink all inodes even directories with the dir option as false because a
   * directory may not be empty.
   */
  rc = rtems_rfs_unlink (fs, old_parent, ino, doff,
                         rtems_rfs_unlink_dir_allowed);
  if (rc)
  {
    return rtems_rfs_rtems_error ("rename: unlinking", rc);
  }

  return 0;
}
Example #16
0
/**
 * The following routine does a sync on an inode node. Currently it flushes
 * everything related to this device.
 *
 * @param iop
 * @return int
 */
int
rtems_rfs_rtems_fdatasync (rtems_libio_t* iop)
{
  int rc;

  rc = rtems_rfs_buffer_sync (rtems_rfs_rtems_pathloc_dev (&iop->pathinfo));
  if (rc)
    return rtems_rfs_rtems_error ("fdatasync: sync", rc);

  return 0;
}
Example #17
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);
}
Example #18
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;
}
Example #19
0
/**
 * This routine will behave in one of three ways based on the state of argument
 * whence. Based on the state of its value the offset argument will be
 * interpreted using one of the following methods:
 *
 *   SEEK_SET - offset is the absolute byte offset from the start of the
 *              logical start of the dirent sequence that represents the
 *              directory
 *   SEEK_CUR - offset is used as the relative byte offset from the current
 *              directory position index held in the iop structure
 *   SEEK_END - N/A --> This will cause an assert.
 *
 * @param iop
 * @param offset
 * @param whence
 * return rtems_off64_t
 */
static rtems_off64_t
rtems_rfs_rtems_dir_lseek (rtems_libio_t* iop,
                           rtems_off64_t  offset,
                           int            whence)
{
  switch (whence)
  {
    case SEEK_SET:   /* absolute move from the start of the file */
    case SEEK_CUR:   /* relative move */
      break;

     case SEEK_END:   /* Movement past the end of the directory via lseek */
                      /* is not a permitted operation                     */
    default:
      return rtems_rfs_rtems_error ("dir_lseek: bad whence", EINVAL);
      break;
  }
  return 0;
}
Example #20
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;
}
Example #21
0
static int
rtems_rfs_rtems_symlink (const rtems_filesystem_location_info_t* parent_loc,
                         const char*                             node_name,
                         size_t                                  node_name_len,
                         const char*                             target)
{
  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (parent_loc);
  rtems_rfs_ino          parent = rtems_rfs_rtems_get_pathloc_ino (parent_loc);
  int                    rc;

  rc = rtems_rfs_symlink (fs, node_name, node_name_len,
                          target, strlen (target),
                          geteuid(), getegid(), parent);
  if (rc)
  {
    return rtems_rfs_rtems_error ("symlink: linking", rc);
  }

  return 0;
}
Example #22
0
static ssize_t
rtems_rfs_rtems_readlink (const rtems_filesystem_location_info_t* pathloc,
                          char*                                   buf,
                          size_t                                  bufsize)
{
  rtems_rfs_file_system*  fs = rtems_rfs_rtems_pathloc_dev (pathloc);
  rtems_rfs_ino           ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
  size_t                  length;
  int                     rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_READLINK))
    printf ("rtems-rfs-rtems: readlink: in: ino:%" PRId32 "\n", ino);

  rc = rtems_rfs_symlink_read (fs, ino, buf, bufsize, &length);
  if (rc)
  {
    return rtems_rfs_rtems_error ("readlink: reading link", rc);
  }

  return (ssize_t) length;
}
Example #23
0
/**
 * Routine to remove a node from the RFS file system.
 *
 * @param parent_pathloc
 * @param pathloc
 * @return int
 */
int
rtems_rfs_rtems_rmnod (const rtems_filesystem_location_info_t* parent_pathloc,
                       const rtems_filesystem_location_info_t* pathloc)
{
  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
  rtems_rfs_ino          parent = rtems_rfs_rtems_get_pathloc_ino (parent_pathloc);
  rtems_rfs_ino          ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
  uint32_t               doff = rtems_rfs_rtems_get_pathloc_doff (pathloc);
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_RMNOD))
    printf ("rtems-rfs: rmnod: parent:%" PRId32 " doff:%" PRIu32 ", ino:%" PRId32 "\n",
            parent, doff, ino);

  rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_if_empty);
  if (rc)
  {
    return rtems_rfs_rtems_error ("rmnod: unlinking", rc);
  }

  return 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;
}
Example #25
0
/**
 * The following rouine creates a new link node under parent with the name
 * given in name. The link node is set to point to the node at targetloc.
 */
static int
rtems_rfs_rtems_link (const rtems_filesystem_location_info_t *parentloc,
                      const rtems_filesystem_location_info_t *targetloc,
                      const char *name,
                      size_t namelen)
{
  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (targetloc);
  rtems_rfs_ino          target = rtems_rfs_rtems_get_pathloc_ino (targetloc);
  rtems_rfs_ino          parent = rtems_rfs_rtems_get_pathloc_ino (parentloc);
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_LINK))
    printf ("rtems-rfs-rtems: link: in: parent:%" PRId32 " target:%" PRId32 "\n",
            parent, target);

  rc = rtems_rfs_link (fs, name, namelen, parent, target, false);
  if (rc)
  {
    return rtems_rfs_rtems_error ("link: linking", rc);
	}


	return 0;
}
Example #26
0
static rtems_filesystem_eval_path_generic_status
rtems_rfs_rtems_eval_token(
  rtems_filesystem_eval_path_context_t *ctx,
  void *arg,
  const char *token,
  size_t tokenlen
)
{
  rtems_filesystem_eval_path_generic_status status =
    RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
  rtems_rfs_inode_handle* inode = arg;
  bool access_ok = rtems_rfs_rtems_eval_perms (ctx, RTEMS_FS_PERMS_EXEC, inode);

  if (access_ok) {
    if (rtems_filesystem_is_current_directory (token, tokenlen)) {
      rtems_filesystem_eval_path_clear_token (ctx);
    } else {
      rtems_filesystem_location_info_t *currentloc =
        rtems_filesystem_eval_path_get_currentloc( ctx );
      rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc);
      rtems_rfs_ino entry_ino;
      uint32_t entry_doff;
      int rc = rtems_rfs_dir_lookup_ino (
        fs,
        inode,
        token,
        tokenlen,
        &entry_ino,
        &entry_doff
      );

      if (rc == 0) {
        rc = rtems_rfs_inode_close (fs, inode);
        if (rc == 0) {
          rc = rtems_rfs_inode_open (fs, entry_ino, inode, true);
        }

        if (rc != 0) {
          /*
           * This prevents the rtems_rfs_inode_close() from doing something in
           * rtems_rfs_rtems_eval_path().
           */
          memset (inode, 0, sizeof(*inode));
        }
      } else {
        status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY;
        rc = -1;
      }

      if (rc == 0) {
        bool is_sym_link = rtems_rfs_rtems_node_type_by_inode (inode)
          == RTEMS_FILESYSTEM_SYM_LINK;
        int eval_flags = rtems_filesystem_eval_path_get_flags (ctx);
        bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0;
        bool terminal = !rtems_filesystem_eval_path_has_path (ctx);

        rtems_filesystem_eval_path_clear_token (ctx);

        if (is_sym_link && (follow_sym_link || !terminal)) {
          rtems_rfs_rtems_follow_link (ctx, fs, entry_ino);
        } else {
          rc = rtems_rfs_rtems_set_handlers (currentloc, inode) ? 0 : EIO;
          if (rc == 0) {
            rtems_rfs_rtems_set_pathloc_ino (currentloc, entry_ino);
            rtems_rfs_rtems_set_pathloc_doff (currentloc, entry_doff);

            if (!terminal) {
              status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
            }
          } else {
            rtems_filesystem_eval_path_error (
              ctx,
              rtems_rfs_rtems_error ("eval_path: set handlers", rc)
            );
          }
        }
      }
    }
  }

  return status;
}
Example #27
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;
}
Example #28
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;
}
Example #29
0
int
rtems_rfs_rtems_fstat (const rtems_filesystem_location_info_t* pathloc,
                       struct stat*                            buf)
{
  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
  rtems_rfs_ino          ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
  rtems_rfs_inode_handle inode;
  rtems_rfs_file_shared* shared;
  uint16_t               mode;
  int                    rc;

  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_STAT))
    printf ("rtems-rfs-rtems: stat: in: ino:%" PRId32 "\n", ino);

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

  mode = rtems_rfs_inode_get_mode (&inode);

  if (RTEMS_RFS_S_ISCHR (mode) || RTEMS_RFS_S_ISBLK (mode))
  {
    buf->st_rdev =
      rtems_filesystem_make_dev_t (rtems_rfs_inode_get_block (&inode, 0),
                                   rtems_rfs_inode_get_block (&inode, 1));
  }

  buf->st_dev     = rtems_rfs_fs_device (fs);
  buf->st_ino     = rtems_rfs_inode_ino (&inode);
  buf->st_mode    = rtems_rfs_rtems_mode (mode);
  buf->st_nlink   = rtems_rfs_inode_get_links (&inode);
  buf->st_uid     = rtems_rfs_inode_get_uid (&inode);
  buf->st_gid     = rtems_rfs_inode_get_gid (&inode);

  /*
   * Need to check is the ino is an open file. If so we take the values from
   * the open file rather than the inode.
   */
  shared = rtems_rfs_file_get_shared (fs, rtems_rfs_inode_ino (&inode));

  if (shared)
  {
    buf->st_atime   = rtems_rfs_file_shared_get_atime (shared);
    buf->st_mtime   = rtems_rfs_file_shared_get_mtime (shared);
    buf->st_ctime   = rtems_rfs_file_shared_get_ctime (shared);
    buf->st_blocks  = rtems_rfs_file_shared_get_block_count (shared);

    if (S_ISLNK (buf->st_mode))
      buf->st_size = rtems_rfs_file_shared_get_block_offset (shared);
    else
      buf->st_size = rtems_rfs_file_shared_get_size (fs, shared);
  }
  else
  {
    buf->st_atime   = rtems_rfs_inode_get_atime (&inode);
    buf->st_mtime   = rtems_rfs_inode_get_mtime (&inode);
    buf->st_ctime   = rtems_rfs_inode_get_ctime (&inode);
    buf->st_blocks  = rtems_rfs_inode_get_block_count (&inode);

    if (S_ISLNK (buf->st_mode))
      buf->st_size = rtems_rfs_inode_get_block_offset (&inode);
    else
      buf->st_size = rtems_rfs_inode_get_size (fs, &inode);
  }

  buf->st_blksize = rtems_rfs_fs_block_size (fs);

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

  return 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;
}