You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ad...@apache.org on 2016/01/23 02:49:24 UTC

[2/3] incubator-mynewt-site git commit: Added framework and basic details for Newtron File System and File System Abstraction

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/ec910044/mkdocs/search_index.json
----------------------------------------------------------------------
diff --git a/mkdocs/search_index.json b/mkdocs/search_index.json
index 97cec19..f805483 100644
--- a/mkdocs/search_index.json
+++ b/mkdocs/search_index.json
@@ -907,8 +907,8 @@
         }, 
         {
             "location": "/modules/filesystem/", 
-            "text": "Filesystem\n\n\nMynewt provides a Flash File System abstraction layer (fs) to allow you to swap out the default Newtron File System (nffs) with a different file system of your choice. \n\n\nDescription\n\n\nThe default file system used in the Mynewt OS is the Newtron Flash File System (nffs). Hence the \nnffs\n egg description lists \nlibs/fs\n as a dependency. \n\n\negg.name: libs/nffs\negg.vers: 0.1\negg.identities: NFFS\negg.deps:\n    - libs/os\n    - libs/fs\n    - libs/testutil\n    - hw/hal\n\n\n\n\nIf the user wishes to use a different flash file system (say, \"ownffs\"), the directory containing \"ownffs\" code must include the \negg.yml\n file with the dependency on \nlibs/fs\n listed as shown above. \"ownffs\" uses the \nlibs/fs\n API available in mynewt, thus eliminating the need to change other parts of the projec.\n\n\nData structures\n\n\nList of Functions\n\n\n\n\nThe functions available in this OS feature are:\n\n\n\n\nfs_ls_file\n\n\nfs_ls_dir\
 n\n\nadd the rest\n\n\n\n\nFunction Reference\n\n\n\n\n fs_ls_file \n\n\n    static void\n    fs_ls_file(const char *name, struct fs_file *file)\n\n\n\n\n\n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nname\n\n\nexplain argument\n\n\n\n\n\n\nfile\n\n\nexplain argument\n\n\n\n\n\n\n\n\nReturned values\n\n\nList any values returned.\nError codes?\n\n\nNotes\n\n\nAny special feature/special benefit that we want to tout. \nDoes it need to be used with some other specific functions?\nAny caveats to be careful about (e.g. high memory requirements).\n\n\nExample\n\n\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n\n fs_ls_dir \n\n\n   static void\n   fs_ls_dir(const char *name)\n\n\n\n\n\n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nxx\n\n\nexplain argument xx\n\n\n\n\n\n\nyy\n\n\nexplain argument yy\n\n\n\n\n\n\n\n\nReturned values\n\n\nList any values returned.\nError codes?\n\n\nNotes\n\n\nAny special feature/specia
 l benefit that we want to tout. \nDoes it need to be used with some other specific functions?\nAny caveats to be careful about (e.g. high memory requirements).\n\n\nExample\n\n\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n\n next_one \n\n\n   \nInsert function callout here \n\n\n\n\n\n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nxx\n\n\nexplain argument xx\n\n\n\n\n\n\nyy\n\n\nexplain argument yy\n\n\n\n\n\n\n\n\nReturned values\n\n\nList any values returned.\nError codes?\n\n\nNotes\n\n\nAny special feature/special benefit that we want to tout. \nDoes it need to be used with some other specific functions?\nAny caveats to be careful about (e.g. high memory requirements).\n\n\nExample\n\n\n\n\nInsert the code snippet here", 
-            "title": "File System"
+            "text": "Filesystem\n\n\nMynewt provides a Flash File System abstraction layer (fs) to allow you to swap out the default Newtron File System (nffs) with a different file system of your choice. \n\n\nDescription\n\n\nThe default file system used in the Mynewt OS is the Newtron Flash File System (nffs). Hence the \nnffs\n egg description lists \nlibs/fs\n as a dependency. \n\n\negg.name: libs/nffs\negg.vers: 0.1\negg.identities: NFFS\negg.deps:\n    - libs/os\n    - libs/fs\n    - libs/testutil\n    - hw/hal\n\n\n\n\nIf the user wishes to use a different flash file system (say, \"ownffs\"), the directory containing \"ownffs\" code must include the \negg.yml\n file stating the dependency on \nlibs/fs\n listed as shown above. \"ownffs\" uses the \nlibs/fs\n API available in mynewt, thus minimizing changes to other parts of the project.\n\n\nNote that this generic file system (\nfs\n) API does not expose any file system detection, initialization, and formatting functions. The
 se function calls remain specific to the chosen file system. For example, Project Slinky uses the default Newtron File System (nffs) and therefore calls nffs_init() to initialize the nffs memory and data structures before any other file system operations are attempted. As shown below, the egg for Project Slinky includes the \nlibs/imgmgr\n egg which in turn includes the \nlibs/bootutil\n egg. The egg description for \nlibs/bootutil\n specifies \nfs/nffs\n as a dependency.\n\n\n\n    egg.name: project/slinky\n    egg.vers: 0.1\n    egg.deps:\n        - libs/os\n        - libs/console/full\n        - libs/shell\n        - libs/newtmgr\n        - libs/imgmgr\n        - sys/config\n        - sys/log\n        - sys/stats\n\n\n\n\n\n    egg.name: libs/imgmgr\n    egg.vers: 0.1\n    egg.deps:\n        - libs/newtmgr\n        - libs/bootutil\n    egg.deps.FS:\n        - fs/fs\n    egg.cflags.FS: -DFS_PRESENT\n\n\n\n\n\n    egg.name: libs/bootutil\n    egg.vers: 0.1 \n    egg.deps: \n       
  - fs/nffs\n        - libs/os \n        - libs/testutil\n        - hw/hal\n\n\n\n\nData Structures\n\n\nAPI\n\n\n   struct fs_file;\n\n\n\n\nThe functions available in this OS feature are:\n\n\n\n\nfs_open\n\n\nfs_close\n\n\nfs_read\n\n\nfs_write\n\n\nfs_seek\n\n\nfs_getpos\n\n\nfs_filelen\n\n\nfs_unlink\n\n\nfs_rename\n\n\nfs_mkdir\n\n\nfs_opendir\n\n\nfs_readdir\n\n\nfs_closedir\n\n\nfs_dirent_name\n\n\nfs_dirent_is_dir\n\n\n\n\nAdditional file system utilities that bundle some of the basic functions above are:\n\n\n\n\nfsutil_read_file\n\n\nfsutil_write_file\n\n\n\n\nAPI Reference\n\n\n\n\n fs_open \n\n\n    int\n    fs_open(const char *filename, uint8_t access_flags, struct fs_file **out_file);\n\n\n\n\nOpens a file at the specified path.  The result of opening a nonexistent file depends on the access flags specified.  All intermediate directories must already exist.\n\n\nBy default (when nffs is the underlying filesystem used) the mode strings passed to fopen() map to nffs_open
 ()'s access flags as follows:\n\n\n    \nr\n  -  NFFS_ACCESS_READ\n    \nr+\n -  NFFS_ACCESS_READ | NFFS_ACCESS_WRITE\n    \nw\n  -  NFFS_ACCESS_WRITE | NFFS_ACCESS_TRUNCATE\n    \nw+\n -  NFFS_ACCESS_READ | NFFS_ACCESS_WRITE | NFFS_ACCESS_TRUNCATE\n    \na\n  -  NFFS_ACCESS_WRITE | NFFS_ACCESS_APPEND\n    \na+\n -  NFFS_ACCESS_READ | NFFS_ACCESS_WRITE | NFFS_ACCESS_APPEND\n\n\n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nfilename\n\n\nPointer to the file created at the path of the specified filename\n\n\n\n\n\n\naccess_flags\n\n\nFlags controlling file access; see above table\n\n\n\n\n\n\nout_file\n\n\nOn success, a pointer to the newly-created file handle gets written here\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\nAny special feature/special benefit that we want to tout. \nDoes it need to be used with some other specific functions?\nAny caveats to be careful about (e.g. high memory requireme
 nts).\n\n\nExample\n\n\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n\n fs_close \n\n\n   int\n   fs_close(struct fs_file *file);  \n\n\n\n\nCloses the specified file and invalidates the file handle.  If the file has already been unlinked, and this is the last open handle to the file, this operation causes the file to be deleted from disk.\n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nfile\n\n\nPointer to the file to close\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\nAny special feature/special benefit that we want to tout. \nDoes it need to be used with some other specific functions?\nAny caveats to be careful about (e.g. high memory requirements).\n\n\nExample\n\n\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n\n fs_read \n\n\n   int\n   fs_read(struct fs_file *file, uint32_t len, void *out_data, uint32_t *out_len);\n\n\n\n\nReads data from the specified file.  If more data is requ
 ested than remains in the file, all available data is retrieved.  \n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nfile\n\n\nPointer to the the file to read from\n\n\n\n\n\n\nlen\n\n\nThe number of bytes to attempt to read\n\n\n\n\n\n\nout_data\n\n\nThe destination buffer to read into\n\n\n\n\n\n\nout_len\n\n\nOn success, the number of bytes actually read gets written here.  Pass null if you don't care.\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\nThis type of short read results in a success return code.\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n\n fs_write \n\n\n   int\n   fs_write(struct fs_file *file, const void *data, int len);\n\n\n\n\nWrites the supplied data to the current offset of the specified file handle.  \n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nfile\n\n\nPointer to the file to write to\n\n\n\n\n\n\ndata\n\n\nThe data to wr
 ite\n\n\n\n\n\n\nlen\n\n\nThe number of bytes to write\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_seek \n\n\n   int\n   fs_seek(struct fs_file *file, uint32_t offset);\n\n\n\n\nPositions a file's read and write pointer at the specified offset.  The offset is expressed as the number of bytes from the start of the file (i.e., seeking to offset 0 places the pointer at the first byte in the file). \n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nfile\n\n\nPointer to the file to reposition\n\n\n\n\n\n\noffset\n\n\nThe 0-based file offset to seek to\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_getpos \n\n\n   uint32_t\n   fs_getpos(const struct fs_file *file);\n\n\n\n\nRetrieves the current read and write position
  of the specified open file. \n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nfile\n\n\nPointer to the file to query\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\nThe file offset, in bytes\n\n\n\n\nNotes\n\n\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_filelen \n\n\n   int\n   fs_filelen(const struct fs_file *file, uint32_t *out_len);\n\n\n\n\n\nRetrieves the current length of the specified open file.\n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nfile\n\n\nPointer to the file to query\n\n\n\n\n\n\nout_len\n\n\nOn success, the number of bytes in the file gets written here\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_unlink \n\n\n   int\n   fs_unlink(const char *filename);\n\n\n\n\n\nUnlinks the file or directory at the specified path.  If the path refers to a directory, all the
  directory's descendants are recursively unlinked.  Any open file handles refering to an unlinked file remain valid, and can be read from and written to.\n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nfilename\n\n\nThe path of the file or directory to unlink\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_rename \n\n\n   int\n   fs_rename(const char *from, const char *to);\n\n\n\n\n\nPerforms a rename and / or move of the specified source path to the specified destination.  \n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\nfrom\n\n\nThe source path\n\n\n\n\n\n\nto\n\n\nThe destination path\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\nThe source path can refer to either a file or a directory.  All intermediate directories in the destination path must
  already exist.  If the source path refers to a file, the destination path must contain a full filename path, rather than just the new parent directory.  If an object already exists at the specified destination path, this function causes it to be unlinked prior to the rename (i.e., the destination gets clobbered).\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_mkdir \n\n\n   int\n   fs_mkdir(const char *path);\n\n\n\n\n\nCreates the directory represented by the specified path.  \n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\npath\n\n\nPointer to the directory to create\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure.\n\n\n\n\nNotes\n\n\nAll intermediate directories must already exist.  The specified path must start with a '/' character.\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_opendir \n\n\n\n   int\n   fs_opendir(const char *path, struct fs_dir **out_dir);\n\n\n\n\n\n
 Opens the directory at the specified path.  The directory's contents can be read with subsequent calls to fs_readdir().  When you are done with the directory handle, close it with fs_closedir(). \n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\npath\n\n\nPointer to the directory to create\n\n\n\n\n\n\nout_dir\n\n\nOn success, points to the directory handle\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nFS_ENOENT if the specified directory does not exist (no such file)\n\n\nOther nonzero on error.\n\n\n\n\nNotes\n\n\nUnlinking files from the directory while it is open may result in unpredictable behavior.  New files can be created inside the directory.\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_readdir \n\n\n   int\n   fs_readdir(struct fs_dir *dir, struct fs_dirent **out_dirent);\n\n\n\n\n\nReads the next entry in an open directory. \n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\n
 dir\n\n\nThe directory handle to read from\n\n\n\n\n\n\nout_dirent\n\n\nOn success, points to the next child entry in the specified directory\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nFS_ENOENT if there are no more entries in the parent directory\n\n\nOther nonzero on error.\n\n\n\n\nNotes\n\n\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_closedir \n\n\n   int\n   fs_closedir(struct fs_dir *dir);\n\n\n\n\n\nCloses the specified directory handle. \n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\ndir\n\n\nPointer to the directory to close\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_dirent_name \n\n\n   int\n   fs_dirent_name(const struct fs_dirent *dirent, size_t max_len,\n     char *out_name, uint8_t *out_name_len);\n\n\n\n\n\nRetrieves the filename of the specified directory entry. \n\n\nA
 rguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\ndirent\n\n\nPointer to the directory entry to query\n\n\n\n\n\n\nmax_len\n\n\nSize of the \"out_name\" character buffer\n\n\n\n\n\n\nout_name\n\n\nOn success, the entry's filename is written here; always null-terminated\n\n\n\n\n\n\nout_name_len\n\n\nOn success, contains the actual length of the filename, NOT including the null-terminator\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\nThe retrieved filename is always null-terminated.  To ensure enough space to hold the full filename plus a null-termintor, a destination buffer of size  (filename max length + 1) should be used.\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fs_dirent_is_dir \n\n\n   int\n   fs_dirent_is_dir(const struct fs_dirent *dirent);\n\n\n\n\n\nTells you whether the specified directory entry is a sub-directory or a regular file. \n\n\nArguments\n\n\n\n\n\n\n\n\nArgumen
 ts\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\ndirent\n\n\nPointer to the directory entry to query\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n1: The entry is a directory\n\n\n0: The entry is a regular file.\n\n\n\n\nNotes\n\n\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fsutil_read_file \n\n\n   int\n   fsutil_read_file(const char *path, uint32_t offset, uint32_t len, void *dst,\n                    uint32_t *out_len);\n\n\n\n\nCalls fs_open(), fs_read(), and fs_close() to open a file at the specified path, retrieve data from the file starting from the specified offset, and close the file and invalidate the file handle.\n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\npath\n\n\nPointer to the directory entry to query\n\n\n\n\n\n\noffset\n\n\nPosition of the file's read pointer\n\n\n\n\n\n\nlen\n\n\nNumber of bytes to attempt to read\n\n\n\n\n\n\ndst\n\n\nDestination buffer to read into\n\n\n\n\n\n\nout_len\n\n\nOn success, the number of 
 bytes actually read gets written here.  Pass null if you don't care.\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\n\n\nExample\n\n\n\n\nInsert the code snippet here\n\n\n\n\n\n\n\n fsutil_write_file \n\n\n   int\n   fsutil_write_file(const char *path, const void *data, uint32_t len);\n\n\n\n\nCalls fs_open(), fs_write(), and fs_close() to open a file at the specified path, write the supplied data to the current offset of the specified file handle, and close the file and invalidate the file handle.\n\n\nArguments\n\n\n\n\n\n\n\n\nArguments\n\n\nDescription\n\n\n\n\n\n\n\n\n\n\npath\n\n\nPointer to the file to write to\n\n\n\n\n\n\ndata\n\n\nThe data to write\n\n\n\n\n\n\nlen\n\n\nThe number of bytes to write\n\n\n\n\n\n\n\n\nReturned values\n\n\n\n\n0 on success\n\n\nnonzero on failure\n\n\n\n\nNotes\n\n\n\n\nExample\n\n\n\n\nInsert the code snippet here", 
+            "title": "File System Abstraction"
         }, 
         {
             "location": "/modules/filesystem/#filesystem", 
@@ -917,48 +917,118 @@
         }, 
         {
             "location": "/modules/filesystem/#description", 
-            "text": "The default file system used in the Mynewt OS is the Newtron Flash File System (nffs). Hence the  nffs  egg description lists  libs/fs  as a dependency.   egg.name: libs/nffs\negg.vers: 0.1\negg.identities: NFFS\negg.deps:\n    - libs/os\n    - libs/fs\n    - libs/testutil\n    - hw/hal  If the user wishes to use a different flash file system (say, \"ownffs\"), the directory containing \"ownffs\" code must include the  egg.yml  file with the dependency on  libs/fs  listed as shown above. \"ownffs\" uses the  libs/fs  API available in mynewt, thus eliminating the need to change other parts of the projec.", 
+            "text": "The default file system used in the Mynewt OS is the Newtron Flash File System (nffs). Hence the  nffs  egg description lists  libs/fs  as a dependency.   egg.name: libs/nffs\negg.vers: 0.1\negg.identities: NFFS\negg.deps:\n    - libs/os\n    - libs/fs\n    - libs/testutil\n    - hw/hal  If the user wishes to use a different flash file system (say, \"ownffs\"), the directory containing \"ownffs\" code must include the  egg.yml  file stating the dependency on  libs/fs  listed as shown above. \"ownffs\" uses the  libs/fs  API available in mynewt, thus minimizing changes to other parts of the project.  Note that this generic file system ( fs ) API does not expose any file system detection, initialization, and formatting functions. These function calls remain specific to the chosen file system. For example, Project Slinky uses the default Newtron File System (nffs) and therefore calls nffs_init() to initialize the nffs memory and data structures before any other fil
 e system operations are attempted. As shown below, the egg for Project Slinky includes the  libs/imgmgr  egg which in turn includes the  libs/bootutil  egg. The egg description for  libs/bootutil  specifies  fs/nffs  as a dependency.  \n    egg.name: project/slinky\n    egg.vers: 0.1\n    egg.deps:\n        - libs/os\n        - libs/console/full\n        - libs/shell\n        - libs/newtmgr\n        - libs/imgmgr\n        - sys/config\n        - sys/log\n        - sys/stats  \n    egg.name: libs/imgmgr\n    egg.vers: 0.1\n    egg.deps:\n        - libs/newtmgr\n        - libs/bootutil\n    egg.deps.FS:\n        - fs/fs\n    egg.cflags.FS: -DFS_PRESENT  \n    egg.name: libs/bootutil\n    egg.vers: 0.1 \n    egg.deps: \n        - fs/nffs\n        - libs/os \n        - libs/testutil\n        - hw/hal", 
             "title": "Description"
         }, 
         {
             "location": "/modules/filesystem/#data-structures", 
             "text": "", 
-            "title": "Data structures"
+            "title": "Data Structures"
         }, 
         {
-            "location": "/modules/filesystem/#list-of-functions", 
-            "text": "The functions available in this OS feature are:   fs_ls_file  fs_ls_dir  add the rest", 
-            "title": "List of Functions"
+            "location": "/modules/filesystem/#api", 
+            "text": "struct fs_file;  The functions available in this OS feature are:   fs_open  fs_close  fs_read  fs_write  fs_seek  fs_getpos  fs_filelen  fs_unlink  fs_rename  fs_mkdir  fs_opendir  fs_readdir  fs_closedir  fs_dirent_name  fs_dirent_is_dir   Additional file system utilities that bundle some of the basic functions above are:   fsutil_read_file  fsutil_write_file", 
+            "title": "API"
         }, 
         {
-            "location": "/modules/filesystem/#function-reference", 
+            "location": "/modules/filesystem/#api-reference", 
             "text": "", 
-            "title": "Function Reference"
+            "title": "API Reference"
         }, 
         {
-            "location": "/modules/filesystem/#fs_ls_file", 
-            "text": "static void\n    fs_ls_file(const char *name, struct fs_file *file)   Arguments     Arguments  Description      name  explain argument    file  explain argument     Returned values  List any values returned.\nError codes?  Notes  Any special feature/special benefit that we want to tout. \nDoes it need to be used with some other specific functions?\nAny caveats to be careful about (e.g. high memory requirements).  Example    Insert the code snippet here", 
-            "title": " fs_ls_file "
+            "location": "/modules/filesystem/#fs_open", 
+            "text": "int\n    fs_open(const char *filename, uint8_t access_flags, struct fs_file **out_file);  Opens a file at the specified path.  The result of opening a nonexistent file depends on the access flags specified.  All intermediate directories must already exist.  By default (when nffs is the underlying filesystem used) the mode strings passed to fopen() map to nffs_open()'s access flags as follows:       r   -  NFFS_ACCESS_READ\n     r+  -  NFFS_ACCESS_READ | NFFS_ACCESS_WRITE\n     w   -  NFFS_ACCESS_WRITE | NFFS_ACCESS_TRUNCATE\n     w+  -  NFFS_ACCESS_READ | NFFS_ACCESS_WRITE | NFFS_ACCESS_TRUNCATE\n     a   -  NFFS_ACCESS_WRITE | NFFS_ACCESS_APPEND\n     a+  -  NFFS_ACCESS_READ | NFFS_ACCESS_WRITE | NFFS_ACCESS_APPEND  Arguments     Arguments  Description      filename  Pointer to the file created at the path of the specified filename    access_flags  Flags controlling file access; see above table    out_file  On success, a pointer to the newly-created file handle
  gets written here     Returned values   0 on success  nonzero on failure   Notes  Any special feature/special benefit that we want to tout. \nDoes it need to be used with some other specific functions?\nAny caveats to be careful about (e.g. high memory requirements).  Example    Insert the code snippet here", 
+            "title": " fs_open "
         }, 
         {
-            "location": "/modules/filesystem/#fs_ls_dir", 
-            "text": "static void\n   fs_ls_dir(const char *name)   Arguments     Arguments  Description      xx  explain argument xx    yy  explain argument yy     Returned values  List any values returned.\nError codes?  Notes  Any special feature/special benefit that we want to tout. \nDoes it need to be used with some other specific functions?\nAny caveats to be careful about (e.g. high memory requirements).  Example    Insert the code snippet here", 
-            "title": " fs_ls_dir "
+            "location": "/modules/filesystem/#fs_close", 
+            "text": "int\n   fs_close(struct fs_file *file);    Closes the specified file and invalidates the file handle.  If the file has already been unlinked, and this is the last open handle to the file, this operation causes the file to be deleted from disk.  Arguments     Arguments  Description      file  Pointer to the file to close     Returned values   0 on success  nonzero on failure   Notes  Any special feature/special benefit that we want to tout. \nDoes it need to be used with some other specific functions?\nAny caveats to be careful about (e.g. high memory requirements).  Example    Insert the code snippet here", 
+            "title": " fs_close "
         }, 
         {
-            "location": "/modules/filesystem/#next_one", 
-            "text": "Insert function callout here     Arguments     Arguments  Description      xx  explain argument xx    yy  explain argument yy     Returned values  List any values returned.\nError codes?  Notes  Any special feature/special benefit that we want to tout. \nDoes it need to be used with some other specific functions?\nAny caveats to be careful about (e.g. high memory requirements).  Example   Insert the code snippet here", 
-            "title": " next_one "
+            "location": "/modules/filesystem/#fs_read", 
+            "text": "int\n   fs_read(struct fs_file *file, uint32_t len, void *out_data, uint32_t *out_len);  Reads data from the specified file.  If more data is requested than remains in the file, all available data is retrieved.    Arguments     Arguments  Description      file  Pointer to the the file to read from    len  The number of bytes to attempt to read    out_data  The destination buffer to read into    out_len  On success, the number of bytes actually read gets written here.  Pass null if you don't care.     Returned values   0 on success  nonzero on failure   Notes  This type of short read results in a success return code.  Example   Insert the code snippet here", 
+            "title": " fs_read "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_write", 
+            "text": "int\n   fs_write(struct fs_file *file, const void *data, int len);  Writes the supplied data to the current offset of the specified file handle.    Arguments     Arguments  Description      file  Pointer to the file to write to    data  The data to write    len  The number of bytes to write     Returned values   0 on success  nonzero on failure   Notes   Example   Insert the code snippet here", 
+            "title": " fs_write "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_seek", 
+            "text": "int\n   fs_seek(struct fs_file *file, uint32_t offset);  Positions a file's read and write pointer at the specified offset.  The offset is expressed as the number of bytes from the start of the file (i.e., seeking to offset 0 places the pointer at the first byte in the file).   Arguments     Arguments  Description      file  Pointer to the file to reposition    offset  The 0-based file offset to seek to     Returned values   0 on success  nonzero on failure   Notes   Example   Insert the code snippet here", 
+            "title": " fs_seek "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_getpos", 
+            "text": "uint32_t\n   fs_getpos(const struct fs_file *file);  Retrieves the current read and write position of the specified open file.   Arguments     Arguments  Description      file  Pointer to the file to query     Returned values   The file offset, in bytes   Notes   Example   Insert the code snippet here", 
+            "title": " fs_getpos "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_filelen", 
+            "text": "int\n   fs_filelen(const struct fs_file *file, uint32_t *out_len);  Retrieves the current length of the specified open file.  Arguments     Arguments  Description      file  Pointer to the file to query    out_len  On success, the number of bytes in the file gets written here     Returned values   0 on success  nonzero on failure   Notes   Example   Insert the code snippet here", 
+            "title": " fs_filelen "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_unlink", 
+            "text": "int\n   fs_unlink(const char *filename);  Unlinks the file or directory at the specified path.  If the path refers to a directory, all the directory's descendants are recursively unlinked.  Any open file handles refering to an unlinked file remain valid, and can be read from and written to.  Arguments     Arguments  Description      filename  The path of the file or directory to unlink     Returned values   0 on success  nonzero on failure   Notes   Example   Insert the code snippet here", 
+            "title": " fs_unlink "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_rename", 
+            "text": "int\n   fs_rename(const char *from, const char *to);  Performs a rename and / or move of the specified source path to the specified destination.    Arguments     Arguments  Description      from  The source path    to  The destination path     Returned values   0 on success  nonzero on failure   Notes  The source path can refer to either a file or a directory.  All intermediate directories in the destination path must already exist.  If the source path refers to a file, the destination path must contain a full filename path, rather than just the new parent directory.  If an object already exists at the specified destination path, this function causes it to be unlinked prior to the rename (i.e., the destination gets clobbered).  Example   Insert the code snippet here", 
+            "title": " fs_rename "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_mkdir", 
+            "text": "int\n   fs_mkdir(const char *path);  Creates the directory represented by the specified path.    Arguments     Arguments  Description      path  Pointer to the directory to create     Returned values   0 on success  nonzero on failure.   Notes  All intermediate directories must already exist.  The specified path must start with a '/' character.  Example   Insert the code snippet here", 
+            "title": " fs_mkdir "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_opendir", 
+            "text": "int\n   fs_opendir(const char *path, struct fs_dir **out_dir);  Opens the directory at the specified path.  The directory's contents can be read with subsequent calls to fs_readdir().  When you are done with the directory handle, close it with fs_closedir().   Arguments     Arguments  Description      path  Pointer to the directory to create    out_dir  On success, points to the directory handle     Returned values   0 on success  FS_ENOENT if the specified directory does not exist (no such file)  Other nonzero on error.   Notes  Unlinking files from the directory while it is open may result in unpredictable behavior.  New files can be created inside the directory.  Example   Insert the code snippet here", 
+            "title": " fs_opendir "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_readdir", 
+            "text": "int\n   fs_readdir(struct fs_dir *dir, struct fs_dirent **out_dirent);  Reads the next entry in an open directory.   Arguments     Arguments  Description      dir  The directory handle to read from    out_dirent  On success, points to the next child entry in the specified directory     Returned values   0 on success  FS_ENOENT if there are no more entries in the parent directory  Other nonzero on error.   Notes   Example   Insert the code snippet here", 
+            "title": " fs_readdir "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_closedir", 
+            "text": "int\n   fs_closedir(struct fs_dir *dir);  Closes the specified directory handle.   Arguments     Arguments  Description      dir  Pointer to the directory to close     Returned values   0 on success  nonzero on failure   Notes   Example   Insert the code snippet here", 
+            "title": " fs_closedir "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_dirent_name", 
+            "text": "int\n   fs_dirent_name(const struct fs_dirent *dirent, size_t max_len,\n     char *out_name, uint8_t *out_name_len);  Retrieves the filename of the specified directory entry.   Arguments     Arguments  Description      dirent  Pointer to the directory entry to query    max_len  Size of the \"out_name\" character buffer    out_name  On success, the entry's filename is written here; always null-terminated    out_name_len  On success, contains the actual length of the filename, NOT including the null-terminator     Returned values   0 on success  nonzero on failure   Notes  The retrieved filename is always null-terminated.  To ensure enough space to hold the full filename plus a null-termintor, a destination buffer of size  (filename max length + 1) should be used.  Example   Insert the code snippet here", 
+            "title": " fs_dirent_name "
+        }, 
+        {
+            "location": "/modules/filesystem/#fs_dirent_is_dir", 
+            "text": "int\n   fs_dirent_is_dir(const struct fs_dirent *dirent);  Tells you whether the specified directory entry is a sub-directory or a regular file.   Arguments     Arguments  Description      dirent  Pointer to the directory entry to query     Returned values   1: The entry is a directory  0: The entry is a regular file.   Notes   Example   Insert the code snippet here", 
+            "title": " fs_dirent_is_dir "
+        }, 
+        {
+            "location": "/modules/filesystem/#fsutil_read_file", 
+            "text": "int\n   fsutil_read_file(const char *path, uint32_t offset, uint32_t len, void *dst,\n                    uint32_t *out_len);  Calls fs_open(), fs_read(), and fs_close() to open a file at the specified path, retrieve data from the file starting from the specified offset, and close the file and invalidate the file handle.  Arguments     Arguments  Description      path  Pointer to the directory entry to query    offset  Position of the file's read pointer    len  Number of bytes to attempt to read    dst  Destination buffer to read into    out_len  On success, the number of bytes actually read gets written here.  Pass null if you don't care.     Returned values   0 on success  nonzero on failure   Notes   Example   Insert the code snippet here", 
+            "title": " fsutil_read_file "
+        }, 
+        {
+            "location": "/modules/filesystem/#fsutil_write_file", 
+            "text": "int\n   fsutil_write_file(const char *path, const void *data, uint32_t len);  Calls fs_open(), fs_write(), and fs_close() to open a file at the specified path, write the supplied data to the current offset of the specified file handle, and close the file and invalidate the file handle.  Arguments     Arguments  Description      path  Pointer to the file to write to    data  The data to write    len  The number of bytes to write     Returned values   0 on success  nonzero on failure   Notes   Example   Insert the code snippet here", 
+            "title": " fsutil_write_file "
         }, 
         {
             "location": "/modules/nffs/", 
-            "text": "Newtron Flash Filesystem\n\n\nMynewt comes with the flash file system called the Newtron Flash File System (nffs) which is designed with two priorities that makes it suitable for embedded use: \n\n\n\n\nMinimal RAM usage\n\n\nReliability\n\n\n\n\nMynewt also provides an abstraction layer API (fs) to allow you to swap out nffs with a different file system of your choice.\n\n\nDescription\n\n\nDescribe module here, special features, how pieces fit together etc.\n\n\nDisk and data structures\n\n\nAt the top level, an nffs disk is partitioned into areas.  An area is a region\nof disk with the following properties:\n\n\n\n\nAn area can be fully erased without affecting any other areas.\n\n\nA write to one area does not restrict writes to other areas.\n\n\n\n\nNote\n: Some flash hardware divides its memory space into \"blocks.\"  Writes within a block must be sequential, but writes to one block have no effect on what parts of other blocks can be written.  Thus, for fl
 ash hardware with such a restriction, each area must comprise a discrete number of blocks.\n\n\nWhile not strictly necessary, it is recommended that all areas have the same\nsize.\n\n\nOn disk, each area is prefixed with the following header:\n\n\n/** On-disk representation of an area header. */\nstruct nffs_disk_area {\n    uint32_t nda_magic[4];  /* NFFS_AREA_MAGIC{0,1,2,3} */\n    uint32_t nda_length;    /* Total size of area, in bytes. */\n    uint8_t nda_ver;        /* Current nffs version: 0 */\n    uint8_t nda_gc_seq;     /* Garbage collection count. */\n    uint8_t reserved8;\n    uint8_t nda_id;         /* 0xff if scratch area. */\n};\n\n\n\n\nBeyond its header, an area contains a sequence of disk objects, representing\nthe contents of the file system.  There are two types of objects: \ninodes\n and\n\ndata blocks\n.  An inode represents a file or directory; a data block represents\npart of a file's contents.\n\n\n/** On-disk representation of an inode (file or directory). 
 */\nstruct nffs_disk_inode {\n    uint32_t ndi_magic;         /* NFFS_INODE_MAGIC */\n    uint32_t ndi_id;            /* Unique object ID. */\n    uint32_t ndi_seq;           /* Sequence number; greater supersedes\n                                   lesser. */\n    uint32_t ndi_parent_id;     /* Object ID of parent directory inode. */\n    uint8_t reserved8;\n    uint8_t ndi_filename_len;   /* Length of filename, in bytes. */\n    uint16_t ndi_crc16;         /* Covers rest of header and filename. */\n    /* Followed by filename. */\n};\n\n\n\n\nAn inode filename's length cannot exceed 256 bytes.  The filename is not\nnull-terminated.  The following ASCII characters are not allowed in a\nfilename:\n    * /  (slash character)\n    * \\0 (NUL character)\n\n\n/** On-disk representation of a data block. */\nstruct nffs_disk_block {\n    uint32_t ndb_magic;     /* NFFS_BLOCK_MAGIC */\n    uint32_t ndb_id;        /* Unique object ID. */\n    uint32_t ndb_seq;       /* Sequence number; grea
 ter supersedes lesser. */\n    uint32_t ndb_inode_id;  /* Object ID of owning inode. */\n    uint32_t ndb_prev_id;   /* Object ID of previous block in file;\n                               NFFS_ID_NONE if this is the first block. */\n    uint16_t ndb_data_len;  /* Length of data contents, in bytes. */\n    uint16_t ndb_crc16;     /* Covers rest of header and data. */\n    /* Followed by 'ndb_data_len' bytes of data. */\n};\n\n\n\n\nEach data block contains the ID of the previous data block in the file.\nTogether, the set of blocks in a file form a reverse singly-linked list.\n\n\nThe maximum number of data bytes that a block can contain is determined at\ninitialization-time.  The result is the greatest number which satisfies all of\nthe following restrictions:\n    o No more than 2048.\n    o At least two maximum-sized blocks can fit in the smallest area.\n\n\nThe 2048 number was chosen somewhat arbitrarily, and may change in the future.\n\n\nID space\n\n\nAll disk objects have a un
 ique 32-bit ID.  The ID space is partitioned as\nfollows:\n      * 0x00000000 - 0x0fffffff: Directory inodes.\n      * 0x10000000 - 0x7fffffff: File inodes.\n      * 0x80000000 - 0xfffffffe: Data blocks.\n      * 0xffffffff             : Reserved (NFFS_ID_NONE)\n\n\nScratch area\n\n\nA valid nffs file system must contain a single \"scratch area.\"  The scratch\narea does not contain any objects of its own, and is only used during garbage\ncollection.  The scratch area must have a size greater than or equal to each\nof the other areas in flash.\n\n\nRAM representation\n\n\nEvery object in the file system is stored in a 256-entry hash table.  An\nobject's hash key is derived from its 32-bit ID.  Each list in the hash table\nis sorted by time of use; most-recently-used is at the front of the list. All\nobjects are represented by the following structure:\n\n\n/**\n * What gets stored in the hash table.  Each entry represents a data block or\n * an inode.\n */\nstruct nffs_hash_entry {\n
     SLIST_ENTRY(nffs_hash_entry) nhe_next;\n    uint32_t nhe_id;        /* 0 - 0x7fffffff if inode; else if block. */\n    uint32_t nhe_flash_loc; /* Upper-byte = area idx; rest = area offset. */\n};\n\n\n\n\nFor each data block, the above structure is all that is stored in RAM.  To\nacquire more information about a data block, the block header must be read\nfrom flash.\n\n\nInodes require a fuller RAM representation to capture the structure of the\nfile system.  There are two types of inodes: \nfiles\n and \ndirectories\n.  Each\ninode hash entry is actually an instance of the following structure:\n\n\n/** Each inode hash entry is actually one of these. */\nstruct nffs_inode_entry {\n    struct nffs_hash_entry nie_hash_entry;\n    SLIST_ENTRY(nffs_inode_entry) nie_sibling_next;\n    union {\n        struct nffs_inode_list nie_child_list;           /* If directory */\n        struct nffs_hash_entry *nie_last_block_entry;    /* If file */\n    };\n    uint8_t nie_refcnt;\n};\n\n\n\n\
 nA directory inode contains a list of its child files and directories\n(fie_child_list).  These entries are sorted alphabetically using the ASCII\ncharacter set.\n\n\nA file inode contains a pointer to the last data block in the file\n(nie_last_block_entry).  For most file operations, the reversed block list must\nbe walked backwards.  This introduces a number of speed inefficiencies:\n    * All data blocks must be read to determine the length of the file.\n    * Data blocks often need to be processed sequentially.  The reversed\n      nature of the block list transforms this from linear time to an O(n^2)\n      operation.\n\n\nFurthermore, obtaining information about any constituent data block requires a\nseparate flash read.\n\n\nInode cache and Data Block cache\n\n\nThe speed issues are addressed by a pair of caches.  Cached inodes entries\ncontain the file length and a much more convenient doubly-linked list of\ncached data blocks.  The benefit of using caches is that the size o
 f the\ncaches need not be proportional to the size of the file system.  In other\nwords, caches can address speed efficiency concerns without negatively\nimpacting the file system's scalability.\n\n\nnffs requires both caches during normal operation, so it is not possible to\ndisable them.  However, the cache sizes are configurable, and both caches can\nbe configured with a size of one if RAM usage must be minimized.\n\n\nThe following data structures are used in the inode and data block caches.\n\n\n/** Full data block representation; not stored permanently in RAM. */\nstruct nffs_block {\n    struct nffs_hash_entry *nb_hash_entry;   /* Points to real block entry. */\n    uint32_t nb_seq;                         /* Sequence number; greater\n                                                supersedes lesser. */\n    struct nffs_inode_entry *nb_inode_entry; /* Owning inode. */\n    struct nffs_hash_entry *nb_prev;         /* Previous block in file. */\n    uint16_t nb_data_len;       
              /* # of data bytes in block. */\n    uint16_t reserved16;\n};\n\n/** Represents a single cached data block. */\nstruct nffs_cache_block {\n    TAILQ_ENTRY(nffs_cache_block) ncb_link; /* Next / prev cached block. */\n    struct nffs_block ncb_block;            /* Full data block. */\n    uint32_t ncb_file_offset;               /* File offset of this block. */\n};\n\n/** Full inode representation; not stored permanently in RAM. */\nstruct nffs_inode {\n    struct nffs_inode_entry *ni_inode_entry; /* Points to real inode entry. */\n    uint32_t ni_seq;                         /* Sequence number; greater\n                                                supersedes lesser. */\n    struct nffs_inode_entry *ni_parent;      /* Points to parent directory. */\n    uint8_t ni_filename_len;                 /* # chars in filename. */\n    uint8_t ni_filename[NFFS_SHORT_FILENAME_LEN]; /* First 3 bytes. */\n};\n\n/** Doubly-linked tail queue of cached blocks; contained in cached inodes
 . */\nTAILQ_HEAD(nffs_block_cache_list, nffs_block_cache_entry);\n\n/** Represents a single cached file inode. */\nstruct nffs_cache_inode {\n    TAILQ_ENTRY(nffs_cache_inode) nci_link;        /* Sorted; LRU at tail. */\n    struct nffs_inode nci_inode;                   /* Full inode. */\n    struct nffs_cache_block_list nci_block_list;   /* List of cached blocks. */\n    uint32_t nci_file_size;                        /* Total file size. */\n};\n\n\n\n\nOnly file inodes are cached; directory inodes are never cached.\n\n\nWithin a cached inode, all cached data blocks are contiguous.  E.g., if the\nstart and end of a file are cached, then the middle must also be cached.  A\ndata block is only cached if its owning file is also cached.\n\n\nInternally, cached inodes are stored in a singly-linked list, ordered by time\nof use.  The most-recently-used entry is the first element in the list.  If a\nnew inode needs to be cached, but the inode cache is full, the\nleast-recently-used entry i
 s freed to make room for the new one.  The\nfollowing operations cause an inode to be cached:\n\n\n\n\nQuerying a file's length.\n\n\nSeeking within a file.\n\n\nReading from a file.\n\n\nWriting to a file.\n\n\n\n\nThe following operations cause a data block to be cached:\n\n\n\n\nReading from the block.\n\n\nWriting to the block.\n\n\n\n\nIf one of the above operations is applied to a data block that is not currently\ncached, nffs uses the following procedure to cache the necessary block:\n\n\n\n\nIf none of the owning inode's blocks are currently cached, allocate a\n       cached block entry corresponding to the requested block and insert it\n       into the inode's list.\n\n\nElse if the requested file offset is less than that of the first cached\n       block, bridge the gap between the inode's sequence of cached blocks and\n       the block that now needs to be cached.  This is accomplished by caching\n       each block in the gap, finishing with the requested block.\n\n\nElse
  (the requested offset is beyond the end of the cache),\n   a. If the requested offset belongs to the block that immediately follows the end of the cache, cache the block and append it to the list.\n   b. Else, clear the cache, and populate it with the single entry corresponding to the requested block.\n\n\n\n\nIf the system is unable to allocate a cached block entry at any point during\nthe above procedure, the system frees up other blocks currently in the cache. This is accomplished as follows:\n\n\n\n\nIterate the inode cache in reverse (i.e., start with the least-recently-used entry).  For each entry:\n   a. If the entry's cached block list is empty, advance to the next entry.\n   b. Else, free all the cached blocks in the entry's list.\n\n\n\n\nBecause the system imposes a minimum block cache size of one, the above\nprocedure will always reclaim at least one cache block entry.  The above\nprocedure may result in the freeing of the block list that belongs to the very\ninode bein
 g operated on.  This is OK, as the final block to get cached is\nalways the block being requested.\n\n\nConfiguration\n\n\nThe file system is configured by populating fields in a global structure.\nEach field in the structure corresponds to a setting.  All configuration must\nbe done prior to calling nffs_init().  The configuration structure is defined\nas follows:\n\n\n\nstruct nffs_config {\n    /** Maximum number of inodes; default=1024. */\n    uint32_t nc_num_inodes;\n\n    /** Maximum number of data blocks; default=4096. */\n    uint32_t nc_num_blocks;\n\n    /** Maximum number of open files; default=4. */\n    uint32_t nc_num_files;\n\n    /** Inode cache size; default=4. */\n    uint32_t nc_num_cache_inodes;\n\n    /** Data block cache size; default=64. */\n    uint32_t nc_num_cache_blocks;\n    };\n\nextern struct nffs_config nffs_config;\n\n\n\n\nAny fields that are set to 0 (or not set at all) inherit the corresponding\ndefault value.  This means that it is impossible to 
 configure any setting with\na value of zero.\n\n\nInitialization\n\n\nThere are two means of initializing an nffs file system:\n\n\n\n\nRestore an existing file system via detection.\n\n\nCreate a new file system via formatting.\n\n\n\n\nBoth methods require the user to describe how the flash memory is divided into\nareas.  This is accomplished with an array of struct nffs_area_desc, defined as\nfollows:\n\n\nstruct nffs_area_desc {\n    uint32_t nad_offset;    /* Flash offset of start of area. */\n    uint32_t nad_length;    /* Size of area, in bytes. */\n};\n\n\n\n\nAn array of area descriptors is terminated by an entry with a fad_length field\nof 0.\n\n\nOne common initialization sequence is the following:\n\n\n\n\nDetect an nffs file system anywhere in flash.\n\n\nIf no file system detected, format a new file system in a specific\n        region of flash.\n\n\n\n\nDetection\n\n\nThe file system detection process consists of scanning a specified set of\nflash regions for valid nf
 fs areas, and then populating the RAM representation\nof the file system with the detected objects.  Detection is initiated with the\nfollowing function:\n\n\n/**\n * Searches for a valid nffs file system among the specified areas.  This\n * function succeeds if a file system is detected among any subset of the\n * supplied areas.  If the area set does not contain a valid file system,\n * a new one can be created via a separate call to nffs_format().\n *\n * @param area_descs        The area set to search.  This array must be\n *                              terminated with a 0-length area.\n *\n * @return                  0 on success;\n *                          NFFS_ECORRUPT if no valid file system was detected;\n *                          other nonzero on error.\n */\nint nffs_detect(const struct nffs_area_desc *area_descs);\n\n\n\n\nAs indicated, not every area descriptor needs to reference a valid nffs area.\nDetection is successful as long as a complete file system is detec
 ted\nsomewhere in the specified regions of flash.  If an application is unsure\nwhere a file system might be located, it can initiate detection across the\nentire flash region.\n\n\nA detected file system is valid if:\n\n\n\n\nAt least one non-scratch area is present.\n\n\nAt least one scratch area is present (only the first gets used if there is more than one).\n\n\nThe root directory inode is present.\n\n\n\n\nDuring detection, each indicated region of flash is checked for a valid area\nheader.  The contents of each valid non-scratch area are then restored into\nthe nffs RAM representation.  The following procedure is applied to each object\nin the area:\n\n\n\n\n\n\nVerify the object's integrity via a crc16 check.  If invalid, the object is discarded and the procedure restarts on the next object in the area.\n\n\n\n\n\n\nConvert the disk object into its corresponding RAM representation and insert it into the hash table.  If the object is an inode, its reference count is initializ
 ed to 1, indicating ownership by its parent directory.\n\n\n\n\n\n\nIf an object with the same ID is already present, then one supersedes the other.  Accept the object with the greater sequence number and discard the other.\n\n\n\n\n\n\nIf the object references a nonexistant inode (parent directory in the case of an inode; owning file in the case of a data block), insert a temporary \"dummy\" inode into the hash table so that inter-object links can be maintained until the absent inode is eventually restored.  Dummy inodes are identified by a reference count of 0.\n\n\n\n\n\n\nIf a delete record for an inode is encountered, the inode's parent pointer is set to null to indicate that it should be removed from RAM.\n\n\n\n\n\n\nIf nffs encounters an object that cannot be identified (i.e., its magic number\nis not valid), it scans the remainder of the flash area for the next valid\nmagic number.  Upon encountering a valid object, nffs resumes the procedure\ndescribed above.\n\n\nAfter al
 l areas have been restored, a sweep is performed across the entire RAM\nrepresentation so that invalid inodes can be deleted from memory.\n\n\nFor each directory inode:\n\n\n\n\nIf its reference count is 0 (i.e., it is a dummy), migrate its children to the /lost+found directory, and delete it from the RAM representation. This should only happen in the case of file system corruption.\n\n\nIf its parent reference is null (i.e., it was deleted), delete it and all its children from the RAM representation.\n\n\n\n\nFor each file inode:\n\n\n\n\nIf its reference count is 0 (i.e., it is a dummy), delete it from the RAM representation.  This should only happen in the case of file system corruption.  (We should try to migrate the file to the lost+found directory in this case, as mentioned in the todo section).\n\n\n\n\nWhen an object is deleted during this sweep, it is only deleted from the RAM\nrepresentation; nothing is written to disk.\n\n\nWhen objects are migrated to the lost+found dire
 ctory, their parent inode\nreference is permanently updated on the disk.\n\n\nIn addition, a single scratch area is identified during the detection process.\nThe first area whose 'fda_id' value is set to 0xff is designated as the file\nsystem scratch area.  If no valid scratch area is found, the cause could be\nthat the system was restarted while a garbage collection cycle was in progress.\nSuch a condition is identified by the presence of two areas with the same ID.\nIn such a case, the shorter of the two areas is erased and designated as the\nscratch area.\n\n\nFormatting\n\n\nA new file system is created via formatting.  Formatting is achieved via the\nfollowing function:\n\n\n/**\n * Erases all the specified areas and initializes them with a clean nffs\n * file system.\n *\n * @param area_descs        The set of areas to format.\n *\n * @return                  0 on success;\n *                          nonzero on failure.\n */\nint nffs_format(const struct nffs_area_desc *area_
 descs);\n\n\n\n\nOn success, an area header is written to each of the specified locations.  The\nlargest area in the set is designated as the initial scratch area.\n\n\nFlash writes\n\n\nThe nffs implementation always writes in a strictly sequential fashion within an\narea.  For each area, the system keeps track of the current offset.  Whenever\nan object gets written to an area, it gets written to that area's current\noffset, and the offset is increased by the object's disk size.\n\n\nWhen a write needs to be performed, the nffs implementation selects the\nappropriate destination area by iterating though each area until one with\nsufficient free space is encountered.\n\n\nThere is no write buffering.  Each call to a write function results in a write\noperation being sent to the flash hardware.\n\n\nNew objects\n\n\nWhenever a new object is written to disk, it is assigned the following\nproperties:\n    * ID: A unique value is selected from the 32-bit ID space, as appropriate\n     
  for the object's type.\n    * Sequence number: 0\n\n\nWhen a new file or directory is created, a corresponding inode is written to\nflash.  Likewise, a new data block also results in the writing of a\ncorresponding disk object.\n\n\nMoving/Renaming files and directories\n\n\nWhen a file or directory is moved or renamed, its corresponding inode is\nrewritten to flash with the following properties:\n\n\n\n\nID: Unchanged\n\n\nSequence number: Previous value plus one.\n\n\nParent inode: As specified by the move / rename operation.\n\n\nFilename: As specified by the move / rename operation.\n\n\n\n\nBecause the inode's ID is unchanged, all dependent objects remain valid.\n\n\nUnlinking files and directories\n\n\nWhen a file or directory is unlinked from its parent directory, a deletion\nrecord for the unlinked inode gets written to flash.  The deletion record is an\ninode with the following properties:\n\n\n\n\nID: Unchanged\n\n\nSequence number: Previous value plus one.\n\n\nParent in
 ode ID: NFFS_ID_NONE\n\n\n\n\nWhen an inode is unlinked, no deletion records need to be written for the\ninode's dependent objects (constituent data blocks or child inodes).  During\nthe next file system detection, it is recognized that the objects belong to\na deleted inode, so they are not restored into the RAM representation.\n\n\nIf a file has an open handle at the time it gets unlinked, application code\ncan continued to use the file handle to read and write data.  All files retain\na reference count, and a file isn't deleted from the RAM representation until\nits reference code drops to 0.  Any attempt to open an unlinked file fails,\neven if the file is referenced by other file handles.\n\n\nWriting to a file\n\n\nThe following procedure is used whenever the application code writes to a file.\nFirst, if the write operation specifies too much data to fit into a single\nblock, the operation is split into several separate write operations.  Then,\nfor each write operation:\n\n\n
 1. Determine which existing blocks the write operation overlaps (n = number of overwritten blocks).\n\n\n2. If n = 0, this is an append operation.  Write a data block with the following properties:\n\n\n\n\nID: New unique value.\n\n\nSequence number: 0.\n\n\n\n\n3. Else (n \n 1), this write overlaps existing data.\n\n\n(a) For each block in [1, 2, ... n-1], write a new block containing the updated contents.  Each new block supersedes the block it overwrites.  That is, each block has the following properties:\n\n\n\n\nID: Unchanged\n\n\nSequence number: Previous value plus one.\n\n\n\n\n(b) Write the nth block.  The nth block includes all appended data, if any.  As with the other blocks, its ID is unchanged and its sequence number is incremented.\n\n\nAppended data can only be written to the end of the file.  That is, \"holes\" are\nnot supported.\n\n\nGarbage collection\n\n\nWhen the file system is too full to accomodate a write operation, the system\nmust perform garbage collection
  to make room.  The garbage collection\nprocedure is described below:\n\n\n\n\n\n\nThe non-scratch area with the lowest garbage collection sequence number is selected as the \"source area.\"  If there are other areas with the same sequence number, the one with the smallest flash offset is selected. \n\n\n\n\n\n\nThe source area's ID is written to the scratch area's header, transforming it into a non-scratch ID.  This former scratch area is now known as the \"destination area.\"\n\n\n\n\n\n\nThe RAM representation is exhaustively searched for collectible objects.  The following procedure is applied to each inode in the system:\n\n\n\n\nIf the inode is resident in the source area, copy the inode record to the destination area.\n\n\nIf the inode is a file inode, walk the inode's list of data blocks, starting with the last block in the file.  Each block that is resident in the source area is copied to the destination area.  If there is a run of two or more blocks that are resident in th
 e source area, they are consolidated and copied to the destination area as a single new block (subject to the maximum block size restriction).\n\n\n\n\n\n\n\n\nThe source area is reformatted as a scratch sector (i.e., is is fully erased, and its header is rewritten with an ID of 0xff).  The area's garbage collection sequence number is incremented prior to rewriting the header.  This area is now the new scratch sector.\n\n\n\n\n\n\nMiscellaneous measures\n\n\n\n\n\n\nRAM usage:\n\n\n\n\n24 bytes per inode\n\n\n12 bytes per data block\n\n\n36 bytes per inode cache entry\n\n\n32 bytes per data block cache entry\n\n\n\n\n\n\n\n\nMaximum filename size: 256 characters (no null terminator required)\n\n\n\n\nDisallowed filename characters: '/' and '\\0'\n\n\n\n\nFuture enhancements\n\n\n\n\nAPI function to traverse a directory.\n\n\nMigrate corrupt files to the /lost+found directory during restore, rather than discarding them from RAM.\n\n\nError correction.\n\n\nEncryption.\n\n\nCompressio
 n.", 
-            "title": "Newtron File System"
+            "text": "Newtron Flash Filesystem (nffs)\n\n\nMynewt comes with the flash file system called the Newtron Flash File System (nffs) which is designed with two priorities that makes it suitable for embedded use: \n\n\n\n\nMinimal RAM usage\n\n\nReliability\n\n\n\n\nMynewt also provides an abstraction layer API (fs) to allow you to swap out nffs with a different file system of your choice.\n\n\nDescription\n\n\nDescribe module here, special features, how pieces fit together etc.\n\n\nDisk and data structures\n\n\nAt the top level, an nffs disk is partitioned into areas.  An area is a region\nof disk with the following properties:\n\n\n\n\nAn area can be fully erased without affecting any other areas.\n\n\nA write to one area does not restrict writes to other areas.\n\n\n\n\nNote\n: Some flash hardware divides its memory space into \"blocks.\"  Writes within a block must be sequential, but writes to one block have no effect on what parts of other blocks can be written.  Thus,
  for flash hardware with such a restriction, each area must comprise a discrete number of blocks.\n\n\nWhile not strictly necessary, it is recommended that all areas have the same\nsize.\n\n\nOn disk, each area is prefixed with the following header:\n\n\n/** On-disk representation of an area header. */\nstruct nffs_disk_area {\n    uint32_t nda_magic[4];  /* NFFS_AREA_MAGIC{0,1,2,3} */\n    uint32_t nda_length;    /* Total size of area, in bytes. */\n    uint8_t nda_ver;        /* Current nffs version: 0 */\n    uint8_t nda_gc_seq;     /* Garbage collection count. */\n    uint8_t reserved8;\n    uint8_t nda_id;         /* 0xff if scratch area. */\n};\n\n\n\n\nBeyond its header, an area contains a sequence of disk objects, representing\nthe contents of the file system.  There are two types of objects: \ninodes\n and\n\ndata blocks\n.  An inode represents a file or directory; a data block represents\npart of a file's contents.\n\n\n/** On-disk representation of an inode (file or direc
 tory). */\nstruct nffs_disk_inode {\n    uint32_t ndi_magic;         /* NFFS_INODE_MAGIC */\n    uint32_t ndi_id;            /* Unique object ID. */\n    uint32_t ndi_seq;           /* Sequence number; greater supersedes\n                                   lesser. */\n    uint32_t ndi_parent_id;     /* Object ID of parent directory inode. */\n    uint8_t reserved8;\n    uint8_t ndi_filename_len;   /* Length of filename, in bytes. */\n    uint16_t ndi_crc16;         /* Covers rest of header and filename. */\n    /* Followed by filename. */\n};\n\n\n\n\nAn inode filename's length cannot exceed 256 bytes.  The filename is not\nnull-terminated.  The following ASCII characters are not allowed in a\nfilename:\n    * /  (slash character)\n    * \\0 (NUL character)\n\n\n/** On-disk representation of a data block. */\nstruct nffs_disk_block {\n    uint32_t ndb_magic;     /* NFFS_BLOCK_MAGIC */\n    uint32_t ndb_id;        /* Unique object ID. */\n    uint32_t ndb_seq;       /* Sequence numbe
 r; greater supersedes lesser. */\n    uint32_t ndb_inode_id;  /* Object ID of owning inode. */\n    uint32_t ndb_prev_id;   /* Object ID of previous block in file;\n                               NFFS_ID_NONE if this is the first block. */\n    uint16_t ndb_data_len;  /* Length of data contents, in bytes. */\n    uint16_t ndb_crc16;     /* Covers rest of header and data. */\n    /* Followed by 'ndb_data_len' bytes of data. */\n};\n\n\n\n\nEach data block contains the ID of the previous data block in the file.\nTogether, the set of blocks in a file form a reverse singly-linked list.\n\n\nThe maximum number of data bytes that a block can contain is determined at\ninitialization-time.  The result is the greatest number which satisfies all of\nthe following restrictions:\n    o No more than 2048.\n    o At least two maximum-sized blocks can fit in the smallest area.\n\n\nThe 2048 number was chosen somewhat arbitrarily, and may change in the future.\n\n\nID space\n\n\nAll disk objects ha
 ve a unique 32-bit ID.  The ID space is partitioned as\nfollows:\n      * 0x00000000 - 0x0fffffff: Directory inodes.\n      * 0x10000000 - 0x7fffffff: File inodes.\n      * 0x80000000 - 0xfffffffe: Data blocks.\n      * 0xffffffff             : Reserved (NFFS_ID_NONE)\n\n\nScratch area\n\n\nA valid nffs file system must contain a single \"scratch area.\"  The scratch\narea does not contain any objects of its own, and is only used during garbage\ncollection.  The scratch area must have a size greater than or equal to each\nof the other areas in flash.\n\n\nRAM representation\n\n\nEvery object in the file system is stored in a 256-entry hash table.  An\nobject's hash key is derived from its 32-bit ID.  Each list in the hash table\nis sorted by time of use; most-recently-used is at the front of the list. All\nobjects are represented by the following structure:\n\n\n/**\n * What gets stored in the hash table.  Each entry represents a data block or\n * an inode.\n */\nstruct nffs_hash_en
 try {\n    SLIST_ENTRY(nffs_hash_entry) nhe_next;\n    uint32_t nhe_id;        /* 0 - 0x7fffffff if inode; else if block. */\n    uint32_t nhe_flash_loc; /* Upper-byte = area idx; rest = area offset. */\n};\n\n\n\n\nFor each data block, the above structure is all that is stored in RAM.  To\nacquire more information about a data block, the block header must be read\nfrom flash.\n\n\nInodes require a fuller RAM representation to capture the structure of the\nfile system.  There are two types of inodes: \nfiles\n and \ndirectories\n.  Each\ninode hash entry is actually an instance of the following structure:\n\n\n/** Each inode hash entry is actually one of these. */\nstruct nffs_inode_entry {\n    struct nffs_hash_entry nie_hash_entry;\n    SLIST_ENTRY(nffs_inode_entry) nie_sibling_next;\n    union {\n        struct nffs_inode_list nie_child_list;           /* If directory */\n        struct nffs_hash_entry *nie_last_block_entry;    /* If file */\n    };\n    uint8_t nie_refcnt;\n};\n
 \n\n\n\nA directory inode contains a list of its child files and directories\n(fie_child_list).  These entries are sorted alphabetically using the ASCII\ncharacter set.\n\n\nA file inode contains a pointer to the last data block in the file\n(nie_last_block_entry).  For most file operations, the reversed block list must\nbe walked backwards.  This introduces a number of speed inefficiencies:\n    * All data blocks must be read to determine the length of the file.\n    * Data blocks often need to be processed sequentially.  The reversed\n      nature of the block list transforms this from linear time to an O(n^2)\n      operation.\n\n\nFurthermore, obtaining information about any constituent data block requires a\nseparate flash read.\n\n\nInode cache and Data Block cache\n\n\nThe speed issues are addressed by a pair of caches.  Cached inodes entries\ncontain the file length and a much more convenient doubly-linked list of\ncached data blocks.  The benefit of using caches is that the
  size of the\ncaches need not be proportional to the size of the file system.  In other\nwords, caches can address speed efficiency concerns without negatively\nimpacting the file system's scalability.\n\n\nnffs requires both caches during normal operation, so it is not possible to\ndisable them.  However, the cache sizes are configurable, and both caches can\nbe configured with a size of one if RAM usage must be minimized.\n\n\nThe following data structures are used in the inode and data block caches.\n\n\n/** Full data block representation; not stored permanently in RAM. */\nstruct nffs_block {\n    struct nffs_hash_entry *nb_hash_entry;   /* Points to real block entry. */\n    uint32_t nb_seq;                         /* Sequence number; greater\n                                                supersedes lesser. */\n    struct nffs_inode_entry *nb_inode_entry; /* Owning inode. */\n    struct nffs_hash_entry *nb_prev;         /* Previous block in file. */\n    uint16_t nb_data_len;
                     /* # of data bytes in block. */\n    uint16_t reserved16;\n};\n\n/** Represents a single cached data block. */\nstruct nffs_cache_block {\n    TAILQ_ENTRY(nffs_cache_block) ncb_link; /* Next / prev cached block. */\n    struct nffs_block ncb_block;            /* Full data block. */\n    uint32_t ncb_file_offset;               /* File offset of this block. */\n};\n\n/** Full inode representation; not stored permanently in RAM. */\nstruct nffs_inode {\n    struct nffs_inode_entry *ni_inode_entry; /* Points to real inode entry. */\n    uint32_t ni_seq;                         /* Sequence number; greater\n                                                supersedes lesser. */\n    struct nffs_inode_entry *ni_parent;      /* Points to parent directory. */\n    uint8_t ni_filename_len;                 /* # chars in filename. */\n    uint8_t ni_filename[NFFS_SHORT_FILENAME_LEN]; /* First 3 bytes. */\n};\n\n/** Doubly-linked tail queue of cached blocks; contained in cached
  inodes. */\nTAILQ_HEAD(nffs_block_cache_list, nffs_block_cache_entry);\n\n/** Represents a single cached file inode. */\nstruct nffs_cache_inode {\n    TAILQ_ENTRY(nffs_cache_inode) nci_link;        /* Sorted; LRU at tail. */\n    struct nffs_inode nci_inode;                   /* Full inode. */\n    struct nffs_cache_block_list nci_block_list;   /* List of cached blocks. */\n    uint32_t nci_file_size;                        /* Total file size. */\n};\n\n\n\n\nOnly file inodes are cached; directory inodes are never cached.\n\n\nWithin a cached inode, all cached data blocks are contiguous.  E.g., if the\nstart and end of a file are cached, then the middle must also be cached.  A\ndata block is only cached if its owning file is also cached.\n\n\nInternally, cached inodes are stored in a singly-linked list, ordered by time\nof use.  The most-recently-used entry is the first element in the list.  If a\nnew inode needs to be cached, but the inode cache is full, the\nleast-recently-used 
 entry is freed to make room for the new one.  The\nfollowing operations cause an inode to be cached:\n\n\n\n\nQuerying a file's length.\n\n\nSeeking within a file.\n\n\nReading from a file.\n\n\nWriting to a file.\n\n\n\n\nThe following operations cause a data block to be cached:\n\n\n\n\nReading from the block.\n\n\nWriting to the block.\n\n\n\n\nIf one of the above operations is applied to a data block that is not currently\ncached, nffs uses the following procedure to cache the necessary block:\n\n\n\n\nIf none of the owning inode's blocks are currently cached, allocate a\n       cached block entry corresponding to the requested block and insert it\n       into the inode's list.\n\n\nElse if the requested file offset is less than that of the first cached\n       block, bridge the gap between the inode's sequence of cached blocks and\n       the block that now needs to be cached.  This is accomplished by caching\n       each block in the gap, finishing with the requested block.\n\
 n\nElse (the requested offset is beyond the end of the cache),\n   a. If the requested offset belongs to the block that immediately follows the end of the cache, cache the block and append it to the list.\n   b. Else, clear the cache, and populate it with the single entry corresponding to the requested block.\n\n\n\n\nIf the system is unable to allocate a cached block entry at any point during\nthe above procedure, the system frees up other blocks currently in the cache. This is accomplished as follows:\n\n\n\n\nIterate the inode cache in reverse (i.e., start with the least-recently-used entry).  For each entry:\n   a. If the entry's cached block list is empty, advance to the next entry.\n   b. Else, free all the cached blocks in the entry's list.\n\n\n\n\nBecause the system imposes a minimum block cache size of one, the above\nprocedure will always reclaim at least one cache block entry.  The above\nprocedure may result in the freeing of the block list that belongs to the very\nino
 de being operated on.  This is OK, as the final block to get cached is\nalways the block being requested.\n\n\nConfiguration\n\n\nThe file system is configured by populating fields in a global structure.\nEach field in the structure corresponds to a setting.  All configuration must\nbe done prior to calling nffs_init().  The configuration structure is defined\nas follows:\n\n\n\nstruct nffs_config {\n    /** Maximum number of inodes; default=1024. */\n    uint32_t nc_num_inodes;\n\n    /** Maximum number of data blocks; default=4096. */\n    uint32_t nc_num_blocks;\n\n    /** Maximum number of open files; default=4. */\n    uint32_t nc_num_files;\n\n    /** Inode cache size; default=4. */\n    uint32_t nc_num_cache_inodes;\n\n    /** Data block cache size; default=64. */\n    uint32_t nc_num_cache_blocks;\n    };\n\nextern struct nffs_config nffs_config;\n\n\n\n\nAny fields that are set to 0 (or not set at all) inherit the corresponding\ndefault value.  This means that it is impossi
 ble to configure any setting with\na value of zero.\n\n\nInitialization\n\n\nThere are two means of initializing an nffs file system:\n\n\n\n\nRestore an existing file system via detection.\n\n\nCreate a new file system via formatting.\n\n\n\n\nBoth methods require the user to describe how the flash memory is divided into\nareas.  This is accomplished with an array of struct nffs_area_desc, defined as\nfollows:\n\n\nstruct nffs_area_desc {\n    uint32_t nad_offset;    /* Flash offset of start of area. */\n    uint32_t nad_length;    /* Size of area, in bytes. */\n};\n\n\n\n\nAn array of area descriptors is terminated by an entry with a fad_length field\nof 0.\n\n\nOne common initialization sequence is the following:\n\n\n\n\nDetect an nffs file system anywhere in flash.\n\n\nIf no file system detected, format a new file system in a specific\n        region of flash.\n\n\n\n\nDetection\n\n\nThe file system detection process consists of scanning a specified set of\nflash regions for v
 alid nffs areas, and then populating the RAM representation\nof the file system with the detected objects.  Detection is initiated with the\nfollowing function:\n\n\n/**\n * Searches for a valid nffs file system among the specified areas.  This\n * function succeeds if a file system is detected among any subset of the\n * supplied areas.  If the area set does not contain a valid file system,\n * a new one can be created via a separate call to nffs_format().\n *\n * @param area_descs        The area set to search.  This array must be\n *                              terminated with a 0-length area.\n *\n * @return                  0 on success;\n *                          NFFS_ECORRUPT if no valid file system was detected;\n *                          other nonzero on error.\n */\nint nffs_detect(const struct nffs_area_desc *area_descs);\n\n\n\n\nAs indicated, not every area descriptor needs to reference a valid nffs area.\nDetection is successful as long as a complete file system i
 s detected\nsomewhere in the specified regions of flash.  If an application is unsure\nwhere a file system might be located, it can initiate detection across the\nentire flash region.\n\n\nA detected file system is valid if:\n\n\n\n\nAt least one non-scratch area is present.\n\n\nAt least one scratch area is present (only the first gets used if there is more than one).\n\n\nThe root directory inode is present.\n\n\n\n\nDuring detection, each indicated region of flash is checked for a valid area\nheader.  The contents of each valid non-scratch area are then restored into\nthe nffs RAM representation.  The following procedure is applied to each object\nin the area:\n\n\n\n\n\n\nVerify the object's integrity via a crc16 check.  If invalid, the object is discarded and the procedure restarts on the next object in the area.\n\n\n\n\n\n\nConvert the disk object into its corresponding RAM representation and insert it into the hash table.  If the object is an inode, its reference count is in
 itialized to 1, indicating ownership by its parent directory.\n\n\n\n\n\n\nIf an object with the same ID is already present, then one supersedes the other.  Accept the object with the greater sequence number and discard the other.\n\n\n\n\n\n\nIf the object references a nonexistant inode (parent directory in the case of an inode; owning file in the case of a data block), insert a temporary \"dummy\" inode into the hash table so that inter-object links can be maintained until the absent inode is eventually restored.  Dummy inodes are identified by a reference count of 0.\n\n\n\n\n\n\nIf a delete record for an inode is encountered, the inode's parent pointer is set to null to indicate that it should be removed from RAM.\n\n\n\n\n\n\nIf nffs encounters an object that cannot be identified (i.e., its magic number\nis not valid), it scans the remainder of the flash area for the next valid\nmagic number.  Upon encountering a valid object, nffs resumes the procedure\ndescribed above.\n\n\nA
 fter all areas have been restored, a sweep is performed across the entire RAM\nrepresentation so that invalid inodes can be deleted from memory.\n\n\nFor each directory inode:\n\n\n\n\nIf its reference count is 0 (i.e., it is a dummy), migrate its children to the /lost+found directory, and delete it from the RAM representation. This should only happen in the case of file system corruption.\n\n\nIf its parent reference is null (i.e., it was deleted), delete it and all its children from the RAM representation.\n\n\n\n\nFor each file inode:\n\n\n\n\nIf its reference count is 0 (i.e., it is a dummy), delete it from the RAM representation.  This should only happen in the case of file system corruption.  (We should try to migrate the file to the lost+found directory in this case, as mentioned in the todo section).\n\n\n\n\nWhen an object is deleted during this sweep, it is only deleted from the RAM\nrepresentation; nothing is written to disk.\n\n\nWhen objects are migrated to the lost+fou
 nd directory, their parent inode\nreference is permanently updated on the disk.\n\n\nIn addition, a single scratch area is identified during the detection process.\nThe first area whose 'fda_id' value is set to 0xff is designated as the file\nsystem scratch area.  If no valid scratch area is found, the cause could be\nthat the system was restarted while a garbage collection cycle was in progress.\nSuch a condition is identified by the presence of two areas with the same ID.\nIn such a case, the shorter of the two areas is erased and designated as the\nscratch area.\n\n\nFormatting\n\n\nA new file system is created via formatting.  Formatting is achieved via the\nfollowing function:\n\n\n/**\n * Erases all the specified areas and initializes them with a clean nffs\n * file system.\n *\n * @param area_descs        The set of areas to format.\n *\n * @return                  0 on success;\n *                          nonzero on failure.\n */\nint nffs_format(const struct nffs_area_desc
  *area_descs);\n\n\n\n\nOn success, an area header is written to each of the specified locations.  The\nlargest area in the set is designated as the initial scratch area.\n\n\nFlash writes\n\n\nThe nffs implementation always writes in a strictly sequential fashion within an\narea.  For each area, the system keeps track of the current offset.  Whenever\nan object gets written to an area, it gets written to that area's current\noffset, and the offset is increased by the object's disk size.\n\n\nWhen a write needs to be performed, the nffs implementation selects the\nappropriate destination area by iterating though each area until one with\nsufficient free space is encountered.\n\n\nThere is no write buffering.  Each call to a write function results in a write\noperation being sent to the flash hardware.\n\n\nNew objects\n\n\nWhenever a new object is written to disk, it is assigned the following\nproperties:\n    * ID: A unique value is selected from the 32-bit ID space, as appropriate
 \n      for the object's type.\n    * Sequence number: 0\n\n\nWhen a new file or directory is created, a corresponding inode is written to\nflash.  Likewise, a new data block also results in the writing of a\ncorresponding disk object.\n\n\nMoving/Renaming files and directories\n\n\nWhen a file or directory is moved or renamed, its corresponding inode is\nrewritten to flash with the following properties:\n\n\n\n\nID: Unchanged\n\n\nSequence number: Previous value plus one.\n\n\nParent inode: As specified by the move / rename operation.\n\n\nFilename: As specified by the move / rename operation.\n\n\n\n\nBecause the inode's ID is unchanged, all dependent objects remain valid.\n\n\nUnlinking files and directories\n\n\nWhen a file or directory is unlinked from its parent directory, a deletion\nrecord for the unlinked inode gets written to flash.  The deletion record is an\ninode with the following properties:\n\n\n\n\nID: Unchanged\n\n\nSequence number: Previous value plus one.\n\n\nPa
 rent inode ID: NFFS_ID_NONE\n\n\n\n\nWhen an inode is unlinked, no deletion records need to be written for the\ninode's dependent objects (constituent data blocks or child inodes).  During\nthe next file system detection, it is recognized that the objects belong to\na deleted inode, so they are not restored into the RAM representation.\n\n\nIf a file has an open handle at the time it gets unlinked, application code\ncan continued to use the file handle to read and write data.  All files retain\na reference count, and a file isn't deleted from the RAM representation until\nits reference code drops to 0.  Any attempt to open an unlinked file fails,\neven if the file is referenced by other file handles.\n\n\nWriting to a file\n\n\nThe following procedure is used whenever the application code writes to a file.\nFirst, if the write operation specifies too much data to fit into a single\nblock, the operation is split into several separate write operations.  Then,\nfor each write operation
 :\n\n\n1. Determine which existing blocks the write operation overlaps (n = number of overwritten blocks).\n\n\n2. If n = 0, this is an append operation.  Write a data block with the following properties:\n\n\n\n\nID: New unique value.\n\n\nSequence number: 0.\n\n\n\n\n3. Else (n \n 1), this write overlaps existing data.\n\n\n(a) For each block in [1, 2, ... n-1], write a new block containing the updated contents.  Each new block supersedes the block it overwrites.  That is, each block has the following properties:\n\n\n\n\nID: Unchanged\n\n\nSequence number: Previous value plus one.\n\n\n\n\n(b) Write the nth block.  The nth block includes all appended data, if any.  As with the other blocks, its ID is unchanged and its sequence number is incremented.\n\n\nAppended data can only be written to the end of the file.  That is, \"holes\" are\nnot supported.\n\n\nGarbage collection\n\n\nWhen the file system is too full to accomodate a write operation, the system\nmust perform garbage col
 lection to make room.  The garbage collection\nprocedure is described below:\n\n\n\n\n\n\nThe non-scratch area with the lowest garbage collection sequence number is selected as the \"source area.\"  If there are other areas with the same sequence number, the one with the smallest flash offset is selected. \n\n\n\n\n\n\nThe source area's ID is written to the scratch area's header, transforming it into a non-scratch ID.  This former scratch area is now known as the \"destination area.\"\n\n\n\n\n\n\nThe RAM representation is exhaustively searched for collectible objects.  The following procedure is applied to each inode in the system:\n\n\n\n\nIf the inode is resident in the source area, copy the inode record to the destination area.\n\n\nIf the inode is a file inode, walk the inode's list of data blocks, starting with the last block in the file.  Each block that is resident in the source area is copied to the destination area.  If there is a run of two or more blocks that are residen
 t in the source area, they are consolidated and copied to the destination area as a single new block (subject to the maximum block size restriction).\n\n\n\n\n\n\n\n\nThe source area is reformatted as a scratch sector (i.e., is is fully erased, and its header is rewritten with an ID of 0xff).  The area's garbage collection sequence number is incremented prior to rewriting the header.  This area is now the new scratch sector.\n\n\n\n\n\n\nMiscellaneous measures\n\n\n\n\n\n\nRAM usage:\n\n\n\n\n24 bytes per inode\n\n\n12 bytes per data block\n\n\n36 bytes per inode cache entry\n\n\n32 bytes per data block cache entry\n\n\n\n\n\n\n\n\nMaximum filename size: 256 characters (no null terminator required)\n\n\n\n\nDisallowed filename characters: '/' and '\\0'\n\n\n\n\nFuture enhancements\n\n\n\n\nAPI function to traverse a directory.\n\n\nMigrate corrupt files to the /lost+found directory during restore, rather than discarding them from RAM.\n\n\nError correction.\n\n\nEncryption.\n\n\nCom
 pression.", 
+            "title": "Newtron Flash File System"
         }, 
         {
-            "location": "/modules/nffs/#newtron-flash-filesystem", 
+            "location": "/modules/nffs/#newtron-flash-filesystem-nffs", 
             "text": "Mynewt comes with the flash file system called the Newtron Flash File System (nffs) which is designed with two priorities that makes it suitable for embedded use:    Minimal RAM usage  Reliability   Mynewt also provides an abstraction layer API (fs) to allow you to swap out nffs with a different file system of your choice.", 
-            "title": "Newtron Flash Filesystem"
+            "title": "Newtron Flash Filesystem (nffs)"
         }, 
         {
             "location": "/modules/nffs/#description", 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/ec910044/modules/baselibc/index.html
----------------------------------------------------------------------
diff --git a/modules/baselibc/index.html b/modules/baselibc/index.html
index d5d72fc..2179f6b 100644
--- a/modules/baselibc/index.html
+++ b/modules/baselibc/index.html
@@ -9,7 +9,7 @@
         <link rel="canonical" href="http://mynewt.incubator.apache.org/modules/baselibc/">
         <link rel="shortcut icon" href="../../img/favicon.ico">
 
-	<title>Baselibc library - Mynewt Testing</title>
+	<title>Baselibc library - Apache Mynewt</title>
 
         <link href="../../css/bootstrap-3.0.3.min.css" rel="stylesheet">
         <link href="../../css/font-awesome-4.0.3.css" rel="stylesheet">
@@ -150,10 +150,10 @@
                             <li class="toctree-l2"><a href="../bootloader/">Bootloader</a></li>
                             
                         
-                            <li class="toctree-l2"><a href="../filesystem/">File System</a></li>
+                            <li class="toctree-l2"><a href="../filesystem/">File System Abstraction</a></li>
                             
                         
-                            <li class="toctree-l2"><a href="../nffs/">Newtron File System</a></li>
+                            <li class="toctree-l2"><a href="../nffs/">Newtron Flash File System</a></li>
                             
                         
                             <li class="toctree-l2"><a href="../testutil/">Test Utilities</a></li>

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-site/blob/ec910044/modules/bootloader/index.html
----------------------------------------------------------------------
diff --git a/modules/bootloader/index.html b/modules/bootloader/index.html
index 672c93f..04f9aa2 100644
--- a/modules/bootloader/index.html
+++ b/modules/bootloader/index.html
@@ -9,7 +9,7 @@
         <link rel="canonical" href="http://mynewt.incubator.apache.org/modules/bootloader/">
         <link rel="shortcut icon" href="../../img/favicon.ico">
 
-	<title>Bootloader - Mynewt Testing</title>
+	<title>Bootloader - Apache Mynewt</title>
 
         <link href="../../css/bootstrap-3.0.3.min.css" rel="stylesheet">
         <link href="../../css/font-awesome-4.0.3.css" rel="stylesheet">
@@ -168,10 +168,10 @@
                                 
                             
                         
-                            <li class="toctree-l2"><a href="../filesystem/">File System</a></li>
+                            <li class="toctree-l2"><a href="../filesystem/">File System Abstraction</a></li>
                             
                         
-                            <li class="toctree-l2"><a href="../nffs/">Newtron File System</a></li>
+                            <li class="toctree-l2"><a href="../nffs/">Newtron Flash File System</a></li>
                             
                         
                             <li class="toctree-l2"><a href="../testutil/">Test Utilities</a></li>