summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-26 16:05:59 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-26 16:05:59 +0000
commit2a3e5f6cd969f93fbb56d7ba2b63d7d8da11e756 (patch)
tree6ecb4e1b2918a65b64e0d3daef3723d5da1344d1
parentd88d061f01f4238008e4f24910820b63e5bd7c82 (diff)
downloadnuttx-2a3e5f6cd969f93fbb56d7ba2b63d7d8da11e756.tar.gz
nuttx-2a3e5f6cd969f93fbb56d7ba2b63d7d8da11e756.tar.bz2
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
-rw-r--r--nuttx/fs/Makefile2
-rw-r--r--nuttx/fs/fs_closedir.c31
-rw-r--r--nuttx/fs/fs_inodefinddir.c129
-rw-r--r--nuttx/fs/fs_internal.h60
-rw-r--r--nuttx/fs/fs_opendir.c142
-rw-r--r--nuttx/fs/fs_readdir.c112
-rw-r--r--nuttx/fs/fs_rewinddir.c64
-rw-r--r--nuttx/fs/fs_seekdir.c103
-rw-r--r--nuttx/fs/fs_telldir.c22
9 files changed, 401 insertions, 264 deletions
diff --git a/nuttx/fs/Makefile b/nuttx/fs/Makefile
index 69ffce62d..468e4e803 100644
--- a/nuttx/fs/Makefile
+++ b/nuttx/fs/Makefile
@@ -43,7 +43,7 @@ AOBJS = $(ASRCS:.S=$(OBJEXT))
CSRCS = fs_open.c fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_dup.c \
fs_opendir.c fs_closedir.c fs_readdir.c fs_readdirr.c \
fs_seekdir.c fs_telldir.c fs_rewinddir.c fs_fsync.c fs_files.c \
- fs_inode.c fs_inodefind.c fs_inodefinddir.c fs_inodereserve.c \
+ fs_inode.c fs_inodefind.c fs_inodereserve.c \
fs_inoderemove.c fs_registerdriver.c fs_unregisterdriver.c \
fs_registerblockdriver.c fs_unregisterblockdriver.c \
fs_mount.c fs_umount.c fs_unlink.c fs_mkdir.c fs_rmdir.c \
diff --git a/nuttx/fs/fs_closedir.c b/nuttx/fs/fs_closedir.c
index fd2d79d05..a8104b4d2 100644
--- a/nuttx/fs/fs_closedir.c
+++ b/nuttx/fs/fs_closedir.c
@@ -77,22 +77,41 @@ int closedir(FAR DIR *dirp)
{
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
- if (!idir)
+ if (!idir || !idir->root)
{
*get_errno_ptr() = EBADF;
return ERROR;
}
- /* Release our references on the contained inodes */
+ /* The way that we handle the close operation depends on what kind of root
+ * inode we have open.
+ */
- if (idir->root)
+ if (IS_MOUNTPT_INODE(idir->root))
{
- inode_release(idir->root);
+ /* The node is a file system mointpoint */
+
+#warning "Mountpoint support not implemented"
+ *get_errno_ptr() = ENOSYS;
+ return ERROR;
+ }
+ else
+ {
+ /* The node is part of the root psuedo file system, release
+ * our contained reference to the 'next' inode.
+ */
+
+ if (idir->u.psuedo.next)
+ {
+ inode_release(idir->u.psuedo.next);
+ }
}
- if (idir->next)
+ /* Release our references on the contained 'root' inode */
+
+ if (idir->root)
{
- inode_release(idir->next);
+ inode_release(idir->root);
}
/* Then release the container */
diff --git a/nuttx/fs/fs_inodefinddir.c b/nuttx/fs/fs_inodefinddir.c
deleted file mode 100644
index dcd6f4f30..000000000
--- a/nuttx/fs/fs_inodefinddir.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/************************************************************
- * fs_inodefinddir.c
- *
- * Copyright (C) 2007 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name Gregory Nutt nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ************************************************************/
-
-/************************************************************
- * Included Files
- ************************************************************/
-
-#include <nuttx/config.h>
-#include <sys/types.h>
-#include <string.h>
-#include <errno.h>
-#include <nuttx/fs.h>
-#include "fs_internal.h"
-
-#if CONFIG_NFILE_DESCRIPTORS >0
-
-/************************************************************
- * Definitions
- ************************************************************/
-
-/************************************************************
- * Private Variables
- ************************************************************/
-
-/************************************************************
- * Public Variables
- ************************************************************/
-
-/************************************************************
- * Private Functions
- ************************************************************/
-
-/************************************************************
- * Public Functions
- ************************************************************/
-
-/************************************************************
- * Name: inode_finddir
- *
- * 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.
- *
- ************************************************************/
-
-FAR struct inode *inode_finddir(const char *path)
-{
- FAR struct inode *node;
- FAR struct inode *child = 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();
-
- /* Handle some special cases */
-
- node = inode_search(&path, (FAR void*)NULL, (FAR void*)NULL, (FAR const char**)NULL);
- if (node)
- {
- /* Does the inode have a child? If so that the child
- * would be the 'head' of a list of nodes under the
- * directory.
- */
-
- child = node->i_child;
- if (child)
- {
- /* If found, then increment the count of
- * references on the child node.
- */
-
- child->i_crefs++;
- }
- }
- inode_semgive();
- return child;
-}
-
-#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/fs/fs_internal.h b/nuttx/fs/fs_internal.h
index 2912ff2b7..c20ab2176 100644
--- a/nuttx/fs/fs_internal.h
+++ b/nuttx/fs/fs_internal.h
@@ -79,12 +79,56 @@
struct internal_dir_s
{
- struct inode *root; /* The start inode (in case we
- * rewind) */
- struct inode *next; /* The inode to use for the next call
- * to readdir() */
- struct dirent dir; /* Populated using inode when readdir
- * is called */
+ /* This is the node that was opened by opendir. The type of the inode
+ * determines the way that the readdir() operations are performed. For the
+ * psuedo root psuedo-file system, it is also used to support rewind.
+ *
+ * We hold a reference on this inode so we know that it will persist until
+ * closedir() is called (although inodes linked to this inode may change).
+ */
+
+ struct inode *root;
+
+ /* This keeps track of the current directory position for telldir */
+
+ off_t position;
+
+ /* Retained control information depends on the type of file system that
+ * provides is provides the mountpoint. Ideally this information should
+ * be hidden behind an opaque, file-system-dependent void *, but we put
+ * the private definitions in line here for now to reduce allocations.
+ */
+
+ union
+ {
+ /* For the root psuedo-file system, we need retain only the 'next' inode
+ * need for the next readdir() operation. We hold a reference on this
+ * inode so we know that it will persist until closedir is called.
+ */
+
+ struct
+ {
+ struct inode *next; /* The inode for the next call to readdir() */
+ } psuedo;
+
+#ifdef CONFIG_FS_FAT
+ /* For fat, we need to retun the start cluster, current cluster, current
+ * sector and current directory index.
+ */
+
+ struct
+ {
+ uint32 startcluster; /* Starting cluster of directory */
+ uint32 currcluster; /* The current cluster being read */
+ size_t currsector; /* The current sector being read */
+ unsigned int dirindex; /* The next directory entry to read */
+ } fat;
+#endif
+ } u;
+
+ /* In any event, this the actual struct dirent that is returned by readdir */
+
+ struct dirent dir; /* Populated when readdir is called */
};
/****************************************************************************
@@ -128,10 +172,6 @@ EXTERN STATUS inode_remove(const char *path);
EXTERN FAR struct inode *inode_find(const char *path, const char **relpath);
-/* fs_inodefinddir.c *********************************************************/
-
-EXTERN FAR struct inode *inode_finddir(const char *path);
-
/* fs_inodeaddref.c **********************************************************/
EXTERN void inode_addref(FAR struct inode *inode);
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 */
diff --git a/nuttx/fs/fs_readdir.c b/nuttx/fs/fs_readdir.c
index 54a880328..4c2d79227 100644
--- a/nuttx/fs/fs_readdir.c
+++ b/nuttx/fs/fs_readdir.c
@@ -50,61 +50,30 @@
************************************************************/
/************************************************************
- * Public Functions
- ************************************************************/
-
-/************************************************************
- * Name: readdir
- *
- * Description:
- * The readdir() function returns a pointer to a dirent
- * structure representing the next directory entry in the
- * directory stream pointed to by dir. It returns NULL on
- * reaching the end-of-file or if an error occurred.
- *
- * Inputs:
- * dirp -- An instance of type DIR created by a previous
- * call to opendir();
- *
- * Return:
- * The readdir() function returns a pointer to a dirent
- * structure, or NULL if an error occurs or end-of-file
- * is reached. On error, errno is set appropriately.
- *
- * EBADF - Invalid directory stream descriptor dir
- *
+ * Name: readpsuedodir
************************************************************/
-#if CONFIG_NFILE_DESCRIPTORS > 0
-
-FAR struct dirent *readdir(DIR *dirp)
+static inline FAR struct dirent *readpsuedodir(struct internal_dir_s *idir)
{
- FAR struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
FAR struct inode *prev;
- if (!idir)
- {
- *get_errno_ptr() = EBADF;
- return NULL;
- }
-
/* Check if we are at the end of the list */
- if (!idir->next)
+ if (!idir->u.psuedo.next)
{
return NULL;
}
/* Copy the inode name into the dirent structure */
- strncpy(idir->dir.d_name, idir->next->i_name, NAME_MAX+1);
+ strncpy(idir->dir.d_name, idir->u.psuedo.next->i_name, NAME_MAX+1);
/* If the node has file operations, we will say that it is
* a file.
*/
idir->dir.d_type = 0;
- if (idir->next->u.i_ops)
+ if (idir->u.psuedo.next->u.i_ops)
{
idir->dir.d_type |= DTYPE_FILE;
}
@@ -113,7 +82,7 @@ FAR struct dirent *readdir(DIR *dirp)
* is a directory. NOTE: that the node can be both!
*/
- if (idir->next->i_child || !idir->next->u.i_ops)
+ if (idir->u.psuedo.next->i_child || !idir->u.psuedo.next->u.i_ops)
{
idir->dir.d_type |= DTYPE_DIRECTORY;
}
@@ -122,14 +91,14 @@ FAR struct dirent *readdir(DIR *dirp)
inode_semtake();
- prev = idir->next;
- idir->next = prev->i_peer; /* The next node to visit */
+ prev = idir->u.psuedo.next;
+ idir->u.psuedo.next = prev->i_peer; /* The next node to visit */
- if (idir->next)
+ if (idir->u.psuedo.next)
{
/* Increment the reference count on this next node */
- idir->next->i_crefs++;
+ idir->u.psuedo.next->i_crefs++;
}
inode_semgive();
@@ -142,4 +111,65 @@ FAR struct dirent *readdir(DIR *dirp)
return &idir->dir;
}
+/************************************************************
+ * Public Functions
+ ************************************************************/
+
+/************************************************************
+ * Name: readdir
+ *
+ * Description:
+ * The readdir() function returns a pointer to a dirent
+ * structure representing the next directory entry in the
+ * directory stream pointed to by dir. It returns NULL on
+ * reaching the end-of-file or if an error occurred.
+ *
+ * Inputs:
+ * dirp -- An instance of type DIR created by a previous
+ * call to opendir();
+ *
+ * Return:
+ * The readdir() function returns a pointer to a dirent
+ * structure, or NULL if an error occurs or end-of-file
+ * is reached. On error, errno is set appropriately.
+ *
+ * EBADF - Invalid directory stream descriptor dir
+ *
+ ************************************************************/
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+
+FAR struct dirent *readdir(DIR *dirp)
+{
+ FAR struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
+
+ /* Sanity checks */
+
+ if (!idir || !idir->root)
+ {
+ *get_errno_ptr() = EBADF;
+ return NULL;
+ }
+
+ /* The way we handle the readdir depends on the type of inode
+ * that we are dealing with.
+ */
+
+ if (INODE_IS_MOUNTPT(idir->root))
+ {
+ /* The node is a file system mointpoint */
+
+#warning "Mountpoint support not implemented"
+ *get_errno_ptr() = ENOSYS;
+ return NULL;
+ }
+ else
+ {
+ /* The node is part of the root psuedo file system, release
+ * our contained reference to the 'next' inode.
+ */
+ return readpsuedodir(idir);
+ }
+}
+
#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/fs/fs_rewinddir.c b/nuttx/fs/fs_rewinddir.c
index a5de2784b..0f08da250 100644
--- a/nuttx/fs/fs_rewinddir.c
+++ b/nuttx/fs/fs_rewinddir.c
@@ -48,6 +48,35 @@
* Private Functions
************************************************************/
+#if CONFIG_NFILE_DESCRIPTORS > 0
+
+static inline void rewindpsuedodir(struct internal_dir_s *idir)
+{
+ struct inode *prev;
+
+ inode_semtake();
+
+ /* Reset the position to the beginning */
+
+ prev = idir->u.psuedo.next; /* (Save to delete later) */
+ idir->u.psuedo.next = idir->root; /* The next node to visit */
+ idir->position = 0; /* Reset position */
+
+ /* Increment the reference count on the root=next node. We
+ * should now have two references on the inode.
+ */
+
+ idir->root->i_crefs++;
+ inode_semgive();
+
+ /* Then release the reference to the old next inode */
+
+ if (prev)
+ {
+ inode_release(prev);
+ }
+}
+
/************************************************************
* Public Functions
************************************************************/
@@ -68,33 +97,32 @@
*
************************************************************/
-#if CONFIG_NFILE_DESCRIPTORS > 0
-
void rewinddir(FAR DIR *dirp)
{
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
- struct inode *prev;
- if (idir)
- {
- inode_semtake();
+ /* Sanity checks */
- prev = idir->next;
- idir->next = idir->root; /* The next node to visit */
+ if (!idir || !idir->root)
+ {
+ return;
+ }
- if (idir->next)
- {
- /* Increment the reference count on this next node */
+ /* The way we handle the readdir depends on the type of inode
+ * that we are dealing with.
+ */
- idir->next->i_crefs++;
- }
+ if (INODE_IS_MOUNTPT(idir->root))
+ {
+ /* The node is a file system mointpoint */
- inode_semgive();
+#warning "Mountpoint support not implemented"
+ }
+ else
+ {
+ /* The node is part of the root psuedo file system */
- if (prev)
- {
- inode_release(prev);
- }
+ rewindpsuedodir(idir);
}
}
diff --git a/nuttx/fs/fs_seekdir.c b/nuttx/fs/fs_seekdir.c
index aa0ee907d..bdc03d88c 100644
--- a/nuttx/fs/fs_seekdir.c
+++ b/nuttx/fs/fs_seekdir.c
@@ -48,6 +48,61 @@
* Private Functions
************************************************************/
+#if CONFIG_NFILE_DESCRIPTORS > 0
+
+static inline void seekpsuedodir(struct internal_dir_s *idir, off_t offset)
+{
+ struct inode *curr;
+ struct inode *prev;
+ off_t pos;
+
+ /* Determine a starting point for the seek. If the seek
+ * is "forward" from the current position, then we will
+ * start at the current poisition. Otherwise, we will
+ * "rewind" to the root dir.
+ */
+
+ if ( offset < idir->position )
+ {
+ pos = 0;
+ curr = idir->root;
+ }
+ else
+ {
+ pos = idir->position;
+ curr = idir->u.psuedo.next;
+ }
+
+ /* Traverse the peer list starting at the 'root' of the
+ * the list until we find the node at 'offset". If devices
+ * are being registered and unregistered, then this can
+ * be a very unpredictable operation.
+ */
+
+ inode_semtake();
+ for (; curr && pos != offset; pos++, curr = curr->i_peer);
+
+ /* Now get the inode to vist next time that readdir() is called */
+
+ prev = idir->u.psuedo.next;
+ idir->u.psuedo.next = curr; /* The next node to visit (might be null) */
+ idir->position = pos; /* Might be beyond the last dirent */
+
+ if (curr)
+ {
+ /* Increment the reference count on this next node */
+
+ curr->i_crefs++;
+ }
+
+ inode_semgive();
+
+ if (prev)
+ {
+ inode_release(prev);
+ }
+}
+
/************************************************************
* Public Functions
************************************************************/
@@ -71,46 +126,32 @@
*
************************************************************/
-#if CONFIG_NFILE_DESCRIPTORS > 0
-
void seekdir(FAR DIR *dirp, off_t offset)
{
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
- struct inode *curr;
- struct inode *prev;
- off_t i;
-
- if (idir)
- {
- /* Traverse the peer list starting at the 'root' of the
- * the list until we find the node at 'offset". If devices
- * are being registered and unregistered, then this can
- * be a very unpredictable operation.
- */
- inode_semtake();
- for (i = 0, curr = idir->root;
- curr && i != offset;
- i++, curr = curr->i_peer);
+ /* Sanity checks */
- /* Now get the inode to vist next time that readdir() is called */
-
- prev = idir->next;
- idir->next = curr; /* The next node to visit */
+ if (!idir || !idir->root)
+ {
+ return;
+ }
- if (curr)
- {
- /* Increment the reference count on this next node */
+ /* The way we handle the readdir depends on the type of inode
+ * that we are dealing with.
+ */
- curr->i_crefs++;
- }
+ if (INODE_IS_MOUNTPT(idir->root))
+ {
+ /* The node is a file system mointpoint */
- inode_semgive();
+#warning "Mountpoint support not implemented"
+ }
+ else
+ {
+ /* The node is part of the root psuedo file system */
- if (prev)
- {
- inode_release(prev);
- }
+ seekpsuedodir(idir, offset);
}
}
diff --git a/nuttx/fs/fs_telldir.c b/nuttx/fs/fs_telldir.c
index 781a46469..31103d777 100644
--- a/nuttx/fs/fs_telldir.c
+++ b/nuttx/fs/fs_telldir.c
@@ -77,30 +77,16 @@
off_t telldir(FAR DIR *dirp)
{
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
- struct inode *curr;
- off_t offs;
- if (!idir)
+ if (!idir || !idir->root)
{
*get_errno_ptr() = EBADF;
- return -1;
+ return (off_t)-1;
}
- /* Traverse the peer list starting at the 'root' of the
- * the list until we find the 'next' node. If devices
- * are being registered and unregistered, then this can
- * be a very unpredictable operation.
- */
+ /* Just return the current position */
- inode_semtake();
- for (offs = 0, curr = idir->root;
- curr && curr != idir->next;
- offs++, curr = curr->i_peer);
-
- /* We should have an offset now corresponding to idir->next.*/
-
- inode_semgive();
- return offs;
+ return idir->position;
}
#endif /* CONFIG_NFILE_DESCRIPTORS */