<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.30 (Ruby 2.6.10) -->
<?rfc docmapping="yes"?>
<?rfc comments="yes"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-haynes-nfsv4-swap-07" category="std" consensus="true" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.31.0 -->
  <front>
    <title abbrev="atomic EXCHANGE_RANGE">Adding an Atomic EXCHANGE_RANGE Operation to NFSv4.2</title>
    <seriesInfo name="Internet-Draft" value="draft-haynes-nfsv4-swap-07"/>
    <author initials="T." surname="Haynes" fullname="Thomas Haynes">
      <organization>Hammerspace</organization>
      <address>
        <email>loghyr@gmail.com</email>
      </address>
    </author>
    <date/>
    <area>General</area>
    <workgroup>Network File System Version 4</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 43?>

<t>The Network File System version 4.2 (NFSv4.2) does not provide
support for atomic multi-block updates to file data.  This document
introduces a new EXCHANGE_RANGE operation which provides for such
atomic updates.  This document extends NFSv4.2 (see RFC7862).</t>
    </abstract>
    <note>
      <name>Note to Readers</name>
      <?line 50?>

<t>Discussion of this draft takes place
on the NFSv4 working group mailing list (nfsv4@ietf.org),
which is archived at
<eref target="https://mailarchive.ietf.org/arch/search/?email_list=nfsv4"/>. Source
code and issues list for this draft can be found at
<eref target="https://github.com/ietf-wg-nfsv4/exchange_range"/>.</t>
      <t>Working Group information can be found at <eref target="https://github.com/ietf-wg-nfsv4"/>.</t>
    </note>
  </front>
  <middle>
    <?line 61?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>With the Network File System version 4.2 (NFSv4.2), atomic updates
to a file are not guaranteed.  A single WRITE operation might span
multiple data blocks; another client doing a READ might then encounter
a partial WRITE.  In addition, multiple WRITE operations, even
within the same compound, may not be atomically applied to a file.
In some implementations, multiple WRITE operations within the same
compound may appear to be applied atomically, but this behavior is
implementation-specific and not guaranteed by the protocol.</t>
      <t>This document introduces the EXCHANGE_RANGE operation, which is
<bcp14>OPTIONAL</bcp14> to implement, to NFSv4.2.  EXCHANGE_RANGE atomically
exchanges a range of content between two files.  A client can easily
determine whether or not a server supports the EXCHANGE_RANGE
operation by examining the return code of the operation.  If the
server does not support the EXCHANGE_RANGE operation, the server
returns NFS4ERR_NOTSUPP.</t>
      <t>Using the process described in <xref target="RFC8178"/>, the revisions in this
document extend NFSv4.2 <xref target="RFC7862"/>.  They are built on top of the
external data representation (XDR) <xref target="RFC4506"/> generated from
<xref target="RFC7863"/>.</t>
    </section>
    <section anchor="definitions">
      <name>Definitions</name>
      <t>The definitions of the following terms are referenced as follows:</t>
      <ul spacing="normal">
        <li>
          <t>change_info4 (<xref section="3.3.3" sectionFormat="of" target="RFC8881"/>)</t>
        </li>
        <li>
          <t>CLONE (<xref section="15.13" sectionFormat="of" target="RFC7862"/>)</t>
        </li>
        <li>
          <t>clone_blksize (<xref section="12.2.1" sectionFormat="of" target="RFC7862"/>)</t>
        </li>
        <li>
          <t>NFS4ERR_NOTSUPP (<xref section="15.1.1.5" sectionFormat="of" target="RFC8881"/>)</t>
        </li>
        <li>
          <t>READ (<xref section="18.22" sectionFormat="of" target="RFC8881"/>)</t>
        </li>
        <li>
          <t>WRITE (<xref section="18.32" sectionFormat="of" target="RFC8881"/>)</t>
        </li>
      </ul>
    </section>
    <section anchor="requirements-language">
      <name>Requirements Language</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

</section>
    <section anchor="use-cases">
      <name>Use Cases</name>
      <t>The EXCHANGE_RANGE operation addresses a class of problems that
cannot be solved without loss of atomicity by existing NFSv4.2
operations.  This section motivates the operation by contrasting
it with a hypothetical one-way transfer primitive and then presenting
five concrete use cases.</t>
      <t>Consider an operation called XFER_RANGE that atomically copies
data from a source range to a destination range -- essentially
CLONE (<xref section="15.13" sectionFormat="of" target="RFC7862"/>) with an atomicity guarantee.
XFER_RANGE would be a useful primitive in its own right for cases
where one-way data movement is all that is needed.  EXCHANGE_RANGE
differs from it in one critical respect: EXCHANGE_RANGE atomically
swaps the contents of both ranges.  Neither range is "the source"
and neither is "the destination" -- both hold meaningful data
before the operation and both hold meaningful data after. While the
protocol distinguishes SAVED_FH and CURRENT_FH for access control
purposes, the semantics of the operation treat both ranges
symmetrically. The following examples illustrate when the distinction
matters.</t>
      <t>The use cases below share a common requirement: both ranges contain
valid data before the operation, and both must remain valid after
the operation, with no externally visible intermediate state.  A
sequence of one-way operations (e.g., CLONE, WRITE, or a hypothetical
XFER_RANGE) cannot provide this guarantee, as they either destroy
one side of the data or introduce a window in which observers may
see partially updated state.</t>
      <dl>
        <dt>A/B deployment:</dt>
        <dd>
          <t>A server pre-computes version 2 of a dataset into fileB while
version 1 remains live in fileA.  At the moment of go-live, the
operator wants to atomically swap which file is current.
XFER_RANGE(B-&gt;A) overwrites fileA and destroys version 1.
XFER_RANGE(A-&gt;B) does the same in the other direction.  Neither
preserves both versions.  EXCHANGE_RANGE atomically swaps the
two, leaving version 1 intact in fileB for inspection or rollback.
This example applies when the two versions reside in fixed locations
or ranges that cannot be renamed or redirected atomically (e.g.,
shared file layouts or range-based consumers).</t>
        </dd>
        <dt>Checkpoint and restore:</dt>
        <dd>
          <t>A process maintains a live range and a checkpoint range.  A
checkpoint is performed by EXCHANGE_RANGE(live, checkpoint): the
checkpoint range now holds the saved state and the live range
holds what was the checkpoint.  A restore is performed by the
identical call.  The self-inverse property means the mechanism
for save and restore are the same operation.  XFER_RANGE requires
two distinct one-way operations and cannot guarantee that a
restore returns exactly what was saved without additional
bookkeeping.</t>
        </dd>
        <dt>Circular log rotation:</dt>
        <dd>
          <t>Segment 0 is being read by consumers; segment 1 has been filled
by a writer and is ready to become the new read segment.  Both
segments hold valuable data -- neither is scratch space.
EXCHANGE_RANGE atomically swaps their roles.  XFER_RANGE(1-&gt;0)
destroys segment 0's content before readers have finished with
it. In systems with multiple independent readers, coordination
is not feasible, and readers must never observe a partially rotated
state.</t>
        </dd>
        <dt>Erasure coding stripe rebuild:</dt>
        <dd>
          <t>During a pNFS Flex Files (<xref target="I-D.haynes-nfsv4-flexfiles-v2"/>)
reconstruction, a data server has rebuilt a stripe from parity
into a staging buffer.  Both the live stripe and the staging
buffer exist and are valid.  EXCHANGE_RANGE atomically promotes
the staging buffer to live and moves the old live data into the
staging buffer, where it remains available for integrity
verification or rollback if the new stripe fails a subsequent
check.  XFER_RANGE would overwrite the live stripe before that
verification can occur. This avoids both the need to copy data
and any window in which parity and data are inconsistent.</t>
        </dd>
        <dt>Atomic file update via clone-then-swap:</dt>
        <dd>
          <t>This is the case where XFER_RANGE would be sufficient, and it
is worth stating clearly.  A client CLONEs a source file to a
temporary working copy, modifies the copy, and then wants to
atomically publish the result.  XFER_RANGE(temp-&gt;source)
accomplishes this: the temporary file is discarded and source is
updated atomically.  EXCHANGE_RANGE handles this case as well,
and adds one benefit: after the swap, the temporary file holds
the previous content of source, providing a no-cost rollback
path -- invoke EXCHANGE_RANGE again and the original state is
restored.  An implementation that does not need rollback can
simply discard the old content; one that does need it gets it
without additional operations.</t>
        </dd>
      </dl>
      <t>A composition of existing operations (e.g., CLONE followed by WRITE,
or two XFER_RANGE operations) cannot provide the same guarantees
as EXCHANGE_RANGE. Such compositions either:</t>
      <ul spacing="normal">
        <li>
          <t>destroy one side of the data, or</t>
        </li>
        <li>
          <t>expose an intermediate state to other clients, or</t>
        </li>
        <li>
          <t>require external coordination not available at the protocol level.</t>
        </li>
      </ul>
      <t>EXCHANGE_RANGE provides these guarantees as a single atomic operation.</t>
    </section>
    <section anchor="operation-81-exchangerange-exchange-a-range-of-a-file-into-another-file">
      <name>Operation 81: EXCHANGE_RANGE - Exchange a range of a file into another file</name>
      <section anchor="arguments">
        <name>ARGUMENTS</name>
        <figure anchor="fig-EXCHANGE_RANGE4args">
          <name>XDR for EXCHANGE_RANGE4args</name>
          <sourcecode type="xdr"><![CDATA[
 /// const OP_EXCHANGE_RANGE = 81;
 ///
 /// struct EXCHANGE_RANGE4args {
 ///         /* SAVED_FH: source file */
 ///         /* CURRENT_FH: destination file */
 ///         stateid4        era_src_stateid;
 ///         stateid4        era_dst_stateid;
 ///         offset4         era_src_offset;
 ///         offset4         era_dst_offset;
 ///         length4         era_count;
 /// };
]]></sourcecode>
        </figure>
      </section>
      <section anchor="results">
        <name>RESULTS</name>
        <figure anchor="fig-EXCHANGE_RANGE4res">
          <name>XDR for EXCHANGE_RANGE4res</name>
          <sourcecode type="xdr"><![CDATA[
 /// struct EXCHANGE_RANGE4resok {
 ///         change_info4    err_src_cinfo;
 ///         change_info4    err_dst_cinfo;
 /// };
 ///
 /// union EXCHANGE_RANGE4res switch (nfsstat4 err_status) {
 ///  case NFS4_OK:
 ///          EXCHANGE_RANGE4resok err_resok4;
 ///  default:
 ///          void;
 /// };
]]></sourcecode>
        </figure>
        <t>The following case arms are added to the nfs_argop4 and nfs_resop4
dispatch unions in the base XDR:</t>
        <figure anchor="fig-dispatch">
          <name>Dispatch union case arms for EXCHANGE_RANGE</name>
          <sourcecode type="xdr"><![CDATA[
 /// /* In nfs_argop4: */
 /// case OP_EXCHANGE_RANGE:
 ///         EXCHANGE_RANGE4args opexchange_range;
 ///
 /// /* In nfs_resop4: */
 /// case OP_EXCHANGE_RANGE:
 ///         EXCHANGE_RANGE4res opexchange_range;
]]></sourcecode>
        </figure>
      </section>
      <section anchor="description">
        <name>DESCRIPTION</name>
        <t>The EXCHANGE_RANGE operation is used to exchange file content from
a source file specified by the SAVED_FH value into a destination
file specified by CURRENT_FH without actually copying the data,
e.g., by using a block exchange mechanism.</t>
        <t>Both SAVED_FH and CURRENT_FH <bcp14>MUST</bcp14> be regular files.  If either
SAVED_FH or CURRENT_FH is not a regular file, the operation <bcp14>MUST</bcp14>
fail and return NFS4ERR_WRONG_TYPE.</t>
        <t>The era_dst_stateid <bcp14>MUST</bcp14> refer to a stateid that is valid for a WRITE
operation and follows the rules for stateids in Section 8.2.5 of
<xref target="RFC8881"/> and Section 18.32.3 of <xref target="RFC8881"/>.  The era_src_stateid <bcp14>MUST</bcp14>
refer to a stateid that is valid for a READ operation and follows
the rules for stateids in Section 8.2.5 of <xref target="RFC8881"/> and Section 18.22.3
of <xref target="RFC8881"/>.  If either stateid is invalid, then the operation
<bcp14>MUST</bcp14> fail.</t>
        <t>The era_src_offset is the starting offset within the source file
from which the data to be exchanged will be obtained, and the
era_dst_offset is the starting offset of the target region into which
the exchanged data will be placed.  An offset of 0 (zero) indicates
the start of the respective file.  The number of bytes to be exchanged
is obtained from era_count, except that an era_count of 0 (zero)
indicates that the number of bytes to be exchanged is the count of
bytes between era_src_offset and the EOF of the source file; in this
case the derived count ends at the source EOF, so the alignment
exception below always applies.  Both era_src_offset and era_dst_offset
<bcp14>MUST</bcp14> be aligned to the clone block size (Section 12.2.1 of <xref target="RFC7862"/>).
The number of bytes to be exchanged <bcp14>MUST</bcp14> be a multiple of the clone
block size, except in the case in which era_src_offset plus the number
of bytes to be exchanged is equal to the source file size.</t>
        <t>If era_src_offset or era_src_offset + era_count is greater than the
size of the source file, the operation <bcp14>MUST</bcp14> fail with NFS4ERR_INVAL.
It is valid for era_dst_offset or era_dst_offset + era_count to be
greater than the current size of the destination file.</t>
        <t>If SAVED_FH and CURRENT_FH refer to the same file and the source
and target ranges overlap, the operation <bcp14>MUST</bcp14> fail with NFS4ERR_INVAL.
This restriction avoids undefined behavior that could arise from
overlapping atomic replacement of data within a single file.</t>
        <t>If the target area of the EXCHANGE_RANGE operation ends beyond the
end of the destination file, the new size of the destination file
<bcp14>MUST</bcp14> be set to era_dst_offset plus the number of bytes exchanged.
The contents of any block not part of the target area <bcp14>MUST</bcp14> be the
same as if the file size were extended by a WRITE.</t>
        <t>If the number of bytes to be exchanged (using the derived count when
era_count is 0) is not a multiple of the clone block size and
era_dst_offset plus the derived count is less than the current size
of the destination file, the operation <bcp14>MUST</bcp14> fail with NFS4ERR_INVAL.</t>
        <t>This restriction avoids modifying a portion of a clone block while
leaving the remainder of that clone block within the destination
file unchanged, which could otherwise lead to implementation-dependent
results and potential data integrity issues.</t>
        <t>If a conflicting byte-range lock exists on either the source or the
destination range at the time of the operation, the server <bcp14>MUST</bcp14> return
NFS4ERR_LOCKED before performing any exchange.  The source range
requires at minimum read access; the destination range requires write
access.</t>
        <t>The EXCHANGE_RANGE operation is atomic in that other operations <bcp14>MUST
NOT</bcp14> see any intermediate states between the state of the two files
before the operation and after the operation.  A READ of the
destination file <bcp14>MUST NOT</bcp14> see some blocks of the target area exchanged
without all of them being exchanged.  A WRITE to the source area <bcp14>MUST</bcp14>
either have no effect on the data of the target file or be fully
reflected in the target area of the destination file.</t>
        <t>Atomicity is defined with respect to NFSv4.2 READ and WRITE operations
issued by other clients; the protocol makes no guarantees regarding
the visibility of intermediate states to server-internal mechanisms.</t>
        <t>Upon successful completion, the server <bcp14>MUST</bcp14> update the change, mtime,
and ctime attributes of both the source and destination files.</t>
        <t>The completion status of the operation is indicated by err_status.</t>
        <t>Upon success, the response includes err_resok4, which contains two
change_info4 values: err_src_cinfo for the source file and
err_dst_cinfo for the destination file.  Each change_info4 carries
the change attribute value before (cinfo_before) and after
(cinfo_after) the exchange, sampled atomically with the operation.
Clients <bcp14>MAY</bcp14> use these values to update their attribute caches for
both files without issuing a subsequent GETATTR.  When
cinfo_atomic is TRUE, the client <bcp14>MAY</bcp14> treat the before/after pair
as a precise record of the transition; when FALSE, the client <bcp14>MUST</bcp14>
treat the cached change attribute as potentially stale and
revalidate on next access.  Because EXCHANGE_RANGE is its own
inverse, a client confirming execution <bcp14>MUST</bcp14> compare cinfo_before
against a previously recorded value -- comparing cinfo_after is
insufficient, as two executions leave cinfo_after equal to the
original cinfo_before.</t>
        <t>Within an NFSv4.1 or NFSv4.2 session, the SEQUENCE operation
(<xref section="18.46" sectionFormat="of" target="RFC8881"/>) provides exactly-once execution
semantics via the slot identifier and sequenceid carried in each
compound: the server's session reply cache detects retransmissions
and returns the cached reply without re-executing the operation.
The discussion below addresses replay protection across server
reboots, where session state is not preserved.</t>
        <t>Stateids supplied with the EXCHANGE_RANGE operation provide protection
against replay across server reboots, lease expiration, or state
revocation.  After a server reboot, all previously issued stateids
are invalidated, and replay of a prior EXCHANGE_RANGE operation
<bcp14>MUST</bcp14> fail with an appropriate error.</t>
        <t>Because EXCHANGE_RANGE is its own inverse -- applying it twice to
the same ranges returns both files to their original state -- clients
<bcp14>MUST NOT</bcp14> assume that a successfully replayed EXCHANGE_RANGE operation
produced a net change.  Clients that require confirmation <bcp14>MUST</bcp14>
validate the resulting file contents or metadata, such as via the
change attribute.</t>
        <t>Per Section 3.3.1 of <xref target="RFC7862"/>, EXCHANGE_RANGE is not
an operation which can be sent to a data server.</t>
      </section>
      <section anchor="errors">
        <name>ERRORS</name>
        <t>The EXCHANGE_RANGE operation returns the full set of errors defined
in <xref target="tbl-ops-and-errors"/>.  The following errors are specific to this
operation:</t>
        <dl>
          <dt>NFS4ERR_WRONG_TYPE:</dt>
          <dd>
            <t>Either SAVED_FH or CURRENT_FH is not a regular file.</t>
          </dd>
          <dt>NFS4ERR_INVAL:</dt>
          <dd>
            <t>era_src_offset or era_dst_offset is not aligned to the clone block
size; or the count is not a valid multiple of the clone block size
and the range does not end at the source EOF; or the source range
extends beyond the source file; or SAVED_FH and CURRENT_FH are the
same file and the source and target ranges overlap.</t>
          </dd>
          <dt>NFS4ERR_BAD_STATEID, NFS4ERR_EXPIRED, NFS4ERR_ADMIN_REVOKED,</dt>
          <dd>
            <t/>
          </dd>
          <dt>NFS4ERR_DELEG_REVOKED, NFS4ERR_OLD_STATEID, NFS4ERR_OPENMODE:</dt>
          <dd>
            <t>The era_src_stateid or era_dst_stateid is not valid for the required
access mode, has expired, or has been revoked.</t>
          </dd>
          <dt>NFS4ERR_LOCKED:</dt>
          <dd>
            <t>A conflicting byte-range lock on the source or destination range
prevents the exchange.</t>
          </dd>
        </dl>
      </section>
    </section>
    <section anchor="operations-and-their-valid-errors">
      <name>Operations and Their Valid Errors</name>
      <t>The operations and their valid errors are presented in
<xref target="tbl-ops-and-errors"/>.  All error codes not defined in this document
are defined in Section 15 of <xref target="RFC8881"/> and Section 11 of <xref target="RFC7862"/>.</t>
      <dl anchor="tbl-ops-and-errors">
        <dt>EXCHANGE_RANGE:</dt>
        <dd>
          <t>NFS4ERR_ACCESS,
NFS4ERR_ADMIN_REVOKED,
NFS4ERR_BADXDR,
NFS4ERR_BAD_STATEID,
NFS4ERR_DEADSESSION,
NFS4ERR_DELAY,
NFS4ERR_DELEG_REVOKED,
NFS4ERR_DQUOT,
NFS4ERR_EXPIRED,
NFS4ERR_FBIG,
NFS4ERR_FHEXPIRED,
NFS4ERR_GRACE,
NFS4ERR_INVAL,
NFS4ERR_IO,
NFS4ERR_ISDIR,
NFS4ERR_LOCKED,
NFS4ERR_MOVED,
NFS4ERR_NOFILEHANDLE,
NFS4ERR_NOSPC,
NFS4ERR_NOTSUPP,
NFS4ERR_OLD_STATEID,
NFS4ERR_OPENMODE,
NFS4ERR_OP_NOT_IN_SESSION,
NFS4ERR_PNFS_IO_HOLE,
NFS4ERR_PNFS_NO_LAYOUT,
NFS4ERR_REP_TOO_BIG,
NFS4ERR_REP_TOO_BIG_TO_CACHE,
NFS4ERR_REQ_TOO_BIG,
NFS4ERR_RETRY_UNCACHED_REP,
NFS4ERR_ROFS,
NFS4ERR_SERVERFAULT,
NFS4ERR_STALE,
NFS4ERR_SYMLINK,
NFS4ERR_TOO_MANY_OPS,
NFS4ERR_WRONG_TYPE</t>
        </dd>
      </dl>
      <t>If the destination file has active pNFS layouts that prevent atomic
modification of the target range, the server <bcp14>MAY</bcp14> return an appropriate
pNFS-related error.</t>
    </section>
    <section anchor="extraction-of-xdr">
      <name>Extraction of XDR</name>
      <t>This document contains the external data representation (XDR)
<xref target="RFC4506"/> description of the EXCHANGE_RANGE operation.  The XDR
description is presented in a manner that facilitates easy extraction
into a ready-to-compile format. To extract the machine-readable XDR
description, use the following shell script:</t>
      <sourcecode type="shell"><![CDATA[
#!/bin/sh
grep '^ *///' $* | sed 's?^ */// ??' | sed 's?^ *///$??'
]]></sourcecode>
      <t>For example, if the script is named 'extract.sh' and this document is
named 'exchange_range.txt', execute the following command:</t>
      <sourcecode type="shell"><![CDATA[
sh extract.sh < exchange_range.txt > exchange_range_prot.x
]]></sourcecode>
      <t>This script removes leading blank spaces and the sentinel sequence '///'
from each line. XDR descriptions with the sentinel sequence are embedded
throughout the document.</t>
      <t>Note that the XDR code contained in this document depends on types from
the NFSv4.2 nfs4_prot.x file (generated from <xref target="RFC7863"/>).  This includes
both nfs types that end with a 4, such as offset4, length4, etc., as
well as more generic types such as uint32_t and uint64_t.</t>
      <t>While the XDR can be appended to that from <xref target="RFC7863"/>, the code snippets
should be placed in their appropriate sections within the existing XDR.</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>The EXCHANGE_RANGE operation is subject to the same security
considerations as other NFSv4.2 operations that modify file data.</t>
      <t>The caller <bcp14>MUST</bcp14> have appropriate access to both the source file
(read access) and the destination file (write access).  Servers
<bcp14>MUST</bcp14> enforce authorization checks on both filehandles before
performing the exchange.</t>
      <t>Within a session, the SEQUENCE mechanism (<xref section="18.46" sectionFormat="of" target="RFC8881"/>)
prevents duplicate execution via the slot identifier and sequenceid.
After a server reboot, previously issued stateids are invalidated,
preventing replay of prior operations across reboots.</t>
      <t>Because EXCHANGE_RANGE is its own inverse, a double execution returns
both files to their original state.  A client checking only the final
value of the change attribute cannot distinguish zero executions from
two executions, since both cases leave the files in their original
state while the change attribute may have been incremented an even
number of times.  The change_info4 values returned in err_src_cinfo
and err_dst_cinfo enable precise confirmation: a client <bcp14>MUST</bcp14> record
the change attribute of both files before the first attempt and
compare cinfo_before from the response against that recorded value to
confirm a single net execution.  Comparing only cinfo_after is
insufficient for this purpose.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC4506">
          <front>
            <title>XDR: External Data Representation Standard</title>
            <author fullname="M. Eisler" initials="M." role="editor" surname="Eisler"/>
            <date month="May" year="2006"/>
            <abstract>
              <t>This document describes the External Data Representation Standard (XDR) protocol as it is currently deployed and accepted. This document obsoletes RFC 1832. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="67"/>
          <seriesInfo name="RFC" value="4506"/>
          <seriesInfo name="DOI" value="10.17487/RFC4506"/>
        </reference>
        <reference anchor="RFC7862">
          <front>
            <title>Network File System (NFS) Version 4 Minor Version 2 Protocol</title>
            <author fullname="T. Haynes" initials="T." surname="Haynes"/>
            <date month="November" year="2016"/>
            <abstract>
              <t>This document describes NFS version 4 minor version 2; it describes the protocol extensions made from NFS version 4 minor version 1. Major extensions introduced in NFS version 4 minor version 2 include the following: Server-Side Copy, Application Input/Output (I/O) Advise, Space Reservations, Sparse Files, Application Data Blocks, and Labeled NFS.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7862"/>
          <seriesInfo name="DOI" value="10.17487/RFC7862"/>
        </reference>
        <reference anchor="RFC7863">
          <front>
            <title>Network File System (NFS) Version 4 Minor Version 2 External Data Representation Standard (XDR) Description</title>
            <author fullname="T. Haynes" initials="T." surname="Haynes"/>
            <date month="November" year="2016"/>
            <abstract>
              <t>This document provides the External Data Representation (XDR) description for NFS version 4 minor version 2.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7863"/>
          <seriesInfo name="DOI" value="10.17487/RFC7863"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC8178">
          <front>
            <title>Rules for NFSv4 Extensions and Minor Versions</title>
            <author fullname="D. Noveck" initials="D." surname="Noveck"/>
            <date month="July" year="2017"/>
            <abstract>
              <t>This document describes the rules relating to the extension of the NFSv4 family of protocols. It covers the creation of minor versions, the addition of optional features to existing minor versions, and the correction of flaws in features already published as Proposed Standards. The rules relating to the construction of minor versions and the interaction of minor version implementations that appear in this document supersede the minor versioning rules in RFC 5661 and other RFCs defining minor versions.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8178"/>
          <seriesInfo name="DOI" value="10.17487/RFC8178"/>
        </reference>
        <reference anchor="RFC8881">
          <front>
            <title>Network File System (NFS) Version 4 Minor Version 1 Protocol</title>
            <author fullname="D. Noveck" initials="D." role="editor" surname="Noveck"/>
            <author fullname="C. Lever" initials="C." surname="Lever"/>
            <date month="August" year="2020"/>
            <abstract>
              <t>This document describes the Network File System (NFS) version 4 minor version 1, including features retained from the base protocol (NFS version 4 minor version 0, which is specified in RFC 7530) and protocol extensions made subsequently. The later minor version has no dependencies on NFS version 4 minor version 0, and is considered a separate protocol.</t>
              <t>This document obsoletes RFC 5661. It substantially revises the treatment of features relating to multi-server namespace, superseding the description of those features appearing in RFC 5661.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8881"/>
          <seriesInfo name="DOI" value="10.17487/RFC8881"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="I-D.haynes-nfsv4-flexfiles-v2">
          <front>
            <title>Parallel NFS (pNFS) Flexible File Layout Version 2</title>
            <author fullname="Thomas Haynes" initials="T." surname="Haynes">
              <organization>Hammerspace</organization>
            </author>
            <date day="27" month="March" year="2026"/>
            <abstract>
              <t>   Parallel NFS (pNFS) allows a separation between the metadata (onto a
   metadata server) and data (onto a storage device) for a file.  The
   Flexible File Layout Type Version 2 is defined in this document as an
   extension to pNFS that allows the use of storage devices that require
   only a limited degree of interaction with the metadata server and use
   already-existing protocols.  Data protection is also added to provide
   integrity.  Both Client-side mirroring and the Erasure Coding
   algorithms are used for data protection.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-haynes-nfsv4-flexfiles-v2-03"/>
        </reference>
        <reference anchor="XFS-EXCHANGE-RANGE">
          <front>
            <title>ioctl_xfs_exchange_range(2) - Exchange data between files (Accessed January 2026)</title>
            <author>
              <organization>Linux man-pages project</organization>
            </author>
            <date year="2024" month="July"/>
          </front>
          <seriesInfo name="Linux" value="6.10"/>
        </reference>
      </references>
    </references>
    <?line 529?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>Christoph Helwig brought the XFS exchange range implementation
(<xref target="XFS-EXCHANGE-RANGE"/>) to the author's attention, which prompted
this document.</t>
      <t>Darrick Wong, David Noveck, Pali Rohar, Rick Macklem, and Christoph
Helwig helped review the document.</t>
      <t>Chris Inacio, Brian Pawlowski, and Gorry Fairhurst helped guide
this process.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
PYq7eQLs0k+CXQFjX49Op9cQ4YzPT3seHRj/8h7vVTUPRqfvzi+nk/FPV5Ch
9vzLp+OL8Rv/2I++utgx59X78eW7q9MxN2Vt11uCkwyqGcjRBmlkhSW9jrnD
iZqS8xhCEmwYJCONRjQvm+5SNNJ35DbaiTZ3Nn8KAshbRY+83M6huev8XqxO
E8e2W0AYk7gh2/gTbWZMqsQK3GnhZRPKew40Tq5Fkd9XTyrsCNScPtJ9WWaf
y/u6F/7I9QRfNpeZPlmM6hq2ra4ZsADDRnBOTsbX19gK9oQoNV+AJP5yOuk8
8XIUPD6FRPUaZj2/umw/vhh96DwIpDP84sfbq5vwgZP34NHZ6/M3rc9vdwx6
MxmdjMMHZKZaD65an65Pz1s7ZEkMn7y7+qn94PLq7PxiDPw9vRi3n1+/P2k/
oFuv4aNQEcPHoortZzgBbGC6g7Xv4Q/YyvTtVZsGen55NQXGX922ODoZv5/e
XF1NO1wMHsP/pyejk7fj9vc/7n7tZvJhentJ409xlta3V2ctCbseT34aT85G
txctkoARbeqvP7y7OL/8a/gI1343uvwA7GhN2bgyamjYoX0eV94CntAQRVxO
pEZpdxeDohSxHpLuKu4KdU297eIn58chygGZplTj22GfwnX6pUkJeXAxIIQN
j/SLKTI3KFv3lwcaeGEV9NE9eeVchVfO+ZZwEVL+VGgikQUSEL6Fdy8CK4dg
epRlRkooi2iO0BHBRBCRIyLqdqOkN4PuCvSrnO5NJdwzDYHfQN/kbjTRtYb0
BqxeH8dTO2CHkp6DFILgx64MhlA0RFp36JH66j8OZkl2YFdY1Cr08//SXx8c
HDzXv/ta/7fGJpTn9gd+pn/44Xn32e/gGfXJqDN0gHxvqOfqGbwc+UG69PNc
djGwq+fiLFo/HGGVH9f6vZ3qsXrek5yzuzG8FQhTtfZkV7pZSf9Rb0+nv+88
nGJeNXjkvfCVYSa+NNwHj/g9Odk0yu742oVtAha68WtSn+fq58hE7jHALFfj
XekBHlQoaLbJ+7ZnQPdm1jOD3VqQvpR5vaQ8lpRUWIZBQV6ZpuKOC9BPTYgq
7PCbmksOVBqoNoXhC7SUIDnIIFvYY2EI24C99g8y6OAHGfbdFWsH+zEyBVPI
7EQbRpVyo/q4yUekkbHnmhThjKv5AIERhR3YOGSNSBytjtE6TejerkFtvjma
cvEdP3x7PEWO+KuxzA3ORvDufub73qJqax8CUyHvbJbAaEj37Mr11nM3hqDX
CMkFSarcLW/9LItvZAYSyHZB/FFTBcdd/Y6Cn6/4VLXC1rN/CNLtc1grk9Gv
pDWTEUspS3EHGcRmtGkuiwU/BCVgMF48F9iZQP5wexKlYn2xgy9TGXUvqNTs
e4XY8iJ7fCVDxoHMXPMlU06pDf5iEco8/aCX/AwaX/EgOfVZuuvWFzwuKDJ1
wteffeV5J/zlUXn9afhL+fA4rouUsPAAKPwyxGugnoBWnoZVdBdWcXTwpTSH
rjC2EgbgDAEJ9vPvACd0fymv0Zs0+5MUXH0eJGn9qg4eGzVB4e9ncF0bL+Ix
POoS0i7kK436wSV2jX1FITrKdqqFmPawswAEhyjkS+OMobpyum101lGsGNZ5
8GZiixb8GSXSA0rAEvwBhzW7dex+wt99aqrvWIexEhHsqGgIDwXvDIsbinuG
wkKGycidO3Q9hH6GDWYttVcEnXdXMVwpiPcflCFhNgSvK7ysQmZT7UK52TS2
SjoOaRRkqoV3V7kSQps+D4S1/CEhsuUBcZKJT6Dize+jya8SkPU8H12OdljO
0KthmJrlPJLDKiu/Y0Z3aWCS0fwuyx9SE/MdS4iE+RRN/Kdniyi15tlHvEVc
ggTmxUq/NelDAv6eHK94Vwh/fXer/B5Eq5yPYPr2LyEijC7mmw3cc0uHkMnP
C7if1INDIVcfbAu2cIp4OWTzP+f4Y5On0T0k1pcQkszvevo9GAg9yVdR2dMT
HPQO9gr0MAzr96JkLxAcFYSL3yfmoRtI0Gh9nkGcmvf0azD+Gcz/gF2gdwlP
+CYvy40+i5JyVaMkyXygrbFhuuWi9UD9H9VZzaNdVAAA

-->

</rfc>
