summaryrefslogtreecommitdiff
path: root/nuttx/fs/fs_inode.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-03-14 22:41:09 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-03-14 22:41:09 +0000
commit1df59ef5f64b5af480e4048e904f65d0682fc56b (patch)
tree9d9bab896ace384c17eb83026921f5e8218bae8c /nuttx/fs/fs_inode.c
parent78cbcfd2a16c0cf3763173ce0a14d656bede0135 (diff)
downloadpx4-nuttx-1df59ef5f64b5af480e4048e904f65d0682fc56b.tar.gz
px4-nuttx-1df59ef5f64b5af480e4048e904f65d0682fc56b.tar.bz2
px4-nuttx-1df59ef5f64b5af480e4048e904f65d0682fc56b.zip
Added opendir, readdir, closedir, etc.
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@62 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs/fs_inode.c')
-rw-r--r--nuttx/fs/fs_inode.c419
1 files changed, 83 insertions, 336 deletions
diff --git a/nuttx/fs/fs_inode.c b/nuttx/fs/fs_inode.c
index c6d673190..10936c8be 100644
--- a/nuttx/fs/fs_inode.c
+++ b/nuttx/fs/fs_inode.c
@@ -34,10 +34,6 @@
************************************************************/
/************************************************************
- * Compilation Switches
- ************************************************************/
-
-/************************************************************
* Included Files
************************************************************/
@@ -56,9 +52,6 @@
* Definitions
************************************************************/
-#define INODE_SEMGIVE() \
- sem_post(&tree_sem)
-
/************************************************************
* Private Variables
************************************************************/
@@ -75,21 +68,9 @@ FAR struct inode *root_inode = NULL;
* Private Functions
************************************************************/
-static void _inode_semtake(void)
-{
- /* Take the semaphore (perhaps waiting) */
-
- while (sem_wait(&tree_sem) != 0)
- {
- /* The only case that an error should occr here is if
- * the wait was awakened by a signal.
- */
-
- ASSERT(*get_errno_ptr() == EINTR);
- }
-}
-
-#define _inode_semgive(void) sem_post(&tree_sem)
+/************************************************************
+ * Name: _inode_compare
+ ************************************************************/
static int _inode_compare(const char *fname,
FAR struct inode *node)
@@ -152,49 +133,79 @@ static int _inode_compare(const char *fname,
}
}
-static int _inode_namelen(const char *name)
-{
- const char *tmp = name;
- while(*tmp && *tmp != '/') tmp++;
- return tmp - name;
-}
+/************************************************************
+ * Public Functions
+ ************************************************************/
-static void _inode_namecpy(char *dest, const char *src)
-{
- while(*src && *src != '/') *dest++ = *src++;
- *dest='\0';
-}
+/************************************************************
+ * Name: fs_initialize
+ *
+ * Description:
+ * This is called from the OS initialization logic to configure
+ * the file system.
+ *
+ ************************************************************/
-static const char *_inode_nextname(const char *name)
+void fs_initialize(void)
{
- while (*name && *name != '/') name++;
- if (*name) name++;
- return name;
+ /* Initialize the semaphore to one (to support one-at-
+ * a-time access to the inode tree).
+ */
+
+ (void)sem_init(&tree_sem, 0, 1);
+
+ /* Initialize files array (if it is used) */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (files_initialize != NULL)
+#endif
+ {
+ files_initialize();
+ }
}
-static FAR struct inode *_inode_alloc(const char *name,
- struct file_operations *fops,
- mode_t mode, void *private)
+/************************************************************
+ * Name: inode_semtake
+ ************************************************************/
+
+void inode_semtake(void)
{
- int namelen = _inode_namelen(name);
- FAR struct inode *node = (FAR struct inode*)malloc(FSNODE_SIZE(namelen));
- if (node)
+ /* Take the semaphore (perhaps waiting) */
+
+ while (sem_wait(&tree_sem) != 0)
{
- node->i_peer = NULL;
- node->i_child = NULL;
- node->i_ops = fops;
-#ifdef CONFIG_FILE_MODE
- node->i_mode = mode;
-#endif
- node->i_private = private;
- _inode_namecpy(node->i_name, name);
+ /* The only case that an error should occr here is if
+ * the wait was awakened by a signal.
+ */
+
+ ASSERT(*get_errno_ptr() == EINTR);
}
- return node;
}
-static FAR struct inode *_inode_find(const char **path,
- FAR struct inode **peer,
- FAR struct inode **parent)
+/************************************************************
+ * Name: inode_semgive
+ ************************************************************/
+
+void inode_semgive(void)
+{
+ sem_post(&tree_sem);
+}
+
+/************************************************************
+ * Name: inode_search
+ *
+ * Description:
+ * Find the inode associated with 'path' returning the
+ * inode references and references to its companion nodes.
+ *
+ * Assumptions:
+ * The caller holds the tree_sem
+ *
+ ************************************************************/
+
+FAR struct inode *inode_search(const char **path,
+ FAR struct inode **peer,
+ FAR struct inode **parent)
{
const char *name = *path + 1; /* Skip over leading '/' */
FAR struct inode *node = root_inode;
@@ -237,7 +248,7 @@ static FAR struct inode *_inode_find(const char **path,
* (2) the node we are looking for is "blow" this one.
*/
- name = _inode_nextname(name);
+ name = inode_nextname(name);
if (!*name)
{
/* We are at the end of the path, so this must be
@@ -278,296 +289,32 @@ static FAR struct inode *_inode_find(const char **path,
return node;
}
-static void _inode_insert(FAR struct inode *node,
- FAR struct inode *peer,
- FAR struct inode *parent)
-{
- /* If peer is non-null, then new node simply goes to the right
- * of that peer node.
- */
-
- if (peer)
- {
- node->i_peer = peer->i_peer;
- peer->i_peer = node;
- }
-
- /* If parent is non-null, then it must go at the head of its
- * list of children.
- */
-
- else if (parent)
- {
- node->i_peer = parent->i_child;
- parent->i_child = node;
- }
-
- /* Otherwise, this must be the new root_inode */
-
- else
- {
- node->i_peer = root_inode;
- root_inode = node;
- }
-}
-
-static void _inode_remove(struct inode *node,
- struct inode *peer,
- struct inode *parent)
-{
- /* 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;
-}
+/************************************************************
+ * Name: inode_free
+ ************************************************************/
-static void _inode_free(FAR struct inode *node)
+void inode_free(FAR struct inode *node)
{
if (node)
{
- _inode_free(node->i_peer);
- _inode_free(node->i_child);
+ inode_free(node->i_peer);
+ inode_free(node->i_child);
free(node);
}
}
/************************************************************
- * Public Functions
+ * Name: inode_nextname
+ *
+ * Description:
+ * Given a path with node names separated by '/', return
+ * the next node name.
+ *
************************************************************/
-/* This is called from the OS initialization logic to configure
- * the file system.
- */
-
-void fs_initialize(void)
+const char *inode_nextname(const char *name)
{
- /* Initialize the semaphore to one (to support one-at-
- * a-time access to the inode tree).
- */
-
- (void)sem_init(&tree_sem, 0, 1);
-
- /* Initialize files array (if it is used) */
-
-#ifdef CONFIG_HAVE_WEAKFUNCTIONS
- if (files_initialize != NULL)
-#endif
- {
- files_initialize();
- }
-}
-
-/* This is called from the open() logic to get a reference
- * to the inode associatged with a path.
- */
-
-FAR struct inode *inode_find(const char *path)
-{
- 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_find(&path, (FAR void*)NULL, (FAR void*)NULL);
- if (node) node->i_crefs++;
- _inode_semgive();
- return node;
-}
-
-/* Increment the reference count on an inode (as when a file
- * descriptor is dup'ed.
- */
-
-void inode_addref(FAR struct inode *inode)
-{
- if (inode)
- {
- _inode_semtake();
- inode->i_crefs++;
- _inode_semgive();
- }
-}
-
-/* This is called from close() logic when it no longer refers
- * to the inode.
- */
-
-void inode_release(FAR struct inode *node)
-{
- if (node)
- {
- /* Decrement the references of the inode */
-
- _inode_semtake();
- if (node->i_crefs)
- {
- node->i_crefs--;
- }
-
- /* If the subtree was previously deleted and the reference
- * count has decrement to zero, then delete the inode
- * now.
- */
-
- if (node->i_crefs <= 0 && (node->i_flags & FSNODEFLAG_DELETED) != 0)
- {
- _inode_semgive();
- _inode_free(node->i_child);
- free(node);
- }
- else
- {
- _inode_semgive();
- }
- }
-}
-
-
-STATUS register_inode(const char *path,
- struct file_operations *fops,
- mode_t mode, void *private)
-{
- const char *name = path;
- FAR struct inode *left;
- FAR struct inode *parent;
-
- if (!*path || path[0] != '/')
- {
- return ERROR;
- }
-
- /* Find the location to insert the new subtree */
-
- _inode_semtake();
- if (_inode_find(&name, &left, &parent) != NULL)
- {
- /* Is is an error if the node already exists in the tree */
-
- _inode_semgive();
- return ERROR;
- }
-
- /* 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.
- */
-
- const char *next_name = _inode_nextname(name);
- if (*next_name)
- {
- /* Insert an operationless node */
-
- node = _inode_alloc(name, NULL, mode, NULL);
- 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, fops, mode, private);
- if (node)
- {
- _inode_insert(node, left, parent);
- _inode_semgive();
- return 0;
- }
- }
-
- /* We get here on failures to allocate node memory */
-
- _inode_semgive();
- return ERROR;
- }
-}
-
-STATUS unregister_inode(const char *path)
-{
- const char *name = path;
- FAR struct inode *node;
- FAR struct inode *left;
- FAR struct inode *parent;
-
- if (*path && path[0] == '/')
- {
- return ERROR;
- }
-
- /* Find the node to delete */
-
- _inode_semtake();
- node = _inode_find(&name, &left, &parent);
- if (node)
- {
- /* Found it, now remove it from the tree */
-
- _inode_remove(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;
- _inode_semgive();
- }
- else
- {
- /* And delete it now -- recursively to delete all of its children */
-
- _inode_semgive();
- _inode_free(node->i_child);
- free(node);
- return OK;
- }
- }
-
- /* The node does not exist or it has references */
- _inode_semgive();
- return ERROR;
+ while (*name && *name != '/') name++;
+ if (*name) name++;
+ return name;
}