summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-26 19:22:34 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-05-26 19:22:34 +0000
commita0fcefa90d39c5510c3f62bdbd3f2f128f211d6b (patch)
tree1deba65ce2f157d8f25da5498676e306742887e8
parentf93e30156c033d77182a052549a5e355a5d0a5a0 (diff)
downloadpx4-nuttx-a0fcefa90d39c5510c3f62bdbd3f2f128f211d6b.tar.gz
px4-nuttx-a0fcefa90d39c5510c3f62bdbd3f2f128f211d6b.tar.bz2
px4-nuttx-a0fcefa90d39c5510c3f62bdbd3f2f128f211d6b.zip
Finish FAT directory operations; add option to disable mountpoints; fix ARM compile errors
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@252 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/ChangeLog4
-rw-r--r--nuttx/Documentation/NuttX.html6
-rw-r--r--nuttx/Documentation/NuttxPortingGuide.html7
-rw-r--r--nuttx/arch/arm/src/common/up_unblocktask.c1
-rw-r--r--nuttx/configs/README.txt2
-rw-r--r--nuttx/configs/c5471evm/defconfig1
-rw-r--r--nuttx/configs/m68332evb/defconfig1
-rw-r--r--nuttx/configs/mcu123-lpc214x/defconfig1
-rw-r--r--nuttx/configs/ntosd-dm320/defconfig1
-rw-r--r--nuttx/configs/pjrc-8051/defconfig1
-rw-r--r--nuttx/configs/sim/defconfig1
-rw-r--r--nuttx/fs/Makefile7
-rw-r--r--nuttx/fs/fs_closedir.c37
-rw-r--r--nuttx/fs/fs_fat32.c185
-rw-r--r--nuttx/fs/fs_fat32.h9
-rw-r--r--nuttx/fs/fs_fat32util.c296
-rw-r--r--nuttx/fs/fs_fsync.c2
-rw-r--r--nuttx/fs/fs_internal.h57
-rw-r--r--nuttx/fs/fs_mkdir.c2
-rw-r--r--nuttx/fs/fs_mount.c2
-rw-r--r--nuttx/fs/fs_open.c2
-rw-r--r--nuttx/fs/fs_opendir.c10
-rw-r--r--nuttx/fs/fs_readdir.c90
-rw-r--r--nuttx/fs/fs_registerblockdriver.c4
-rw-r--r--nuttx/fs/fs_rename.c2
-rw-r--r--nuttx/fs/fs_rewinddir.c33
-rw-r--r--nuttx/fs/fs_rmdir.c2
-rw-r--r--nuttx/fs/fs_seekdir.c93
-rw-r--r--nuttx/fs/fs_telldir.c4
-rw-r--r--nuttx/fs/fs_umount.c2
-rw-r--r--nuttx/fs/fs_unlink.c2
-rw-r--r--nuttx/fs/fs_unregisterblockdriver.c2
-rw-r--r--nuttx/include/nuttx/fs.h8
-rw-r--r--nuttx/sched/pthread_create.c1
-rw-r--r--nuttx/tools/mkconfig.c6
35 files changed, 630 insertions, 254 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 1579ded46..e9f87947d 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -143,5 +143,9 @@
* Added unlink(), mkdir(), rmdir(), and rename()
* Fixed several serious FAT errors with oflags handling (&& instead of &)
* Added FAT support for unlink(), mkdir(), rmdir(), and rename
+ * Added FAT support for opendir(), closedir(), readdir(), seekdir(),
+ telldir(), rewindir().
+ * Fixed ARM compilation errors introduced in 1.2.5 (that is what I get
+ for only testing on the simulation).
* Started m68322
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 50ba2f76a..c2828bf4b 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
- <p>Last Updated: May 21, 2007</p>
+ <p>Last Updated: May 26, 2007</p>
</td>
</tr>
</table>
@@ -574,6 +574,10 @@ Other memory:
* Added unlink(), mkdir(), rmdir(), and rename()
* Fixed several serious FAT errors with oflags handling (&& instead of &)
* Added FAT support for unlink(), mkdir(), rmdir(), and rename()
+ * Added FAT support for opendir(), closedir(), readdir(), seekdir(),
+ telldir(), rewindir().
+ * Fixed ARM compilation errors introduced in 1.2.5 (that is what I get
+ for only testing on the simulation).
* Started m68322
</pre></ul>
diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html
index e7270063e..8cd9d06e3 100644
--- a/nuttx/Documentation/NuttxPortingGuide.html
+++ b/nuttx/Documentation/NuttxPortingGuide.html
@@ -16,7 +16,7 @@
</b></big>
<p><small>by</small></p>
<p>Gregory Nutt</p>
- <p><small>Last Update: April 30, 2007</small></p>
+ <p><small>Last Update: May 26, 2007</small></p>
</center>
<center><h1>Table of Contents</h1></center>
@@ -1211,8 +1211,9 @@ The system can be re-made subsequently by just typing <code>make</code>.
</ul>
<ul>
- <code>CONFIG_DISABLE_CLOCK</code>, <code>CONFI_DISABLE_POSIX_TIMERS</code>, <code>CONFIG_DISABLE_PTHREAD</code>,
- <code>CONFIG_DISABLE_SIGNALS</code>, <code>CONFIG_DISABLE_MQUEUE</code>,
+ <code>CONFIG_DISABLE_CLOCK</code>, <code>CONFI_DISABLE_POSIX_TIMERS</code>,
+ <code>CONFIG_DISABLE_PTHREAD</code>, <code>CONFIG_DISABLE_SIGNALS</code>,
+ <code>CONFIG_DISABLE_MQUEUE</code>, <code>CONFIG_DISABLE_MOUNTPOUNT</code>
</ul>
<h2>Miscellaneous libc settings</h2>
diff --git a/nuttx/arch/arm/src/common/up_unblocktask.c b/nuttx/arch/arm/src/common/up_unblocktask.c
index f907c6161..32176f152 100644
--- a/nuttx/arch/arm/src/common/up_unblocktask.c
+++ b/nuttx/arch/arm/src/common/up_unblocktask.c
@@ -43,6 +43,7 @@
#include <debug.h>
#include <nuttx/arch.h>
#include "os_internal.h"
+#include "clock_internal.h"
#include "up_internal.h"
/************************************************************
diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt
index 734e00a31..77d41e131 100644
--- a/nuttx/configs/README.txt
+++ b/nuttx/configs/README.txt
@@ -159,7 +159,7 @@ defconfig -- This is a configuration file similar to the Linux
up waiting tasks.
CONFIG_DISABLE_CLOCK, CONFIG_DISABLE_POSIX_TIMERS, CONFIG_DISABLE_PTHREAD.
- CONFIG_DISABLE_SIGNALS, CONFIG_DISABLE_MQUEUE
+ CONFIG_DISABLE_SIGNALS, CONFIG_DISABLE_MQUEUE, CONFIG_DISABLE_MOUNTPOUNT
Misc libc settings
diff --git a/nuttx/configs/c5471evm/defconfig b/nuttx/configs/c5471evm/defconfig
index 5968c4f69..a534ae283 100644
--- a/nuttx/configs/c5471evm/defconfig
+++ b/nuttx/configs/c5471evm/defconfig
@@ -157,6 +157,7 @@ CONFIG_DISABLE_POSIX_TIMERS=n
CONFIG_DISABLE_PTHREAD=n
CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n
+CONFIG_DISABLE_MOUNTPOINT=y
#
# Misc libc settings
diff --git a/nuttx/configs/m68332evb/defconfig b/nuttx/configs/m68332evb/defconfig
index a8f6fcde4..2df6f2e51 100644
--- a/nuttx/configs/m68332evb/defconfig
+++ b/nuttx/configs/m68332evb/defconfig
@@ -146,6 +146,7 @@ CONFIG_DISABLE_POSIX_TIMERS=n
CONFIG_DISABLE_PTHREAD=n
CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n
+CONFIG_DISABLE_MOUNTPOINT=y
#
# Misc libc settings
diff --git a/nuttx/configs/mcu123-lpc214x/defconfig b/nuttx/configs/mcu123-lpc214x/defconfig
index fd4e7f043..e9e97326b 100644
--- a/nuttx/configs/mcu123-lpc214x/defconfig
+++ b/nuttx/configs/mcu123-lpc214x/defconfig
@@ -170,6 +170,7 @@ CONFIG_DISABLE_POSIX_TIMERS=n
CONFIG_DISABLE_PTHREAD=n
CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n
+CONFIG_DISABLE_MOUNTPOINT=y
#
# Misc libc settings
diff --git a/nuttx/configs/ntosd-dm320/defconfig b/nuttx/configs/ntosd-dm320/defconfig
index 9aaf69df8..aa6270250 100644
--- a/nuttx/configs/ntosd-dm320/defconfig
+++ b/nuttx/configs/ntosd-dm320/defconfig
@@ -155,6 +155,7 @@ CONFIG_DISABLE_POSIX_TIMERS=n
CONFIG_DISABLE_PTHREAD=n
CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n
+CONFIG_DISABLE_MOUNTPOINT=y
#
# Misc libc settings
diff --git a/nuttx/configs/pjrc-8051/defconfig b/nuttx/configs/pjrc-8051/defconfig
index 3e27c1a8b..bc6084f0b 100644
--- a/nuttx/configs/pjrc-8051/defconfig
+++ b/nuttx/configs/pjrc-8051/defconfig
@@ -143,6 +143,7 @@ CONFIG_DISABLE_POSIX_TIMERS=y
CONFIG_DISABLE_PTHREAD=y
CONFIG_DISABLE_SIGNALS=y
CONFIG_DISABLE_MQUEUE=y
+CONFIG_DISABLE_MOUNTPOINT=y
#
# Misc libc settings
diff --git a/nuttx/configs/sim/defconfig b/nuttx/configs/sim/defconfig
index c61d757fa..59f05d4ac 100644
--- a/nuttx/configs/sim/defconfig
+++ b/nuttx/configs/sim/defconfig
@@ -111,6 +111,7 @@ CONFIG_DISABLE_POSIX_TIMERS=n
CONFIG_DISABLE_PTHREAD=n
CONFIG_DISABLE_SIGNALS=n
CONFIG_DISABLE_MQUEUE=n
+CONFIG_DISABLE_MOUNTPOINT=n
#
# Misc libc settings
diff --git a/nuttx/fs/Makefile b/nuttx/fs/Makefile
index 468e4e803..4ba32383d 100644
--- a/nuttx/fs/Makefile
+++ b/nuttx/fs/Makefile
@@ -45,12 +45,15 @@ CSRCS = fs_open.c fs_close.c fs_read.c fs_write.c fs_ioctl.c fs_dup.c \
fs_seekdir.c fs_telldir.c fs_rewinddir.c fs_fsync.c fs_files.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_inodeaddref.c fs_inoderelease.c
+ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y)
+CSRCS += fs_registerblockdriver.c fs_unregisterblockdriver.c \
fs_mount.c fs_umount.c fs_unlink.c fs_mkdir.c fs_rmdir.c \
- fs_rename.c fs_inodeaddref.c fs_inoderelease.c
+ fs_rename.c
ifeq ($(CONFIG_FS_FAT),y)
CSRCS += fs_fat32.c fs_fat32util.c
endif
+endif
COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS)
diff --git a/nuttx/fs/fs_closedir.c b/nuttx/fs/fs_closedir.c
index a8104b4d2..6c81ace6d 100644
--- a/nuttx/fs/fs_closedir.c
+++ b/nuttx/fs/fs_closedir.c
@@ -76,8 +76,12 @@
int closedir(FAR DIR *dirp)
{
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
+ struct inode *inode;
+#endif
+ int ret;
- if (!idir || !idir->root)
+ if (!idir || !idir->fd_root)
{
*get_errno_ptr() = EBADF;
return ERROR;
@@ -87,31 +91,44 @@ int closedir(FAR DIR *dirp)
* inode we have open.
*/
- if (IS_MOUNTPT_INODE(idir->root))
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
+ inode = idir->fd_root;
+ 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 closedir() method (not an error if it does not)
+ */
-#warning "Mountpoint support not implemented"
- *get_errno_ptr() = ENOSYS;
- return ERROR;
+ if (inode->u.i_mops && inode->u.i_mops->closedir)
+ {
+ /* Perform the closedir() operation */
+
+ ret = inode->u.i_mops->closedir(inode, idir);
+ if (ret < 0)
+ {
+ *get_errno_ptr() = -ret;
+ return ERROR;
+ }
+ }
}
else
+#endif
{
/* The node is part of the root psuedo file system, release
* our contained reference to the 'next' inode.
*/
- if (idir->u.psuedo.next)
+ if (idir->u.psuedo.fd_next)
{
- inode_release(idir->u.psuedo.next);
+ inode_release(idir->u.psuedo.fd_next);
}
}
/* Release our references on the contained 'root' inode */
- if (idir->root)
+ if (idir->fd_root)
{
- inode_release(idir->root);
+ inode_release(idir->fd_root);
}
/* Then release the container */
diff --git a/nuttx/fs/fs_fat32.c b/nuttx/fs/fs_fat32.c
index accfa8007..adb6c47b6 100644
--- a/nuttx/fs/fs_fat32.c
+++ b/nuttx/fs/fs_fat32.c
@@ -59,7 +59,8 @@
#include "fs_internal.h"
#include "fs_fat32.h"
-#if CONFIG_FS_FAT
+#ifdef CONFIG_FS_FAT
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
/****************************************************************************
* Definitions
@@ -85,6 +86,8 @@ 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_readdir(struct inode *mountpt, struct internal_dir_s *dir);
+static int fat_rewinddir(struct inode *mountpt, struct internal_dir_s *dir);
static int fat_bind(FAR struct inode *blkdriver, const void *data,
void **handle);
@@ -120,6 +123,9 @@ const struct mountpt_operations fat_operations =
fat_sync,
fat_opendir,
+ NULL,
+ fat_readdir,
+ fat_rewinddir,
fat_bind,
fat_unbind,
@@ -296,7 +302,7 @@ static int fat_open(FAR struct file *filp, const char *relpath,
/* Save information that can be used later to recover the directory entry */
ff->ff_dirsector = fs->fs_currentsector;
- ff->ff_dirindex = dirinfo.fd_index;
+ ff->ff_dirindex = dirinfo.dir.fd_index;
/* File cluster/size info */
@@ -1248,10 +1254,10 @@ static int fat_opendir(struct inode *mountpt, const char *relpath, struct intern
{
/* 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;
+ dir->u.fat.fd_startcluster = 0;
+ dir->u.fat.fd_currcluster = 0;
+ dir->u.fat.fd_currsector = fs->fs_rootbase;
+ dir->u.fat.fd_index = 2;
}
/* This is not the root directory. Verify that it is some kind of directory */
@@ -1266,12 +1272,168 @@ static int fat_opendir(struct inode *mountpt, const char *relpath, struct intern
{
/* The entry is a directory */
- dir->u.fat.startcluster =
+ dir->u.fat.fd_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;
+ dir->u.fat.fd_currcluster = dir->u.fat.fd_startcluster;
+ dir->u.fat.fd_currsector = fat_cluster2sector(fs, dir->u.fat.fd_currcluster);
+ dir->u.fat.fd_index = 2;
+ }
+
+ fat_semgive(fs);
+ return OK;
+
+errout_with_semaphore:
+ fat_semgive(fs);
+ return ERROR;
+}
+
+/****************************************************************************
+ * Name: fat_readdir
+ *
+ * Description: Read the next directory entry
+ *
+ ****************************************************************************/
+
+static int fat_readdir(struct inode *mountpt, struct internal_dir_s *dir)
+{
+ struct fat_mountpt_s *fs;
+ unsigned int dirindex;
+ ubyte *direntry;
+ ubyte ch;
+ ubyte attribute;
+ 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;
+ }
+
+ /* Read the next directory entry */
+
+ dir->fd_dir.d_name[0] = '\0';
+ while (dir->u.fat.fd_currsector && dir->fd_dir.d_name[0] == '\0')
+ {
+ ret = fat_fscacheread(fs, dir->u.fat.fd_currsector);
+ if ( ret < 0)
+ {
+ goto errout_with_semaphore;
+ }
+
+ /* Get a reference to the current directory entry */
+
+ dirindex = (dir->u.fat.fd_index & DIRSEC_NDXMASK(fs)) * 32;
+ direntry = &fs->fs_buffer[dirindex];
+
+ /* Has it reached to end of the directory */
+
+ ch = *direntry;
+ if (ch == DIR0_ALLEMPTY)
+ {
+ /* We signal the end of the directory by returning the
+ * special error -ENOENT
+ */
+
+ ret = -ENOENT;
+ goto errout_with_semaphore;
+ }
+
+ /* No, is the current entry a valid entry? */
+
+ attribute = DIR_GETATTRIBUTES(direntry);
+ if (ch != DIR0_EMPTY && (attribute & FATATTR_VOLUMEID) == 0)
+ {
+ /* Yes.. get the name from the directory info */
+
+ (void)fat_dirname2path(dir->fd_dir.d_name, direntry);
+
+ /* And the file type */
+
+ if ((attribute & FATATTR_DIRECTORY) == 0)
+ {
+ dir->fd_dir.d_type = DTYPE_FILE;
+ }
+ else
+ {
+ dir->fd_dir.d_type = DTYPE_DIRECTORY;
+ }
+ }
+
+ /* Set up the next directory index */
+
+ if (fat_nextdirentry(fs, &dir->u.fat) != OK)
+ {
+ dir->u.fat.fd_currsector = 0;
+ }
+ }
+
+ fat_semgive(fs);
+ return OK;
+
+errout_with_semaphore:
+ fat_semgive(fs);
+ return ERROR;
+}
+
+/****************************************************************************
+ * Name: fat_rewindir
+ *
+ * Description: Reset directory read to the first entry
+ *
+ ****************************************************************************/
+
+static int fat_rewinddir(struct inode *mountpt, struct internal_dir_s *dir)
+{
+ struct fat_mountpt_s *fs;
+ 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;
+ }
+
+ /* Check if this is the root directory */
+
+ if (dir->u.fat.fd_startcluster == 0)
+ {
+ /* Handler the FAT12/16 root directory */
+
+ dir->u.fat.fd_currcluster = 0;
+ dir->u.fat.fd_currsector = fs->fs_rootbase;
+ dir->u.fat.fd_index = 2;
+ }
+
+ /* This is not the root directory */
+
+ else
+ {
+ dir->u.fat.fd_currcluster = dir->u.fat.fd_startcluster;
+ dir->u.fat.fd_currsector = fat_cluster2sector(fs, dir->u.fat.fd_currcluster);
+ dir->u.fat.fd_index = 2;
}
fat_semgive(fs);
@@ -1589,7 +1751,7 @@ static int fat_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
DIR_PUTFSTCLUSTHI(direntry, dircluster >> 16);
DIR_PUTFSTCLUSTLO(direntry, dircluster);
- parentcluster = dirinfo.fd_startcluster;
+ parentcluster = dirinfo.dir.fd_startcluster;
if (fs->fs_type != FSTYPE_FAT32 && parentcluster == fs->fs_rootbase)
{
parentcluster = 0;
@@ -1833,4 +1995,5 @@ int fat_rename(struct inode *mountpt, const char *oldrelpath,
* Public Functions
****************************************************************************/
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_FS_FAT */
diff --git a/nuttx/fs/fs_fat32.h b/nuttx/fs/fs_fat32.h
index dd86b3fa2..4bf1edde7 100644
--- a/nuttx/fs/fs_fat32.h
+++ b/nuttx/fs/fs_fat32.h
@@ -492,10 +492,7 @@ struct fat_dirinfo_s
#ifdef CONFIG_FAT_LCNAMES
ubyte fd_ntflags; /* NTRes lower case flags */
#endif
- uint16 fd_index; /* Current index */
- size_t fd_startcluster; /* Start cluster number */
- size_t fd_currcluster; /* Current cluster number */
- size_t fd_currsector; /* Current sector */
+ struct fs_fatdir_s dir; /* Used with opendir, readdir, etc. */
ubyte *fd_entry; /* A pointer to the raw 32-byte entry */
};
@@ -556,11 +553,13 @@ EXTERN sint32 fat_extendchain(struct fat_mountpt_s *fs, uint32 cluster);
/* Help for traverseing directory trees */
-EXTERN int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
+EXTERN int fat_nextdirentry(struct fat_mountpt_s *fs, struct fs_fatdir_s *dir);
EXTERN int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
const char *path);
EXTERN int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
+EXTERN int fat_dirname2path(char *path, ubyte *direntry);
+
/* File creation and removal helpers */
EXTERN int fat_dirtruncate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo);
diff --git a/nuttx/fs/fs_fat32util.c b/nuttx/fs/fs_fat32util.c
index d6d3da0cd..c44e2c6bd 100644
--- a/nuttx/fs/fs_fat32util.c
+++ b/nuttx/fs/fs_fat32util.c
@@ -57,7 +57,8 @@
#include "fs_internal.h"
#include "fs_fat32.h"
-#if CONFIG_FS_FAT
+#ifdef CONFIG_FS_FAT
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
/****************************************************************************
* Definitions
@@ -253,113 +254,6 @@ static inline int fat_path2dirname(const char **path, struct fat_dirinfo_s *diri
}
/****************************************************************************
- * Name: fat_dirname2path
- *
- * Desciption: Convert a filename in a raw directory entry into a user
- * filename. This is essentially the inverse operation of that performed
- * by fat_path2dirname. See that function for more details.
- *
- ****************************************************************************/
-
-static inline int fat_dirname2path(char *path, struct fat_dirinfo_s *dirinfo)
-{
- const unsigned char *direntry = dirinfo->fd_entry;
- int ch;
- int ndx;
-
- /* Check if we will be doing upper to lower case conversions */
-
-#ifdef CONFIG_FAT_LCNAMES
- dirinfo->fd_ntflags = DIR_GETNTRES(direntry);
-#endif
-
- /* Get the 8-byte filename */
-
- for (ndx = 0; ndx < 8; ndx++)
- {
- /* Get the next filename character from the directory entry */
-
- ch = direntry[ndx];
-
- /* Any space (or ndx==8) terminates the filename */
-
- if (ch == ' ')
- {
- break;
- }
-
- /* In this version, we never write 0xe5 in the directoryfilenames
- * (because we do not handle any character sets where 0xe5 is valid
- * in a filaname), but we could encounted this in a filesystem
- * written by some other system
- */
-
- if (ndx == 0 && ch == DIR0_E5)
- {
- ch = 0xe5;
- }
-
- /* Check if we should perform upper to lower case conversion
- * of the (whole) filename.
- */
-
-#ifdef CONFIG_FAT_LCNAMES
- if (dirinfo->fd_ntflags & FATNTRES_LCNAME && isupper(ch))
- {
- ch = tolower(ch);
- }
-#endif
- /* Copy the next character into the filename */
-
- *path++ = ch;
- }
-
- /* Check if there is an extension */
-
- if (direntry[8] != ' ')
- {
- /* Yes, output the dot before the extension */
-
- *path++ = '.';
-
- /* Then output the (up to) 3 character extension */
-
- for (ndx = 8; ndx < 11; ndx++)
- {
- /* Get the next extensions character from the directory entry */
-
- ch = dirinfo->fd_name[ndx];
-
- /* Any space (or ndx==11) terminates the extension */
-
- if (ch == ' ')
- {
- break;
- }
-
- /* Check if we should perform upper to lower case conversion
- * of the (whole) filename.
- */
-
-#ifdef CONFIG_FAT_LCNAMES
- if (ntflags & FATNTRES_LCEXT && isupper(ch))
- {
- ch = tolower(ch);
- }
-#endif
- /* Copy the next character into the filename */
-
- *path++ = ch;
- }
- }
-
- /* Put a null terminator at the end of the filename */
-
- *path = '\0';
- return OK;
-}
-
-/****************************************************************************
* Name: fat_checkfsinfo
*
* Desciption: Read the FAT32 FSINFO sector
@@ -1412,14 +1306,14 @@ sint32 fat_extendchain(struct fat_mountpt_s *fs, uint32 cluster)
*
****************************************************************************/
-int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
+int fat_nextdirentry(struct fat_mountpt_s *fs, struct fs_fatdir_s *dir)
{
unsigned int cluster;
unsigned int ndx;
/* Increment the index to the next 32-byte directory entry */
- ndx = dirinfo->fd_index + 1;
+ ndx = dir->fd_index + 1;
/* Check if all of the directory entries in this sectory have
* been examined.
@@ -1429,13 +1323,13 @@ int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
{
/* Yes, then we will have to read the next sector */
- dirinfo->fd_currsector++;
+ dir->fd_currsector++;
/* For FAT12/16, the root directory is a group of sectors relative
* to the first sector of the fat volume.
*/
- if (!dirinfo->fd_currcluster)
+ if (!dir->fd_currcluster)
{
/* For FAT12/13, the boot record tells us number of 32-bit directories
* that are contained in the root directory. This should correspond to
@@ -1470,7 +1364,7 @@ int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
{
/* Get next cluster */
- cluster = fat_getcluster(fs, dirinfo->fd_currcluster);
+ cluster = fat_getcluster(fs, dir->fd_currcluster);
/* Check if a valid cluster was obtained. */
@@ -1482,15 +1376,15 @@ int fat_nextdirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo)
/* Initialize for new cluster */
- dirinfo->fd_currcluster = cluster;
- dirinfo->fd_currsector = fat_cluster2sector(fs, cluster);
+ dir->fd_currcluster = cluster;
+ dir->fd_currsector = fat_cluster2sector(fs, cluster);
}
}
}
- /* Save the new index into dirinfo->fd_currsector */
+ /* Save the new index into dir->fd_currsector */
- dirinfo->fd_index = ndx;
+ dir->fd_index = ndx;
return OK;
}
@@ -1522,9 +1416,9 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
* the first cluster of the root directory.
*/
- dirinfo->fd_startcluster = cluster;
- dirinfo->fd_currcluster = cluster;
- dirinfo->fd_currsector = fat_cluster2sector(fs, cluster);
+ dirinfo->dir.fd_startcluster = cluster;
+ dirinfo->dir.fd_currcluster = cluster;
+ dirinfo->dir.fd_currsector = fat_cluster2sector(fs, cluster);
}
else
{
@@ -1532,14 +1426,14 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
* relative to the first sector of the fat volume.
*/
- dirinfo->fd_startcluster = 0;
- dirinfo->fd_currcluster = 0;
- dirinfo->fd_currsector = cluster;
+ dirinfo->dir.fd_startcluster = 0;
+ dirinfo->dir.fd_currcluster = 0;
+ dirinfo->dir.fd_currsector = cluster;
}
/* fd_index is the index into the current directory table */
- dirinfo->fd_index = 0;
+ dirinfo->dir.fd_index = 0;
/* If no path was provided, then the root directory must be exactly
* what the caller is looking for.
@@ -1577,7 +1471,7 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
{
/* Read the next sector into memory */
- ret = fat_fscacheread(fs, dirinfo->fd_currsector);
+ ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
if (ret < 0)
{
return ret;
@@ -1585,7 +1479,7 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
/* Get a pointer to the directory entry */
- direntry = &fs->fs_buffer[DIRSEC_BYTENDX(fs, dirinfo->fd_index)];
+ direntry = &fs->fs_buffer[DIRSEC_BYTENDX(fs, dirinfo->dir.fd_index)];
/* Check if we are at the end of the directory */
@@ -1606,7 +1500,7 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
/* No... get the next directory index and try again */
- if (fat_nextdirentry(fs, dirinfo) != OK)
+ if (fat_nextdirentry(fs, &dirinfo->dir) != OK)
{
return -ENOENT;
}
@@ -1646,9 +1540,9 @@ int fat_finddirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo,
/* The restart scanning at the new directory */
- dirinfo->fd_currcluster = dirinfo->fd_startcluster = cluster;
- dirinfo->fd_currsector = fat_cluster2sector(fs, cluster);
- dirinfo->fd_index = 2;
+ dirinfo->dir.fd_currcluster = dirinfo->dir.fd_startcluster = cluster;
+ dirinfo->dir.fd_currsector = fat_cluster2sector(fs, cluster);
+ dirinfo->dir.fd_index = 2;
}
}
@@ -1670,21 +1564,21 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
/* Re-initialize directory object */
- cluster = dirinfo->fd_startcluster;
+ cluster = dirinfo->dir.fd_startcluster;
if (cluster)
{
/* Cluster chain can be extended */
- dirinfo->fd_currcluster = cluster;
- dirinfo->fd_currsector = fat_cluster2sector(fs, cluster);
+ dirinfo->dir.fd_currcluster = cluster;
+ dirinfo->dir.fd_currsector = fat_cluster2sector(fs, cluster);
}
else
{
/* Fixed size FAT12/16 root directory is at fixxed offset/size */
- dirinfo->fd_currsector = fs->fs_rootbase;
+ dirinfo->dir.fd_currsector = fs->fs_rootbase;
}
- dirinfo->fd_index = 0;
+ dirinfo->dir.fd_index = 0;
for (;;)
{
@@ -1692,7 +1586,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
/* Read the directory sector into fs_buffer */
- ret = fat_fscacheread(fs, dirinfo->fd_currsector);
+ ret = fat_fscacheread(fs, dirinfo->dir.fd_currsector);
if (ret < 0)
{
return ret;
@@ -1700,7 +1594,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
/* Get a pointer to the entry at fd_index */
- dirindex = (dirinfo->fd_index & DIRSEC_NDXMASK(fs)) * 32;
+ dirindex = (dirinfo->dir.fd_index & DIRSEC_NDXMASK(fs)) * 32;
direntry = &fs->fs_buffer[dirindex];
/* Check if this directory entry is empty */
@@ -1714,7 +1608,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
return OK;
}
- ret = fat_nextdirentry(fs, dirinfo);
+ ret = fat_nextdirentry(fs, &dirinfo->dir);
if (ret < 0)
{
return ret;
@@ -1737,7 +1631,7 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
/* Try to extend the cluster chain for this directory */
- cluster = fat_extendchain(fs, dirinfo->fd_currcluster);
+ cluster = fat_extendchain(fs, dirinfo->dir.fd_currcluster);
if (cluster < 0)
{
return cluster;
@@ -1774,6 +1668,115 @@ int fat_allocatedirentry(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo
}
/****************************************************************************
+ * Name: fat_dirname2path
+ *
+ * Desciption: Convert a filename in a raw directory entry into a user
+ * filename. This is essentially the inverse operation of that performed
+ * by fat_path2dirname. See that function for more details.
+ *
+ ****************************************************************************/
+
+int fat_dirname2path(char *path, ubyte *direntry)
+{
+#ifdef CONFIG_FAT_LCNAMES
+ ubyte ntflags;
+#endif
+ int ch;
+ int ndx;
+
+ /* Check if we will be doing upper to lower case conversions */
+
+#ifdef CONFIG_FAT_LCNAMES
+ ntflags = DIR_GETNTRES(direntry);
+#endif
+
+ /* Get the 8-byte filename */
+
+ for (ndx = 0; ndx < 8; ndx++)
+ {
+ /* Get the next filename character from the directory entry */
+
+ ch = direntry[ndx];
+
+ /* Any space (or ndx==8) terminates the filename */
+
+ if (ch == ' ')
+ {
+ break;
+ }
+
+ /* In this version, we never write 0xe5 in the directoryfilenames
+ * (because we do not handle any character sets where 0xe5 is valid
+ * in a filaname), but we could encounted this in a filesystem
+ * written by some other system
+ */
+
+ if (ndx == 0 && ch == DIR0_E5)
+ {
+ ch = 0xe5;
+ }
+
+ /* Check if we should perform upper to lower case conversion
+ * of the (whole) filename.
+ */
+
+#ifdef CONFIG_FAT_LCNAMES
+ if (ntflags & FATNTRES_LCNAME && isupper(ch))
+ {
+ ch = tolower(ch);
+ }
+#endif
+ /* Copy the next character into the filename */
+
+ *path++ = ch;
+ }
+
+ /* Check if there is an extension */
+
+ if (direntry[8] != ' ')
+ {
+ /* Yes, output the dot before the extension */
+
+ *path++ = '.';
+
+ /* Then output the (up to) 3 character extension */
+
+ for (ndx = 8; ndx < 11; ndx++)
+ {
+ /* Get the next extensions character from the directory entry */
+
+ ch = direntry[DIR_NAME + ndx];
+
+ /* Any space (or ndx==11) terminates the extension */
+
+ if (ch == ' ')
+ {
+ break;
+ }
+
+ /* Check if we should perform upper to lower case conversion
+ * of the (whole) filename.
+ */
+
+#ifdef CONFIG_FAT_LCNAMES
+ if (ntflags & FATNTRES_LCEXT && isupper(ch))
+ {
+ ch = tolower(ch);
+ }
+#endif
+ /* Copy the next character into the filename */
+
+ *path++ = ch;
+ }
+ }
+
+ /* Put a null terminator at the end of the filename */
+
+ *path = '\0';
+ return OK;
+}
+
+/****************************************************************************
* Name: fat_dirtruncate
*
* Desciption: Truncate an existing file to zero length
@@ -1955,9 +1958,9 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory)
* sub-directory is empty
*/
- dirinfo.fd_currcluster = dircluster;
- dirinfo.fd_currsector = fat_cluster2sector(fs, dircluster);
- dirinfo.fd_index = 2;
+ dirinfo.dir.fd_currcluster = dircluster;
+ dirinfo.dir.fd_currsector = fat_cluster2sector(fs, dircluster);
+ dirinfo.dir.fd_index = 2;
/* Loop until either (1) an entry is found in the directory
* (error), (2) the directory is found to be empty, or (3) some
@@ -1973,7 +1976,7 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory)
* subdirectory sector is in the cache
*/
- ret = fat_fscacheread(fs, dirinfo.fd_currsector);
+ ret = fat_fscacheread(fs, dirinfo.dir.fd_currsector);
if (ret < 0)
{
return ret;
@@ -1981,7 +1984,7 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory)
/* Get a reference to the next entry in the directory */
- subdirindex = (dirinfo.fd_index & DIRSEC_NDXMASK(fs)) * 32;
+ subdirindex = (dirinfo.dir.fd_index & DIRSEC_NDXMASK(fs)) * 32;
subdirentry = &fs->fs_buffer[subdirindex];
/* Is this the last entry in the direcory? */
@@ -2007,7 +2010,7 @@ int fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory)
/* Get the next directgory entry */
- ret = fat_nextdirentry(fs, &dirinfo);
+ ret = fat_nextdirentry(fs, &dirinfo.dir);
if (ret < 0)
{
return ret;
@@ -2298,7 +2301,7 @@ int fat_updatefsinfo(struct fat_mountpt_s *fs)
FSI_PUTFREECOUNT(fs->fs_buffer, fs->fs_fsifreecount);
FSI_PUTNXTFREE(fs->fs_buffer, fs->fs_fsinextfree);
FSI_PUTTRAILSIG(fs->fs_buffer, 0xaa550000);
-
+
/* Then flush this to disk */
fs->fs_currentsector = fs->fs_fsinfo;
@@ -2313,4 +2316,5 @@ int fat_updatefsinfo(struct fat_mountpt_s *fs)
return ret;
}
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_FS_FAT */
diff --git a/nuttx/fs/fs_fsync.c b/nuttx/fs/fs_fsync.c
index 7ae7f131b..6aec06daa 100644
--- a/nuttx/fs/fs_fsync.c
+++ b/nuttx/fs/fs_fsync.c
@@ -48,6 +48,7 @@
#include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
/****************************************************************************
* Definitions
@@ -137,4 +138,5 @@ int fsync(int fd)
return ERROR;
}
+#endif /* CONFIG_DISABLE_MOUNTPOINT */
#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/fs/fs_internal.h b/nuttx/fs/fs_internal.h
index c20ab2176..432344515 100644
--- a/nuttx/fs/fs_internal.h
+++ b/nuttx/fs/fs_internal.h
@@ -73,10 +73,34 @@
* Public Types
****************************************************************************/
-/* The internal representation of type DIR is just a
- * container for an inode reference and a dirent structure.
+/* The internal representation of type DIR is just a container for an inode
+ * reference, a position, a dirent structure, and file-system-specific
+ * information.
+ *
+ * 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 fs_psuedodir_s
+{
+ struct inode *fd_next; /* The inode for the next call to readdir() */
+};
+
+#ifdef CONFIG_FS_FAT
+/* For fat, we need to retun the start cluster, current cluster, current
+ * sector and current directory index.
*/
+struct fs_fatdir_s
+{
+ uint32 fd_startcluster; /* Start cluster number of the directory*/
+ uint32 fd_currcluster; /* Current cluster number being read*/
+ size_t fd_currsector; /* Current sector being read*/
+ unsigned int fd_index; /* Current index of the directory entry to read */
+};
+#endif
+
struct internal_dir_s
{
/* This is the node that was opened by opendir. The type of the inode
@@ -87,11 +111,11 @@ struct internal_dir_s
* closedir() is called (although inodes linked to this inode may change).
*/
- struct inode *root;
+ struct inode *fd_root;
/* This keeps track of the current directory position for telldir */
- off_t position;
+ off_t fd_position;
/* Retained control information depends on the type of file system that
* provides is provides the mountpoint. Ideally this information should
@@ -101,34 +125,15 @@ struct internal_dir_s
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;
-
+ struct fs_psuedodir_s 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;
+ struct fs_fatdir_s fat;
#endif
} u;
/* In any event, this the actual struct dirent that is returned by readdir */
- struct dirent dir; /* Populated when readdir is called */
+ struct dirent fd_dir; /* Populated when readdir is called */
};
/****************************************************************************
diff --git a/nuttx/fs/fs_mkdir.c b/nuttx/fs/fs_mkdir.c
index 3536744dd..4b828e4df 100644
--- a/nuttx/fs/fs_mkdir.c
+++ b/nuttx/fs/fs_mkdir.c
@@ -46,6 +46,7 @@
#include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
/****************************************************************************
* Definitions
@@ -130,4 +131,5 @@ int mkdir(const char *pathname, mode_t mode)
return ERROR;
}
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/fs/fs_mount.c b/nuttx/fs/fs_mount.c
index 3e6a564b2..1f64b1eb2 100644
--- a/nuttx/fs/fs_mount.c
+++ b/nuttx/fs/fs_mount.c
@@ -46,6 +46,7 @@
#include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
/* At least one filesystem must be defined, or this file will not compile.
* It may be desire-able to make filesystems dynamically registered at
@@ -272,4 +273,5 @@ int mount(const char *source, const char *target,
}
#endif /* Need at least filesystem */
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* Need file descriptor support */
diff --git a/nuttx/fs/fs_open.c b/nuttx/fs/fs_open.c
index 55427c0d3..b401aebf7 100644
--- a/nuttx/fs/fs_open.c
+++ b/nuttx/fs/fs_open.c
@@ -153,12 +153,14 @@ int open(const char *path, int oflags, ...)
ret = OK;
if (inode->u.i_ops->open)
{
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
if (INODE_IS_MOUNTPT(inode))
{
ret = inode->u.i_mops->open((FAR struct file*)&list->fl_files[fd],
relpath, oflags, mode);
}
else
+#endif
{
ret = inode->u.i_ops->open((FAR struct file*)&list->fl_files[fd]);
}
diff --git a/nuttx/fs/fs_opendir.c b/nuttx/fs/fs_opendir.c
index 0b5a8969f..6791195a2 100644
--- a/nuttx/fs/fs_opendir.c
+++ b/nuttx/fs/fs_opendir.c
@@ -197,11 +197,12 @@ FAR DIR *opendir(const char *path)
* 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 */
+ dir->fd_root = inode; /* Save the inode where we start */
+ dir->fd_position = 0; /* This is the position in the read stream */
/* Is this a not in the psuedo filesystem? */
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
if (INODE_IS_MOUNTPT(inode))
{
/* The node is a file system mointpoint. Verify that the mountpoint
@@ -224,11 +225,12 @@ FAR DIR *opendir(const char *path)
}
}
else
+#endif
{
/* 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() */
+ inode_addref(inode); /* Now we have two references on inode */
+ dir->u.psuedo.fd_next = inode; /* This is the next node to use for readdir() */
}
return ((DIR*)dir);
diff --git a/nuttx/fs/fs_readdir.c b/nuttx/fs/fs_readdir.c
index 4c2d79227..6cb3eb099 100644
--- a/nuttx/fs/fs_readdir.c
+++ b/nuttx/fs/fs_readdir.c
@@ -53,52 +53,59 @@
* Name: readpsuedodir
************************************************************/
-static inline FAR struct dirent *readpsuedodir(struct internal_dir_s *idir)
+#if CONFIG_NFILE_DESCRIPTORS > 0
+
+static inline int readpsuedodir(struct internal_dir_s *idir)
{
FAR struct inode *prev;
/* Check if we are at the end of the list */
- if (!idir->u.psuedo.next)
+ if (!idir->u.psuedo.fd_next)
{
- return NULL;
+ /* End of file and error conditions are not distinguishable
+ * with readdir. Here we return -ENOENT to signal the end
+ * of the directory.
+ */
+
+ return -ENOENT;
}
/* Copy the inode name into the dirent structure */
- strncpy(idir->dir.d_name, idir->u.psuedo.next->i_name, NAME_MAX+1);
+ strncpy(idir->fd_dir.d_name, idir->u.psuedo.fd_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->u.psuedo.next->u.i_ops)
+ idir->fd_dir.d_type = 0;
+ if (idir->u.psuedo.fd_next->u.i_ops)
{
- idir->dir.d_type |= DTYPE_FILE;
+ idir->fd_dir.d_type |= DTYPE_FILE;
}
/* If the node has child node(s), then we will say that it
* is a directory. NOTE: that the node can be both!
*/
- if (idir->u.psuedo.next->i_child || !idir->u.psuedo.next->u.i_ops)
+ if (idir->u.psuedo.fd_next->i_child || !idir->u.psuedo.fd_next->u.i_ops)
{
- idir->dir.d_type |= DTYPE_DIRECTORY;
+ idir->fd_dir.d_type |= DTYPE_DIRECTORY;
}
/* Now get the inode to vist next time that readdir() is called */
inode_semtake();
- prev = idir->u.psuedo.next;
- idir->u.psuedo.next = prev->i_peer; /* The next node to visit */
+ prev = idir->u.psuedo.fd_next;
+ idir->u.psuedo.fd_next = prev->i_peer; /* The next node to visit */
- if (idir->u.psuedo.next)
+ if (idir->u.psuedo.fd_next)
{
/* Increment the reference count on this next node */
- idir->u.psuedo.next->i_crefs++;
+ idir->u.psuedo.fd_next->i_crefs++;
}
inode_semgive();
@@ -108,7 +115,7 @@ static inline FAR struct dirent *readpsuedodir(struct internal_dir_s *idir)
inode_release(prev);
}
- return &idir->dir;
+ return OK;
}
/************************************************************
@@ -137,39 +144,72 @@ static inline FAR struct dirent *readpsuedodir(struct internal_dir_s *idir)
*
************************************************************/
-#if CONFIG_NFILE_DESCRIPTORS > 0
-
FAR struct dirent *readdir(DIR *dirp)
{
FAR struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
+ struct inode *inode;
+ int ret;
/* Sanity checks */
- if (!idir || !idir->root)
+ if (!idir || !idir->fd_root)
{
- *get_errno_ptr() = EBADF;
- return NULL;
+ ret = EBADF;
+ goto errout;
}
/* The way we handle the readdir depends on the type of inode
* that we are dealing with.
*/
- if (INODE_IS_MOUNTPT(idir->root))
+ inode = idir->fd_root;
+ 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 readdir() method
+ */
+
+ if (!inode->u.i_mops || !inode->u.i_mops->readdir)
+ {
+ ret = EACCES;
+ goto errout;
+ }
-#warning "Mountpoint support not implemented"
- *get_errno_ptr() = ENOSYS;
- return NULL;
+ /* Perform the readdir() operation */
+
+ ret = inode->u.i_mops->readdir(inode, idir);
}
else
{
/* The node is part of the root psuedo file system, release
* our contained reference to the 'next' inode.
*/
- return readpsuedodir(idir);
+ ret = readpsuedodir(idir);
+ }
+
+ /* ret < 0 is an error. Special case: ret = -ENOENT is end of file */
+
+ if ( ret < 0)
+ {
+ if (ret == -ENOENT)
+ {
+ ret = OK;
+ }
+ else
+ {
+ ret = -ret;
+ }
+ goto errout;
}
+
+ /* Success */
+
+ idir->fd_position++;
+ return &idir->fd_dir;
+
+errout:
+ *get_errno_ptr() = ret;
+ return NULL;
}
#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/fs/fs_registerblockdriver.c b/nuttx/fs/fs_registerblockdriver.c
index 1e51deb37..7e6b26157 100644
--- a/nuttx/fs/fs_registerblockdriver.c
+++ b/nuttx/fs/fs_registerblockdriver.c
@@ -43,6 +43,8 @@
#include <nuttx/fs.h>
#include "fs_internal.h"
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
+
/************************************************************
* Definitions
************************************************************/
@@ -98,3 +100,5 @@ STATUS register_blockdriver(const char *path,
inode_semgive();
return ret;
}
+
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
diff --git a/nuttx/fs/fs_rename.c b/nuttx/fs/fs_rename.c
index cf5208eea..40c29e80b 100644
--- a/nuttx/fs/fs_rename.c
+++ b/nuttx/fs/fs_rename.c
@@ -46,6 +46,7 @@
#include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
/****************************************************************************
* Definitions
@@ -154,4 +155,5 @@ int rename(const char *oldpath, const char *newpath)
return ERROR;
}
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/fs/fs_rewinddir.c b/nuttx/fs/fs_rewinddir.c
index 0f08da250..f276fa5a5 100644
--- a/nuttx/fs/fs_rewinddir.c
+++ b/nuttx/fs/fs_rewinddir.c
@@ -48,6 +48,10 @@
* Private Functions
************************************************************/
+/************************************************************
+ * Name: rewindpsuedodir
+ ************************************************************/
+
#if CONFIG_NFILE_DESCRIPTORS > 0
static inline void rewindpsuedodir(struct internal_dir_s *idir)
@@ -58,15 +62,15 @@ static inline void rewindpsuedodir(struct internal_dir_s *idir)
/* 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 */
+ prev = idir->u.psuedo.fd_next; /* (Save to delete later) */
+ idir->u.psuedo.fd_next = idir->fd_root; /* The next node to visit */
+ idir->fd_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++;
+ idir->fd_root->i_crefs++;
inode_semgive();
/* Then release the reference to the old next inode */
@@ -100,10 +104,13 @@ static inline void rewindpsuedodir(struct internal_dir_s *idir)
void rewinddir(FAR DIR *dirp)
{
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
+ struct inode *inode;
+#endif
/* Sanity checks */
- if (!idir || !idir->root)
+ if (!idir || !idir->fd_root)
{
return;
}
@@ -112,13 +119,23 @@ void rewinddir(FAR DIR *dirp)
* that we are dealing with.
*/
- if (INODE_IS_MOUNTPT(idir->root))
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
+ inode = idir->fd_root;
+ 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 rewinddir() method
+ */
+
+ if (inode->u.i_mops && inode->u.i_mops->rewinddir)
+ {
+ /* Perform the rewinddir() operation */
-#warning "Mountpoint support not implemented"
+ inode->u.i_mops->rewinddir(inode, idir);
+ }
}
else
+#endif
{
/* The node is part of the root psuedo file system */
diff --git a/nuttx/fs/fs_rmdir.c b/nuttx/fs/fs_rmdir.c
index c999206fb..22631957e 100644
--- a/nuttx/fs/fs_rmdir.c
+++ b/nuttx/fs/fs_rmdir.c
@@ -46,6 +46,7 @@
#include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
/****************************************************************************
* Definitions
@@ -130,4 +131,5 @@ int rmdir(const char *pathname)
return ERROR;
}
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/fs/fs_seekdir.c b/nuttx/fs/fs_seekdir.c
index bdc03d88c..5a4dae6c3 100644
--- a/nuttx/fs/fs_seekdir.c
+++ b/nuttx/fs/fs_seekdir.c
@@ -50,6 +50,10 @@
#if CONFIG_NFILE_DESCRIPTORS > 0
+/************************************************************
+ * Name: seekpsuedodir
+ ************************************************************/
+
static inline void seekpsuedodir(struct internal_dir_s *idir, off_t offset)
{
struct inode *curr;
@@ -62,15 +66,15 @@ static inline void seekpsuedodir(struct internal_dir_s *idir, off_t offset)
* "rewind" to the root dir.
*/
- if ( offset < idir->position )
+ if ( offset < idir->fd_position )
{
pos = 0;
- curr = idir->root;
+ curr = idir->fd_root;
}
else
{
- pos = idir->position;
- curr = idir->u.psuedo.next;
+ pos = idir->fd_position;
+ curr = idir->u.psuedo.fd_next;
}
/* Traverse the peer list starting at the 'root' of the
@@ -84,9 +88,9 @@ static inline void seekpsuedodir(struct internal_dir_s *idir, off_t offset)
/* 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 */
+ prev = idir->u.psuedo.fd_next;
+ idir->u.psuedo.fd_next = curr; /* The next node to visit (might be null) */
+ idir->fd_position = pos; /* Might be beyond the last dirent */
if (curr)
{
@@ -104,6 +108,73 @@ static inline void seekpsuedodir(struct internal_dir_s *idir, off_t offset)
}
/************************************************************
+ * Name: seekmountptdir
+ ************************************************************/
+
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
+static inline void seekmountptdir(struct internal_dir_s *idir, off_t offset)
+{
+ struct inode *inode;
+ 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.
+ */
+
+ inode = idir->fd_root;
+ if ( offset < idir->fd_position )
+ {
+ if (inode->u.i_mops && inode->u.i_mops->rewinddir)
+ {
+ /* Perform the rewinddir() operation */
+
+ inode->u.i_mops->rewinddir(inode, idir);
+ pos = 0;
+ }
+ else
+ {
+ /* We can't do the seek and there is no way to return
+ * an error indication.
+ */
+
+ return;
+ }
+ }
+ else
+ {
+ pos = idir->fd_position;
+ }
+
+ /* This is a brute force approach... we will just read
+ * directory entries until we are at the desired position.
+ */
+
+ while (pos < offset)
+ {
+ if (!inode->u.i_mops || !inode->u.i_mops->readdir ||
+ inode->u.i_mops->readdir(inode, idir) < 0)
+ {
+ /* We can't read the next entry and there is no way to return
+ * an error indication.
+ */
+
+ return;
+ }
+
+ /* Increment the position on each successful read */
+
+ pos++;
+ }
+
+ /* If we get here the the directory position has been successfully set */
+
+ idir->fd_position = pos;
+}
+#endif
+
+/************************************************************
* Public Functions
************************************************************/
@@ -132,7 +203,7 @@ void seekdir(FAR DIR *dirp, off_t offset)
/* Sanity checks */
- if (!idir || !idir->root)
+ if (!idir || !idir->fd_root)
{
return;
}
@@ -141,13 +212,15 @@ void seekdir(FAR DIR *dirp, off_t offset)
* that we are dealing with.
*/
- if (INODE_IS_MOUNTPT(idir->root))
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
+ if (INODE_IS_MOUNTPT(idir->fd_root))
{
/* The node is a file system mointpoint */
-#warning "Mountpoint support not implemented"
+ seekmountptdir(idir, offset);
}
else
+#endif
{
/* The node is part of the root psuedo file system */
diff --git a/nuttx/fs/fs_telldir.c b/nuttx/fs/fs_telldir.c
index 31103d777..dc886ba24 100644
--- a/nuttx/fs/fs_telldir.c
+++ b/nuttx/fs/fs_telldir.c
@@ -78,7 +78,7 @@ off_t telldir(FAR DIR *dirp)
{
struct internal_dir_s *idir = (struct internal_dir_s *)dirp;
- if (!idir || !idir->root)
+ if (!idir || !idir->fd_root)
{
*get_errno_ptr() = EBADF;
return (off_t)-1;
@@ -86,7 +86,7 @@ off_t telldir(FAR DIR *dirp)
/* Just return the current position */
- return idir->position;
+ return idir->fd_position;
}
#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/fs/fs_umount.c b/nuttx/fs/fs_umount.c
index c4abde95b..347719982 100644
--- a/nuttx/fs/fs_umount.c
+++ b/nuttx/fs/fs_umount.c
@@ -45,6 +45,7 @@
#include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
/****************************************************************************
* Definitions
@@ -176,4 +177,5 @@ int umount(const char *target)
return ERROR;
}
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/fs/fs_unlink.c b/nuttx/fs/fs_unlink.c
index 46c7f0cd0..2c7386b19 100644
--- a/nuttx/fs/fs_unlink.c
+++ b/nuttx/fs/fs_unlink.c
@@ -46,6 +46,7 @@
#include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
/****************************************************************************
* Definitions
@@ -130,4 +131,5 @@ int unlink(const char *pathname)
return ERROR;
}
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/fs/fs_unregisterblockdriver.c b/nuttx/fs/fs_unregisterblockdriver.c
index 98786b534..cae8d931c 100644
--- a/nuttx/fs/fs_unregisterblockdriver.c
+++ b/nuttx/fs/fs_unregisterblockdriver.c
@@ -44,6 +44,7 @@
#include "fs_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
/****************************************************************************
* Definitions
@@ -82,4 +83,5 @@ STATUS unregister_blockdriver(const char *path)
return ret;
}
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
#endif
diff --git a/nuttx/include/nuttx/fs.h b/nuttx/include/nuttx/fs.h
index 313624178..c703bcf36 100644
--- a/nuttx/include/nuttx/fs.h
+++ b/nuttx/include/nuttx/fs.h
@@ -79,6 +79,7 @@ struct file_operations
/* This structure provides information about the state of a block driver */
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
struct geometry
{
boolean geo_available; /* TRUE: The device is vailable */
@@ -114,6 +115,7 @@ struct block_operations
*/
struct inode;
+struct internal_dir_s;
struct mountpt_operations
{
/* The mountpoint open method differs from the driver open method
@@ -148,6 +150,9 @@ struct mountpt_operations
/* Directory operations */
int (*opendir)(struct inode *mountpt, const char *relpath, struct internal_dir_s *dir);
+ int (*closedir)(struct inode *mountpt, struct internal_dir_s *dir);
+ int (*readdir)(struct inode *mountpt, struct internal_dir_s *dir);
+ int (*rewinddir)(struct inode *mountpt, struct internal_dir_s *dir);
/* General volume-related mountpoint operations: */
@@ -163,6 +168,7 @@ struct mountpt_operations
* file stat(), file attributes, file truncation, etc.
*/
};
+#endif /* CONFIG_DISABLE_MOUNTPOUNT */
/* This structure represents one inode in the Nuttx psuedo-file system */
@@ -175,8 +181,10 @@ struct inode
union
{
const struct file_operations *i_ops; /* Driver operations for inode */
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
const struct block_operations *i_bops; /* Block driver operations */
const struct mountpt_operations *i_mops; /* Operations on a mountpoint */
+#endif
} u;
#ifdef CONFIG_FILE_MODE
mode_t i_mode; /* Access mode flags */
diff --git a/nuttx/sched/pthread_create.c b/nuttx/sched/pthread_create.c
index 058541126..998867349 100644
--- a/nuttx/sched/pthread_create.c
+++ b/nuttx/sched/pthread_create.c
@@ -48,6 +48,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/arch.h>
#include "os_internal.h"
+#include "clock_internal.h"
#include "pthread_internal.h"
/************************************************************
diff --git a/nuttx/tools/mkconfig.c b/nuttx/tools/mkconfig.c
index 161fc60f7..b9c91598c 100644
--- a/nuttx/tools/mkconfig.c
+++ b/nuttx/tools/mkconfig.c
@@ -236,6 +236,12 @@ int main(int argc, char **argv, char **envp)
printf("# undef CONFIG_STDIO_BUFFER_SIZE\n");
printf("# define CONFIG_STDIO_BUFFER_SIZE 0\n");
printf("#endif\n\n");
+ printf("/* If mountpoint support in not included, then no filesystem can\n");
+ printf(" * be supported.\n");
+ printf(" */\n\n");
+ printf("#ifdef CONFIG_DISABLE_MOUNTPOINT\n");
+ printf("# undef CONFIG_FS_FAT\n");
+ printf("#endif\n\n");
printf("/* Verbose debug only makes sense if debug is enabled */\n\n");
printf("#ifndef CONFIG_DEBUG\n");
printf("# undef CONFIG_DEBUG_VERBOSE\n");