summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-26 16:37:37 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-26 16:37:37 +0000
commitf93e30156c033d77182a052549a5e355a5d0a5a0 (patch)
tree9d0b407a1d5a2b105ea82ff905e9d640f0573ed5
parent2a3e5f6cd969f93fbb56d7ba2b63d7d8da11e756 (diff)
downloadnuttx-f93e30156c033d77182a052549a5e355a5d0a5a0.tar.gz
nuttx-f93e30156c033d77182a052549a5e355a5d0a5a0.tar.bz2
nuttx-f93e30156c033d77182a052549a5e355a5d0a5a0.zip
Add readdir() on mountpoints
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@251 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/fs/fs_fat32.c87
-rw-r--r--nuttx/fs/fs_opendir.c25
-rw-r--r--nuttx/include/nuttx/fs.h4
3 files changed, 101 insertions, 15 deletions
diff --git a/nuttx/fs/fs_fat32.c b/nuttx/fs/fs_fat32.c
index 3f2974109..accfa8007 100644
--- a/nuttx/fs/fs_fat32.c
+++ b/nuttx/fs/fs_fat32.c
@@ -83,6 +83,9 @@ static off_t fat_seek(FAR struct file *filp, off_t offset, int whence);
static int fat_ioctl(FAR struct file *filp, int cmd, unsigned long arg);
static int fat_sync(FAR struct file *filp);
+static int fat_opendir(struct inode *mountpt, const char *relpath,
+ struct internal_dir_s *dir);
+
static int fat_bind(FAR struct inode *blkdriver, const void *data,
void **handle);
static int fat_unbind(void *handle);
@@ -116,6 +119,8 @@ const struct mountpt_operations fat_operations =
fat_ioctl,
fat_sync,
+ fat_opendir,
+
fat_bind,
fat_unbind,
fat_unlink,
@@ -795,7 +800,7 @@ static ssize_t fat_write(FAR struct file *filp, const char *buffer,
goto errout_with_semaphore;
}
}
-
+
/* Copy the partial sector from the user buffer */
writesize = fs->fs_hwsectorsize - sectorindex;
@@ -1048,7 +1053,7 @@ static off_t fat_seek(FAR struct file *filp, off_t offset, int whence)
}
/* If we extended the size of the file, then mark the file as modified. */
-
+
if ((ff->ff_oflags & O_WROK) != 0 && ff->ff_position > ff->ff_size)
{
ff->ff_size = ff->ff_position;
@@ -1200,6 +1205,84 @@ static int fat_sync(FAR struct file *filp)
}
/****************************************************************************
+ * Name: fat_opendir
+ *
+ * Description: Open a directory for read access
+ *
+ ****************************************************************************/
+
+static int fat_opendir(struct inode *mountpt, const char *relpath, struct internal_dir_s *dir)
+{
+ struct fat_mountpt_s *fs;
+ struct fat_dirinfo_s dirinfo;
+ int ret;
+
+ /* Sanity checks */
+
+ DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
+
+ /* Recover our private data from the inode instance */
+
+ fs = mountpt->i_private;
+
+ /* Make sure that the mount is still healthy */
+
+ fat_semtake(fs);
+ ret = fat_checkmount(fs);
+ if (ret != OK)
+ {
+ goto errout_with_semaphore;
+ }
+
+ /* Find the requested directory */
+
+ ret = fat_finddirentry(fs, &dirinfo, relpath);
+ if (ret < 0)
+ {
+ goto errout_with_semaphore;
+ }
+
+ /* Check if this is the root directory */
+
+ if (dirinfo.fd_entry == NULL)
+ {
+ /* Handler the FAT12/16 root directory */
+
+ dir->u.fat.startcluster = 0;
+ dir->u.fat.currcluster = 0;
+ dir->u.fat.currsector = fs->fs_rootbase;
+ dir->u.fat.dirindex = 2;
+ }
+
+ /* This is not the root directory. Verify that it is some kind of directory */
+
+ else if (DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY)
+ {
+ /* The entry is not a directory */
+ ret = -ENOTDIR;
+ goto errout_with_semaphore;
+ }
+ else
+ {
+ /* The entry is a directory */
+
+ dir->u.fat.startcluster =
+ ((uint32)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) |
+ DIR_GETFSTCLUSTLO(dirinfo.fd_entry);
+ dir->u.fat.currcluster = dir->u.fat.startcluster;
+ dir->u.fat.currsector = fat_cluster2sector(fs, dir->u.fat.currcluster);
+ dir->u.fat.dirindex = 2;
+ }
+
+ fat_semgive(fs);
+ return OK;
+
+errout_with_semaphore:
+ fat_semgive(fs);
+ return ERROR;
+}
+
+/****************************************************************************
* Name: fat_bind
*
* Description: This implements a portion of the mount operation. This
diff --git a/nuttx/fs/fs_opendir.c b/nuttx/fs/fs_opendir.c
index 24462d53b..0b5a8969f 100644
--- a/nuttx/fs/fs_opendir.c
+++ b/nuttx/fs/fs_opendir.c
@@ -126,17 +126,6 @@ static inline FAR struct inode *fs_finddirnode(const char *path, const char **re
}
/************************************************************
- * 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
************************************************************/
@@ -215,9 +204,19 @@ FAR DIR *opendir(const char *path)
if (INODE_IS_MOUNTPT(inode))
{
- /* The node is a file system mointpoint */
+ /* The node is a file system mointpoint. Verify that the mountpoint
+ * supports the opendir() method
+ */
+
+ if (!inode->u.i_mops || !inode->u.i_mops->opendir)
+ {
+ ret = ENOSYS;
+ goto errout_with_direntry;
+ }
+
+ /* Perform the opendir() operation */
- ret = fs_openmountptdir(inode, relpath, dir);
+ ret = inode->u.i_mops->opendir(inode, relpath, dir);
if (ret < 0)
{
ret = -ret;
diff --git a/nuttx/include/nuttx/fs.h b/nuttx/include/nuttx/fs.h
index 42ba19661..313624178 100644
--- a/nuttx/include/nuttx/fs.h
+++ b/nuttx/include/nuttx/fs.h
@@ -145,6 +145,10 @@ struct mountpt_operations
int (*sync)(FAR struct file *filp);
+ /* Directory operations */
+
+ int (*opendir)(struct inode *mountpt, const char *relpath, struct internal_dir_s *dir);
+
/* General volume-related mountpoint operations: */
int (*bind)(FAR struct inode *blkdriver, const void *data, void **handle);