diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-03-14 22:41:09 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-03-14 22:41:09 +0000 |
commit | 1df59ef5f64b5af480e4048e904f65d0682fc56b (patch) | |
tree | 9d9bab896ace384c17eb83026921f5e8218bae8c /nuttx/fs/fs_inode.c | |
parent | 78cbcfd2a16c0cf3763173ce0a14d656bede0135 (diff) | |
download | px4-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.c | 419 |
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; } |