示例#1
0
static rtems_filesystem_node_types_t
rtems_rfs_rtems_node_type_by_inode (rtems_rfs_inode_handle* inode)
{
  /*
   * Do not return RTEMS_FILESYSTEM_HARD_LINK because this would result in an
   * eval link which does not make sense in the case of the RFS file
   * system. All directory entries are links to an inode. A link such as a HARD
   * link is actually the normal path to a regular file, directory, device
   * etc's inode. Links to inodes can be considered "the real" one, yet they
   * are all links.
   */
  uint16_t mode = rtems_rfs_inode_get_mode (inode);
  if (RTEMS_RFS_S_ISDIR (mode))
    return RTEMS_FILESYSTEM_DIRECTORY;
  else if (RTEMS_RFS_S_ISLNK (mode))
    return RTEMS_FILESYSTEM_SYM_LINK;
  else if (RTEMS_RFS_S_ISBLK (mode) || RTEMS_RFS_S_ISCHR (mode))
    return RTEMS_FILESYSTEM_DEVICE;
  else
    return RTEMS_FILESYSTEM_MEMORY_FILE;
}
示例#2
0
bool
rtems_rfs_rtems_set_handlers (rtems_filesystem_location_info_t* loc,
                              rtems_rfs_inode_handle*           inode)
{
  uint16_t mode = rtems_rfs_inode_get_mode (inode);
  loc->handlers = NULL;
  if (RTEMS_RFS_S_ISDIR (mode))
    loc->handlers = rtems_rfs_rtems_handlers (dir);
  else if (RTEMS_RFS_S_ISCHR (mode) || RTEMS_RFS_S_ISBLK(mode))
    loc->handlers = rtems_rfs_rtems_handlers (device);
  else if (RTEMS_RFS_S_ISLNK (mode))
    loc->handlers = rtems_rfs_rtems_handlers (link);
  else if (RTEMS_RFS_S_ISREG (mode))
    loc->handlers = rtems_rfs_rtems_handlers (file);
  else
  {
    printf ("rtems-rfs: mode type unknown: %04x\n", mode);
    return false;
  }
  return true;
}
示例#3
0
int
rtems_rfs_inode_create (rtems_rfs_file_system*  fs,
                        rtems_rfs_ino           parent,
                        const char*             name,
                        size_t                  length,
                        uint16_t                mode,
                        uint16_t                links,
                        uid_t                   uid,
                        gid_t                   gid,
                        rtems_rfs_ino*          ino)
{
  rtems_rfs_inode_handle parent_inode;
  rtems_rfs_inode_handle inode;
  int                    rc;

  if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_CREATE))
  {
    const char* type = "unknown";
    int         c;
    if (RTEMS_RFS_S_ISDIR (mode))
      type = "dir";
    else if (RTEMS_RFS_S_ISCHR (mode))
      type = "char";
    else if (RTEMS_RFS_S_ISBLK (mode))
      type = "block";
    else if (RTEMS_RFS_S_ISREG (mode))
      type = "file";
    else if (RTEMS_RFS_S_ISLNK (mode))
      type = "link";
    printf("rtems-rfs: inode-create: parent:%" PRIu32 " name:", parent);
    for (c = 0; c < length; c++)
      printf ("%c", name[c]);
    printf (" type:%s mode:%04x (%03o)\n", type, mode, mode & ((1 << 10) - 1));
  }

  /*
   * The file type is field within the mode. Check we have a sane mode set.
   */
  switch (mode & RTEMS_RFS_S_IFMT)
  {
    case RTEMS_RFS_S_IFDIR:
    case RTEMS_RFS_S_IFCHR:
    case RTEMS_RFS_S_IFBLK:
    case RTEMS_RFS_S_IFREG:
    case RTEMS_RFS_S_IFLNK:
      break;
    default:
      return EINVAL;
  }

  rc = rtems_rfs_inode_alloc (fs, parent, ino);
  if (rc > 0)
    return rc;

  rc = rtems_rfs_inode_open (fs, *ino, &inode, true);
  if (rc > 0)
  {
    rtems_rfs_inode_free (fs, *ino);
    return rc;
  }

  rc = rtems_rfs_inode_initialise (&inode, links, mode, uid, gid);
  if (rc > 0)
  {
    rtems_rfs_inode_close (fs, &inode);
    rtems_rfs_inode_free (fs, *ino);
    return rc;
  }

  /*
   * Only handle the specifics of a directory. Let caller handle the others.
   *
   * The inode delete will free the inode.
   */
  if (RTEMS_RFS_S_ISDIR (mode))
  {
    rc = rtems_rfs_dir_add_entry (fs, &inode, ".", 1, *ino);
    if (rc == 0)
      rc = rtems_rfs_dir_add_entry (fs, &inode, "..", 2, parent);
    if (rc > 0)
    {
      rtems_rfs_inode_delete (fs, &inode);
      rtems_rfs_inode_close (fs, &inode);
      return rc;
    }
  }

  rc = rtems_rfs_inode_open (fs, parent, &parent_inode, true);
  if (rc > 0)
  {
    rtems_rfs_inode_delete (fs, &inode);
    rtems_rfs_inode_close (fs, &inode);
    return rc;
  }

  rc = rtems_rfs_dir_add_entry (fs, &parent_inode, name, length, *ino);
  if (rc > 0)
  {
    rtems_rfs_inode_delete (fs, &inode);
    rtems_rfs_inode_close (fs, &inode);
    rtems_rfs_inode_close (fs, &parent_inode);
    return rc;
  }

  /*
   * If the node is a directory update the parent link count as the
   * new directory has the '..' link that points to the parent.
   */
  if (RTEMS_RFS_S_ISDIR (mode))
    rtems_rfs_inode_set_links (&parent_inode,
                               rtems_rfs_inode_get_links (&parent_inode) + 1);

  rc = rtems_rfs_inode_close (fs, &parent_inode);
  if (rc > 0)
  {
    rtems_rfs_inode_delete (fs, &inode);
    rtems_rfs_inode_close (fs, &inode);
    return rc;
  }

  rc = rtems_rfs_inode_close (fs, &inode);
  if (rc > 0)
  {
    rtems_rfs_inode_free (fs, *ino);
    return rc;
  }

  return 0;
}
示例#4
0
int
rtems_rfs_symlink_read (rtems_rfs_file_system* fs,
                        rtems_rfs_ino          link,
                        char*                  path,
                        size_t                 size,
                        size_t*                length)
{
  rtems_rfs_inode_handle inode;
  int                    rc;

  if (rtems_rfs_trace (RTEMS_RFS_TRACE_SYMLINK_READ))
    printf ("rtems-rfs: symlink-read: link:%" PRIu32 "\n", link);

  rc = rtems_rfs_inode_open (fs, link, &inode, true);
  if (rc)
    return rc;

  if (!RTEMS_RFS_S_ISLNK (rtems_rfs_inode_get_mode (&inode)))
  {
    rtems_rfs_inode_close (fs, &inode);
    return EINVAL;
  }

  *length = rtems_rfs_inode_get_block_offset (&inode);

  if (size < *length)
  {
    *length = size;
  }

  if (rtems_rfs_inode_get_block_count (&inode) == 0)
  {
    memcpy (path, inode.node->data.name, *length);
  }
  else
  {
    rtems_rfs_block_map     map;
    rtems_rfs_block_no      block;
    rtems_rfs_buffer_handle buffer;
    char*                   data;

    rc = rtems_rfs_block_map_open (fs, &inode, &map);
    if (rc > 0)
    {
      rtems_rfs_inode_close (fs, &inode);
      return rc;
    }

    rc = rtems_rfs_block_map_seek (fs, &map, 0, &block);
    if (rc > 0)
    {
      rtems_rfs_block_map_close (fs, &map);
      rtems_rfs_inode_close (fs, &inode);
      return rc;
    }

    rc = rtems_rfs_buffer_handle_open (fs, &buffer);
    if (rc > 0)
    {
      rtems_rfs_block_map_close (fs, &map);
      rtems_rfs_inode_close (fs, &inode);
      return rc;
    }

    rc = rtems_rfs_buffer_handle_request (fs, &buffer, block, false);
    if (rc > 0)
    {
      rtems_rfs_block_map_close (fs, &map);
      rtems_rfs_inode_close (fs, &inode);
      return rc;
    }

    data = rtems_rfs_buffer_data (&buffer);
    memcpy (path, data, *length);

    rc = rtems_rfs_buffer_handle_close (fs, &buffer);
    if (rc > 0)
    {
      rtems_rfs_block_map_close (fs, &map);
      rtems_rfs_inode_close (fs, &inode);
      return rc;
    }

    rc = rtems_rfs_block_map_close (fs, &map);
    if (rc > 0)
    {
      rtems_rfs_inode_close (fs, &inode);
      return rc;
    }
  }

  rc = rtems_rfs_inode_close (fs, &inode);

  return rc;
}
示例#5
0
static int
rtems_rfs_shell_inode (rtems_rfs_file_system* fs, int argc, char *argv[])
{
  rtems_rfs_ino start;
  rtems_rfs_ino end;
  rtems_rfs_ino total;
  rtems_rfs_ino ino;
  bool          show_all;
  bool          error_check_only;
  bool          forced;
  bool          have_start;
  bool          have_end;
  int           arg;
  int           b;
  int           rc;

  total = fs->group_inodes * fs->group_count;
  start = RTEMS_RFS_ROOT_INO;
  end = total - 1;
  show_all = false;
  error_check_only = false;
  forced = false;
  have_start = have_end = false;

  for (arg = 1; arg < argc; arg++)
  {
    if (argv[arg][0] == '-')
    {
      switch (argv[arg][1])
      {
        case 'a':
          show_all = true;
          break;
        case 'e':
          error_check_only = true;
          break;
        case 'f':
          forced = true;
          break;
        default:
          printf ("warning: option ignored: %s\n", argv[arg]);
          break;
      }
    }
    else
    {
      if (have_end && have_start)
        printf ("warning: option ignored: %s\n", argv[arg]);
      else if (!have_start)
      {
        start = end = strtoul (argv[arg], 0, 0);
        have_start = true;
      }
      else
      {
        end = strtoul (argv[arg], 0, 0);
        have_end = true;
      }
    }
  }

  if ((start >= total) || (end >= total))
  {
    printf ("error: inode out of range (0->%" PRId32 ").\n", total - 1);
    return 1;
  }

  rtems_rfs_shell_lock_rfs (fs);
  
  for (ino = start; ino <= end; ino++)
  {
    rtems_rfs_inode_handle inode;
    bool                   allocated;

    rc = rtems_rfs_group_bitmap_test (fs, true, ino, &allocated);
    if (rc > 0)
    {
      rtems_rfs_shell_unlock_rfs (fs);
      printf ("error: testing inode state: ino=%" PRIu32 ": (%d) %s\n",
              ino, rc, strerror (rc));
      return 1;
    }

    if (show_all || allocated)
    {
      uint16_t mode;
      bool     error;

      rc = rtems_rfs_inode_open (fs, ino, &inode, true);
      if (rc > 0)
      {
        rtems_rfs_shell_unlock_rfs (fs);
        printf ("error: opening inode handle: ino=%" PRIu32 ": (%d) %s\n",
                ino, rc, strerror (rc));
        return 1;
      }

      error = false;
      
      mode = rtems_rfs_inode_get_mode (&inode);

      if (error_check_only)
      {
        if (!RTEMS_RFS_S_ISDIR (mode) &&
            !RTEMS_RFS_S_ISCHR (mode) &&
            !RTEMS_RFS_S_ISBLK (mode) &&
            !RTEMS_RFS_S_ISREG (mode) &&
            !RTEMS_RFS_S_ISLNK (mode))
          error = true;
        else
        {
#if NEED_TO_HANDLE_DIFFERENT_TYPES
          int b;
          for (b = 0; b < RTEMS_RFS_INODE_BLOCKS; b++)
          {
            uint32_t block;
            block = rtems_rfs_inode_get_block (&inode, b);
            if ((block <= RTEMS_RFS_SUPERBLOCK_SIZE) ||
                (block >= rtems_rfs_fs_blocks (fs)))
              error = true;
          }
#endif
        }
      }

      if (!error_check_only || error)
      {
        printf (" %5" PRIu32 ": pos=%06" PRIu32 ":%04zx %c ",
                ino, rtems_rfs_buffer_bnum (&inode.buffer),
                inode.offset * RTEMS_RFS_INODE_SIZE,
                allocated ? 'A' : 'F');
    
        if (!allocated && !forced)
          printf (" --\n");
        else
        {      
          const char* type;
          type = "UKN";
          if (RTEMS_RFS_S_ISDIR (mode))
            type = "DIR";
          else if (RTEMS_RFS_S_ISCHR (mode))
            type = "CHR";
          else if (RTEMS_RFS_S_ISBLK (mode))
            type = "BLK";
          else if (RTEMS_RFS_S_ISREG (mode))
            type = "REG";
          else if (RTEMS_RFS_S_ISLNK (mode))
            type = "LNK";
          printf ("links=%03i mode=%04x (%s/%03o) bo=%04u bc=%04" PRIu32 " b=[",
                  rtems_rfs_inode_get_links (&inode),
                  mode, type, mode & ((1 << 10) - 1),
                  rtems_rfs_inode_get_block_offset (&inode),
                  rtems_rfs_inode_get_block_count (&inode));
          for (b = 0; b < (RTEMS_RFS_INODE_BLOCKS - 1); b++)
            printf ("%" PRIu32 " ", rtems_rfs_inode_get_block (&inode, b));
          printf ("%" PRIu32 "]\n", rtems_rfs_inode_get_block (&inode, b));
        }
      }
      
      rc = rtems_rfs_inode_close (fs, &inode);
      if (rc > 0)
      {
        rtems_rfs_shell_unlock_rfs (fs);
        printf ("error: closing inode handle: ino=%" PRIu32 ": (%d) %s\n",
                ino, rc, strerror (rc));
        return 1;
      }
    }
  }
  
  rtems_rfs_shell_unlock_rfs (fs);
  
  return 0;
}