Esempio n. 1
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;
}
Esempio n. 2
0
static int
rtems_rfs_write_root_dir (const char* name)
{
  rtems_rfs_file_system* fs;
  rtems_rfs_inode_handle inode;
  rtems_rfs_ino          ino;
  int                    rc;

  /*
   * External API so returns -1.
   */
  rc = rtems_rfs_fs_open (name, NULL, RTEMS_RFS_FS_FORCE_OPEN, &fs);
  if (rc < 0)
  {
    printf ("rtems-rfs: format: file system open failed: %d: %s\n",
            errno, strerror (errno));
    return -1;
  }
  
  rc = rtems_rfs_inode_alloc (fs, RTEMS_RFS_ROOT_INO, &ino);
  if (rc > 0)
  {
    printf ("rtems-rfs: format: inode allocation failed: %d: %s\n",
            rc, strerror (rc));
    rtems_rfs_fs_close (fs);
    return rc;
  }

  if (ino != RTEMS_RFS_ROOT_INO)
  {
    printf ("rtems-rfs: format: allocated inode not root ino: %" PRId32 "\n", ino);
    rtems_rfs_fs_close (fs);
    return rc;
  }
  
  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
  if (rc > 0)
  {
    printf ("rtems-rfs: format: inode open failed: %d: %s\n",
            rc, strerror (rc));
    rtems_rfs_group_bitmap_free (fs, true, ino);
    rtems_rfs_fs_close (fs);
    return rc;
  }

  rc = rtems_rfs_inode_initialise (&inode, 0,
                                   (RTEMS_RFS_S_IFDIR | RTEMS_RFS_S_IRWXU |
                                    RTEMS_RFS_S_IXGRP | RTEMS_RFS_S_IXOTH),
                                   0, 0);
  if (rc > 0)
    printf ("rtems-rfs: format: inode initialise failed: %d: %s\n",
            rc, strerror (rc));
  
  rc = rtems_rfs_dir_add_entry (fs, &inode, ".", 1, ino);
  if (rc > 0)
    printf ("rtems-rfs: format: directory add failed: %d: %s\n",
            rc, strerror (rc));
  
  rc = rtems_rfs_inode_close (fs, &inode);
  if (rc > 0)
    printf ("rtems-rfs: format: inode close failed: %d: %s\n",
            rc, strerror (rc));
  
  rc = rtems_rfs_fs_close (fs);
  if (rc < 0)
    printf ("rtems-rfs: format: file system close failed: %d: %s\n",
            errno, strerror (errno));
  
  return rc;
}