summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/fs/nxffs/Make.defs6
-rwxr-xr-xnuttx/fs/nxffs/README.txt94
-rw-r--r--nuttx/fs/nxffs/nxffs.h7
-rw-r--r--nuttx/fs/nxffs/nxffs_dirent.c222
-rw-r--r--nuttx/fs/nxffs/nxffs_ioctl.c100
-rw-r--r--nuttx/fs/nxffs/nxffs_open.c4
-rw-r--r--nuttx/include/nuttx/dirent.h14
7 files changed, 440 insertions, 7 deletions
diff --git a/nuttx/fs/nxffs/Make.defs b/nuttx/fs/nxffs/Make.defs
index 558fd6be6..88c3d9cee 100644
--- a/nuttx/fs/nxffs/Make.defs
+++ b/nuttx/fs/nxffs/Make.defs
@@ -35,9 +35,9 @@
ifeq ($(CONFIG_FS_NXFFS),y)
ASRCS +=
-CSRCS += nxffs_block.c nxffs_blockstats.c nxffs_cache.c \
- nxffs_initialize.c nxffs_inode.c nxffs_open.c nxffs_reformat.c \
- nxffs_stat.c nxffs_unlink.c nxffs_util.c
+CSRCS += nxffs_block.c nxffs_blockstats.c nxffs_cache.c nxffs_dirent.c \
+ nxffs_initialize.c nxffs_inode.c nxffs_ioctl.c nxffs_open.c \
+ nxffs_reformat.c nxffs_stat.c nxffs_unlink.c nxffs_util.c
# Argument for dependency checking
diff --git a/nuttx/fs/nxffs/README.txt b/nuttx/fs/nxffs/README.txt
new file mode 100755
index 000000000..a2577e1f8
--- /dev/null
+++ b/nuttx/fs/nxffs/README.txt
@@ -0,0 +1,94 @@
+General NXFFS organization
+==========================
+
+The following example assumes 4 logical blocks per FLASH erase block. The
+actual relationship is determined by the FLASH geometry reported by the MTD
+driver.
+
+ERASE LOGICAL Inodes begin with a inode header. inode may
+BLOCK BLOCK CONTENTS be marked as "deleted," pending clean-up.
+ n 4*n --+--------------+
+ |BBBBBBBBBBBBBB| Logic block header
+ |IIIIIIIIIIIIII| Inodes begin with a inode header
+ |DDDDDDDDDDDDDD| Data block containing inode data block
+ | (Inode Data) |
+ 4*n+1 --+--------------+
+ |BBBBBBBBBBBBBB| Logic block header
+ |DDDDDDDDDDDDDD| Inodes may consist of multiple data blocks
+ | (Inode Data) |
+ |IIIIIIIIIIIIII| Next inode header
+ | | Possibly a few unused bytes at the end of a block
+ 4*n+2 --+--------------+
+ |BBBBBBBBBBBBBB| Logic block header
+ |DDDDDDDDDDDDDD|
+ | (Inode Data) |
+ 4*n+3 --+--------------+
+ |BBBBBBBBBBBBBB| Logic block header
+ |IIIIIIIIIIIIII| Next inode header
+ |DDDDDDDDDDDDDD|
+ | (Inode Data) |
+ n+1 4*(n+1) --+--------------+
+ |BBBBBBBBBBBBBB| Logic block header
+ | | All FLASH is unused after the end of the final
+ | | inode.
+ --+--------------+
+
+General operation
+=================
+
+ Inodes are written starting at the beginning of FLASH. As inodes are
+ deleted, they are marked as deleted but not removed. As new inodes are
+ written, allocations proceed to toward the end of the FLASH -- thus,
+ supporting wear leveling by using all FLASH blocks equally.
+
+ When the FLASH becomes full (no more space at the end of the FLASH), a
+ clean-up operation must be performed: All inodes marked deleted are
+ finally removed and the remaining inodes are packed at the beginning of
+ the FLASH. Allocations then continue at the freed FLASH memory at the
+ end of the FLASH.
+
+Headers
+=======
+ BLOCK HEADER:
+ The block header is used to determine if the block has every been
+ formatted and also indicates bad blocks which should never be used.
+
+ INODE HEADER:
+ Each inode begins with an inode header that contains, among other things,
+ the name of the inode, the offset to the first data block, and the
+ length of the inode data.
+
+ At present, the only kind of inode support is a file. So for now, the
+ term file and inode are interchangeable.
+
+ INODE DATA HEADER:
+ Inode data is enclosed in a data header. For a given inode, there
+ is at most one inode data block per logical block. If the inode data
+ spans more than one logical block, then the inode data may be enclosed
+ in multiple data blocks, one per logical block.
+
+NXFFS Limitations
+=================
+
+This implementation is very simple as, as a result, has several limitations
+that you should be aware before opting to use NXFFS:
+
+1. Since the files are contiguous in FLASH and since allocations always
+ proceed toward the end of the FLASH, there can only be one file opened
+ for writing at a time. Multiple files may be opened for reading.
+
+2. Files may not be increased in size after they have been closed. The
+ O_APPEND open flag is not supported.
+
+3. Files are always written sequential. Seeking within a file opened for
+ writing will not work.
+
+4. There are no directories, however, '/' may be used within a file name
+ string providing some illusion of directories.
+
+5. Files may be opened for reading or for writing, but not both: The O_RDWR
+ open flag is not supported.
+
+6. The clean-up process occurs only during a write when the free FLASH
+ memory at the end of the FLASH is exhausted. Thus, occasionally, file
+ writing may take a long time.
diff --git a/nuttx/fs/nxffs/nxffs.h b/nuttx/fs/nxffs/nxffs.h
index 091260552..4f903a072 100644
--- a/nuttx/fs/nxffs/nxffs.h
+++ b/nuttx/fs/nxffs/nxffs.h
@@ -73,14 +73,14 @@
* n 4*n --+--------------+
* |BBBBBBBBBBBBBB| Logic block header
* |IIIIIIIIIIIIII| Inodes begin with a inode header
- * |DDDDDDDDDDDDD| Data block containing inode data block
+ * |DDDDDDDDDDDDDD| Data block containing inode data block
* | (Inode Data) |
* 4*n+1 --+--------------+
* |BBBBBBBBBBBBBB| Logic block header
* |DDDDDDDDDDDDDD| Inodes may consist of multiple data blocks
* | (Inode Data) |
* |IIIIIIIIIIIIII| Next inode header
- * | | Possibly a few unused bytes at the end of a block
+ * | | Possibly a few unused bytes at the end of a block
* 4*n+2 --+--------------+
* |BBBBBBBBBBBBBB| Logic block header
* |DDDDDDDDDDDDDD|
@@ -141,7 +141,6 @@
* 6. The clean-up process occurs only during a write when the free FLASH
* memory at the end of the FLASH is exhausted. Thus, occasionally, file
* writing may take a long time.
- *
*/
/* Values for logical block state. Basically, there are only two, perhaps
@@ -703,7 +702,7 @@ extern int nxffs_rminode(FAR struct nxffs_volume_s *volume, FAR const char *name
* - nxffs_open() and nxffs_close() are defined in nxffs_open.c
* - nxffs_ioctl() is defined in nxffs_ioctl.c
* - nxffs_opendir(), nxffs_readdir(), and nxffs_rewindir() are defined in
- * nxffs_dir.c
+ * nxffs_dirent.c
* - nxffs_stat() and nxffs_statfs() are defined in nxffs_stat.c
* - nxffs_unlink() is defined nxffs_unlink.c
*
diff --git a/nuttx/fs/nxffs/nxffs_dirent.c b/nuttx/fs/nxffs/nxffs_dirent.c
new file mode 100644
index 000000000..bd53ffe0c
--- /dev/null
+++ b/nuttx/fs/nxffs/nxffs_dirent.c
@@ -0,0 +1,222 @@
+/****************************************************************************
+ * fs/nxffs/nxffs_dirent.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * References: Linux/Documentation/filesystems/romfs.txt
+ *
+ * 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 NuttX 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 <string.h>
+#include <dirent.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/fs.h>
+#include <nuttx/mtd.h>
+#include <nuttx/dirent.h>
+
+#include "nxffs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_opendir
+ *
+ * Description:
+ * Open a directory for read access
+ *
+ ****************************************************************************/
+
+int nxffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
+ FAR struct fs_dirent_s *dir)
+{
+ struct nxffs_volume_s *volume;
+ int ret;
+
+ fvdbg("relpath: \"%s\"\n", relpath ? relpath : "NULL");
+
+ /* Sanity checks */
+
+ DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
+
+ /* Recover the file system state from the NuttX inode instance */
+
+ volume = mountpt->i_private;
+ ret = sem_wait(&volume->exclsem);
+ if (ret != OK)
+ {
+ goto errout;
+ }
+
+ /* The requested directory must be the volume-relative "root" directory */
+
+ if (relpath && relpath[0] != '\0')
+ {
+ ret = -ENOENT;
+ goto errout_with_semaphore;
+ }
+
+ /* Set the offset to the offset to the first valid inode */
+
+ dir->u.nxffs.nx_offset = volume->inoffset;
+ ret = OK;
+
+errout_with_semaphore:
+ sem_post(&volume->exclsem);
+errout:
+ return ret;
+}
+
+/****************************************************************************
+ * Name: nxffs_readdir
+ *
+ * Description: Read the next directory entry
+ *
+ ****************************************************************************/
+
+int nxffs_readdir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir)
+{
+ FAR struct nxffs_volume_s *volume;
+ FAR struct nxffs_entry_s entry;
+ off_t offset;
+ int ret;
+
+ /* Sanity checks */
+
+ DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
+
+ /* Recover the file system state from the NuttX inode instance */
+
+ volume = mountpt->i_private;
+ ret = sem_wait(&volume->exclsem);
+ if (ret != OK)
+ {
+ goto errout;
+ }
+
+ /* Read the next inode header from the offset */
+
+ offset = dir->u.nxffs.nx_offset;
+ ret = nxffs_nextentry(volume, offset, &entry);
+
+ /* If the read was successful, then handle the reported inode. Note
+ * that when the last inode has been reported, the value -ENOENT will
+ * be returned.. which is correct for the readdir() method.
+ */
+
+ if (ret == OK)
+ {
+ /* Return the filename and file type */
+
+ fvdbg("Offset %d: \"%s\"\n", entry.hoffset, entry.name);
+ dir->fd_dir.d_type = DTYPE_FILE;
+ strncpy(dir->fd_dir.d_name, entry.name, NAME_MAX+1);
+
+ /* Discard this entry and set the next offset using the rw data
+ * length as the offset increment. This is, of course, not accurate
+ * because it does not account for the data headers that enclose the
+ * data. But it is guaranteed to be less than or equal to the
+ * correct offset and, hence, better then searching byte-for-byte.
+ */
+
+ dir->u.nxffs.nx_offset = entry.doffset + entry.datlen;
+ nxffs_freeentry(&entry);
+ ret = OK;
+ }
+
+ sem_post(&volume->exclsem);
+errout:
+ return ret;
+}
+
+/****************************************************************************
+ * Name: nxffs_rewindir
+ *
+ * Description:
+ * Reset directory read to the first entry
+ *
+ ****************************************************************************/
+
+int nxffs_rewinddir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir)
+{
+ FAR struct nxffs_volume_s *volume;
+ int ret;
+
+ fvdbg("Entry\n");
+
+ /* Sanity checks */
+
+ DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
+
+ /* Recover the file system state from the NuttX inode instance */
+
+ volume = mountpt->i_private;
+ ret = sem_wait(&volume->exclsem);
+ if (ret != OK)
+ {
+ goto errout;
+ }
+
+ /* Reset the offset to the FLASH offset to the first valid inode */
+
+ dir->u.nxffs.nx_offset = volume->inoffset;
+ ret = OK;
+
+ sem_post(&volume->exclsem);
+errout:
+ return ret;
+}
diff --git a/nuttx/fs/nxffs/nxffs_ioctl.c b/nuttx/fs/nxffs/nxffs_ioctl.c
new file mode 100644
index 000000000..d5fe2ece8
--- /dev/null
+++ b/nuttx/fs/nxffs/nxffs_ioctl.c
@@ -0,0 +1,100 @@
+/****************************************************************************
+ * fs/nxffs/nxffs_ioctl.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * References: Linux/Documentation/filesystems/romfs.txt
+ *
+ * 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 NuttX 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 <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/fs.h>
+#include <nuttx/mtd.h>
+
+#include "nxffs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_ioctl
+ *
+ * Description:
+ * Standard mountpoint ioctl method.
+ *
+ ****************************************************************************/
+
+int nxffs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
+{
+ FAR struct nxffs_volume_s *volume;
+
+ fvdbg("cmd: %d arg: %08lx\n", cmd, arg);
+
+ /* Sanity checks */
+
+ DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
+
+ /* Recover the file system state from the open file */
+
+ volume = filep->f_inode->i_private;
+ DEBUGASSERT(volume != NULL);
+
+ /* No ioctl commands yet supported */
+
+ return -ENOTTY;
+}
diff --git a/nuttx/fs/nxffs/nxffs_open.c b/nuttx/fs/nxffs/nxffs_open.c
index a7caebca5..88bfbf3ff 100644
--- a/nuttx/fs/nxffs/nxffs_open.c
+++ b/nuttx/fs/nxffs/nxffs_open.c
@@ -289,6 +289,10 @@ static inline int nxffs_rdopen(FAR struct nxffs_volume_s *volume,
/****************************************************************************
* Name: nxffs_freeofile
+ *
+ * Description:
+ * Free resources held by an open file.
+ *
****************************************************************************/
static inline void nxffs_freeofile(FAR struct nxffs_ofile_s *ofile)
diff --git a/nuttx/include/nuttx/dirent.h b/nuttx/include/nuttx/dirent.h
index 27835a4b2..82e0a55c3 100644
--- a/nuttx/include/nuttx/dirent.h
+++ b/nuttx/include/nuttx/dirent.h
@@ -105,6 +105,17 @@ struct fs_binfsdir_s
unsigned int fb_index; /* Index to the next named entry point */
};
#endif
+
+#ifdef CONFIG_FS_NXFFS
+/* NXFFS is the tiny NuttX wear-leveling FLASH file system. The state value is
+ * the offset in FLASH memory to the next inode entry.
+ */
+
+struct fs_nxffsdir_s
+{
+ off_t nx_offset; /* Offset to the next inode */
+};
+#endif
#endif /* CONFIG_DISABLE_MOUNTPOINT */
struct fs_dirent_s
@@ -153,7 +164,10 @@ struct fs_dirent_s
#ifdef CONFIG_APPS_BINDIR
struct fs_binfsdir_s binfs;
#endif
+#ifdef CONFIG_FS_NXFFS
+ struct fs_nxffsdir_s nxffs;
#endif
+#endif /* !CONFIG_DISABLE_MOUNTPOINT */
} u;
/* In any event, this the actual struct dirent that is returned by readdir */