Exemplo n.º 1
0
bool rtems_filesystem_iterate(
  rtems_per_filesystem_routine routine,
  void *routine_arg
)
{
  rtems_chain_control *chain = &filesystem_chain;
  const rtems_filesystem_table_t *table_entry = &rtems_filesystem_table [0];
  rtems_chain_node *node = NULL;
  bool stop = false;

  while ( table_entry->type && !stop ) {
    stop = (*routine)( table_entry, routine_arg );
    ++table_entry;
  }

  if ( !stop ) {
    rtems_libio_lock();
    for (
      node = rtems_chain_first( chain );
      !rtems_chain_is_tail( chain, node ) && !stop;
      node = rtems_chain_next( node )
    ) {
      const filesystem_node *fsn = (filesystem_node *) node;

      stop = (*routine)( &fsn->entry, routine_arg );
    }
    rtems_libio_unlock();
  }

  return stop;
}
Exemplo n.º 2
0
static int pipe_lock(void)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;

  if (pipe_semaphore == RTEMS_ID_NONE) {
    rtems_libio_lock();

    if (pipe_semaphore == RTEMS_ID_NONE) {
      sc = rtems_semaphore_create(
        rtems_build_name('P', 'I', 'P', 'E'),
        1,
        RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
        RTEMS_NO_PRIORITY,
        &pipe_semaphore
      );
    }

    rtems_libio_unlock();
  }

  if (sc == RTEMS_SUCCESSFUL) {
    sc = rtems_semaphore_obtain(pipe_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
  }

  if (sc == RTEMS_SUCCESSFUL) {
    return 0;
  } else {
    return -ENOMEM;
  }
}
Exemplo n.º 3
0
void rtems_libio_free(
  rtems_libio_t *iop
)
{
  rtems_filesystem_location_free( &iop->pathinfo );

  rtems_libio_lock();

    iop->flags = 0;
    iop->data1 = rtems_libio_iop_freelist;
    rtems_libio_iop_freelist = iop;

  rtems_libio_unlock();
}
Exemplo n.º 4
0
Arquivo: libio.c Projeto: gedare/rtems
void rtems_libio_free(
  rtems_libio_t *iop
)
{
  rtems_filesystem_location_free( &iop->pathinfo );

  rtems_libio_lock();

  iop = memset( iop, 0, sizeof( *iop ) );
  *rtems_libio_iop_free_tail = iop;
  rtems_libio_iop_free_tail = &iop->data1;

  rtems_libio_unlock();
}
Exemplo n.º 5
0
Arquivo: rap.c Projeto: ChOr82/RTEMS
static bool
rtems_rap_data_init (void)
{
    /*
     * Lock the RAP. We only create a lock if a call is made. First we test if a
     * lock is present. If one is present we lock it. If not the libio lock is
     * locked and we then test the lock again. If not present we create the lock
     * then release libio lock.
     */
    if (!rap_.lock)
    {
        rtems_libio_lock ();

        if (!rap_.lock)
        {
            rtems_status_code sc;
            rtems_id          lock;

            /*
             * Create the RAP lock.
             */
            sc = rtems_semaphore_create (rtems_build_name ('R', 'A', 'P', '_'),
                                         1, RTEMS_MUTEX_ATTRIBS,
                                         RTEMS_NO_PRIORITY, &lock);
            if (sc != RTEMS_SUCCESSFUL)
                return false;

            sc = rtems_semaphore_obtain (lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
            if (sc != RTEMS_SUCCESSFUL)
            {
                rtems_semaphore_delete (lock);
                return false;
            }

            rap_.lock = lock;

            /*
             * Initialise the objects list and create any required services.
             */
            rtems_chain_initialize_empty (&rap_.apps);
        }

        rtems_libio_unlock ();

        rtems_rap_unlock ();
    }
    return true;
}
Exemplo n.º 6
0
rtems_libio_t *rtems_libio_allocate( void )
{
  rtems_libio_t *iop = NULL;

  rtems_libio_lock();

  if (rtems_libio_iop_freelist) {
    iop = rtems_libio_iop_freelist;
    rtems_libio_iop_freelist = iop->data1;
    memset( iop, 0, sizeof(*iop) );
    iop->flags = LIBIO_FLAGS_OPEN;
  }

  rtems_libio_unlock();

  return iop;
}
Exemplo n.º 7
0
static int open_files(void)
{
  int free_count = 0;
  rtems_libio_t *iop;

  rtems_libio_lock();

  iop = rtems_libio_iop_freelist;
  while (iop != NULL) {
    ++free_count;

    iop = iop->data1;
  }

  rtems_libio_unlock();

  return (int) rtems_libio_number_iops - free_count;
}
Exemplo n.º 8
0
Arquivo: libio.c Projeto: gedare/rtems
rtems_libio_t *rtems_libio_allocate( void )
{
  rtems_libio_t *iop;

  rtems_libio_lock();

  iop = rtems_libio_iop_free_head;

  if ( iop != NULL ) {
    void *next;

    next = iop->data1;
    rtems_libio_iop_free_head = next;

    if ( next == NULL ) {
      rtems_libio_iop_free_tail = &rtems_libio_iop_free_head;
    }
  }

  rtems_libio_unlock();

  return iop;
}
Exemplo n.º 9
0
bool rtems_filesystem_mount_iterate(
  rtems_per_filesystem_mount_routine routine,
  void *routine_arg
)
{
  rtems_chain_node *node = NULL;
  bool stop = false;

  rtems_libio_lock();
  for (
    node = rtems_chain_first( &mount_chain );
    !rtems_chain_is_tail( &mount_chain, node ) && !stop;
    node = rtems_chain_next( node )
  ) {
    const rtems_filesystem_mount_table_entry_t *mt_entry =
      (rtems_filesystem_mount_table_entry_t *) node;

    stop = (*routine)( mt_entry, routine_arg );
  }
  rtems_libio_unlock();

  return stop;
}
Exemplo n.º 10
0
void rtems_filesystem_default_unlock(
  const rtems_filesystem_mount_table_entry_t *mt_entry
)
{
  rtems_libio_unlock();
}
Exemplo n.º 11
0
int mount(
  const char                 *source,
  const char                 *target,
  const char                 *filesystemtype,
  rtems_filesystem_options_t options,
  const void                 *data
)
{
  rtems_filesystem_fsmount_me_t mount_h = NULL;
  rtems_filesystem_location_info_t      loc;
  rtems_filesystem_mount_table_entry_t *mt_entry = NULL;
  rtems_filesystem_location_info_t     *loc_to_free = NULL;
  bool has_target = target != NULL;
  size_t target_length = 0;

  /*
   *  Are the file system options valid?
   */

  if ( options != RTEMS_FILESYSTEM_READ_ONLY &&
       options != RTEMS_FILESYSTEM_READ_WRITE )
    rtems_set_errno_and_return_minus_one( EINVAL );

  /*
   *  Get mount handler
   */
  mount_h = rtems_filesystem_get_mount_handler( filesystemtype );
  if ( !mount_h )
    rtems_set_errno_and_return_minus_one( EINVAL );

  /*
   * Allocate a mount table entry
   */
  mt_entry = alloc_mount_table_entry(
    source,
    target,
    filesystemtype,
    &target_length
  );
  if ( !mt_entry )
    rtems_set_errno_and_return_minus_one( ENOMEM );

  mt_entry->mt_fs_root.mt_entry = mt_entry;
  mt_entry->options = options;
  mt_entry->pathconf_limits_and_options = rtems_filesystem_default_pathconf;

  /*
   *  The mount_point should be a directory with read/write/execute
   *  permissions in the existing tree.
   */

  if ( has_target ) {
    if ( rtems_filesystem_evaluate_path(
           target, target_length, RTEMS_LIBIO_PERMS_RWX, &loc, true ) == -1 )
      goto cleanup_and_bail;

    loc_to_free = &loc;

    /*
     * Test for node_type_h
     */

    if (!loc.ops->node_type_h) {
      errno =  ENOTSUP;
      goto cleanup_and_bail;
    }

    /*
     *  Test to see if it is a directory
     */

    if ( loc.ops->node_type_h( &loc ) != RTEMS_FILESYSTEM_DIRECTORY ) {
      errno = ENOTDIR;
      goto cleanup_and_bail;
    }

    /*
     *  You can only mount one file system onto a single mount point.
     */

    if ( rtems_filesystem_mount_iterate( is_node_fs_root, loc.node_access ) ) {
      errno = EBUSY;
      goto cleanup_and_bail;
    }

    /*
     *  This must be a good mount point, so move the location information
     *  into the allocated mount entry.  Note:  the information that
     *  may have been allocated in loc should not be sent to freenode
     *  until the system is unmounted.  It may be needed to correctly
     *  traverse the tree.
     */

    mt_entry->mt_point_node.node_access = loc.node_access;
    mt_entry->mt_point_node.handlers = loc.handlers;
    mt_entry->mt_point_node.ops = loc.ops;
    mt_entry->mt_point_node.mt_entry = loc.mt_entry;

    /*
     *  This link to the parent is only done when we are dealing with system
     *  below the base file system
     */

    if ( !loc.ops->mount_h ){
      errno = ENOTSUP;
      goto cleanup_and_bail;
    }

    if ( loc.ops->mount_h( mt_entry ) ) {
      goto cleanup_and_bail;
    }
  } else {
    /*
     * Do we already have a base file system ?
     */
    if ( !rtems_chain_is_empty( &mount_chain ) ) {
      errno = EINVAL;
      goto cleanup_and_bail;
    }

    /*
     *  This is a mount of the base file system --> The
     *  mt_point_node.node_access will be left to null to indicate that this
     *  is the root of the entire file system.
     */
  }

  if ( (*mount_h)( mt_entry, data ) ) {
    /*
     * Try to undo the mount operation
     */
    if ( loc.ops->unmount_h ) {
      loc.ops->unmount_h( mt_entry );
    }
    goto cleanup_and_bail;
  }

  /*
   *  Add the mount table entry to the mount table chain
   */
  rtems_libio_lock();
  rtems_chain_append( &mount_chain, &mt_entry->Node );
  rtems_libio_unlock();

  if ( !has_target )
    rtems_filesystem_root = mt_entry->mt_fs_root;

  return 0;

cleanup_and_bail:

  free( mt_entry );

  if ( loc_to_free )
    rtems_filesystem_freenode( loc_to_free );

  return -1;
}
Exemplo n.º 12
0
int unmount(
    const char *path
)
{
    rtems_filesystem_location_info_t      loc;
    rtems_filesystem_location_info_t     *fs_root_loc;
    rtems_filesystem_location_info_t     *fs_mount_loc;
    rtems_filesystem_mount_table_entry_t *mt_entry;

    /*
     *  Get
     *    The root node of the mounted filesytem.
     *    The node for the directory that the fileystem is mounted on.
     *    The mount entry that is being refered to.
     */

    if ( rtems_filesystem_evaluate_path( path, strlen( path ), 0x0, &loc, true ) )
        return -1;

    mt_entry     = loc.mt_entry;
    fs_mount_loc = &mt_entry->mt_point_node;
    fs_root_loc  = &mt_entry->mt_fs_root;

    /*
     * Verify this is the root node for the file system to be unmounted.
     */

    if ( fs_root_loc->node_access != loc.node_access ) {
        rtems_filesystem_freenode( &loc );
        rtems_set_errno_and_return_minus_one( EACCES );
    }

    /*
     * Free the loc node and just use the nodes from the mt_entry .
     */

    rtems_filesystem_freenode( &loc );

    /*
     * Verify Unmount is supported by both filesystems.
     */

    if ( !fs_mount_loc->ops->unmount_h )
        rtems_set_errno_and_return_minus_one( ENOTSUP );

    if ( !fs_root_loc->ops->fsunmount_me_h )
        rtems_set_errno_and_return_minus_one( ENOTSUP );


    /*
     *  Verify the current node is not in this filesystem.
     *  XXX - Joel I have a question here wasn't code added
     *        that made the current node thread based instead
     *        of system based?  I thought it was but it doesn't
     *        look like it in this version.
     */

    if ( rtems_filesystem_current.mt_entry == mt_entry )
        rtems_set_errno_and_return_minus_one( EBUSY );

    /*
     *  Verify there are no file systems below the path specified
     */

    if ( rtems_filesystem_mount_iterate( is_fs_below_mount_point,
                                         fs_root_loc->mt_entry ) )
        rtems_set_errno_and_return_minus_one( EBUSY );

    /*
     *  Run the file descriptor table to determine if there are any file
     *  descriptors that are currently active and reference nodes in the
     *  file system that we are trying to unmount
     */

    if ( rtems_libio_is_open_files_in_fs( mt_entry ) == 1 )
        rtems_set_errno_and_return_minus_one( EBUSY );

    /*
     * Allow the file system being unmounted on to do its cleanup.
     * If it fails it will set the errno to the approprate value
     * and the fileystem will not be modified.
     */

    if (( fs_mount_loc->ops->unmount_h )( mt_entry ) != 0 )
        return -1;

    /*
     *  Allow the mounted filesystem to unmark the use of the root node.
     *
     *  Run the unmount function for the subordinate file system.
     *
     *  If we fail to unmount the filesystem remount it on the base filesystems
     *  directory node.
     *
     *  NOTE:  Fatal error is called in a case which should never happen
     *         This was response was questionable but the best we could
     *         come up with.
     */

    if ((fs_root_loc->ops->fsunmount_me_h )( mt_entry ) != 0) {
        if (( fs_mount_loc->ops->mount_h )( mt_entry ) != 0 )
            rtems_fatal_error_occurred( 0 );
        return -1;
    }

    /*
     *  Extract the mount table entry from the chain
     */

    rtems_libio_lock();
    rtems_chain_extract( &mt_entry->Node );
    rtems_libio_unlock();

    /*
     *  Free the memory node that was allocated in mount
     *  Free the memory associated with the extracted mount table entry.
     */

    rtems_filesystem_freenode( fs_mount_loc );
    free( mt_entry );

    return 0;
}