diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-05-26 16:05:59 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-05-26 16:05:59 +0000 |
commit | 2a3e5f6cd969f93fbb56d7ba2b63d7d8da11e756 (patch) | |
tree | 6ecb4e1b2918a65b64e0d3daef3723d5da1344d1 /nuttx/fs/fs_opendir.c | |
parent | d88d061f01f4238008e4f24910820b63e5bd7c82 (diff) | |
download | px4-nuttx-2a3e5f6cd969f93fbb56d7ba2b63d7d8da11e756.tar.gz px4-nuttx-2a3e5f6cd969f93fbb56d7ba2b63d7d8da11e756.tar.bz2 px4-nuttx-2a3e5f6cd969f93fbb56d7ba2b63d7d8da11e756.zip |
Setting up for mountpoint support
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@250 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs/fs_opendir.c')
-rw-r--r-- | nuttx/fs/fs_opendir.c | 142 |
1 files changed, 132 insertions, 10 deletions
diff --git a/nuttx/fs/fs_opendir.c b/nuttx/fs/fs_opendir.c index b02d97bf7..24462d53b 100644 --- a/nuttx/fs/fs_opendir.c +++ b/nuttx/fs/fs_opendir.c @@ -41,6 +41,7 @@ #include <sys/types.h> #include <stdlib.h> #include <dirent.h> +#include <string.h> #include <errno.h> #include <nuttx/fs.h> #include "fs_internal.h" @@ -50,6 +51,92 @@ ************************************************************/ /************************************************************ + * Name: fs_finddirnode + * + * Description: + * This is called from the opendir() logic to get a reference + * to the inode associated with a directory. There are no + * real directories in this design; For our purposes, a + * directory inode is simply one that has children or one + * that is a mountpoint for a "real" file system + * + ************************************************************/ + +static inline FAR struct inode *fs_finddirnode(const char *path, const char **relpath) +{ + FAR struct inode *node; + FAR struct inode *root = NULL; + + /* If we are given 'nothing' then we will interpret this as + * request for the root inode. + */ + + if (!path || *path == 0 || strcmp(path, "/") == 0) + { + return root_inode; + } + + /* We don't know what to do with relative pathes */ + + if (*path != '/') + { + return NULL; + } + + /* Find the node matching the path. */ + + inode_semtake(); + node = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL, relpath); + if (node) + { + + /* Is this a not in the psuedo filesystem? */ + + if (INODE_IS_MOUNTPT(node)) + { + /* Yes, then return the inode itself as the 'root' of + * the directory. The actually directory is at relpath into the + * mounted filesystem. Increment the count of references + * on the inode. + */ + + root = node; + root->i_crefs++; + } + else + { + /* It is a node in the psuedo filesystem. Does the inode have a child? + * If so that the child would be the 'root' of a list of nodes under + * the directory. + */ + + root = node->i_child; + if (root) + { + /* If found, then increment the count of + * references on the child node. + */ + + root->i_crefs++; + } + } + } + inode_semgive(); + return root; +} + +/************************************************************ + * Name: fs_openmountptdir + ************************************************************/ + +static inline int fs_openmountptdir(struct inode *inode, const char *relpath, + struct internal_dir_s *dir) +{ +#warning "Mountpoint support not implemented" + return -ENOSYS; +} + +/************************************************************ * Public Functions ************************************************************/ @@ -87,18 +174,20 @@ FAR DIR *opendir(const char *path) { FAR struct inode *inode; FAR struct internal_dir_s *dir; + const char *relpath; + int ret; /* Get an inode corresponding to the path. On successful * return, we will hold on reference count on the inode. */ - inode = inode_finddir(path); + inode = fs_finddirnode(path, &relpath); if (!inode) { /* 'path' is not a directory.*/ - *get_errno_ptr() = ENOTDIR; - return NULL; + ret = ENOTDIR; + goto errout; } /* Allocate a type DIR -- which is little more than an inode @@ -110,17 +199,50 @@ FAR DIR *opendir(const char *path) { /* Insufficient memory to complete the operation.*/ - *get_errno_ptr() = ENOMEM; - inode_release(inode); - return NULL; + ret = ENOMEM; + goto errout_with_inode; } - /* Populate the DIR structure and return it to the caller */ + /* Populate the DIR structure and return it to the caller. The way that + * we do this depends on whenever this is a "normal" psuedo-file-system + * inode or a file system mountpoint. + */ + + dir->root = inode; /* Save the inode where we start */ + dir->position = 0; /* This is the position in the read stream */ + + /* Is this a not in the psuedo filesystem? */ + + if (INODE_IS_MOUNTPT(inode)) + { + /* The node is a file system mointpoint */ + + ret = fs_openmountptdir(inode, relpath, dir); + if (ret < 0) + { + ret = -ret; + goto errout_with_direntry; + } + } + else + { + /* The node is part of the root psuedo file system */ + + inode_addref(inode); /* Now we have two references on inode */ + dir->u.psuedo.next = inode; /* This is the next node to use for readdir() */ + } - dir->root = inode; /* Save where we started in case we rewind */ - inode_addref(inode); /* Now we have two references on inode */ - dir->next = inode; /* This is the next node to use for readdir() */ return ((DIR*)dir); + + /* Nasty goto's make error handling simpler */ + +errout_with_direntry: + free(dir); +errout_with_inode: + inode_release(inode); +errout: + *get_errno_ptr() = ret; + return NULL; } #endif /* CONFIG_NFILE_DESCRIPTORS */ |