示例#1
0
FAR struct inode *inode_unlink(FAR const char *path)
{
  const char       *name = path;
  FAR struct inode *node;
  FAR struct inode *peer;
  FAR struct inode *parent;

  /* Verify parameters.  Ignore null paths and relative paths */

  if (!path || *path == '\0' || path[0] != '/')
    {
      return NULL;
    }

  /* Find the node to unlink */

  node = inode_search(&name, &peer, &parent, (const char **)NULL);
  if (node)
    {
      /* If peer is non-null, then remove the node from the right of
       * of that peer node.
       */

      if (peer)
        {
          peer->i_peer = node->i_peer;
        }

      /* If parent is non-null, then remove the node from head of
       * of the list of children.
       */

      else if (parent)
        {
          parent->i_child = node->i_peer;
        }

      /* Otherwise, we must be removing the root inode. */

      else
        {
           root_inode = node->i_peer;
        }

      node->i_peer = NULL;
    }

  return node;
}
int inode_remove(FAR const char *path)
{
  const char       *name = path;
  FAR struct inode *node;
  FAR struct inode *left;
  FAR struct inode *parent;

  if (!*path || path[0] != '/')
    {
      return -EINVAL;
    }

  /* Find the node to delete */

  node = inode_search(&name, &left, &parent, (const char **)NULL);
  if (node)
    {
      /* Found it, now remove it from the tree */

      inode_unlink(node, left, parent);

      /* We cannot delete it if there reference to the inode */

      if (node->i_crefs)
        {
          /* In that case, we will mark it deleted, when the FS
           * releases the inode, we will then, finally delete
           * the subtree.
           */

           node->i_flags |= FSNODEFLAG_DELETED;
           return -EBUSY;
        }
      else
        {
          /* And delete it now -- recursively to delete all of its children */

          inode_free(node->i_child);
          kfree(node);
          return OK;
        }
    }

  /* The node does not exist or it has references */

  return -ENOENT;
}
示例#3
0
FAR struct inode *inode_find(FAR const char *path, FAR const char **relpath)
{
    FAR struct inode *node;

    if (!*path || path[0] != '/')
    {
        return NULL;
    }

    /* Find the node matching the path.  If found,
     * increment the count of references on the node.
     */

    inode_semtake();
    node = inode_search(&path, (FAR struct inode**)NULL, (FAR struct inode**)NULL, relpath);
    if (node)
    {
        node->i_crefs++;
    }
    inode_semgive();
    return node;
}
示例#4
0
FAR DIR *opendir(FAR const char *path)
{
  FAR struct inode *inode = NULL;
  FAR struct fs_dirent_s *dir;
  FAR const char *relpath;
  bool isroot = false;
  int ret;

  /* If we are given 'nothing' then we will interpret this as
   * request for the root inode.
   */

  inode_semtake();
  if (!path || *path == 0 || strcmp(path, "/") == 0)
    {
      inode   = root_inode;
      isroot = true;
      relpath = NULL;
    }
  else
    {
      /* We don't know what to do with relative pathes */

      if (*path != '/')
        {
          ret = -ENOTDIR;
          goto errout_with_semaphore;
        }

      /* Find the node matching the path. */

      inode = inode_search(&path, (FAR struct inode**)NULL, (FAR struct inode**)NULL, &relpath);
    }

  /* Did we get an inode? */

  if (!inode)
    {
      /* 'path' is not a does not exist.*/

      ret = ENOTDIR;
      goto errout_with_semaphore;
    }

  /* Allocate a type DIR -- which is little more than an inode
   * container.
   */

  dir = (FAR struct fs_dirent_s *)kuzalloc(sizeof(struct fs_dirent_s));
  if (!dir)
    {
      /* Insufficient memory to complete the operation.*/

      ret = ENOMEM;
      goto errout_with_semaphore;
    }

  /* Populate the DIR structure and return it to the caller.  The way that
   * we do this depends on whenever this is a "normal" pseudo-file-system
   * inode or a file system mountpoint.
   */

  dir->fd_position = 0;      /* This is the position in the read stream */

  /* First, handle the special case of the root inode.  This must be
   * special-cased here because the root inode might ALSO be a mountpoint.
   */

  if (isroot)
    {
      /* Whatever payload the root inode carries, the root inode is always
       * a directory inode in the pseudo-file system
       */

      open_pseudodir(inode, dir);
    }

  /* Is this a node in the pseudo filesystem? Or a mountpoint?  If the node
   * is the root (isroot == TRUE), then this is a special case.
   */

#ifndef CONFIG_DISABLE_MOUNTPOINT
   else if (INODE_IS_MOUNTPT(inode))
     {
       /* Yes, the node is a file system mountpoint */

      dir->fd_root = inode;  /* Save the inode where we start */

      /* Open the directory at the relative path */

      ret = open_mountpoint(inode, relpath, dir);
      if (ret != OK)
        {
           goto errout_with_direntry;
        }
    }
#endif
  else
    {
      /* The node is part of the root pseudo file system.  Does the inode
       * have a child? If so that the child would be the 'root' of a list
       * of nodes under the directory.
       */

      FAR struct inode *child = inode->i_child;
      if (child)
        {
          /* It looks we have a valid pseudo-filesystem directory node. */

          open_pseudodir(child, dir);
        }
      else if (!inode->u.i_ops)
        {
          /* This is a dangling node with no children and no operations. Set
           * up to enumerate an empty directory.
           */

          open_emptydir(dir);
        }
      else
        {
          ret = ENOTDIR;
          goto errout_with_direntry;
        }
    }

  inode_semgive();
  return ((DIR*)dir);

  /* Nasty goto's make error handling simpler */

errout_with_direntry:
  kufree(dir);

errout_with_semaphore:
  inode_semgive();
  set_errno(ret);
  return NULL;
}
示例#5
0
int inode_reserve(FAR const char *path, FAR struct inode **inode)
{
  const char       *name = path;
  FAR struct inode *left;
  FAR struct inode *parent;

  /* Assume failure */

  DEBUGASSERT(path && inode);
  *inode = NULL;

  /* Handle paths that are interpreted as the root directory */

  if (!*path || path[0] != '/')
    {
      return -EINVAL;
    }

  /* Find the location to insert the new subtree */

  if (inode_search(&name, &left, &parent, (FAR const char **)NULL) != NULL)
    {
      /* It is an error if the node already exists in the tree */

      return -EEXIST;
    }

  /* Now we now where to insert the subtree */

  for (;;)
    {
      FAR struct inode *node;

      /* Create a new node -- we need to know if this is the
       * the leaf node or some intermediary.  We can find this
       * by looking at the next name.
       */

      FAR const char *next_name = inode_nextname(name);
      if (*next_name)
        {
          /* Insert an operationless node */

          node = inode_alloc(name);
          if (node)
            {
              inode_insert(node, left, parent);

              /* Set up for the next time through the loop */

              name   = next_name;
              left   = NULL;
              parent = node;
              continue;
            }
        }
      else
        {
          node = inode_alloc(name);
          if (node)
            {
              inode_insert(node, left, parent);
              *inode = node;
              return OK;
            }
        }

      /* We get here on failures to allocate node memory */

      return -ENOMEM;
    }
}