| <!-- |
| Documentation/_templates/layout.html |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. The |
| ASF licenses this file to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance with the |
| License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| License for the specific language governing permissions and limitations |
| under the License. |
| --> |
| |
| |
| |
| <!DOCTYPE html> |
| <html class="writer-html5" lang="en"> |
| <head> |
| <meta charset="utf-8" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" /> |
| |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>MNEMOFS — NuttX latest documentation</title> |
| <link rel="stylesheet" type="text/css" href="../../_static/pygments.css" /> |
| <link rel="stylesheet" type="text/css" href="../../_static/css/theme.css" /> |
| <link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" /> |
| <link rel="stylesheet" type="text/css" href="../../_static/sphinx_collapse.css" /> |
| <link rel="stylesheet" type="text/css" href="../../_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css" /> |
| <link rel="stylesheet" type="text/css" href="../../_static/custom.css" /> |
| |
| |
| <link rel="shortcut icon" href="../../_static/favicon.ico"/> |
| <script src="../../_static/jquery.js"></script> |
| <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script> |
| <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script> |
| <script src="../../_static/doctools.js"></script> |
| <script src="../../_static/sphinx_highlight.js"></script> |
| <script src="../../_static/clipboard.min.js"></script> |
| <script src="../../_static/copybutton.js"></script> |
| <script src="../../_static/design-tabs.js"></script> |
| <script src="../../_static/js/theme.js"></script> |
| <link rel="index" title="Index" href="../../genindex.html" /> |
| <link rel="search" title="Search" href="../../search.html" /> |
| <link rel="next" title="NFS" href="nfs.html" /> |
| <link rel="prev" title="File mapping emulation (mmap)" href="mmap.html" /> |
| </head> |
| |
| <body class="wy-body-for-nav"> |
| <div class="wy-grid-for-nav"> |
| <nav data-toggle="wy-nav-shift" class="wy-nav-side"> |
| <div class="wy-side-scroll"> |
| <div class="wy-side-nav-search" > |
| |
| <a href="../../index.html" class="icon icon-home"> NuttX |
| |
| |
| |
| </a> |
| |
| <!-- this version selector is quite ugly, should be probably replaced by something |
| more modern --> |
| |
| <div class="version-selector"> |
| <select onchange="javascript:location.href = this.value;"> |
| |
| <option value="../../../latest" selected="selected">latest</option> |
| |
| <option value="../../../10.0.0" >10.0.0</option> |
| |
| <option value="../../../10.0.1" >10.0.1</option> |
| |
| <option value="../../../10.1.0" >10.1.0</option> |
| |
| <option value="../../../10.2.0" >10.2.0</option> |
| |
| <option value="../../../10.3.0" >10.3.0</option> |
| |
| <option value="../../../11.0.0" >11.0.0</option> |
| |
| <option value="../../../12.0.0" >12.0.0</option> |
| |
| <option value="../../../12.1.0" >12.1.0</option> |
| |
| <option value="../../../12.2.0" >12.2.0</option> |
| |
| <option value="../../../12.2.1" >12.2.1</option> |
| |
| <option value="../../../12.3.0" >12.3.0</option> |
| |
| <option value="../../../12.4.0" >12.4.0</option> |
| |
| <option value="../../../12.5.0" >12.5.0</option> |
| |
| <option value="../../../12.5.1" >12.5.1</option> |
| |
| <option value="../../../12.6.0" >12.6.0</option> |
| |
| <option value="../../../12.7.0" >12.7.0</option> |
| |
| <option value="../../../12.8.0" >12.8.0</option> |
| |
| <option value="../../../12.9.0" >12.9.0</option> |
| |
| <option value="../../../12.10.0" >12.10.0</option> |
| |
| <option value="../../../12.11.0" >12.11.0</option> |
| |
| </select> |
| </div> |
| |
| |
| <div role="search"> |
| <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get"> |
| <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> |
| <input type="hidden" name="check_keywords" value="yes" /> |
| <input type="hidden" name="area" value="default" /> |
| </form> |
| </div> |
| |
| </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> |
| <p class="caption" role="heading"><span class="caption-text">Table of Contents</span></p> |
| <ul class="current"> |
| <li class="toctree-l1"><a class="reference internal" href="../../index.html">Home</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../introduction/index.html">Introduction</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../quickstart/index.html">Getting Started</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../contributing/index.html">Contributing</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../introduction/inviolables.html">The Inviolable Principles of NuttX</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../platforms/index.html">Supported Platforms</a></li> |
| <li class="toctree-l1 current"><a class="reference internal" href="../index.html">OS Components</a><ul class="current"> |
| <li class="toctree-l2"><a class="reference internal" href="../binfmt.html">Binary Loader</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../drivers/index.html">Device Drivers</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../nxflat.html">NXFLAT</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../nxgraphics/index.html">NX Graphics Subsystem</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../paging.html">On-Demand Paging</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../audio/index.html">Audio Subsystem</a></li> |
| <li class="toctree-l2 current"><a class="reference internal" href="index.html">NuttX File System</a><ul class="current"> |
| <li class="toctree-l3"><a class="reference internal" href="index.html#virtual-file-system-vfs">Virtual File System (VFS)</a></li> |
| <li class="toctree-l3 current"><a class="reference internal" href="index.html#file-systems">File systems</a><ul class="current"> |
| <li class="toctree-l4"><a class="reference internal" href="aio.html">Asynchronous I/O support</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="binfs.html">BINFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="cromfs.html">CROMFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="fat.html">FAT</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="hostfs.html">Host File System</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="littlefs.html">LITTLEFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="mmap.html">File mapping emulation (mmap)</a></li> |
| <li class="toctree-l4 current"><a class="current reference internal" href="#">MNEMOFS</a><ul> |
| <li class="toctree-l5"><a class="reference internal" href="#usage">Usage</a></li> |
| <li class="toctree-l5"><a class="reference internal" href="#nand-flashes">NAND Flashes</a></li> |
| <li class="toctree-l5"><a class="reference internal" href="#design">Design</a></li> |
| </ul> |
| </li> |
| <li class="toctree-l4"><a class="reference internal" href="nfs.html">NFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="nxffs.html">NXFFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="partition.html">Partition Table</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="procfs.html">PROCFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="romfs.html">ROMFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="rpmsgfs.html">RPMSG File System</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="smartfs.html">SMARTFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="shmfs.html">Shared Memory File System</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="spiffs.html">SPIFFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="tmpfs.html">TMPFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="unionfs.html">Union File System</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="userfs.html">User file system</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="zipfs.html">ZipFS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="inotify.html">Inotify</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="nuttxfs.html">Nuttx FS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="nxflat.html">NuttX FLAT Binary Format (NXFLAT)</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="pseudofs.html">Pseudo File System</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="special_files_dev_num.html">Special Files and Device Numbers</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="v9fs.html">V9FS</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="v9fs.html#adding-v9fs-to-the-nuttx-configuration">Adding V9FS to the NuttX Configuration</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="v9fs.html#nfs-mount-command">NFS Mount Command</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="index.html#fs-categories">FS Categories</a></li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li class="toctree-l2"><a class="reference internal" href="../libs/index.html">NuttX libraries</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../net/index.html">Network Support</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../mm/index.html">Memory Management</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../syscall.html">Syscall Layer</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../tools/index.html"><code class="docutils literal notranslate"><span class="pre">/tools</span></code> Host Tools</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../arch/index.html">Architecture-Specific Code</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../boards.html">Boards Support</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../cmake.html">CMake Support</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../openamp.html">OpenAMP Support</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../video.html">Video Subsystem</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../crypto.html">Crypto API Subsystem</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="../wireless.html">Wireless Subsystem</a></li> |
| </ul> |
| </li> |
| <li class="toctree-l1"><a class="reference internal" href="../../applications/index.html">Applications</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../implementation/index.html">Implementation Details</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../reference/index.html">API Reference</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../faq/index.html">FAQ</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../debugging/index.html">Debugging</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../guides/index.html">Guides</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../standards/index.html">Standards</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../glossary.html">Glossary</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../logos/index.html">NuttX Logos</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../_tags/tagsindex.html">Tags</a></li> |
| </ul> |
| |
| </div> |
| </div> |
| </nav> |
| |
| <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > |
| <i data-toggle="wy-nav-top" class="fa fa-bars"></i> |
| <a href="../../index.html">NuttX</a> |
| </nav> |
| |
| <div class="wy-nav-content"> |
| <div class="rst-content"> |
| <div role="navigation" aria-label="Page navigation"> |
| <ul class="wy-breadcrumbs"> |
| <li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li> |
| <li class="breadcrumb-item"><a href="../index.html">OS Components</a></li> |
| <li class="breadcrumb-item"><a href="index.html">NuttX File System</a></li> |
| <li class="breadcrumb-item active">MNEMOFS</li> |
| <li class="wy-breadcrumbs-aside"> |
| <a href="https://github.com/apache/nuttx/blob/master/Documentation/components/filesystem/mnemofs.rst" class="fa fa-github"> Edit on GitHub</a> |
| </li> |
| </ul> |
| <hr/> |
| </div> |
| <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> |
| <div itemprop="articleBody"> |
| |
| <section id="mnemofs"> |
| <h1>MNEMOFS<a class="headerlink" href="#mnemofs" title="Permalink to this heading"></a></h1> |
| <p>Mnemofs is a NAND Flash File System built for NuttX.</p> |
| <section id="usage"> |
| <h2>Usage<a class="headerlink" href="#usage" title="Permalink to this heading"></a></h2> |
| <p>If there’s a NAND flash available at a location, for example, <code class="docutils literal notranslate"><span class="pre">/dev/nand</span></code>, |
| you can mount it with <code class="docutils literal notranslate"><span class="pre">mnemofs</span></code> to a location like <code class="docutils literal notranslate"><span class="pre">/mydir</span></code> using:</p> |
| <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>mount -t mnemofs /dev/nand /mydir |
| </pre></div> |
| </div> |
| <p>The above command will only work if the device was already formatted using |
| mnemofs. For a brand new device, or if you want to switch from an existing |
| file system, this won’t work, and would need a format:</p> |
| <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>mount -t mnemofs -o forceformat /dev/nand /mydir |
| </pre></div> |
| </div> |
| <p>Unsure of whether you need to do a format? This will help:</p> |
| <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>mount -t mnemofs -o autoformat /dev/nand /mydir |
| </pre></div> |
| </div> |
| <p>This will format the device only if it can not detect mnemofs being already |
| formatted onto it. Do note this includes cases where mnemofs is formatted to |
| the device, but it’s been mutilated to the point of being unrecognizable.</p> |
| <p>After this, use it like a regular file system. That’s the job of a file |
| system after all…to hide the storage device’s peculiarities behind an |
| abstraction. A file system is considered good if you don’t have to think |
| about its existence during regular usage.</p> |
| </section> |
| <section id="nand-flashes"> |
| <h2>NAND Flashes<a class="headerlink" href="#nand-flashes" title="Permalink to this heading"></a></h2> |
| <p>Programmatically, the NAND flash has some problems. The whole device can be |
| condensed into three layers: blocks, pages and cells.</p> |
| <p>Cells represent the smallest unit of storage in NAND flashes, but are often |
| ignored, as direct access is not allowed. If a cell stores one bit, it’s a |
| Single Level Cell. There are MLC, TLC, etc. for more bits per cell. Often, |
| the more bits per cell, the lesser is the wear resilience. Thus, higher |
| bits per cell are easier to wear out and become unreliable.</p> |
| <p>Pages are the smallest readable or writable unit of the NAND flash. It’s |
| made up of several cells, and can be expected to have a size of the similar |
| order of 512 B.</p> |
| <p>Blocks are the smallest erasable unit of NAND flash. They are made up of |
| several pages. If a page is already written, it needs to be erased before it |
| can be written again. And since blocks are the smallest erasable unit, the |
| entire block needs to be erased if the user wants to update the contents of |
| one page.</p> |
| <p>The erase operation is what causes a block to wear out. If a block is worn |
| out too much, it will lose its ability to reliably store data. An unreliable |
| block can not guarantee that the data read from the pages in it is the same |
| as what was written to it. This state is called as a bad block.</p> |
| <p>A manufacturer can also deem a block to be unreliable from their testing, |
| and can mark them as bad blocks right from manufacture.</p> |
| <p>A good file system will aim to level out the wear between blocks as much as |
| it can.</p> |
| </section> |
| <section id="design"> |
| <h2>Design<a class="headerlink" href="#design" title="Permalink to this heading"></a></h2> |
| <p>There are various layers and components in mnemofs, and they interact with |
| various layers on abstraction over each other.</p> |
| <p>Mnemofs works on a Copy-On-Write (CoW) basis, which means, if a page needs to |
| be updated, it is copied over in memory, and then the change is applied, and |
| the new data is written to a new location.</p> |
| <section id="r-w-layer"> |
| <h3>R/W Layer<a class="headerlink" href="#r-w-layer" title="Permalink to this heading"></a></h3> |
| <p>This works with the NAND flash device driver directly. It can write an |
| entire page, read an entire page, erase an entire block, check if a block is |
| bad (from it’s bad block marker), or set a block as bad. It’s the simplest |
| layer.</p> |
| </section> |
| <section id="block-allocator"> |
| <h3>Block Allocator<a class="headerlink" href="#block-allocator" title="Permalink to this heading"></a></h3> |
| <p>The block allocator contains two arrays. One is a bit mask is for tracking |
| the free pages, while the other is an array of numbers, one number for each |
| block, denoting the number of pages in that block that are ready to be |
| erased.</p> |
| <p>The block allocator allocates pages or blocks in a sequential manner to keep |
| it fair for all pages, thus, ensuring wear levelling. It also starts from a |
| random offset to prevent bias to the front of the device in case of multiple |
| power losses and reinitialization in such casses. If a block is required it |
| skips pages to the start of the next block. Since block allocations happen |
| only in the journal, they happen in bulk and the number of skipped pages is |
| very minimal.</p> |
| <p>Once reaching the end of the device, it cycles back to the front. Thus any |
| skipped pages get the chance to be allocated in the next cycle.</p> |
| </section> |
| <section id="ctz-layer"> |
| <h3>CTZ Layer<a class="headerlink" href="#ctz-layer" title="Permalink to this heading"></a></h3> |
| <p>This works with the R/W Layer, and acts as an abstraction layer for other |
| components in mnemofs. Mnemofs uses |
| <a class="reference external" href="https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md#ctz-skip-lists">CTZ lists</a> |
| to represent both files and directories in flash. CTZ lists of files contain |
| only the data of the file, while CTZ lists of directories contain directory |
| entries (direntries) for each FS Object (file or directory) grouped into it.</p> |
| <p>This layer abstracts away the complex division of flash space that’s present |
| in CTZ skip lists, and allows users of this layer to not worry about the |
| complexities of a CTZ skip list, and in fact, to feel that the data is like a |
| contiguous space.</p> |
| <p>This layer allows the user to specify a data offset, which refers to the |
| offset into the actual data stored in the CTZ skip list (ie. excluding the |
| pointers), and the number of bytes, and perform operations on the CTZ list |
| almost like if it were a single array.</p> |
| <p>In mnemofs, each CTZ block takes up the space of exactly 1 page, and each |
| pointer takes up 4 bytes.</p> |
| <p>Littlefs design document shows how a CTZ list can be identified using the |
| index of the last CTZ block, and the page number of that CTZ block.</p> |
| </section> |
| <section id="journal"> |
| <h3>Journal<a class="headerlink" href="#journal" title="Permalink to this heading"></a></h3> |
| <p>The journal in mnemofs is made out of <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">+</span> <span class="pre">2</span></code> blocks. The last two block |
| concern the master node. These blocks are arranged in a singly linked list.</p> |
| <p>Due to CoW policy, when a CTZ list is updated, it now has a new location. The |
| first <code class="docutils literal notranslate"><span class="pre">n</span></code> blocks of the journal is responsible for storing logs containing |
| information about this very update. It will contain the old location of the |
| CTZ skip list, and the new location.</p> |
| <p>Thus, when the user requires an updated location of a CTZ list, they will |
| first find the old location by traversing the FS tree in the flash, and then |
| will traverse the journal to find the latest location.</p> |
| <p>So, the FS tree on the flash acts like a “base” state with updates stored in |
| the journal. Each log in journal is followed by a checksum to verify if all |
| of it was written properly. This helps in making it power loss resilient.</p> |
| <p>The journal, when combined with CoW, plays another important role. In pure |
| CoW, any update to a CTZ file will result in it having a new location. This |
| new location will need to be updated in the parent, which itself will have a |
| new location after the update, and so on till it reaches the root. The |
| journal stops this propagation immediately. When the journal is full above |
| a certain limit, it will flush, and apply all of these changes to the FS |
| tree in one go. This helps in wear reduction.</p> |
| <p>The journal mainly works with the CTZ layer, and any updates to a CTZ list |
| using this layer automatically adds a log for it in the journal.</p> |
| <p>The journal starts with a magic sequence, then the number of blocks in the |
| journal (excluding master blocks), and then follows an array with the block |
| numbers of the blocks in the journal (including the master blocks). Following |
| this, logs are stored in the blocks.</p> |
| </section> |
| <section id="master-node-and-root"> |
| <h3>Master Node and Root<a class="headerlink" href="#master-node-and-root" title="Permalink to this heading"></a></h3> |
| <p>The root of the file system is treated like any directory as far as its |
| storage on the flash is concerned. This is because the master node acts as a |
| parent to the root, and contains information of the root in a way identical |
| to direntries.</p> |
| <p>The master node is stored in the master blocks. There are two master blocks, |
| and both are duplicated of each other for backup. Each master block is a |
| block, and thus have multiple pages in them. Each page contains one revision |
| of the master node. The master nodes are written sequentially, and have a |
| timestamp on them as well.</p> |
| <p>When a CTZ list is moved to a new location, the obsolete pages of the old |
| CTZ list are marked for deletion.</p> |
| </section> |
| <section id="lru-cache"> |
| <h3>LRU Cache<a class="headerlink" href="#lru-cache" title="Permalink to this heading"></a></h3> |
| <p>Mnemofs has a Least Recently Used (LRU) Cache component. The main use of this |
| component is to reduce wear on the flash at the expense of memory.</p> |
| <p>The LRU is a kernel list of nodes. Each node represents an FS object. Each |
| node also contains a kernel list of deltas. Each delta contains information |
| about an update or deletion from the user (which is what all of the VFS write |
| operations can be condensed to).</p> |
| <p>There’s a pre-configured limit for both deltas per node and nodes in the LRU.</p> |
| <p>If the delta list in a node is full, and another is to be added, all the |
| existing deltas in the list are clubbed together and written to the flash |
| using the CTZ layer. The layer also automatically adds a log for this update. |
| When a node receives a delta, it is bumped from its current location in the |
| LRU to be at the front. This way, the last node in the LRU is always the |
| least used node.</p> |
| <p>If the node limit is reached in the LRU, and a new node is to be added to the |
| LRU, then the final node (which is also the least recently used node), is |
| popped from the LRU to make space for the new node. This popped node is then |
| written to the flash using the CTZ layer as well.</p> |
| <p>The LRU helps in clubbing updates to a single FS object and thus helps in |
| reducing the wear of the flash.</p> |
| </section> |
| <section id="journal-flush"> |
| <h3>Journal Flush<a class="headerlink" href="#journal-flush" title="Permalink to this heading"></a></h3> |
| <p>The latest master node revision is the most useful out of the revisions. As |
| in CoW it’s prudent to update the FS tree from bottom up, the root is the |
| last one to get updated in the case of a journal flush.</p> |
| <p>The logs are just location updates. So, when a journal flush occurs, it will |
| update the locations of all the children in the parent. This updates the |
| parent, and then this update goes through the same procedure as any other |
| update.</p> |
| <p>This is why it’s best to start the flush operation when the journal is filled |
| up over a certain limit, instead of waiting it to be full. Why? Any log of |
| a parent makes any log of its children written <strong>before</strong> it useless, as the |
| updated location of the parent can be read to get the updated location of the |
| child till that point in the logs.</p> |
| <p>So, it will be best to move up the FS tree from bottom during update and |
| update the root last, since the root is the parent of every FS object.</p> |
| <p>Once the root is updated, all other journal logs become useless, and can be |
| erased. The root’s log is not written in the first <code class="docutils literal notranslate"><span class="pre">n</span></code> blocks of the |
| journal, but written as a new master node entry in the master blocks.</p> |
| <p>Once the new root is written, the first <code class="docutils literal notranslate"><span class="pre">n</span></code> blocks can be erased, and |
| reallocated (due to the rules of wear levelling). The master blocks however |
| have some conditions for reallocation. This is called moving of the journal.</p> |
| <p>Every time the first <code class="docutils literal notranslate"><span class="pre">n</span></code> blocks are cleared, a new master node is added. |
| The only time a master block needs to be erased is when it becomes full. |
| Thus, if there are <code class="docutils literal notranslate"><span class="pre">p</span></code> pages in a block, the master blocks will be |
| moved along with the rest of the journal for every <code class="docutils literal notranslate"><span class="pre">p</span></code> journal flushes.</p> |
| <p>Before the new master node is written, none of the old pages should be erased |
| to allow rollback to the previous FS tree state. The moment the new master |
| node is updated, any block which has all of the pages in it ready for |
| deletion will be erased to make space.</p> |
| </section> |
| <section id="fs-object-layer"> |
| <h3>FS Object Layer<a class="headerlink" href="#fs-object-layer" title="Permalink to this heading"></a></h3> |
| <p>This layer provides an abstraction for iterating, adding, deleting or |
| reading direntries.</p> |
| <p>This works with the LRU and the journal to get the latest data and thus the |
| user of this layer does not have to worry about these underlying mnemofs |
| components.</p> |
| </section> |
| <section id="vfs-method-layer"> |
| <h3>VFS Method Layer<a class="headerlink" href="#vfs-method-layer" title="Permalink to this heading"></a></h3> |
| <p>VFS method layer contains methods exposed to the VFS. This layer works with |
| the FS Object layer for direntry related tasks, or the LRU for file level |
| read/write tasks.</p> |
| </section> |
| </section> |
| </section> |
| |
| |
| </div> |
| </div> |
| <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> |
| <a href="mmap.html" class="btn btn-neutral float-left" title="File mapping emulation (mmap)" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> |
| <a href="nfs.html" class="btn btn-neutral float-right" title="NFS" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> |
| </div> |
| |
| <hr/> |
| |
| <div role="contentinfo"> |
| <p>© Copyright 2023, The Apache Software Foundation.</p> |
| </div> |
| |
| |
| |
| </footer> |
| </div> |
| </div> |
| </section> |
| </div> |
| <script> |
| jQuery(function () { |
| SphinxRtdTheme.Navigation.enable(true); |
| }); |
| </script> |
| |
| </body> |
| </html> |