Esempio n. 1
0
int mount(
  const char                 *source,
  const char                 *target,
  const char                 *filesystemtype,
  rtems_filesystem_options_t options,
  const void                 *data
)
{
  int rv = 0;

  if (
    options == RTEMS_FILESYSTEM_READ_ONLY
      || options == RTEMS_FILESYSTEM_READ_WRITE
  ) {
    rtems_filesystem_fsmount_me_t fsmount_me_h =
      rtems_filesystem_get_mount_handler( filesystemtype );

    if ( fsmount_me_h != NULL ) {
      size_t target_length = 0;
      rtems_filesystem_mount_table_entry_t *mt_entry = alloc_mount_table_entry(
        source,
        target,
        filesystemtype,
        &target_length
      );

      if ( mt_entry != NULL ) {
        mt_entry->writeable = options == RTEMS_FILESYSTEM_READ_WRITE;

        rv = (*fsmount_me_h)( mt_entry, data );
        if ( rv == 0 ) {
          if ( target != NULL ) {
            rv = register_subordinate_file_system( mt_entry, target );
          } else {
            rv = register_root_file_system( mt_entry );
          }

          if ( rv != 0 ) {
            (*mt_entry->ops->fsunmount_me_h)( mt_entry );
          }
        }

        if ( rv != 0 ) {
          free( mt_entry );
        }
      } else {
        errno = ENOMEM;
        rv = -1;
      }
    } else {
      errno = EINVAL;
      rv = -1;
    }
  } else {
    errno = EINVAL;
    rv = -1;
  }

  return rv;
}
Esempio n. 2
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;
}