diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-04-28 22:24:10 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-04-28 22:24:10 +0000 |
commit | b3c51499ef3e2befc392865934f9df91ebd6b10a (patch) | |
tree | d8a47afb60305fb15d78abb0341533129a354676 /nuttx | |
parent | 7cb2546571c7ac881f4bd0c2c066c974e2174741 (diff) | |
download | px4-nuttx-b3c51499ef3e2befc392865934f9df91ebd6b10a.tar.gz px4-nuttx-b3c51499ef3e2befc392865934f9df91ebd6b10a.tar.bz2 px4-nuttx-b3c51499ef3e2befc392865934f9df91ebd6b10a.zip |
More NXFFS logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3538 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/fs/nxffs/Make.defs | 6 | ||||
-rwxr-xr-x | nuttx/fs/nxffs/README.txt | 94 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs.h | 7 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_dirent.c | 222 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_ioctl.c | 100 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_open.c | 4 | ||||
-rw-r--r-- | nuttx/include/nuttx/dirent.h | 14 |
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 */ |