<?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.34 (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-flexfiles-v2-06" category="std" consensus="true" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.31.0 -->
  <front>
    <title abbrev="Flex File Layout v2">Parallel NFS (pNFS) Flexible File Layout Version 2</title>
    <seriesInfo name="Internet-Draft" value="draft-haynes-nfsv4-flexfiles-v2-06"/>
    <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 82?>

<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 Version 2 Layout Type 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>
    <note>
      <name>Note to Readers</name>
      <?line 93?>

<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/flexfiles-v2"/>.</t>
      <t>Working Group information can be found at <eref target="https://github.com/ietf-wg-nfsv4"/>.</t>
    </note>
  </front>
  <middle>
    <?line 104?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>In Parallel NFS (pNFS) (see Section 12 of <xref target="RFC8881"/>), the metadata
server returns layout type structures that describe where file data is
located.  There are different layout types for different storage systems
and methods of arranging data on storage devices.  <xref target="RFC8435"/> defined
the Flexible File Version 1 Layout Type used with file-based data
servers that are accessed using the NFS protocols: NFSv3 <xref target="RFC1813"/>,
NFSv4.0 <xref target="RFC7530"/>, NFSv4.1 <xref target="RFC8881"/>, and NFSv4.2 <xref target="RFC7862"/>.</t>
      <t>A metadata server that supports the Flexible File Version 2 Layout
Type <bcp14>MUST</bcp14> be an NFSv4.2 server.  The new operations defined by this
document for the metadata server (the TRUST_STATEID family on the
metadata server / storage device control session, and the
CB_CHUNK_REPAIR back-channel callback to clients) are NFSv4.2
operations and have no representation in NFSv4.1 or earlier minor
versions.  Storage devices can speak NFSv3, NFSv4.1, or NFSv4.2, but
some encoding types and coupling configurations narrow that choice;
see <xref target="sec-ff_device_addr4"/> for the exact rules.</t>
      <t>To provide a global state model equivalent to that of the files
layout type, a back-end control protocol might be implemented between
the metadata server and NFSv4.1+ storage devices.  An implementation
can either define its own proprietary mechanism or it could define a
control protocol in a Standards Track document.  The requirements for
a control protocol are specified in <xref target="RFC8881"/> and clarified in
<xref target="RFC8434"/>.</t>
      <t>The control protocol described in this document is based on NFS.  It
does not provide for knowledge of stateids to be passed between the
metadata server and the storage devices.  Instead, the storage
devices are configured such that the metadata server has full access
rights to the data file system and then the metadata server uses
synthetic ids to control client access to individual data files.</t>
      <t>In traditional mirroring of data, the server is responsible for
replicating, validating, and repairing copies of the data file.  With
client-side mirroring, the metadata server provides a layout that
presents the available mirrors to the client.  The client then picks
a mirror to read from and ensures that all writes go to all mirrors.
The client only considers the write transaction to have succeeded if
all mirrors are successfully updated.  In case of error, the client
can use the LAYOUTERROR operation to inform the metadata server,
which is then responsible for the repairing of the mirrored copies of
the file.</t>
      <t>This client side mirroring provides for replication of data but does
not provide for integrity of data.  In the event of an error, a user
would be able to repair the file by silvering the mirror contents.
I.e., they would pick one of the mirror instances and replicate it to
the other instance locations.</t>
      <t>However, lacking integrity checks, silent corruptions are not able to
be detected and the choice of what constitutes the good copy is
difficult.  This document updates the Flexible File Version 1 Layout Type to
version 2 by providing error-detection integrity (checksum) for erasure
coding.  Data blocks are transformed into a header and a chunk.  This
document also introduces new operations that allow the client to roll
back writes to the data file.</t>
      <t>Using the process detailed in <xref target="RFC8178"/>, the revisions in this
document become an extension of 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>
      <t>This document defines <tt>LAYOUT4_FLEX_FILES_V2</tt>, a new and independent
layout type that coexists with the Flexible File Version 1 Layout Type
(<tt>LAYOUT4_FLEX_FILES</tt>, <xref target="RFC8435"/>).  The two layout types are NOT
backward compatible: a flexible file v2 layout cannot be parsed as a flexible file v1 layout
and vice versa.  A server <bcp14>MAY</bcp14> support both layout types simultaneously;
a client selects the desired layout type in its LAYOUTGET request.</t>
    </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="sec-motivation">
      <name>Motivation</name>
      <t>Workloads that need both the throughput of parallel pNFS
data servers and the durability of erasure coding have
driven the work in this draft.  The deployments span
scientific-instrumentation pipelines that produce
petabytes of detector data per year, training-checkpoint
files written hot from machine-learning jobs, archive
workloads in which a single file may hold the only copy of
an experiment's result, and ordinary production
filesystems where read patterns evolve across a file's
lifetime.  These deployments are documented in detail in
<xref target="sec-use-cases"/>; the protocol shape that follows is the
result of looking at them and asking what a pNFS layout
type would have to provide.</t>
      <t>The first thing the deployments share is that erasure
coding moves work off the data servers that are already
the bottleneck in the write-heavy parallel case.
Server-side erasure coding makes each data server compute
its share of the parity transform on every write,
multiplying the per-write CPU cost by (k + m) across the
storage tier and serialising on the data server's limited
compute.  Client-side erasure coding shifts that compute
to the writers, which scale horizontally with the
workload, and lets the data servers stay close to their
strength -- storing and serving bytes.  Flexible file v1
layout (<xref target="RFC8435"/>) already chose client-side compute by
placing replication at the writer; this draft extends that
choice to client-side erasure coding.  Benchmark
measurements summarised in <xref target="sec-implementation-status"/>
confirm that the resulting overhead is competitive with
server-side encoding on realistic workloads and that the
encoding compute scales with the writer population rather
than with the data-server count.</t>
      <t>Client-side erasure coding has a corollary that protocol
designers cannot avoid: when a client fans a stripe out
across multiple data servers and fails mid-write, no
single data server has whole-transaction visibility.  The
state left behind on each data server is a partial
fragment of a write that may or may not have completed
elsewhere.  A server-side coordinator that holds the whole
stripe -- the flexible file v1 case -- can resilver from a
surviving copy without any client involvement.  In the v2
case there is no such coordinator, and the on-wire
protocol must specify how the partial state is reconciled.
This is the load-bearing constraint that shapes the rest
of the design.</t>
      <t>A natural-looking answer is to add a distributed-consensus
protocol between the data servers and have them agree on
which write committed.  That answer is rejected here.
Distributed consensus is operationally expensive,
introduces a synchronisation cost on every write, and
makes the data servers themselves stateful peers in a way
that closes off the simpler implementations the protocol
should accommodate.  Instead, this draft uses two
narrowly-scoped primitives that together provide just
enough on-wire reconciliation: the chunk_guard4
compare-and-swap (CAS) and the CB_CHUNK_REPAIR callback.</t>
      <t>Every CHUNK_WRITE carries a chunk_guard4 -- a 32-bit
per-chunk generation counter and a 32-bit owning-client
short-id -- and the data server performs a per-chunk CAS
on receipt.  If two writers race for the same chunk,
exactly one wins on each data server, the loser receives
NFS4ERR_CHUNK_GUARDED for that chunk, and the chunks the
loser intended to write are left unchanged.  No data
server needs to consult its peers; the CAS is local.  The
cost on the metadata server is bounded by the 8-byte
chunk_guard4 header per chunk plus a 32-bit per-layout
client identifier (<xref target="sec-chunk_guard4"/>,
<xref target="sec-ffv2-mirror4"/>).  Independent collisions on
different chunks resolve independently; there is no
file-wide lock and no global ordering across writes.</t>
      <t>When the per-chunk CAS detects that a stripe ended up
non-atomic -- some shards under writer A's guard, others
under writer B's, or a writer crashed mid-fan-out -- the
metadata server selects a repair client via
CB_CHUNK_REPAIR (<xref target="sec-CB_CHUNK_REPAIR"/>) and that client
drives the repair: it acquires CHUNK_LOCK on the affected
range, reads the surviving shards, decodes through the
erasure transform, writes the reconstructed shards via
CHUNK_WRITE_REPAIR, and clears the errored state via
CHUNK_REPAIRED.  The repair client is exactly one actor
holding a chunk-range lock; the data servers still do not
coordinate among themselves.  The repair-client selection
rule is given in <xref target="sec-repair-selection"/>.</t>
      <t>These two primitives -- the per-chunk CAS and the
callback-driven repair -- replace what would otherwise
require a distributed-consensus protocol.  The CAS handles
the common case at local cost, where independent writers
racing for different chunks resolve independently and
concurrent writers on the same chunk get a clean win/loss
decision.  CB_CHUNK_REPAIR handles the rare case of
partial-failure non-atomicity with a single coordinator
selected per repair episode.  The cost model is asymmetric
on purpose: the hot path pays for an 8-byte header and a
local CAS; the cold path pays for a selected actor and a
small number of round-trips.</t>
      <t>The CHUNK_* operation set in this draft is the minimum
sufficient to drive the chunk state machine
(<xref target="sec-system-model-chunk-state"/>) plus the repair flow
above.  CHUNK_WRITE places PENDING content; CHUNK_FINALIZE
signals that the writer is done with a generation;
CHUNK_COMMIT promotes that generation to durable, globally
visible state; CHUNK_READ retrieves it; CHUNK_HEADER_READ
provides the fast probe that lets repair coordinators and
recovering writers inspect chunk metadata without reading
payloads.  CHUNK_LOCK, CHUNK_UNLOCK, CHUNK_ERROR,
CHUNK_REPAIRED, CHUNK_WRITE_REPAIR, and CHUNK_ROLLBACK
together drive the repair flow.  Each operation does one
well-scoped job; the complexity is in the state machine
the operations drive, not in the operation set itself.
Each of these primitives closes a specific gap in the
lifecycle or the repair path.  The detailed treatment of
the operation set is in <xref target="sec-new-ops"/>.</t>
      <t>The same design discipline shapes the rest of the
specification.  The protocol describes wire format and
server obligations; it does not pin a data-server
backend, a control protocol between metadata server and
data server, a checksum algorithm, or a file-attribute
representation on the data server.  Different
implementations resolve these choices differently and
remain conformant.  TRUST_STATEID
(<xref target="sec-tight-coupling-control"/>) is one such control
protocol that this draft defines; storage devices with
their own established control protocols are conformant
without implementing it.  The tagged checksum4
(<xref target="sec-checksum4"/>) lets the metadata server pick any
registered checksum algorithm per file.  The
authorization-outcome parity rule
(<xref target="sec-state-locking"/>) lets data servers that do not
expose a POSIX file namespace satisfy the tight-coupling
requirements without materialising POSIX uid/gid bits.</t>
      <t>A protocol-level consequence of placing erasure coding at
the client is that the layout must be able to describe a
file's storage shape over its full lifetime -- including
the transition windows when the file is being assimilated
from a non-erasure-coded source, re-encoded from one
codec to another, or recovered from a correlated codec
failure through a mirror under a different encoding.
This draft allows a single file's layout to contain
mirrors under different encodings.  The
heterogeneous-mirror capability is not a steady-state
expectation; most files have one encoding most of the
time.  It is the protocol shape that lets transitions
happen while the file remains readable.  The deployment
cases that drive the allowance are catalogued in
<xref target="sec-use-cases"/>.</t>
      <t>Scope note: the consistency goal of flexible file v2
layout is RAID consistency across the shards that make
up an encoded stripe, not POSIX write ordering across
arbitrary application writes.  The protocol does not
attempt to make overlapping application writes from
different clients atomic; that is the province of file
locking (<xref target="RFC8881"/> Section 12) and of application-level
coordination.  What the protocol does guarantee is that
the shards comprising a given stripe agree on which
write produced them -- expressed on the wire as agreement
on the chunk_guard4 value of every chunk that carries
those shards -- so that readers and repair clients never
observe a half-applied stripe.  Readers who need
cross-write ordering beyond a single stripe <bcp14>MUST</bcp14> use the
existing NFSv4 locking primitives.</t>
    </section>
    <section anchor="sec-use-cases">
      <name>Use Cases</name>
      <t>The protocol is designed around three workload classes.  The
percentages below reflect the expected deployment mix in
installations that choose flexible file v2 layout for its combination of
integrity and performance; individual deployments may diverge.</t>
      <dl>
        <dt>Single writer, multiple readers:</dt>
        <dd>
          <t>Approximately 90% of expected deployments.  The common case is a
file written by one client and subsequently read by many.
Examples include artifacts deposited by batch jobs, container
images, and media files.  The protocol is optimized for this
case; see <xref target="sec-system-model-progress"/>.</t>
        </dd>
        <dt>Multiple writers without sustained contention:</dt>
        <dd>
          <t>Approximately 9% of expected deployments.  Files with multiple
concurrent writers where races on the same chunk are rare.
Examples include shared-directory append-only logs and
distributed builds.  The chunk_guard4 CAS primitive and per-chunk
locking cover this case without penalizing the common
single-writer path.</t>
        </dd>
        <dt>Multiple writers, disjoint regions:</dt>
        <dd>
          <t>Approximately 1% of expected deployments.  High-performance
computing (HPC) checkpoint workloads, in which many ranks write
disjoint regions of the same file in lockstep.  The protocol
relies on block alignment to keep per-chunk contention rare
despite overall high writer count.  Contention that does occur
is resolved via the deterministic tiebreaker rule defined in
<xref target="sec-chunk_guard4"/>.</t>
        </dd>
      </dl>
      <t>Scale targets include multi-thousand-client deployments (on the
order of tens of thousands of concurrent clients for HPC
checkpointing), parallel-filesystem replacements, and multi-rack
shared-storage clusters.  The repair protocol (see
<xref target="sec-repair-selection"/>) is designed to let such deployments
tolerate data-server failures and concurrent-writer races without
blocking the critical path for the first two workload classes.</t>
    </section>
    <section anchor="definitions">
      <name>Definitions</name>
      <dl>
        <dt>block:</dt>
        <dd>
          <t>the application's view of file data.  A block is a unit of file
content as observed by an NFS client at the POSIX layer or by the
local file system.  A chunk's payload, after any decoding the client
performs, is presented to the application as one or more blocks.</t>
        </dd>
        <dt>shard:</dt>
        <dd>
          <t>the codec's view.  A shard is a single piece of an encoded stripe
produced by an erasure-coding (or replication) transformation.  A
stripe of k data shards plus m parity shards is the unit a codec
encodes and decodes.  The word "shard" only has meaning while the
codec is reasoning about a stripe; once a shard is at rest on a data
server it is, by virtue of having been transmitted, the payload of a
chunk.</t>
        </dd>
        <dt>chunk:</dt>
        <dd>
          <t>the protocol's unit of file data on the wire, carrying an
envelope that distinguishes it from a block: a compare-and-swap
guard (chunk_guard4 -- atomicity, see <xref target="sec-chunk_guard4"/>), a
checksum (per-chunk integrity), a provenance identifier
(chunk_owner4, see <xref target="sec-chunk_owner4"/>), a lifecycle state
(PENDING / FINALIZED / COMMITTED via the chunk state machine,
see <xref target="sec-system-model-chunk-state"/>), and per-chunk locking that
survives stateid revocation through lock escrow.  A chunk is the
addressable unit named in the CHUNK_* operations defined in this
document and durably persisted by a data server.  A chunk's
payload may be a block (mirrored layout) or a shard
(erasure-coded layout); the wire protocol does not distinguish.
The chunk size <bcp14>MAY</bcp14> differ from the size of the block or shard it
carries.  See <xref target="sec-system-model-chunk-not-block"/> for the
load-bearing role each envelope property plays in the protocol's
consistency story.</t>
        </dd>
      </dl>
      <t>The three terms describe the same data at three different layers and
should be used accordingly.  The codec transforms blocks into shards;
the wire protocol transmits shards as chunk payloads; the data server
persists chunks.  On read the path reverses.</t>
      <t>A protocol-internal note: the chunk state machine
(<xref target="sec-system-model-chunk-state"/>) and several CHUNK_* operations
refer to the per-chunk-offset state records as "blocks" (PENDING /
FINALIZED / COMMITTED / errored).  This is a finer-grained use of
the word, internal to the data server's chunk metadata, and should
not be confused with the application-layer "block" defined above.
Where ambiguity matters, this document writes "chunk-state block"
or relies on context (operation names, state names) to disambiguate.</t>
      <dl>
        <dt>control communication requirements:</dt>
        <dd>
          <t>the specification for information on layouts, stateids, file metadata,
and file data that must be communicated between the metadata server and
the storage devices.  There is a separate set of requirements for each
layout type.</t>
        </dd>
        <dt>control protocol:</dt>
        <dd>
          <t>the particular mechanism that an implementation of a layout type would
use to meet the control communication requirement for that layout type.
This need not be a protocol as normally understood.  In some cases,
the same protocol may be used as a control protocol and storage protocol.</t>
        </dd>
        <dt>client-side mirroring:</dt>
        <dd>
          <t>a feature in which the client, not the server, is responsible for
updating all of the mirrored copies of a layout segment.</t>
        </dd>
        <dt>data block:</dt>
        <dd>
          <t>A block (as defined above) in the client's cache for a file.</t>
        </dd>
        <dt>data file:</dt>
        <dd>
          <t>The data portion of the file, stored on the data server.</t>
        </dd>
        <dt>replication of data:</dt>
        <dd>
          <t>Data replication is making and storing multiple copies of data in
different locations.</t>
        </dd>
        <dt>erasure coding:</dt>
        <dd>
          <t>A data protection scheme where a stripe of data is encoded into
shards (k data shards and m parity shards) so that the original
content can be reconstructed from any sufficient subset of the
shards.  Shards are transmitted as the payload of CHUNK operations
and stored on different data servers.</t>
        </dd>
        <dt>client-side erasure coding:</dt>
        <dd>
          <t>A file based integrity method where copies are maintained in parallel.</t>
        </dd>
        <dt>compare-and-swap (CAS):</dt>
        <dd>
          <t>an atomic primitive from concurrent programming in which an
update is conditional on a prior observed value: the operation
succeeds only if the current value matches an expected prior value,
and otherwise fails so the caller can retry.  In this document, the
chunk_guard4 mechanism (see <xref target="sec-chunk_guard4"/>) implements CAS at
the chunk level; the "expected prior value" is the chunk_guard4 the
writer observed at read time, and the "fail" outcome is
NFS4ERR_CHUNK_GUARDED.</t>
        </dd>
        <dt>(file) data:</dt>
        <dd>
          <t>that part of the file system object that contains the data to be read
or written.  It is the contents of the object rather than the attributes
of the object.</t>
        </dd>
        <dt>data server (DS):</dt>
        <dd>
          <t>a pNFS server that provides the file's data when the file system
object is accessed over a file-based protocol.</t>
        </dd>
        <dt>escrow (lock escrow, MDS-escrow):</dt>
        <dd>
          <t>a state in which a chunk lock is held by the metadata server on
behalf of an as-yet-unselected future owner.  When the metadata
server revokes a client's stateid while the client still holds
chunk locks, the locks are not dropped (which would expose the
chunks to concurrent writers) but are transferred to the metadata
server itself, marked by the reserved cg_client_id value
CHUNK_GUARD_CLIENT_ID_MDS (see <xref target="sec-chunk_guard_mds"/>).  The
metadata server holds the locks in escrow until a repair client
adopts them via CHUNK_LOCK with CHUNK_LOCK_FLAGS_ADOPT (driven by
CB_CHUNK_REPAIR).  An "MDS-escrow owner" is the metadata server
acting in this placeholder role; "in escrow" describes a lock in
this state.  Escrow preserves the lock-continuity invariant
across stateid revocation: at no point during the revocation
sequence is a chunk simultaneously locked and unowned.</t>
        </dd>
        <dt>fencing:</dt>
        <dd>
          <t>the process by which the metadata server prevents the storage devices
from processing I/O from a specific client to a specific file.</t>
        </dd>
        <dt>file layout type:</dt>
        <dd>
          <t>a layout type in which the storage devices are accessed via the NFS
protocol (see Section 5.12.4 of <xref target="RFC8881"/>).</t>
        </dd>
        <dt>gid:</dt>
        <dd>
          <t>the group id, a numeric value that identifies to which group a file
belongs.</t>
        </dd>
        <dt>layout:</dt>
        <dd>
          <t>the information a client uses to access file data on a storage device.
This information includes specification of the protocol (layout type)
and the identity of the storage devices to be used.</t>
        </dd>
        <dt>layout iomode:</dt>
        <dd>
          <t>a grant of either read-only or read/write I/O to the client.</t>
        </dd>
        <dt>layout segment:</dt>
        <dd>
          <t>a sub-division of a layout.  That sub-division might be by the layout
iomode (see Sections 3.3.20 and 12.2.9 of <xref target="RFC8881"/>), a striping pattern
(see Section 13.3 of <xref target="RFC8881"/>), or requested byte range.</t>
        </dd>
        <dt>layout stateid:</dt>
        <dd>
          <t>a 128-bit quantity returned by a server that uniquely defines the
layout state provided by the server for a specific layout that describes
a layout type and file (see Section 12.5.2 of <xref target="RFC8881"/>).  Further,
Section 12.5.3 of <xref target="RFC8881"/> describes differences in handling between
layout stateids and other stateid types.</t>
        </dd>
        <dt>layout type:</dt>
        <dd>
          <t>a specification of both the storage protocol used to access the data
and the aggregation scheme used to lay out the file data on the underlying
storage devices.</t>
        </dd>
        <dt>loose coupling:</dt>
        <dd>
          <t>when the control protocol is a storage protocol.</t>
        </dd>
        <dt>(file) metadata:</dt>
        <dd>
          <t>the part of the file system object that contains various descriptive
data relevant to the file object, as opposed to the file data itself.
This could include the time of last modification, access time, EOF
position, etc.</t>
        </dd>
        <dt>metadata server (MDS):</dt>
        <dd>
          <t>the pNFS server that provides metadata information for a file system
object.  It is also responsible for generating, recalling, and revoking
layouts for file system objects, for performing directory operations,
and for performing I/O operations to regular files when the clients
direct these to the metadata server itself.</t>
        </dd>
        <dt>mirror:</dt>
        <dd>
          <t>a copy of a layout segment.  Note that if one copy of the mirror is
updated, then all copies must be updated.</t>
        </dd>
        <dt>non-systematic encoding:</dt>
        <dd>
          <t>An erasure coding scheme in which the encoded shards do not contain
verbatim copies of the original data.  Every read requires decoding,
even when no shards are lost.  The Mojette non-systematic transform is
an example.</t>
        </dd>
        <dt>proxy server (PS):</dt>
        <dd>
          <t>a peer of the metadata server, defined in
<xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>, that admits client
I/O on the metadata server's behalf -- either as a translator for
clients that cannot speak the file's native codec, or as a
proxy-mediated data path during whole-file move and repair
operations.  A proxy server may additionally act as a data server.</t>
        </dd>
        <dt>recalling a layout:</dt>
        <dd>
          <t>a graceful recall, via a callback, of a specific layout by the metadata
server to the client.  Graceful here means that the client would have
the opportunity to flush any WRITEs, etc., before returning the layout
to the metadata server.</t>
        </dd>
        <dt>revoking a layout:</dt>
        <dd>
          <t>an invalidation of a specific layout by the metadata server.
Once revocation occurs, the metadata server will not accept as valid any
reference to the revoked layout, and a storage device will not accept
any client access based on the layout.</t>
        </dd>
        <dt>resilvering:</dt>
        <dd>
          <t>the act of rebuilding a mirrored copy of a layout segment from a
known good copy of the layout segment.  Note that this can also be done
to create a new mirrored copy of the layout segment.</t>
        </dd>
        <dt>rsize:</dt>
        <dd>
          <t>the data transfer buffer size used for READs.</t>
        </dd>
        <dt>stateid:</dt>
        <dd>
          <t>a 128-bit quantity returned by a server that uniquely defines the set
of locking-related state provided by the server.  Stateids may designate
state related to open files, byte-range locks, delegations, or layouts.</t>
        </dd>
        <dt>storage device:</dt>
        <dd>
          <t>the target to which clients may direct I/O requests when they hold
an appropriate layout.  See Section 2.1 of <xref target="RFC8434"/> for further
discussion of the difference between a data server and a storage device.</t>
        </dd>
        <dt>storage protocol:</dt>
        <dd>
          <t>the protocol used by clients to do I/O operations to the storage
device.  Each layout type specifies the set of storage protocols.</t>
        </dd>
        <dt>systematic encoding:</dt>
        <dd>
          <t>An erasure coding scheme in which the first k of the k+m encoded
shards are identical to the original k data blocks.  A healthy read
(no failures) requires no decoding -- the data shards are read directly.
Decoding is triggered only when data shards are missing.  Reed-Solomon
Vandermonde and Mojette systematic are examples.</t>
        </dd>
        <dt>tight coupling:</dt>
        <dd>
          <t>an arrangement in which the control protocol is one designed
specifically for control communication.  It may be either a proprietary
protocol adapted specifically to a particular metadata server or a
protocol based on a Standards Track document.  The specific
tight-coupling variant defined by this document, in which the
control protocol is the TRUST_STATEID family, is referred to as
trusted-stateid tight coupling (see <xref target="sec-tight-coupling-control"/>).</t>
        </dd>
        <dt>trusted-stateid tight coupling:</dt>
        <dd>
          <t>the specific tight-coupling control protocol defined in this
document, consisting of the operations TRUST_STATEID, REVOKE_STATEID,
and BULK_REVOKE_STATEID.  Within the scope of this document,
unqualified references to "tight coupling" or "tightly coupled" refer
to trusted-stateid tight coupling unless the context explicitly
discusses the general concept.  Other tight-coupling control
protocols (proprietary or future Standards Track) may exist but
are not covered by this specification.</t>
        </dd>
        <dt>uid:</dt>
        <dd>
          <t>the user id, a numeric value that identifies which user owns a file.</t>
        </dd>
        <dt>write hole:</dt>
        <dd>
          <t>A write hole is a data corruption scenario where either two clients
are trying to write to the same chunk or one client is overwriting an
existing chunk of data.</t>
        </dd>
        <dt>wsize:</dt>
        <dd>
          <t>the data transfer buffer size used for WRITEs.</t>
        </dd>
      </dl>
    </section>
    <section anchor="coupling-of-storage-devices">
      <name>Coupling of Storage Devices</name>
      <t>A server implementation may choose either a loosely coupled model or a
tightly coupled model between the metadata server and the storage devices.
<xref target="RFC8434"/> describes the general problems facing pNFS implementations.
This document details how the new flexible file v2 layout addresses
these issues.  To implement the tightly coupled model, a control protocol
has to be defined.  As the flexible file v2 layout imposes no special
requirements on the client, the control protocol will need to provide:</t>
      <ol spacing="normal" type="1"><li>
          <t>management of both security and LAYOUTCOMMITs and</t>
        </li>
        <li>
          <t>a global stateid model and management of these stateids.</t>
        </li>
      </ol>
      <t>When implementing the loosely coupled model, the only control protocol
will be a version of NFS, with no ability to provide a global stateid
model or to prevent clients from using layouts inappropriately.  To enable
client use in that environment, this document will specify how security,
state, and locking are to be managed.</t>
      <t>The loosely and tightly coupled locking models defined in Section 2.3
of <xref target="RFC8435"/> apply equally to this layout type, including the use of
anonymous stateids with loosely coupled storage devices, the handling
of lock and delegation stateids, and the mandatory byte-range lock
requirements for the tightly coupled model.</t>
      <section anchor="layoutcommit">
        <name>LAYOUTCOMMIT</name>
        <t>Regardless of the coupling model, the metadata server has the
responsibility, upon receiving a LAYOUTCOMMIT (see Section 18.42 of
<xref target="RFC8881"/>) to ensure that the semantics of pNFS are respected (see
Section 3.1 of <xref target="RFC8434"/>).  These do include a requirement that data
written to a data storage device be stable before the occurrence of
the LAYOUTCOMMIT.</t>
        <t>It is the responsibility of the client to make sure the data file is
stable before the metadata server begins to query the storage devices
about the changes to the file.  If any WRITE to a storage device did not
result with stable_how equal to FILE_SYNC, a LAYOUTCOMMIT to the metadata
server <bcp14>MUST</bcp14> be preceded by a COMMIT to the storage devices written to.
Note that if the client has not done a COMMIT to the storage device, then
the LAYOUTCOMMIT might not be synchronized to the last WRITE operation
to the storage device.</t>
      </section>
      <section anchor="sec-Fencing-Clients">
        <name>Fencing Clients from the Storage Device</name>
        <t>With loosely coupled storage devices, the metadata server uses synthetic
uids (user ids) and gids (group ids) for the data file, where the uid
owner of the data file is allowed read/write access and the gid owner
is allowed read-only access.  As part of the layout (see ffv2ds_user
and ffv2ds_group in <xref target="sec-ffv2_layout"/>), the client is provided
with the user and group to be used in the Remote Procedure Call
(RPC) <xref target="RFC5531"/> credentials needed to access the data file.
Fencing off of clients is achieved by the metadata server changing
the synthetic uid and/or gid owners of the data file on the storage
device to implicitly revoke the outstanding RPC credentials.  A
client presenting the wrong credential for the desired access will
get an NFS4ERR_ACCESS error.</t>
        <t>With this loosely coupled model, the metadata server is not able to fence
off a single client; it is forced to fence off all clients.  However,
as the other clients react to the fencing, returning their layouts and
trying to get new ones, the metadata server can hand out a new uid and
gid to allow access.</t>
        <t>It is <bcp14>RECOMMENDED</bcp14> to implement common access control methods at the
storage device file system to allow only the metadata server root
(super user) access to the storage device and to set the owner of all
directories holding data files to the root user.  This approach provides
a practical model to enforce access control and fence off cooperative
clients, but it cannot protect against malicious clients; hence, it
provides a level of security equivalent to AUTH_SYS.  It is <bcp14>RECOMMENDED</bcp14>
that the communication between the metadata server and storage device
be secure from eavesdroppers and man-in-the-middle protocol tampering.
The security measure could be physical security (e.g., the servers
are co-located in a physically secure area), encrypted communications,
or some other technique.</t>
        <t>With tightly coupled storage devices, the metadata server
and the storage device agree on the authorization decision
for each client access: a client allowed by the metadata
server to read or write a file is allowed the same access
at the storage device, and a client denied at the metadata
server is denied at the storage device.  How the storage
device reaches that decision is not constrained by this
specification.  Some storage devices replicate the user,
group, mode bits, and ACL of the metadata file onto a
POSIX-shaped local representation of the data file and let
their native filesystem enforce the decision; others (such
as storage devices backed by an object store, a
control-protocol-driven backend, or a backend with no
exposed file namespace) consult the control protocol
directly without ever materializing a POSIX file
representation.  Both approaches are conformant; the
specification's requirement is the authorization-outcome
parity, not the mechanism that produces it.</t>
        <t>The client authenticates with the storage device and
receives the same authorization outcome it would have
received via the metadata server.  In the case of tight
coupling, fencing is the responsibility of the control
protocol and is not described in detail in this document.
Implementations of the tightly coupled locking model (see
<xref target="sec-state-locking"/>) will need a way to prevent access by
certain clients to specific files by invalidating the
corresponding stateids on the storage device; in such a
scenario, the client receives NFS4ERR_BAD_STATEID.</t>
        <t>The client need not know the model used between the metadata server and
the storage device.  It need only react consistently to any errors in
interacting with the storage device.  It <bcp14>SHOULD</bcp14> both return the layout
and error to the metadata server and ask for a new layout.  At that point,
the metadata server can either hand out a new layout, hand out no layout
(forcing the I/O through it), or deny the client further access to
the file.</t>
        <section anchor="implementation-notes-for-synthetic-uidsgids">
          <name>Implementation Notes for Synthetic uids/gids</name>
          <t>The selection method for the synthetic uids and gids to be used for
fencing in loosely coupled storage devices is strictly an implementation
issue.  That is, an administrator might restrict a range of such ids
available to the Lightweight Directory Access Protocol (LDAP) 'uid' field
<xref target="RFC4519"/>.  The administrator might also be able to choose an id that
would never be used to grant access.  Then, when the metadata server had
a request to access a file, a SETATTR would be sent to the storage device
to set the owner and group of the data file.  The user and group might
be selected in a round-robin fashion from the range of available ids.</t>
          <t>Those ids would be sent back as ffv2ds_user and ffv2ds_group to the
client, who would present them as the RPC credentials to the storage
device.  When the client is done accessing the file and the metadata
server knows that no other client is accessing the file, it can
reset the owner and group to restrict access to the data file.</t>
          <t>When the metadata server wants to fence off a client, it changes the
synthetic uid and/or gid to the restricted ids.  Note that using a
restricted id ensures that there is a change of owner and at least one
id available that never gets allowed access.</t>
          <t>Under an AUTH_SYS security model, synthetic uids and gids of 0 <bcp14>SHOULD</bcp14> be
avoided.  These typically either grant super access to files on a storage
device or are mapped to an anonymous id.  In the first case, even if the
data file is fenced, the client might still be able to access the file.
In the second case, multiple ids might be mapped to the anonymous ids.</t>
        </section>
        <section anchor="example-of-using-synthetic-uidsgids">
          <name>Example of using Synthetic uids/gids</name>
          <t>The user loghyr creates a file "ompha.c" on the metadata server, which
then creates a corresponding data file on the storage device.</t>
          <t>The metadata server entry may look like:</t>
          <figure anchor="fig-meta-ompha">
            <name>Metadata's view of ompha.c</name>
            <sourcecode type="shell"><![CDATA[
-rw-r--r--    1 loghyr  staff    1697 Dec  4 11:31 ompha.c
]]></sourcecode>
          </figure>
          <t>On the storage device, the file may be assigned some unpredictable
synthetic uid/gid to deny access:</t>
          <figure anchor="fig-data-ompha">
            <name>Data's view of ompha.c</name>
            <sourcecode type="shell"><![CDATA[
-rw-r-----    1 19452   28418    1697 Dec  4 11:31 data_ompha.c
]]></sourcecode>
          </figure>
          <t>When the file is opened on a client and accessed, the user will try to
get a layout for the data file.  Since the layout knows nothing about
the user (and does not care), it does not matter whether the user loghyr
or garbo opens the file.  The client has to present an uid of 19452
to get write permission.  If it presents any other value for the uid,
then it must give a gid of 28418 to get read access.</t>
          <t>Further, if the metadata server decides to fence the file, it <bcp14>SHOULD</bcp14>
change the uid and/or gid such that these values neither match earlier
values for that file nor match a predictable change based on an earlier
fencing.</t>
          <figure anchor="fig-fenced-ompha">
            <name>Fenced Data's view of ompha.c</name>
            <sourcecode type="shell"><![CDATA[
-rw-r-----    1 19453   28419    1697 Dec  4 11:31 data_ompha.c
]]></sourcecode>
          </figure>
          <t>The set of synthetic gids on the storage device <bcp14>SHOULD</bcp14> be selected such
that there is no mapping in any of the name services used by the storage
device, i.e., each group <bcp14>SHOULD</bcp14> have no members.</t>
          <t>If the layout segment has an iomode of LAYOUTIOMODE4_READ, then the
metadata server <bcp14>SHOULD</bcp14> return a synthetic uid that is not set on the
storage device.  Only the synthetic gid would be valid.</t>
          <t>The client is thus solely responsible for enforcing file permissions
in a loosely coupled model.  To allow loghyr write access, it will send
an RPC to the storage device with a credential of 1066:1067.  To allow
garbo read access, it will send an RPC to the storage device with a
credential of 1067:1067.  The value of the uid does not matter as long
as it is not the synthetic uid granted when getting the layout.</t>
          <t>While pushing the enforcement of permission checking onto the client
may seem to weaken security, the client may already be responsible
for enforcing permissions before modifications are sent to a server.
With cached writes, the client is always responsible for tracking who is
modifying a file and making sure to not coalesce requests from multiple
users into one request.</t>
        </section>
      </section>
      <section anchor="sec-state-locking">
        <name>State and Locking Models</name>
        <t>The coupling model in effect for a given metadata-server /
storage-device pair is not negotiated over the NFS protocol.
The metadata server determines the coupling model from
out-of-band signals: administrative configuration, the
choice and capabilities of the control protocol between
the metadata server and the storage device, the storage
device's data-path protocol version, and the storage
device's backend architecture.  At the NFS protocol level,
the metadata server's expectations of the storage device
follow these classifications:</t>
        <ul spacing="normal">
          <li>
            <t>Storage devices implementing the NFSv3 or NFSv4.0
protocols on the data path are treated as loosely
coupled.</t>
          </li>
          <li>
            <t>NFSv4.1+ storage devices that do not return the
EXCHGID4_FLAG_USE_PNFS_DS flag in EXCHANGE_ID indicate
that they are to be treated as loosely coupled.  From
the locking viewpoint, they are treated in the same way
as NFSv4.0 storage devices.</t>
          </li>
          <li>
            <t>NFSv4.1+ storage devices that identify themselves with
the EXCHGID4_FLAG_USE_PNFS_DS flag set in EXCHANGE_ID
can potentially be tightly coupled.  They use a back-end
control protocol to implement the global stateid model
described in <xref target="RFC8881"/>.</t>
          </li>
        </ul>
        <t>Tight coupling additionally requires a control protocol
between the metadata server and the storage device,
discovered or advertised out-of-band as described above.</t>
        <t>Some storage devices cannot operate under the loosely
coupled model at all.  The loose-coupling model in this
specification relies on the storage device authorizing
client access against synthetic uid and gid values
(<xref target="sec-Fencing-Clients"/>), which presupposes that the data
file has a local representation on the storage device
against which POSIX-style ownership checks can be applied.
Storage devices whose backend has no exposed file namespace
-- for example, object-store-backed data servers, or data
servers driven entirely through a control protocol against
a non-POSIX backend -- do not have that local representation
and <bcp14>MUST</bcp14> operate in the tightly coupled model with a
control protocol that conveys the authorization decision
directly.  A metadata server deploying with such a storage
device cannot fall back to loose coupling.</t>
        <section anchor="loosely-coupled-locking-model">
          <name>Loosely Coupled Locking Model</name>
          <t>When locking-related operations are requested, they are primarily dealt
with by the metadata server, which generates the appropriate stateids.
When an NFSv4 version is used as the data access protocol, the metadata
server may make stateid-related requests of the storage devices.  However,
it is not required to do so, and the resulting stateids are known only
to the metadata server and the storage device.</t>
          <t>Given this basic structure, locking-related operations are handled
as follows:</t>
          <ul spacing="normal">
            <li>
              <t>OPENs are dealt with by the metadata server.  Stateids are
selected by the metadata server and associated with the client
ID describing the client's connection to the metadata server.
The metadata server may need to interact with the storage device to
locate the file to be opened, but no locking-related functionality
need be used on the storage device.</t>
            </li>
            <li>
              <t>OPEN_DOWNGRADE and CLOSE only require local execution on the
metadata server.</t>
            </li>
            <li>
              <t>Advisory byte-range locks can be implemented locally on the
metadata server.  As in the case of OPENs, the stateids associated
with byte-range locks are assigned by the metadata server and only
used on the metadata server.</t>
            </li>
            <li>
              <t>Delegations are assigned by the metadata server that initiates
recalls when conflicting OPENs are processed.  No storage device
involvement is required.</t>
            </li>
            <li>
              <t>TEST_STATEID and FREE_STATEID are processed locally on the
metadata server, without storage device involvement.</t>
            </li>
          </ul>
          <t>All I/O operations to the storage device are done using the anonymous
stateid.  Thus, the storage device has no information about the openowner
and lockowner responsible for issuing a particular I/O operation.
As a result:</t>
          <ul spacing="normal">
            <li>
              <t>Mandatory byte-range locking cannot be supported because the
storage device has no way of distinguishing I/O done on behalf of
the lock owner from those done by others.</t>
            </li>
            <li>
              <t>Enforcement of share reservations is the responsibility of the
client.  Even though I/O is done using the anonymous stateid, the
client <bcp14>MUST</bcp14> ensure that it has a valid stateid associated with the
openowner.</t>
            </li>
          </ul>
          <t>In the event that a stateid is revoked, the metadata server is responsible
for preventing client access, since it has no way of being sure that
the client is aware that the stateid in question has been revoked.</t>
          <t>As the client never receives a stateid generated by a storage device,
there is no client lease on the storage device and no prospect of lease
expiration, even when access is via NFSv4 protocols.  Clients will
have leases on the metadata server.  In dealing with lease expiration,
the metadata server may need to use fencing to prevent revoked stateids
from being relied upon by a client unaware of the fact that they have
been revoked.</t>
        </section>
        <section anchor="tightly-coupled-locking-model">
          <name>Tightly Coupled Locking Model</name>
          <t>When locking-related operations are requested, they are primarily dealt
with by the metadata server, which generates the appropriate stateids.
These stateids <bcp14>MUST</bcp14> be made known to the storage device using control
protocol facilities.  This document defines one such control protocol
-- the TRUST_STATEID, REVOKE_STATEID, and BULK_REVOKE_STATEID
operations in <xref target="sec-tight-coupling-control"/> -- for deployments in
which the storage devices are NFSv4.2 servers willing to implement
the new operations.  A storage device with its own established
back-end control protocol that provides the equivalent functional
capabilities is conformant under this specification without
implementing the TRUST_STATEID family; see
<xref target="sec-tight-coupling-control"/> for the conformance framing.</t>
          <t>When using the TRUST_STATEID control protocol defined in
<xref target="sec-tight-coupling-control"/>, the metadata server and a storage
device establish that they can use it via a two-part handshake,
both parts of which <bcp14>MUST</bcp14> succeed before the metadata server may
issue TRUST_STATEID against that storage device for production
traffic:</t>
          <dl>
            <dt>Capability probe:</dt>
            <dd>
              <t>At control-session setup the metadata
server sends a TRUST_STATEID against the anonymous stateid
(see <xref target="sec-tight-coupling-probe"/>).  A storage device that
supports tight coupling <bcp14>MUST</bcp14> reject the probe with
NFS4ERR_INVAL; a storage device that does not support tight
coupling returns NFS4ERR_NOTSUPP and the metadata server
falls back to loose coupling.  The metadata server records
the result per storage device in ffdv_tightly_coupled.</t>
            </dd>
            <dt>Control-session gating:</dt>
            <dd>
              <t>The metadata server presents
EXCHGID4_FLAG_USE_PNFS_MDS at EXCHANGE_ID when it opens the
control session to the storage device
(see <xref target="sec-tight-coupling-control-session"/>).  The storage
device <bcp14>MUST</bcp14> reject any incoming TRUST_STATEID,
REVOKE_STATEID, or BULK_REVOKE_STATEID that does not arrive
on such a session with NFS4ERR_PERM.  This is the
authorization mechanism that distinguishes the metadata
server from ordinary pNFS clients, which connect with
EXCHGID4_FLAG_USE_PNFS_DS or EXCHGID4_FLAG_USE_NON_PNFS and
are therefore structurally unable to invoke these operations.</t>
            </dd>
          </dl>
          <t>Given this basic structure, locking-related operations are handled
as follows:</t>
          <ul spacing="normal">
            <li>
              <t>OPENs are dealt with primarily on the metadata server.  Stateids
are selected by the metadata server and associated with the client
ID describing the client's connection to the metadata server.
The metadata server needs to interact with the storage device to
locate the file to be opened and to make the storage device aware of
the association between the metadata-server-chosen stateid and the
client and openowner that it represents.  OPEN_DOWNGRADE and CLOSE
are executed initially on the metadata server, but the state change
<bcp14>MUST</bcp14> be propagated to the storage device.</t>
            </li>
            <li>
              <t>Advisory byte-range locks can be implemented locally on the
metadata server.  As in the case of OPENs, the stateids associated
with byte-range locks are assigned by the metadata server and are
available for use on the metadata server.  Because I/O operations
are allowed to present lock stateids, the metadata server needs the
ability to make the storage device aware of the association between
the metadata-server-chosen stateid and the corresponding open stateid
it is associated with.</t>
            </li>
            <li>
              <t>Mandatory byte-range locks can be supported when both the metadata
server and the storage devices have the appropriate support.  As in
the case of advisory byte-range locks, these are assigned by the
metadata server and are available for use on the metadata server.
To enable mandatory lock enforcement on the storage device, the
metadata server needs the ability to make the storage device aware
of the association between the metadata-server-chosen stateid and
the client, openowner, and lock (i.e., lockowner, byte-range, and
lock-type) that it represents.  Because I/O operations are allowed
to present lock stateids, this information needs to be propagated to
all storage devices to which I/O might be directed rather than only
to storage device that contain the locked region.</t>
            </li>
            <li>
              <t>Delegations are assigned by the metadata server that initiates
recalls when conflicting OPENs are processed.  Because I/O operations
are allowed to present delegation stateids, the metadata server
requires the ability:  </t>
              <ol spacing="normal" type="1"><li>
                  <t>to make the storage device aware of the association between
the metadata-server-chosen stateid and the filehandle and
delegation type it represents</t>
                </li>
                <li>
                  <t>to break such an association.</t>
                </li>
              </ol>
            </li>
            <li>
              <t>TEST_STATEID is processed locally on the metadata server, without
storage device involvement.</t>
            </li>
            <li>
              <t>FREE_STATEID is processed on the metadata server, but the metadata
server requires the ability to propagate the request to the
corresponding storage devices.</t>
            </li>
          </ul>
          <t>Because the client will possess and use stateids valid on the storage
device, there will be a client lease on the storage device, and the
possibility of lease expiration does exist.  The best approach for the
storage device is to retain these locks as a courtesy.  However, if it
does not do so, control protocol facilities need to provide the means
to synchronize lock state between the metadata server and storage device.</t>
          <t>Clients will also have leases on the metadata server that are subject
to expiration.  In dealing with lease expiration, the metadata server
would be expected to use control protocol facilities enabling it to
invalidate revoked stateids on the storage device.  In the event the
client is not responsive, the metadata server may need to use fencing
to prevent revoked stateids from being acted upon by the storage device.</t>
        </section>
      </section>
      <section anchor="sec-tight-coupling-control">
        <name>Tight Coupling Control Protocol</name>
        <t>When an NFSv4.2 storage device participates in a tightly coupled
deployment, the metadata server and the storage devices need a
control protocol that:</t>
        <ol spacing="normal" type="1"><li>
            <t>registers the layout stateid with each storage device so the
storage device can validate client I/O independently; and</t>
          </li>
          <li>
            <t>revokes trust promptly when the metadata server withdraws the
client's authorization -- for example, on CB_LAYOUTRECALL
timeout, lease expiry, or layout return after error.</t>
          </li>
        </ol>
        <t>This specification defines one such control protocol, designated
<em>trusted-stateid tight coupling</em>, as three new NFSv4.2 operations:
TRUST_STATEID (<xref target="sec-TRUST_STATEID"/>), REVOKE_STATEID
(<xref target="sec-REVOKE_STATEID"/>), and BULK_REVOKE_STATEID
(<xref target="sec-BULK_REVOKE_STATEID"/>).  These operations are sent by the
metadata server to each storage device over a dedicated control
session (see <xref target="sec-tight-coupling-control-session"/>) and <bcp14>MUST NOT</bcp14>
be sent by pNFS clients.</t>
        <t>Other tight-coupling control protocols may exist or be defined
elsewhere.  Existing pNFS server implementations with established
back-end control protocols -- for example, dCache, which has its
own control protocol between its metadata service and its data
servers -- satisfy the tightly-coupled locking model
(<xref target="sec-state-locking"/>) through their own mechanisms and are
conformant under this specification provided they meet the
functional capabilities described there.  Such implementations
need not adopt the TRUST_STATEID family, and their interoperability
with the TRUST_STATEID family is outside the scope of this
document.</t>
        <t>A storage device that does not implement TRUST_STATEID is treated
as not supporting trusted-stateid tight coupling specifically; the
capability probe in <xref target="sec-tight-coupling-probe"/> detects this and
the metadata server falls back to loose coupling
(<xref target="sec-tight-coupling-compat"/>) or, if the storage device's own
control protocol is in use, that protocol governs.  Within the
remainder of <xref target="sec-tight-coupling-control"/> and its subsections,
unqualified references to "tight coupling" or "tightly coupled"
refer to the trusted-stateid variant defined here.</t>
        <t>The receiver of these operations is any server the metadata
server delegates client-I/O admission to.  In this document that
is the storage device (data server).  The same mechanism applies to a
proxy server <xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/> -- a proxy server may or may not additionally act as a data server, but in
either role it needs the metadata server to register a layout
stateid before it can admit client I/O.  Where this section
says "storage device," read it as "storage device, or proxy
server <xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>"; the flag
check and the three operations are identical for both roles.</t>
        <section anchor="sec-tight-coupling-probe">
          <name>Capability Discovery</name>
          <t>A storage device indicates support for trusted-stateid tight
coupling implicitly, by processing TRUST_STATEID rather than
returning NFS4ERR_NOTSUPP.  (A storage device that supports a
non-TRUST_STATEID form of tight coupling but not the
trusted-stateid variant defined here will return NFS4ERR_NOTSUPP
on this probe; from this specification's perspective it is
treated the same as a storage device that does not support tight
coupling at all.)  The metadata server probes each storage device
during control-session setup:</t>
          <figure anchor="fig-trust-stateid-probe">
            <name>TRUST_STATEID capability probe</name>
            <artwork><![CDATA[
SEQUENCE + PUTROOTFH + TRUST_STATEID(
    tsa_layout_stateid = ANONYMOUS_STATEID,
    tsa_iomode         = LAYOUTIOMODE4_READ,
    tsa_expire         = 0,
    tsa_principal      = "")
]]></artwork>
          </figure>
          <t>The anonymous stateid is used deliberately: a correctly implemented
storage device <bcp14>MUST</bcp14> reject it (see <xref target="sec-TRUST_STATEID"/>), so the
probe cannot accidentally register garbage in the trust table.  The
metadata server interprets the probe response as follows:</t>
          <dl>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>trusted-stateid tight coupling is not supported on this
storage device.  The metadata server falls back to loose coupling
(anonymous stateid plus fencing) and sets ffdv_tightly_coupled
to false for this storage device.</t>
            </dd>
            <dt>NFS4ERR_INVAL:</dt>
            <dd>
              <t>trusted-stateid tight coupling is supported.  The anonymous
stateid was correctly rejected.  The metadata server records the
capability and sets ffdv_tightly_coupled to true for this
storage device.</t>
            </dd>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the storage device accepted an anonymous stateid into
its trust table.  This is a storage device bug.  The metadata
server <bcp14>MAY</bcp14> treat the capability as confirmed to avoid
downgrading to loose coupling, but it <bcp14>MUST</bcp14> immediately issue
REVOKE_STATEID to remove the bogus entry.</t>
            </dd>
          </dl>
          <t>The capability is recorded per storage device, not per file.
Partial support across a mirror set is permitted: each
ff_device_versions4 entry returned by GETDEVICEINFO carries its
own ffdv_tightly_coupled flag, set independently.</t>
        </section>
        <section anchor="sec-tight-coupling-control-session">
          <name>Control Session</name>
          <t>The metadata server establishes an NFSv4.2 session to each
tight-coupling-capable storage device at startup.  On this session
the metadata server acts as the storage device's client and
presents EXCHGID4_FLAG_USE_PNFS_MDS in its EXCHANGE_ID args.</t>
          <t>The storage device <bcp14>MUST</bcp14> verify that any incoming TRUST_STATEID,
REVOKE_STATEID, or BULK_REVOKE_STATEID compound arrives on a
session whose owning client presented EXCHGID4_FLAG_USE_PNFS_MDS
in its EXCHANGE_ID args.  Requests that arrive on any other
session <bcp14>MUST</bcp14> be rejected with NFS4ERR_PERM.  This is the sole
access control on these operations; a pNFS client connecting to
the storage device does not present EXCHGID4_FLAG_USE_PNFS_MDS
and therefore cannot invoke them.</t>
          <t>The EXCHGID4_FLAG_USE_PNFS_MDS check replaces any path- or
filehandle-level gating.  TRUST_STATEID operates on a filehandle
that may be any file on the storage device, and the metadata
server is the sole authority that can legitimately speak this
protocol.</t>
          <t>Because the EXCHGID4_FLAG_USE_PNFS_MDS check relies on the owning
client's self-declaration at EXCHANGE_ID time, the storage device
cannot by itself distinguish a legitimate metadata server from any
other host that sets the flag.  Deployments are therefore
responsible for constraining who can establish a control session
in the first place.  Two mechanisms are <bcp14>RECOMMENDED</bcp14>:</t>
          <ol spacing="normal" type="1"><li>
              <t>The control session <bcp14>SHOULD</bcp14> use RPCSEC_GSS with a machine
principal that the storage device has been configured to
accept as a metadata server.  The storage device validates
the principal before accepting EXCHANGE_ID with
EXCHGID4_FLAG_USE_PNFS_MDS.</t>
            </li>
            <li>
              <t>Alternatively, the control session <bcp14>SHOULD</bcp14> run over a
network path isolated from pNFS clients (for example, a
dedicated management VLAN or mutual TLS (<xref target="RFC9289"/>) with
an allowlisted client certificate), such that only
configured metadata servers can reach the storage device on
that path.</t>
            </li>
          </ol>
          <t>Deploying neither mechanism reduces the authorization strength
of TRUST_STATEID and the revocation operations to "any host
that can reach the storage device can invoke them"; a strict
deployment <bcp14>MUST</bcp14> apply at least one of the above.</t>
        </section>
        <section anchor="sec-tight-coupling-layoutget">
          <name>Flow at LAYOUTGET</name>
          <t>For each new or refreshed layout segment, the metadata server:</t>
          <ol spacing="normal" type="1"><li>
              <t>chooses the layout stateid (as it would without tight coupling);</t>
            </li>
            <li>
              <t>identifies the tight-coupling-capable storage devices in the
mirror set (those for which ffdv_tightly_coupled is true);</t>
            </li>
            <li>
              <t>fans out TRUST_STATEID to each such storage device,
specifying the layout stateid, the layout iomode, a
tsa_expire derived from the metadata server's lease (see
<xref target="sec-tight-coupling-lease"/>), and the client's authenticated
identity in tsa_principal;</t>
            </li>
            <li>
              <t>waits for all fan-outs to complete (or reach their per-storage-device timeout) before returning the layout.</t>
            </li>
          </ol>
          <t>If every storage device in the mirror set rejects the TRUST_STATEID
fan-out, the metadata server <bcp14>MUST NOT</bcp14> return the layout; instead it
returns NFS4ERR_LAYOUTTRYLATER.  If some storage devices accept and
others reject, the metadata server <bcp14>MAY</bcp14> return a layout covering
only the accepting storage devices, subject to the mirror-set rules
for minimum acceptable coverage.  A storage device that returns
NFS4ERR_DELAY is retried until either success or the metadata
server's LAYOUTGET-response budget is exhausted.  If a storage
device returns NFS4ERR_NOTSUPP at this time (having accepted the
probe earlier), the metadata server <bcp14>MUST</bcp14> clear
ffdv_tightly_coupled for this storage device, fall back to loose
coupling, and re-issue the layout accordingly.</t>
        </section>
        <section anchor="sec-tight-coupling-principal">
          <name>Principal Binding and the Kerberos Gap</name>
          <t>The flexible file v1 layout has a known gap: a client authenticated
to the metadata server with Kerberos has no way to present the same
authenticated identity to the storage device, because flexible file
v1 layouts carry only ffds_user / ffds_group (POSIX uid/gid for
AUTH_SYS).  A strict Kerberos deployment on the flexible file v1
layout must either allow AUTH_SYS from the metadata server's subnet
or accept that the flexible file v1 layout's data path is not
Kerberos-protected.</t>
          <t>The tsa_principal field in TRUST_STATEID closes that gap.  When a
client authenticates to the metadata server as a Kerberos
principal (e.g., alice@REALM), the metadata server passes that
principal name to each storage device in tsa_principal.  The
storage device then enforces a two-part check on each CHUNK
operation that presents the layout stateid:</t>
          <t>a.  the stateid is in the trust table and has not expired; and</t>
          <t>b.  the caller's authenticated identity (the RPCSEC_GSS display
    name on the CHUNK compound) matches tsa_principal.</t>
          <t>Both conditions <bcp14>MUST</bcp14> hold.  On principal mismatch the storage
device <bcp14>MUST</bcp14> return NFS4ERR_ACCESS -- the semantics are "you do
not have an authorized layout for this file", which matches the
existing fencing error and avoids the confusion of
NFS4ERR_WRONGSEC (which directs the client to re-authenticate
with a different flavor) or NFS4ERR_BAD_STATEID (which directs
the client to return the layout).</t>
          <t>The metadata server <bcp14>MUST</bcp14> populate tsa_principal with the
RPCSEC_GSS display name of the authenticated client when the
client authenticated to the metadata server via RPCSEC_GSS.  The
metadata server <bcp14>MUST</bcp14> set tsa_principal to the empty string only
for AUTH_SYS and TLS clients (for which there is no server-verified per-user identity).  Setting tsa_principal to the empty
string for an RPCSEC_GSS client disables the principal check on
the storage device and silently re-opens the flexible file v1 layout
Kerberos gap; it is a metadata server bug, not a protocol option.</t>
          <t>If tsa_principal is the empty string, no principal check applies.
This is the expected setting for AUTH_SYS and TLS clients:</t>
          <ul spacing="normal">
            <li>
              <t>AUTH_SYS clients have no server-verified identity.  The
storage device's stateid check and the AUTH_SYS uid/gid on the
data file together constitute the authorization.  In a tightly
coupled deployment the data file's owner/group need not match
the metadata file's, since ffv2ds_user and ffv2ds_group are
ignored (see <xref target="sec-ffv2-mirror4"/>).</t>
            </li>
            <li>
              <t>TLS clients have transport-layer authentication via mutual TLS
(<xref target="RFC9289"/>).  The TLS layer authenticates the client machine;
the stateid check confirms the metadata server authorized that
machine to access this file.  The machine-level authentication
is handled beneath the RPC layer and is not reflected in
tsa_principal.  Opportunistic TLS (STARTTLS without certificate
verification) provides encryption but not authentication, and
therefore has the same authorization properties as plain
AUTH_SYS.</t>
            </li>
          </ul>
          <t>When a client's I/O is routed through a proxy server -- that
is, the layout the metadata server returns to the client has
FFV2_DS_FLAGS_PROXY set on the proxy's ffv2_data_server4 entry,
per <xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/> -- the storage device observes
CHUNK operations arriving from the proxy server's address rather than from
the client directly.  The tsa_principal the metadata server
populates in TRUST_STATEID is the principal the <em>storage device</em>
will observe on those CHUNK operations, and <xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>'s credential-forwarding rules (in particular rule 1,
"Credential pass-through") require the proxy server to forward the
client's credentials verbatim on every CHUNK operation it issues
on the client's behalf.  Therefore:</t>
          <ul spacing="normal">
            <li>
              <t>For an RPCSEC_GSS client whose I/O is proxied through a proxy server,
the metadata server <bcp14>MUST</bcp14> set tsa_principal to the client's
RPCSEC_GSS display name (identical to the non-proxied case).
The storage device's principal check on CHUNK operations will
match against the client's principal on the forwarded
compound, not the proxy server's service identity.</t>
            </li>
            <li>
              <t>For an AUTH_SYS client whose I/O is proxied through a proxy server,
the metadata server <bcp14>MUST</bcp14> set tsa_principal to the empty
string (identical to the non-proxied case).  The proxy server forwards
the client's AUTH_SYS uid/gid; the storage device's stateid
check plus the forwarded AUTH_SYS uid/gid constitute the
authorization.</t>
            </li>
          </ul>
          <t>The metadata server <bcp14>MUST NOT</bcp14> set tsa_principal to the proxy server's own
service principal.  Doing so would require the proxy server to
authenticate to the storage device as itself (bypassing
credential forwarding) which is explicitly prohibited by rule 4 of <xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/> ("proxy server service identity is for the
control plane only").</t>
        </section>
        <section anchor="sec-tight-coupling-trust-gap">
          <name>Client-Detected Trust Gap</name>
          <t>A window exists between a successful TRUST_STATEID fan-out and
the client's first I/O to the storage device.  A transient failure
may cause the storage device to forget or reject the entry before
the client's first CHUNK_WRITE arrives.  The client cannot
distinguish this case from legitimate revocation; both surface as
NFS4ERR_BAD_STATEID on the storage device.</t>
          <t>The recovery path:</t>
          <ol spacing="normal" type="1"><li>
              <t>The client sends LAYOUTERROR(layout_stateid, device_id,
NFS4ERR_BAD_STATEID) to the metadata server.</t>
            </li>
            <li>
              <t>The metadata server retries TRUST_STATEID against the
reporting storage device.  If the retry succeeds, the
metadata server returns NFS4_OK for LAYOUTERROR.  The client
retries the original I/O.</t>
            </li>
            <li>
              <t>If the retry fails -- the storage device is unreachable or
returns a hard error -- the metadata server issues
CB_LAYOUTRECALL for that device and the client returns the
layout segment covering that storage device.  The client is
expected to re-request via LAYOUTGET.</t>
            </li>
          </ol>
          <t>This is the same LAYOUTERROR path used for NFS4ERR_ACCESS or
NFS4ERR_PERM in the fencing model (see <xref target="sec-Fencing-Clients"/>),
with the metadata server's action being "retry TRUST_STATEID"
instead of "rotate uid/gid".</t>
        </section>
        <section anchor="sec-tight-coupling-lease">
          <name>Lease and Renewal</name>
          <t>tsa_expire in a TRUST_STATEID request is a wall-clock expiry
instant expressed as an nfstime4.  The metadata server <bcp14>MUST</bcp14> set
tsa_expire to the current wall-clock time plus the metadata
server's client lease period.</t>
          <t>The metadata server <bcp14>MUST</bcp14> re-issue TRUST_STATEID for an entry
before tsa_expire while the corresponding layout is outstanding.
The <bcp14>RECOMMENDED</bcp14> trigger is: when an entry is within half the
lease period of its tsa_expire, re-issue TRUST_STATEID with a
refreshed tsa_expire.  Renewing on every SEQUENCE that keeps the
layout stateid alive is correct but produces
metadata-server-to-storage-device traffic proportional to the
client's SEQUENCE rate, which is undesirable in steady state.</t>
          <t>If an entry expires on the storage device before the metadata
server renews it -- for example, because the metadata server is
partitioned from the storage device for longer than the lease
period -- the storage device <bcp14>MUST</bcp14> return NFS4ERR_BAD_STATEID to
the client on the next CHUNK operation.  The client returns the
layout to the metadata server and re-requests.  This is the same
recovery path as the trust gap described above.</t>
        </section>
        <section anchor="sec-tight-coupling-ds-crash">
          <name>Storage Device Crash Recovery</name>
          <t>A storage device <bcp14>MAY</bcp14> persist its trust table across restarts.  An
implementation that does so <bcp14>MUST</bcp14> also persist its server-instance
identity, returning the same eir_server_owner.so_minor_id on
EXCHANGE_ID after the restart (per <xref target="RFC8881"/> S18.35), so that
clients and the metadata server observe the device as
continuously available and the persisted trust entries remain
valid against the layout stateids that were issued before the
restart.</t>
          <t>A storage device that does NOT persist its trust table empties
the table on restart and <bcp14>MUST</bcp14> present a new server instance
(incremented so_minor_id) so that clients detect the restart.
The remainder of this section describes the recovery path for
the volatile case.</t>
          <t>The client detects a volatile storage device restart via
NFS4ERR_BADSESSION or NFS4ERR_STALE_CLIENTID on its data server
session.  The client returns the affected layout segment to the
metadata server via LAYOUTRETURN and re-requests via LAYOUTGET.
The metadata server then fans out fresh TRUST_STATEID operations
to the recovered storage device.</t>
          <t>Planned storage device restarts (software upgrade, etc.) <bcp14>SHOULD</bcp14>
drain in-flight CHUNK operations before shutting down.</t>
        </section>
        <section anchor="sec-tight-coupling-mds-crash">
          <name>Metadata Server Crash Recovery</name>
          <t>A metadata server <bcp14>MAY</bcp14> persist all its trust-management state
across restarts.  An implementation that does so <bcp14>MUST</bcp14> also
persist its server-instance identity, returning the same
eir_server_owner.so_minor_id on EXCHANGE_ID after the restart
(per <xref target="RFC8881"/> S18.35), so that storage devices observe the
metadata server as continuously available and accept incoming
TRUST_STATEID and REVOKE_STATEID operations against the existing
trust entries without revalidation.  No grace period is required.</t>
          <t>A metadata server that presents a new server instance
(incremented so_minor_id) on restart follows the recovery path
in the remainder of this section.</t>
          <t>When the metadata server restarts as a new instance, its control
sessions to the storage devices are lost.  Trust entries remain
on the storage devices until tsa_expire, but the metadata server
is no longer renewing them; the entries are effectively orphaned
until the metadata server completes grace.</t>
          <t>When the metadata server reconnects to a storage device with a
new boot epoch -- that is, the EXCHANGE_ID returns a new server
owner on the storage device's view of the metadata server -- the
storage device <bcp14>SHOULD</bcp14> mark all trust entries established under
the prior metadata-server epoch as pending-revalidation.  While an
entry is pending-revalidation:</t>
          <ul spacing="normal">
            <li>
              <t>I/O that presents the entry's stateid <bcp14>MUST</bcp14> receive
NFS4ERR_DELAY, not NFS4ERR_BAD_STATEID.  NFS4ERR_DELAY tells
the client to retry with the same stateid -- the metadata
server is recovering and may yet revalidate the entry.
NFS4ERR_BAD_STATEID would instead cause the client to return
the layout immediately, producing a thundering herd against
the metadata server during grace.</t>
            </li>
            <li>
              <t>An entry remains pending-revalidation until the metadata
server either re-issues TRUST_STATEID for it (which transitions
it back to trusted) or until the entry's tsa_expire elapses
(which removes it).</t>
            </li>
          </ul>
          <t>The metadata server's recovery sequence is:</t>
          <ol spacing="normal" type="1"><li>
              <t>Reconnect to each storage device and establish a fresh
control session.</t>
            </li>
            <li>
              <t>Optionally issue BULK_REVOKE_STATEID with an all-zeros
clientid to each storage device.  This clears the prior trust
table eagerly; skipping this step is correct, because orphan
entries expire via tsa_expire.</t>
            </li>
            <li>
              <t>Enter grace and accept RECLAIM operations from clients.  For
each reclaimed layout, fan out TRUST_STATEID to the relevant
storage devices.</t>
            </li>
            <li>
              <t>Exit grace.  Clients that did not reclaim in time have their
state revoked; the metadata server issues REVOKE_STATEID or
BULK_REVOKE_STATEID on their behalf.</t>
            </li>
          </ol>
          <t>Metadata servers <bcp14>SHOULD</bcp14> persist the set of outstanding
TRUST_STATEID entries (clientid, layout stateid, storage device
address, tsa_expire) to stable storage.  With this persistence
the metadata server can re-issue TRUST_STATEID for all known
entries immediately upon reconnecting to each storage device,
before clients begin reclaiming.  This shrinks the window during
which the storage device returns NFS4ERR_DELAY for client I/O.
Persistence is a latency optimization, not a correctness
requirement: the re-layout path handles recovery in all cases.</t>
        </section>
        <section anchor="sec-tight-coupling-compat">
          <name>Backward Compatibility</name>
          <ul spacing="normal">
            <li>
              <t>NFSv3 storage devices are unchanged.  They are always treated
as loosely coupled; TRUST_STATEID does not exist on NFSv3
servers.</t>
            </li>
            <li>
              <t>NFSv4.2 storage devices for which the TRUST_STATEID probe
returns NFS4ERR_NOTSUPP are treated as loosely coupled;
fencing is the only revocation mechanism, the same as for
NFSv3.</t>
            </li>
            <li>
              <t>NFSv4.2 storage devices for which the probe returns
NFS4ERR_INVAL support tight coupling; the metadata server uses
TRUST_STATEID at LAYOUTGET and REVOKE_STATEID or
BULK_REVOKE_STATEID for revocation instead of fencing.</t>
            </li>
          </ul>
          <t>A single deployment <bcp14>MAY</bcp14> contain a mix of tight-coupled and
loose-coupled storage devices; each is negotiated independently
via the probe.</t>
        </section>
      </section>
    </section>
    <section anchor="device-addressing-and-discovery">
      <name>Device Addressing and Discovery</name>
      <t>Data operations to a storage device require the client to know the
network address of the storage device.  The NFSv4.1+ GETDEVICEINFO
operation (Section 18.40 of <xref target="RFC8881"/>) is used by the client to
retrieve that information.</t>
      <section anchor="sec-ff_device_addr4">
        <name>ff_device_addr4</name>
        <t>The ff_device_addr4 data structure (see <xref target="fig-ff_device_addr4"/>)
is returned by the server as the layout-type-specific opaque field
da_addr_body in the device_addr4 structure by a successful GETDEVICEINFO
operation.</t>
        <t>The ff_device_versions4 and ff_device_addr4 structures are
reused unchanged from <xref target="RFC8435"/>; they are reproduced here for
reader convenience and are not part of the XDR extracted from
this document.</t>
        <figure anchor="fig-ff_device_versions4">
          <name>ff_device_versions4 (reused from RFC 8435)</name>
          <sourcecode type="xdr"><![CDATA[
   struct ff_device_versions4 {
           uint32_t        ffdv_version;
           uint32_t        ffdv_minorversion;
           uint32_t        ffdv_rsize;
           uint32_t        ffdv_wsize;
           bool            ffdv_tightly_coupled;
   };
]]></sourcecode>
        </figure>
        <figure anchor="fig-ff_device_addr4">
          <name>ff_device_addr4 (reused from RFC 8435)</name>
          <sourcecode type="xdr"><![CDATA[
   struct ff_device_addr4 {
           multipath_list4     ffda_netaddrs;
           ff_device_versions4 ffda_versions<>;
   };
]]></sourcecode>
        </figure>
        <t>The ffda_netaddrs field is used to locate the storage device.  It
<bcp14>MUST</bcp14> be set by the server to a list holding one or more of the device
network addresses.</t>
        <t>The ffda_versions array allows the metadata server to present choices
as to NFS version, minor version, and coupling strength to the
client.  The ffdv_version and ffdv_minorversion represent the NFS
protocol to be used to access the storage device.  This layout
specification defines the semantics for ffdv_versions 3 and 4.  If
ffdv_version equals 3, then the server <bcp14>MUST</bcp14> set ffdv_minorversion to
0 and ffdv_tightly_coupled to false.  The client <bcp14>MUST</bcp14> then access the
storage device using the NFSv3 protocol <xref target="RFC1813"/>.  If ffdv_version
equals 4, then the server <bcp14>MUST</bcp14> set ffdv_minorversion to 1 or 2, and
the client <bcp14>MUST</bcp14> access the storage device using NFSv4 with the
specified minor version.</t>
        <t>Two additional constraints narrow the valid set of
(ffdv_version, ffdv_minorversion) tuples in specific cases:</t>
        <ul spacing="normal">
          <li>
            <t>When a mirror's encoding type uses CHUNK_* operations (that
is, any FFV2<em>ENCODING</em>* value other than
FFV2<em>ENCODING_PASSTHROUGH), the corresponding storage device
<bcp14>MUST</bcp14> be advertised with ffdv_version = 4 and
ffdv_minorversion = 2.  CHUNK</em>* operations are NFSv4.2 ops
defined in this document; NFSv3 and NFSv4.1 storage devices
cannot serve a non-PASSTHROUGH mirror.</t>
          </li>
          <li>
            <t>When ffdv_tightly_coupled is true (indicating trusted-stateid
tight coupling), the storage device <bcp14>MUST</bcp14> be advertised with
ffdv_version = 4 and ffdv_minorversion = 2.  The TRUST_STATEID
family of operations is defined as NFSv4.2; NFSv4.1 storage
devices cannot participate in trusted-stateid tight coupling.</t>
          </li>
        </ul>
        <t>PASSTHROUGH mirrors with loose coupling are the only configuration
for which (3, 0) or (4, 1) remain valid; for all other
configurations the storage device <bcp14>MUST</bcp14> be NFSv4.2.</t>
        <t>Note that while the client might determine that it cannot use any of
the configured combinations of ffdv_version, ffdv_minorversion, and
ffdv_tightly_coupled, when it gets the device list from the metadata
server, there is no way to indicate to the metadata server as to
which device it is version incompatible.  However, if the client
waits until it retrieves the layout from the metadata server, it can
at that time clearly identify the storage device in question (see
<xref target="sec-version-errors"/>).</t>
        <t>The ffdv_rsize and ffdv_wsize are used to communicate the maximum
rsize and wsize supported by the storage device.  As the storage
device can have a different rsize or wsize than the metadata server,
the ffdv_rsize and ffdv_wsize allow the metadata server to
communicate that information on behalf of the storage device.</t>
        <t>ffdv_tightly_coupled informs the client as to whether the
metadata server is tightly coupled with this storage device.  The
flag was defined by <xref target="RFC8435"/> as a general tight-coupling
indicator; in flexible file v2 layouts the flag specifically
indicates trusted-stateid tight coupling
(<xref target="sec-tight-coupling-control"/>).  Note that even if the data
protocol is at least NFSv4.1, it may still be the case that there
is loose coupling in effect.  For an NFSv4.2 storage device, the
metadata server sets ffdv_tightly_coupled to true only after
confirming the storage device implements the TRUST_STATEID control
protocol via the capability probe described in
<xref target="sec-tight-coupling-probe"/>.  An NFSv4.2 storage device that does
not implement TRUST_STATEID (returning NFS4ERR_NOTSUPP to the
probe) <bcp14>MUST</bcp14> be advertised with ffdv_tightly_coupled set to false,
regardless of whether it implements some other (non-TRUST_STATEID)
tight-coupling control protocol; from this specification's
perspective, only trusted-stateid tight coupling is interoperable.</t>
        <t>If ffdv_tightly_coupled is not set, then the client <bcp14>MUST</bcp14> commit
writes to the storage devices for the file before sending a
LAYOUTCOMMIT to the metadata server.  That is, the writes <bcp14>MUST</bcp14> be
committed by the client to stable storage via issuing WRITEs with
stable_how == FILE_SYNC or by issuing a COMMIT after WRITEs with
stable_how != FILE_SYNC (see Section 3.3.7 of <xref target="RFC1813"/>).</t>
      </section>
      <section anchor="storage-device-multipathing">
        <name>Storage Device Multipathing</name>
        <t>The flexible file v2 layout supports multipathing to multiple
storage device addresses.  Storage-device-level multipathing is used
for bandwidth scaling via trunking and for higher availability of use
in the event of a storage device failure.  Multipathing allows the
client to switch to another storage device address that may be that
of another storage device that is exporting the same data stripe
unit, without having to contact the metadata server for a new layout.</t>
        <t>To support storage device multipathing, ffda_netaddrs contains an
array of one or more storage device network addresses.  This array
(data type multipath_list4) represents a list of storage devices
(each identified by a network address), with the possibility that
some storage device will appear in the list multiple times.</t>
        <t>The client is free to use any of the network addresses as a
destination to send storage device requests.  If some network
addresses are less desirable paths to the data than others, then the
metadata server <bcp14>SHOULD NOT</bcp14> include those network addresses in
ffda_netaddrs.  If less desirable network addresses exist to provide
failover, the <bcp14>RECOMMENDED</bcp14> method to offer the addresses is to provide
them in a replacement device-ID-to-device-address mapping or a
replacement device ID.  When a client finds no response from the
storage device using all addresses available in ffda_netaddrs, it
<bcp14>SHOULD</bcp14> send a GETDEVICEINFO to attempt to replace the existing
device-ID-to-device-address mappings.  If the metadata server detects
that all network paths represented by ffda_netaddrs are unavailable,
the metadata server <bcp14>SHOULD</bcp14> send a CB_NOTIFY_DEVICEID (if the client
has indicated it wants device ID notifications for changed device
IDs) to change the device-ID-to-device-address mappings to the
available addresses.  If the device ID itself will be replaced, the
metadata server <bcp14>SHOULD</bcp14> recall all layouts with the device ID and thus
force the client to get new layouts and device ID mappings via
LAYOUTGET and GETDEVICEINFO.</t>
        <t>Generally, if two network addresses appear in ffda_netaddrs, they
will designate the same storage device.  When the storage device is
accessed over NFSv4.1 or a higher minor version, the two storage
device addresses will support the implementation of client ID or
session trunking (the latter is <bcp14>RECOMMENDED</bcp14>) as defined in <xref target="RFC8881"/>.
The two storage device addresses will share the same server owner or
major ID of the server owner.  It is not always necessary for the two
storage device addresses to designate the same storage device with
trunking being used.  For example, the data could be read-only, and
the data consist of exact replicas.</t>
      </section>
    </section>
    <section anchor="flexible-file-version-2-layout-type">
      <name>Flexible File Version 2 Layout Type</name>
      <t>The original layouttype4 introduced in <xref target="RFC5662"/> is extended as shown in
<xref target="fig-orig-layout"/>.  The layout_content4 and layout4 structures are
reused unchanged from <xref target="RFC5662"/>; the layouttype4 enum is extended
with the new LAYOUT4_FLEX_FILES_V2 value.  The full enum and
surrounding structures below are reproduced for reader
convenience; only the new constant LAYOUT4_FLEX_FILES_V2 is part
of the XDR extracted from this document (see
<xref target="fig-orig-layout-extract"/>).</t>
      <figure anchor="fig-orig-layout">
        <name>The original layout type (illustrative; reused from RFC 5662 with extension)</name>
        <sourcecode type="xdr"><![CDATA[
       enum layouttype4 {
           LAYOUT4_NFSV4_1_FILES   = 1,
           LAYOUT4_OSD2_OBJECTS    = 2,
           LAYOUT4_BLOCK_VOLUME    = 3,
           LAYOUT4_FLEX_FILES      = 4,
           LAYOUT4_SCSI            = 5,
           LAYOUT4_FLEX_FILES_V2   = 6
       };

       struct layout_content4 {
           layouttype4             loc_type;
           opaque                  loc_body<>;
       };

       struct layout4 {
           offset4                 lo_offset;
           length4                 lo_length;
           layoutiomode4           lo_iomode;
           layout_content4         lo_content;
       };
]]></sourcecode>
      </figure>
      <t>The extracted XDR contribution for this extension is the new
layouttype4 constant alone:</t>
      <figure anchor="fig-orig-layout-extract">
        <name>New layouttype4 value (extracted)</name>
        <sourcecode type="xdr"><![CDATA[
   /// const LAYOUT4_FLEX_FILES_V2 = 6;
]]></sourcecode>
      </figure>
      <t>This document defines structures associated with the layouttype4
value LAYOUT4_FLEX_FILES_V2.  <xref target="RFC8881"/> specifies the loc_body structure
as an XDR type "opaque".  The opaque layout is uninterpreted by the
generic pNFS client layers but is interpreted by the flexible file
layout type implementation.  This section defines the structure of
this otherwise opaque value, ffv2_layout4.</t>
      <section anchor="ffv2codingtype4">
        <name>ffv2_coding_type4</name>
        <figure anchor="fig-ffv2_coding_type4">
          <name>The coding type</name>
          <sourcecode type="xdr"><![CDATA[
   /// enum ffv2_coding_type4 {
   ///     FFV2_ENCODING_PASSTHROUGH             = 1,
   ///     FFV2_ENCODING_MOJETTE_SYSTEMATIC      = 2,
   ///     FFV2_ENCODING_MOJETTE_NON_SYSTEMATIC  = 3,
   ///     FFV2_ENCODING_RS_VANDERMONDE          = 4,
   ///     FFV2_ENCODING_MIRRORED                = 5
   /// };
]]></sourcecode>
        </figure>
        <t>The ffv2_coding_type4 (see <xref target="fig-ffv2_coding_type4"/>) encompasses
a new IANA registry for 'Flexible File Version 2 Layout Type Erasure Coding
Type Registry'.  I.e., instead of defining a new Layout Type for
each erasure coding, we define a new Erasure Coding Type.  The
encoding types this document defines fall into two groups:</t>
        <ul spacing="normal">
          <li>
            <t>FFV2_ENCODING_PASSTHROUGH is the non-chunked, non-integrity
on-ramp from flexible file v1 layout.  It uses NFSv3 WRITE / READ directly
against each replica's data server.  No CHUNK_WRITE, no
CHUNK_READ, no per-chunk CRC.  See <xref target="sec-encoding-passthrough"/>.</t>
          </li>
          <li>
            <t>FFV2_ENCODING_MIRRORED, FFV2_ENCODING_MOJETTE_SYSTEMATIC,
FFV2_ENCODING_MOJETTE_NON_SYSTEMATIC, and
FFV2_ENCODING_RS_VANDERMONDE all use the new operations
defined here: in particular CHUNK_WRITE
(<xref target="sec-CHUNK_WRITE"/>) and CHUNK_READ (<xref target="sec-CHUNK_READ"/>),
which carry the per-chunk checksum this version of the layout
type relies on for end-to-end integrity.  The encoding type
selects how chunks are produced from application data
(mirrored verbatim, Reed-Solomon shards, Mojette
projections); the wire and the storage device are the same
in every case.</t>
          </li>
        </ul>
        <t>The 32-bit ffv2_coding_type4 value space is partitioned by
intended scope -- Standards Track, Experimental, Vendor (open),
and Private / proprietary -- with different allocation policies
per range, so that vendors can assign codec values without
consuming standards-track codepoints.  See
<xref target="tbl-coding-ranges"/> and the accompanying prose in
<xref target="iana-considerations"/> for the range assignments and allocation
policies.</t>
        <section anchor="sec-heterogeneous-mirrors">
          <name>Heterogeneous Mirror Sets</name>
          <t>A single flexible file v2 layout's <tt>ffv2l_mirrors</tt> array <bcp14>MAY</bcp14> carry mirror
entries of different encoding types.  The protocol does not
require the entries to agree -- one mirror can be
FFV2_ENCODING_PASSTHROUGH, another can be
FFV2_ENCODING_RS_VANDERMONDE, both describing the same file's
data range.  This combination is the structural primitive for
three operations that motivate keeping PASSTHROUGH in the
layout type's vocabulary:</t>
          <dl>
            <dt>Assimilate:</dt>
            <dd>
              <t>A file that exists today as a plain copy on
storage outside flexible file v2 layout -- no chunk envelope, no per-chunk
CRC -- enters the namespace as a PASSTHROUGH mirror against
the source bytes as they are.  The metadata server then
adds one or more encoded mirrors (MIRRORED, RS, Mojette) to
the same layout and synchronizes them from the PASSTHROUGH
source.  Clients can read the file via the PASSTHROUGH
mirror immediately; the encoded mirrors become available as
they are populated.  No "rewrite before serve" step is
required.</t>
            </dd>
            <dt>Copy / migrate between encodings:</dt>
            <dd>
              <t>Changing a file from
one encoding to another is "add a mirror in the target
encoding to the same layout, let it sync from any healthy
source mirror, retire the source mirror."  PASSTHROUGH is
the special case where one endpoint of that migration is
"no encoding."</t>
            </dd>
            <dt>Repair across encodings:</dt>
            <dd>
              <t>When an encoded mirror has a
chunk whose CRC fails and whose parity cannot reconstruct,
a PASSTHROUGH mirror in the same layout is an authoritative
source: CHUNK_READ a peer encoded mirror or read the
PASSTHROUGH byte range, then CHUNK_WRITE the repaired
chunk.  The reverse is also true: a byte range on the
PASSTHROUGH copy whose contents the metadata server suspects
has drifted can be repaired by reconstructing from the
verified-CRC chunks of an encoded peer.  Two encodings of
the same file are two independent recovery paths.</t>
            </dd>
          </dl>
          <t>The metadata server is responsible for keeping the entries in
a heterogeneous mirror set in sync; the protocol does not
require client awareness of which encoding produced which
mirror beyond what the layout already states.</t>
        </section>
        <section anchor="sec-encoding-passthrough">
          <name>FFV2_ENCODING_PASSTHROUGH</name>
          <t>FFV2_ENCODING_PASSTHROUGH is the on-ramp from flexible file v1 layout (<xref target="RFC8435"/>)
into the flexible file v2 layout type.  A PASSTHROUGH mirror points at the
file's bytes as they exist on the data server, without the
chunk envelope, checksum header, or chunk_guard4 fields that the
encoded types use.  Client I/O against a PASSTHROUGH mirror
uses NFSv3 WRITE / READ (<xref target="RFC1813"/>) or NFSv4 READ / WRITE
(<xref target="RFC8881"/>) directly -- not CHUNK_WRITE / CHUNK_READ.</t>
          <t>PASSTHROUGH provides:</t>
          <ul spacing="normal">
            <li>
              <t>Replication of data across N data servers, exactly as flexible file v1 layout
does.  Clients write to every replica; clients read from any
one.  N-way redundancy tolerates up to N-1 replica losses.</t>
            </li>
            <li>
              <t>Zero codec compute at the client and zero chunk-metadata
overhead at the server.  The on-disk format is the file
itself.</t>
            </li>
            <li>
              <t>Compatibility with files that already exist outside flexible file v2 layout.
A PASSTHROUGH mirror can be created over an existing
file without rewriting it.</t>
            </li>
          </ul>
          <t>PASSTHROUGH does NOT provide:</t>
          <ul spacing="normal">
            <li>
              <t>Per-chunk integrity.  There is no checksum on the data path.
Silent corruption is undetectable without out-of-band
tooling (e.g., comparing checksums across replicas).</t>
            </li>
            <li>
              <t>Chunk-grained repair.  The repair unit is the whole file:
resilvering picks a trusted replica and replicates it end
to end to the affected replica(s).</t>
            </li>
            <li>
              <t>The concurrent-writer disambiguation that chunk_guard4
provides for encoded types.</t>
            </li>
          </ul>
          <t>PASSTHROUGH is <bcp14>RECOMMENDED</bcp14> for the assimilation, migration, and
heterogeneous-mirror use cases described in
<xref target="sec-heterogeneous-mirrors"/>.  New deployments that do not
need a flexible file v1 layout on-ramp <bcp14>SHOULD</bcp14> use FFV2_ENCODING_MIRRORED for
the integrity guarantees described in
<xref target="sec-encoding-mirrored"/>.</t>
        </section>
        <section anchor="sec-encoding-mirrored">
          <name>FFV2_ENCODING_MIRRORED</name>
          <t>FFV2_ENCODING_MIRRORED is the chunked-with-integrity peer of
PASSTHROUGH.  The chunk produced for each replica is the
application data verbatim -- no transform, no parity shards --
but it travels on the wire and is stored on the data server
through CHUNK_WRITE / CHUNK_READ and so carries every integrity
property the encoded coding types carry.</t>
          <t>What FFV2_ENCODING_MIRRORED keeps from the mirror model:</t>
          <ul spacing="normal">
            <li>
              <t>Zero codec compute at the client.  Each replica's chunk is
the input bytes; there is no transform to apply on write and
nothing to decode on read.</t>
            </li>
            <li>
              <t>Storage cost of N x payload, where N is the replica count.
Mirroring trades storage for redundancy without the
reconstruction machinery that erasure coding requires.</t>
            </li>
            <li>
              <t>Reading any one intact replica is sufficient.  If a replica
fails to verify (see below), the client tries another.</t>
            </li>
          </ul>
          <t>What FFV2_ENCODING_MIRRORED adds beyond PASSTHROUGH, by virtue
of using CHUNK_WRITE and CHUNK_READ:</t>
          <ul spacing="normal">
            <li>
              <t>Per-chunk checksum on write and on read.  The CRC is computed
by the client over the chunk payload, sent on the wire with
the chunk, recomputed by the data server before storing,
and recomputed again from disk by the data server on every
CHUNK_READ.  Wire-level bit flips are caught before the
chunk is stored; on-disk bit rot is caught the next time
the chunk is read.</t>
            </li>
            <li>
              <t>Per-chunk repair granularity.  When one replica's CRC fails
to verify and another replica's verifies, the repair unit
is the chunk, not the file: CHUNK_READ the good replica,
CHUNK_WRITE to the bad replica, done.  No whole-file
resilvering is required.</t>
            </li>
            <li>
              <t>Per-chunk concurrent-writer disambiguation.  Mirrored
writes carry the same chunk_guard4 (<xref target="sec-chunk_guard4"/>)
the erasure coding types do.  Two clients racing to write
the same offset of the same file fan out to every replica
with a guard pair (generation, owning-client short-id) per
chunk; the CHUNK_FINALIZE step resolves which writer's
chunk wins and the other writer observes a deterministic
loss instead of an unresolved split-mirror.</t>
            </li>
          </ul>
          <t>What FFV2_ENCODING_MIRRORED is for: files where the deployment
wants integrity and replication without the storage savings or
the reconstruction story of erasure coding.  Small files that
do not exceed a single stripe, files whose access pattern is
read-mostly and where the N x storage cost is acceptable, and
files where the operator prefers the simplicity of "any one
replica is the file" over "k of (k+m) shards reconstruct the
file."  The coding choice is per-file; a deployment can mix
mirrored and erasure-coded files in the same namespace and
pick whichever fits each file's profile.</t>
          <t>What FFV2_ENCODING_MIRRORED is not: a substitute for erasure
coding when storage efficiency or multi-replica fault tolerance
matters.  An N-way mirror tolerates up to N-1 replica losses
but costs N x the payload; a (k, m) erasure coding tolerates m
losses at (k+m)/k x the payload.  Both have per-chunk
integrity under this document; the choice is the
cost-vs-tolerance one.</t>
        </section>
        <section anchor="encoding-type-interoperability">
          <name>Encoding Type Interoperability</name>
          <t>The data servers do not interpret erasure-coded data -- they store and
return opaque chunks.  The NFS wire protocol likewise does not depend
on the encoding mathematics.  However, a client that writes data using
one encoding type <bcp14>MUST</bcp14> be able to read it back, and a different
client implementation <bcp14>MUST</bcp14> be able to read data written by the first
client if both claim to support the same encoding type.</t>
          <t>This interoperability requirement means that each registered
encoding type <bcp14>MUST</bcp14> fully specify the encoding and decoding
mathematics such that two independent implementations produce
byte-identical encoded output for the same input.  The specification
of a new encoding type <bcp14>MUST</bcp14> include one of the following:</t>
          <ol spacing="normal" type="1"><li>
              <t>A complete mathematical specification of the encoding and decoding
algorithms, including all parameters (e.g., field polynomial,
matrix construction, element size) sufficient for an independent
implementation to produce interoperable results.</t>
            </li>
            <li>
              <t>A reference to a published patent or pending patent application
that contains the algorithm specification.  Implementors can then
evaluate the licensing terms and decide whether to support the
encoding type.</t>
            </li>
            <li>
              <t>A declaration that the encoding type is a proprietary
implementation.  In this case, the encoding type name <bcp14>SHOULD</bcp14>
include an organizational prefix (e.g.,
FFV2_ENCODING_ACME_FOOBAR) to signal that interoperability is
limited to implementations licensed by that organization.</t>
            </li>
          </ol>
          <t>Option 1 is <bcp14>RECOMMENDED</bcp14> for encoding types intended for broad
interoperability.  Options 2 and 3 allow vendors to register encoding
types for use within their own ecosystems while preserving the
encoding type namespace.</t>
          <t>The rationale for this requirement is that erasure coding moves
computation from the server to the client.  If the client cannot
determine how data was encoded, it cannot decode it.  Unlike layout
types (where the server controls the storage format), encoding types
require client-side agreement on the mathematics.</t>
        </section>
      </section>
      <section anchor="sec-ffv2_layout">
        <name>ffv2_layout4</name>
        <section anchor="sec-ffv2_flags4">
          <name>ffv2_flags4</name>
          <figure anchor="fig-ffv2_flags4">
            <name>The ffv2_flags4</name>
            <sourcecode type="xdr"><![CDATA[
   /// const FFV2_FLAGS_NO_LAYOUTCOMMIT  = FF_FLAGS_NO_LAYOUTCOMMIT;
   /// const FFV2_FLAGS_NO_IO_THRU_MDS   = FF_FLAGS_NO_IO_THRU_MDS;
   /// const FFV2_FLAGS_NO_READ_IO       = FF_FLAGS_NO_READ_IO;
   /// const FFV2_FLAGS_WRITE_ONE_MIRROR =
   ///     FF_FLAGS_WRITE_ONE_MIRROR;
   /// const FFV2_FLAGS_ONLY_ONE_WRITER  = 0x00000010;
   ///
   /// typedef uint32_t            ffv2_flags4;
]]></sourcecode>
          </figure>
          <t>The ffv2_flags4 in <xref target="fig-ffv2_flags4"/>  is a bitmap that allows the
metadata server to inform the client of particular conditions that
may result from more or less tight coupling of the storage devices.</t>
          <t>Each flag below describes both the semantics when set and the
normative requirement it places on the client.  When a flag is
not set, the client <bcp14>MUST</bcp14> follow the default behavior described
for its unset state.</t>
          <dl>
            <dt>FFV2_FLAGS_NO_LAYOUTCOMMIT:</dt>
            <dd>
              <t>When set, the client <bcp14>MAY</bcp14> omit the LAYOUTCOMMIT to the
metadata server.  When unset, the client <bcp14>MUST</bcp14> send LAYOUTCOMMIT
per <xref target="RFC8881"/> Section 18.42.</t>
            </dd>
            <dt>FFV2_FLAGS_NO_IO_THRU_MDS:</dt>
            <dd>
              <t>When set, the client <bcp14>MUST NOT</bcp14> proxy I/O operations through
the metadata server, even after detecting a network disconnect
to a storage device.  When unset, the client <bcp14>MAY</bcp14> retry failed
I/O via the metadata server.</t>
            </dd>
            <dt>FFV2_FLAGS_NO_READ_IO:</dt>
            <dd>
              <t>When set, the client <bcp14>MUST NOT</bcp14> issue READ against layouts of
iomode LAYOUTIOMODE4_RW, and <bcp14>MUST</bcp14> instead request a separate
layout of iomode LAYOUTIOMODE4_READ for any read I/O.  When
unset, the client <bcp14>MAY</bcp14> issue READ against either iomode.</t>
            </dd>
            <dt>FFV2_FLAGS_WRITE_ONE_MIRROR:</dt>
            <dd>
              <t>When set, the client <bcp14>MAY</bcp14> update only one mirror of each
layout segment (see <xref target="sec-CSM"/>) and rely on the metadata
server or a peer data server to propagate the update to the
remaining mirrors.  When unset, the client <bcp14>MUST</bcp14> update all
mirrors.</t>
            </dd>
            <dt>FFV2_FLAGS_ONLY_ONE_WRITER:</dt>
            <dd>
              <t>When set, the client is the exclusive writer for the layout
and <bcp14>MAY</bcp14> issue CHUNK_WRITE without setting cwa_guard, retaining
the ability to use CHUNK_ROLLBACK in the event of a write hole
caused by overwriting.  When unset, the client <bcp14>MUST</bcp14> set
cwa_guard on every CHUNK_WRITE so that chunk_guard4 CAS can
prevent collisions across concurrent writers.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="ffv2fileinfo4">
        <name>ffv2_file_info4</name>
        <figure anchor="fig-ffv2_file_info4">
          <name>The ffv2_file_info4</name>
          <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_file_info4 {
   ///     stateid4                ffv2fi_stateid;
   ///     nfs_fh4                 ffv2fi_fh_vers;
   /// };
]]></sourcecode>
        </figure>
        <t>The ffv2_file_info4 is a new structure to help with the stateid
issue discussed in Section 5.1 of <xref target="RFC8435"/>.  I.e., in version 1
of the Flexible File Version 2 Layout Type, there was the singleton ffv2ds_stateid
combined with the ffv2ds_fh_vers array.  I.e., each NFSv4 version
has its own stateid.  In <xref target="fig-ffv2_file_info4"/>, each NFSv4
filehandle has a one-to-one correspondence to a stateid.</t>
      </section>
      <section anchor="sec-ffv2_ds_flags4">
        <name>ffv2_ds_flags4</name>
        <figure anchor="fig-ffv2_ds_flags4">
          <name>The ffv2_ds_flags4</name>
          <sourcecode type="xdr"><![CDATA[
   /// const FFV2_DS_FLAGS_ACTIVE        = 0x00000001;
   /// const FFV2_DS_FLAGS_SPARE         = 0x00000002;
   /// const FFV2_DS_FLAGS_PARITY        = 0x00000004;
   /// const FFV2_DS_FLAGS_REPAIR        = 0x00000008;
   /// typedef uint32_t            ffv2_ds_flags4;
]]></sourcecode>
        </figure>
        <t>The ffv2_ds_flags4 (in <xref target="fig-ffv2_ds_flags4"/>) flags details the
state of the data servers.  With erasure coding algorithms, there
are both Systematic and Non-Systematic approaches.  In the Systematic,
the bits for integrity are placed amongst the resulting transformed
chunk.  Such an implementation would typically see FFV2_DS_FLAGS_ACTIVE
and FFV2_DS_FLAGS_SPARE data servers.  The FFV2_DS_FLAGS_SPARE ones
allow the client to repair a payload without engaging the metadata
server.  I.e., if one of the FFV2_DS_FLAGS_ACTIVE did not respond
to a WRITE_BLOCK, the client could fail the chunk to the
FFV2_DS_FLAGS_SPARE data server.</t>
        <t>With the Non-Systematic approach, the data and integrity live on
different data servers.  Such an implementation would typically see
FFV2_DS_FLAGS_ACTIVE and FFV2_DS_FLAGS_PARITY data servers.  If the
implementation wanted to allow for local repair, it would also use
FFV2_DS_FLAGS_SPARE.</t>
        <t>The FFV2_DS_FLAGS_REPAIR flag informs the client that the
indicated data server is a replacement for a previously failed
ACTIVE data server, whose content has been (or is being)
reconstructed from the surviving shards of the mirror set.  A
REPAIR data server differs from a SPARE in two ways:</t>
        <ul spacing="normal">
          <li>
            <t>A SPARE is standing by with no payload; the client <bcp14>MAY</bcp14> fail
over to it at write time without metadata-server coordination.</t>
          </li>
          <li>
            <t>A REPAIR has been promoted by the metadata server to replace a
failed ACTIVE, and its payload was placed there by a repair
client executing the flow in <xref target="sec-repair-selection"/> rather
than directly by the original writer.  The flag is the
client's indication that reads from this data server return
erasure-decoded content rather than content produced by the
original write.</t>
          </li>
        </ul>
        <t>Clients that rely on write-provenance information (for example,
deployments that track which client wrote which generation)
<bcp14>SHOULD</bcp14> be aware of the REPAIR flag so they do not treat the
reconstructed payload as if it had been written directly by the
cg_client_id recorded in the chunk_guard4; the guard values
still match across the mirror set by construction, but the
physical write path differs.</t>
        <t>Over the lifetime of a file, a single data server <bcp14>MAY</bcp14> transition
ACTIVE -&gt; REPAIR (on replacement) or REPAIR -&gt; ACTIVE (once the
metadata server has accepted the reconstructed content as
authoritative and the fail-over is complete); the metadata
server reflects the current flag set in the next layout it
returns.</t>
      </section>
      <section anchor="ffv2dataserver4">
        <name>ffv2_data_server4</name>
        <figure anchor="fig-ffv2_data_server4">
          <name>The ffv2_data_server4</name>
          <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_data_server4 {
   ///     deviceid4               ffv2ds_deviceid;
   ///     uint32_t                ffv2ds_efficiency;
   ///     ffv2_file_info4         ffv2ds_file_info<>;
   ///     fattr4_owner            ffv2ds_user;
   ///     fattr4_owner_group      ffv2ds_group;
   ///     ffv2_ds_flags4          ffv2ds_flags;
   /// };
]]></sourcecode>
        </figure>
        <t>The ffv2_data_server4 (in <xref target="fig-ffv2_data_server4"/>) describes a data
file and how to access it via the different NFS protocols.</t>
      </section>
      <section anchor="ffv2codingtypedata4">
        <name>ffv2_coding_type_data4</name>
        <figure anchor="fig-ffv2_coding_type_data4">
          <name>The ffv2_coding_type_data4</name>
          <sourcecode type="xdr"><![CDATA[
   /// union ffv2_coding_type_data4 switch
   ///         (ffv2_coding_type4 fctd_coding) {
   ///     case FFV2_ENCODING_PASSTHROUGH:
   ///         ffv2_data_protection4   fctd_protection;
   ///     case FFV2_ENCODING_MIRRORED:
   ///         ffv2_data_protection4   fctd_protection;
   ///     default:
   ///         ffv2_data_protection4   fctd_protection;
   /// };
]]></sourcecode>
        </figure>
        <t>The ffv2_coding_type_data4 (in <xref target="fig-ffv2_coding_type_data4"/>) describes
the data protection geometry for the layout.  All coding types carry an
ffv2_data_protection4 (<xref target="fig-ffv2_data_protection4"/>) specifying the
number of data and parity shards.  The coding type enum determines how
the shards are encoded; the protection structure determines how many
shards there are.</t>
        <t>Although every arm of the union currently carries the same
type, the union form is intentional.  Future revisions of this
specification may assign distinct arm types to specific coding
types; using a union now avoids an incompatible change to the
XDR at that time.</t>
        <t>The (data, parity) tuple is interpreted per encoding type:</t>
        <ul spacing="normal">
          <li>
            <t>FFV2_ENCODING_PASSTHROUGH preserves the flexible file v1 layout-style notation
for backward compatibility: fdp_data is 1 and fdp_parity is
the number of additional copies (e.g., fdp_parity=2 for
3-way mirroring).  The "1" data carrier is the file as
stored; the fdp_parity additional copies are the flexible file v1 layout
mirror replicas.</t>
          </li>
          <li>
            <t>FFV2_ENCODING_MIRRORED uses the N+0 notation: fdp_data is
the number of replicas (e.g., fdp_data=3 for 3-way
mirroring) and fdp_parity <bcp14>MUST</bcp14> be 0.  Every replica is a
full, independent data carrier; mirroring carries no
parity reconstruction.</t>
          </li>
          <li>
            <t>Erasure coding types (FFV2_ENCODING_RS_VANDERMONDE,
FFV2_ENCODING_MOJETTE_SYSTEMATIC,
FFV2_ENCODING_MOJETTE_NON_SYSTEMATIC, and any future types
subsequently registered in the IANA registry established by
this document) use fdp_data &gt;= 2 and fdp_parity &gt;= 1.</t>
          </li>
        </ul>
      </section>
      <section anchor="ffv2stripes4">
        <name>ffv2_stripes4</name>
        <figure anchor="fig-ffv2_stripes4">
          <name>The ffv2_stripes4 structure</name>
          <sourcecode type="xdr"><![CDATA[
   /// enum ffv2_striping {
   ///     FFV2_STRIPING_NONE = 0,
   ///     FFV2_STRIPING_SPARSE = 1,
   ///     FFV2_STRIPING_DENSE = 2
   /// };
   ///
   /// struct ffv2_stripes4 {
   ///         ffv2_data_server4       ffv2s_data_servers<>;
   /// };
]]></sourcecode>
        </figure>
        <t>Each stripe contains a set of data servers in ffv2s_data_servers.
If the stripe is part of a ffv2_coding_type_data4 of
FFV2_ENCODING_PASSTHROUGH or FFV2_ENCODING_MIRRORED, then the
length of ffv2s_data_servers <bcp14>MUST</bcp14> be 1: under both encoding
types each stripe's data lives on a single data server, with
replica multiplicity expressed in ffv2l_mirrors rather than in
ffv2s_data_servers.</t>
      </section>
      <section anchor="sec-ffv2-mirror4">
        <name>ffv2_mirror4</name>
        <figure anchor="fig-ffv2_mirror4">
          <name>The ffv2_mirror4</name>
          <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_mirror4 {
   ///         ffv2_coding_type_data4  ffv2m_coding_type_data;
   ///         ffv2_striping           ffv2m_striping;
   ///         uint32_t                ffv2m_striping_unit_size;
   ///         uint32_t                ffv2m_client_id;
   ///         checksum_algorithm4     ffv2m_checksum_algorithm;
   ///         ffv2_stripes4           ffv2m_stripes<>;
   /// };
]]></sourcecode>
        </figure>
        <t>The ffv2_mirror4 (in <xref target="fig-ffv2_mirror4"/>) describes the Flexible
File Layout Version 2 specific fields.</t>
        <t>The ffv2m_checksum_algorithm field names the checksum
algorithm the client <bcp14>MUST</bcp14> use when computing
cwa_checksums on CHUNK_WRITE and cwra_checksums on
CHUNK_WRITE_REPAIR, and the algorithm the client <bcp14>MUST</bcp14>
expect in cr_checksum on CHUNK_READ responses, for chunks
in this mirror.  The metadata server picks the algorithm
at LAYOUTGET time; the value is one of the registered
checksum_algorithm4 codes (see <xref target="sec-checksum4"/>).
Different mirrors of the same file <bcp14>MAY</bcp14> name different
checksum algorithms, supporting transition cases where one
mirror is being migrated to a stronger algorithm while
others retain the previous algorithm.</t>
        <t>A client that does not implement the algorithm named in
ffv2m_checksum_algorithm <bcp14>MUST</bcp14> return the layout with
NFS4ERR_LAYOUT_CHECKSUM_NOT_SUPPORTED; the metadata
server may then issue a new layout naming a different
algorithm the client supports, or deny the layout request.</t>
        <t>The ffv2m_client_id is a 32-bit value, assigned by the metadata
server at layout-grant time, that the client <bcp14>MUST</bcp14> use as the
cg_client_id field of chunk_guard4 (see <xref target="sec-chunk_guard4"/>) in
every CHUNK_WRITE it issues against the mirror's data servers.
Its purpose is to satisfy the 32-bit-per-field budget of
chunk_guard4 while preserving the guarantee that concurrent
writers on the same file are distinguishable:</t>
        <ul spacing="normal">
          <li>
            <t>The NFSv4 clientid4 (<xref target="RFC8881"/>) is a 64-bit identifier;
<xref target="RFC8881"/> does not constrain how a server populates its
bits, and the bit-layout choices made by any particular
metadata server implementation are not visible to the
client and <bcp14>MUST NOT</bcp14> be assumed by the client.  Folding
clientid4 to 32 bits locally at the client therefore risks
colliding with another client's folded value, which would
violate the uniqueness contract on chunk_guard4.</t>
          </li>
          <li>
            <t>Only the metadata server has the information needed to avoid
such collisions: it sees every layout it grants on a file and
can assign a dense 32-bit ffv2m_client_id that is guaranteed
distinct from the ffv2m_client_ids assigned to other clients
holding concurrent write layouts on the same file.  The
metadata server <bcp14>MUST</bcp14> assign ffv2m_client_id subject to this
uniqueness rule.</t>
          </li>
          <li>
            <t>Because cg_client_id participates in the deterministic
tiebreaker for racing writers (see <xref target="sec-chunk_guard4"/>),
having the metadata server assign it also lets the metadata
server influence which client wins contention by choosing
the numeric ordering of the values it hands out.  Specific
ordering policies are implementation-defined and out of
scope for this document, but the protocol mechanism is
present.</t>
          </li>
        </ul>
        <t>An ffv2m_client_id is scoped to the file and layout for which it
was granted.  A client that holds layouts on two different files
may receive two different ffv2m_client_ids from the same metadata
server, and a client that relinquishes and later re-acquires a
layout on a given file <bcp14>MAY</bcp14> be assigned a different ffv2m_client_id.
ffv2m_client_id does NOT survive a metadata server restart: the
metadata server reassigns values as clients reclaim layouts
during the grace period.</t>
        <t>The ffv2m_coding_type_data is which encoding type is used
by the mirror.</t>
        <t>The ffv2m_striping selects the striping method used by the
mirror.  The three permissible values are FFV2_STRIPING_NONE
(the mirror is not striped), FFV2_STRIPING_SPARSE (stripe units
are mapped to the same physical offset on every data server,
leaving holes), and FFV2_STRIPING_DENSE (stripe units are
packed contiguously on each data server without holes).  See
<xref target="sec-striping"/> for the mapping math for each option.</t>
        <t>The ffv2m_striping_unit_size is the stripe unit size used
by the mirror.  The minimum stripe unit size is 64 bytes.  If
the value of ffv2m_striping is FFV2_STRIPING_NONE, then the value
of ffv2m_striping_unit_size <bcp14>MUST</bcp14> be 1.</t>
        <t>The ffv2m_stripes is the array of stripes for the mirror; the
length of the array is the stripe count.  If there is no
striping or the ffv2m_coding_type_data is FFV2_ENCODING_PASSTHROUGH,
then the length of ffv2m_stripes <bcp14>MUST</bcp14> be 1.  Under
FFV2_ENCODING_MIRRORED the file <bcp14>MAY</bcp14> be striped within each
replica; the constraint that ffv2s_data_servers length is 1
still applies, but ffv2m_stripes may carry multiple stripes.</t>
      </section>
      <section anchor="ffv2layout4">
        <name>ffv2_layout4</name>
        <figure anchor="fig-ffv2_layout4">
          <name>The ffv2_layout4</name>
          <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_layout4 {
   ///     ffv2_mirror4            ffv2l_mirrors<>;
   ///     ffv2_flags4             ffv2l_flags;
   ///     uint32_t                ffv2l_stats_collect_hint;
   /// };
]]></sourcecode>
        </figure>
        <t>The ffv2_layout4 (in <xref target="fig-ffv2_layout4"/>) describes the Flexible
File Layout Version 2.</t>
        <t>The ffv2l_mirrors field is the array of mirrored storage devices that
provide the storage for the current stripe; see <xref target="fig-parallel-filesystem"/>.</t>
        <t>The ffv2l_stats_collect_hint field provides a hint to the client on
how often the server wants it to report LAYOUTSTATS for a file.
The time is in seconds.</t>
        <figure anchor="fig-parallel-filesystem">
          <name>The Relationship between MDS and DSes</name>
          <artwork><![CDATA[
                +-----------+
                |           |
                |           |
                |   File    |
                |           |
                |           |
                +-----+-----+
                      |
     +-------------+-----+----------------+
     |                   |                |
+----+-----+       +-----+----+       +---+----------+
| Mirror 1 |       | Mirror 2 |       | Mirror 3     |
| MIRRORED |       | MIRRORED |       | REED_SOLOMON |
+----+-----+       +-----+----+       +---+----------+
     |                   |                |
     |                   |                |
+-----------+      +-----------+      +-----------+
|+-----------+     | Stripe 1  |      |+-----------+
+| Stripe N  |     +-----------+      +| Stripe N  |
 +-----------+           |             +-----------+
     |                   |                |
     |                   |                |
+-----------+      +-----------+      +-----------+
| Storage   |      | Storage   |      |+-----------+
| Device    |      | Device    |      ||+-----------+
+-----------+      +-----------+      +||  Storage  |
                                       +|  Devices  |
                                        +-----------+
]]></artwork>
        </figure>
        <t>As shown in <xref target="fig-parallel-filesystem"/> if the ffv2m_coding_type_data
is FFV2_ENCODING_PASSTHROUGH or FFV2_ENCODING_MIRRORED, then
each of the stripes <bcp14>MUST</bcp14> only have 1 storage device.  I.e.,
the length of ffv2s_data_servers <bcp14>MUST</bcp14> be 1.  The erasure-coding
encoding types (FFV2_ENCODING_MOJETTE_SYSTEMATIC,
FFV2_ENCODING_MOJETTE_NON_SYSTEMATIC,
FFV2_ENCODING_RS_VANDERMONDE) distribute shards across multiple
storage devices and so carry multiple entries in
ffv2s_data_servers.</t>
        <t>The abstraction here is that for FFV2_ENCODING_PASSTHROUGH and
FFV2_ENCODING_MIRRORED, each stripe describes exactly one data
server.  And for the erasure-coded encoding types, each of the
stripes describes a set of data servers to which the shards are
distributed.  Further, the payload length can be different per
stripe.</t>
      </section>
      <section anchor="ffv2dataprotection4">
        <name>ffv2_data_protection4</name>
        <figure anchor="fig-ffv2_data_protection4">
          <name>The ffv2_data_protection4</name>
          <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_data_protection4 {
   ///     uint32_t fdp_data;    /* data shards (k) */
   ///     uint32_t fdp_parity;  /* parity/redundancy shards (m) */
   /// };
]]></sourcecode>
        </figure>
        <t>The ffv2_data_protection4 (in <xref target="fig-ffv2_data_protection4"/>) describes
the data protection geometry as a pair of counts: the number of data
shards (fdp_data, also known as k) and the number of parity or
redundancy shards (fdp_parity, also known as m).  This structure is
used in both layout hints and layout responses, and applies
uniformly to all coding types:</t>
        <table anchor="fig-protection-examples">
          <name>Example data protection configurations</name>
          <thead>
            <tr>
              <th align="left">Protection Mode</th>
              <th align="left">fdp_data</th>
              <th align="left">fdp_parity</th>
              <th align="left">Total DSes</th>
              <th align="left">Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">Mirroring (3-way)</td>
              <td align="left">1</td>
              <td align="left">2</td>
              <td align="left">3</td>
              <td align="left">3 copies, no encoding</td>
            </tr>
            <tr>
              <td align="left">Striping (6-way)</td>
              <td align="left">6</td>
              <td align="left">0</td>
              <td align="left">6</td>
              <td align="left">Parallel I/O, no redundancy</td>
            </tr>
            <tr>
              <td align="left">RS Vandermonde 4+2</td>
              <td align="left">4</td>
              <td align="left">2</td>
              <td align="left">6</td>
              <td align="left">Tolerates 2 DS failures</td>
            </tr>
            <tr>
              <td align="left">Mojette-sys 8+2</td>
              <td align="left">8</td>
              <td align="left">2</td>
              <td align="left">10</td>
              <td align="left">Tolerates 2 DS failures</td>
            </tr>
          </tbody>
        </table>
        <t>By expressing all protection modes as (fdp_data, fdp_parity) pairs,
a single structure serves mirroring, striping, and all erasure
coding types.  The coding type (<xref target="fig-ffv2_coding_type4"/>) determines
how the shards are encoded; the protection structure determines
how many shards there are.</t>
        <t>The total number of data servers required is fdp_data + fdp_parity.
The storage overhead is fdp_parity / fdp_data (e.g., 50% for 4+2,
25% for 8+2).</t>
      </section>
      <section anchor="sec-ffv2-layouthint">
        <name>ffv2_layouthint4</name>
        <figure anchor="fig-ffv2_layouthint4">
          <name>The ffv2_layouthint4</name>
          <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_layouthint4 {
   ///     ffv2_coding_type4       ffv2lh_supported_types<>;
   ///     ffv2_data_protection4   ffv2lh_preferred_protection;
   /// };
]]></sourcecode>
        </figure>
        <t>The ffv2_layouthint4 (in <xref target="fig-ffv2_layouthint4"/>) describes the
layout_hint (see Section 5.12.4 of <xref target="RFC8881"/>) that the client can
provide to the metadata server.</t>
        <t>The client provides two hints:</t>
        <dl>
          <dt>ffv2lh_supported_types</dt>
          <dd>
            <t>An ordered list of coding types the client supports,
with the most preferred type first.  The server <bcp14>SHOULD</bcp14> select a type
from this list but <bcp14>MAY</bcp14> choose any type it supports.  If the server
does not support any of the listed types, it returns
NFS4ERR_CODING_NOT_SUPPORTED, and the client can retry
with a different list to discover the overlapping set.</t>
          </dd>
          <dt>ffv2lh_preferred_protection</dt>
          <dd>
            <t>The client's preferred data protection geometry as a
(fdp_data, fdp_parity) pair.  The server <bcp14>SHOULD</bcp14> honor this hint but
<bcp14>MAY</bcp14> override it based on server-side policy.  A server that manages
data protection via administrative policy (e.g., per-directory or
per-export objectives) will typically ignore this hint and return the
geometry dictated by policy.</t>
          </dd>
        </dl>
        <t>For example, a client that prefers Mojette systematic with 8+2
protection would send:</t>
        <artwork><![CDATA[
ffv2lh_supported_types = { FFV2_ENCODING_PASSTHROUGH,
                         FFV2_ENCODING_MIRRORED,
                         FFV2_ENCODING_MOJETTE_SYSTEMATIC,
                         FFV2_ENCODING_RS_VANDERMONDE }
ffv2lh_preferred_protection = { fdp_data = 8, fdp_parity = 2 }
]]></artwork>
        <t>A server with a policy of RS 4+2 for this directory would ignore
both hints and return a layout with FFV2_ENCODING_RS_VANDERMONDE
and (fdp_data=4, fdp_parity=2).  A server without erasure coding
might return FFV2_ENCODING_MIRRORED with (fdp_data=3, fdp_parity=0)
for 3-way mirroring with per-chunk integrity, or
FFV2_ENCODING_PASSTHROUGH with (fdp_data=1, fdp_parity=2) for
3-way flexible file v1 layout-compatible mirroring without per-chunk integrity.</t>
        <section anchor="sec-codec-negotiation">
          <name>Codec Negotiation</name>
          <t>Because the coding-type registry is expected to grow over time
(new erasure coding types are added, older ones fall out of favour,
vendors register private codes; see <xref target="iana-considerations"/>),
neither clients nor metadata servers are required to implement
every registered codec.  The protocol uses ffv2_layouthint4 as
the negotiation surface:</t>
          <dl>
            <dt>Client-side advertisement:</dt>
            <dd>
              <t>A client that wishes to influence codec selection <bcp14>SHOULD</bcp14>
send the set of codecs it actually implements in
ffv2lh_supported_types.  A client <bcp14>MUST NOT</bcp14> claim support for
a codec it cannot encode or decode: a false advertisement
produces silent data unavailability when the resulting layout
is issued.</t>
            </dd>
            <dt>Metadata-server selection:</dt>
            <dd>
              <t>The metadata server <bcp14>SHOULD</bcp14> select a codec from the client's
ffv2lh_supported_types list when the server's policy permits.
The server <bcp14>MAY</bcp14> override the hint when its policy dictates a
specific codec (for example, per-export objectives); in that
case the server issues a layout with the policy-dictated
codec and the client <bcp14>MUST</bcp14> either honour it or fail its I/O
with NFS4ERR_CODING_NOT_SUPPORTED.</t>
            </dd>
            <dt>Fallback when no overlap exists:</dt>
            <dd>
              <t>If the server's policy cannot be satisfied by any codec the
client supports, the metadata server has three options:
</t>
              <ol spacing="normal" type="1"><li>
                  <t>Return NFS4ERR_CODING_NOT_SUPPORTED on the LAYOUTGET.
The client <bcp14>MAY</bcp14> retry with a different (possibly empty)
ffv2lh_supported_types list to learn the server's codec
repertoire through the errors returned.</t>
                </li>
                <li>
                  <t>Fall back to I/O via the metadata server itself, so the
client's reads and writes are satisfied by the metadata server
translating to the underlying data server codec on the client's
behalf (see <xref target="sec-Fencing-Clients"/> for the MDS-I/O
fallback).  This is correct but serializes all I/O for
the codec-ignorant client through a single actor.</t>
                </li>
                <li>
                  <t>Route the client through a <strong>translating proxy</strong> that
understands both the file's native codec and a codec
the client does support.  The metadata server issues a layout with
the proxy's data-server entry carrying
FFV2_DS_FLAGS_PROXY and a coding_type the client does
support (typically FFV2_ENCODING_MIRRORED for a minimal
NFSv4.2 client, or FFV2_ENCODING_PASSTHROUGH / a flat
NFSv3 surface for an NFSv3 client).  The proxy encodes
and decodes on the fly
against the real data servers.  This preserves parallel I/O
for the codec-ignorant client that the MDS-I/O
fallback loses.  The proxy registration, directive, and
credential-forwarding rules are defined in the
<xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>; this draft defines only
the layout-flag surface (FFV2_DS_FLAGS_PROXY in
<xref target="sec-ffv2_ds_flags4"/>) that makes the proxy visible to
the client.</t>
                </li>
              </ol>
              <t>Options (1), (2), and (3) are not mutually exclusive: a
given deployment <bcp14>MAY</bcp14> implement any combination.  A
deployment that supports (3) covers all the clients that
(1) and (2) would cover and additionally preserves parallel
I/O for codec-ignorant clients.</t>
            </dd>
            <dt>Runtime codec change:</dt>
            <dd>
              <t>If a metadata server changes its codec policy after layouts
have been issued (for example, a deployment upgrade that
retires an older codec), the metadata server <bcp14>MUST</bcp14> recall the
affected layouts via CB_LAYOUTRECALL and may re-issue new
layouts with the new codec.  Clients that do not support the
new codec LAYOUTRETURN with NFS4ERR_CODING_NOT_SUPPORTED,
and the server either grants a layout using a mutually-supported codec or the client falls back to I/O via the
metadata server.</t>
            </dd>
          </dl>
          <t>This mechanism deliberately avoids a separate capability-bit
handshake at EXCHANGE_ID.  ffv2_layouthint4 already provides
per-request negotiation surface; adding a session-level
capability set would duplicate it and would complicate codec
upgrades without additional value, because a client that
genuinely upgrades its codec set at runtime can simply update
the ffv2lh_supported_types on its next LAYOUTGET.</t>
          <t>Note: In <xref target="fig-ffv2_layout4"/> ffv2_coding_type_data4 is an enumerated
union with the payload of each arm being defined by the protection
type. ffv2m_client_id tells the client which id to use when interacting
with the data servers.</t>
          <t>The ffv2_layout4 structure (see <xref target="fig-ffv2_layout4"/>) specifies a layout
in that portion of the data file described in the current layout
segment.  It is either a single instance or a set of mirrored copies
of that portion of the data file.  When mirroring is in effect, it
protects against loss of data in layout segments.</t>
          <t>While not explicitly shown in <xref target="fig-ffv2_layout4"/>, each layout4
element returned in the logr_layout array of LAYOUTGET4res (see
Section 18.43.2 of <xref target="RFC8881"/>) describes a layout segment.  Hence,
each ffv2_layout4 also describes a layout segment.  It is possible
that the file is concatenated from more than one layout segment.
Each layout segment <bcp14>MAY</bcp14> represent different striping parameters.</t>
          <t>The ffv2m_striping_unit_size field (inside each ffv2_mirror4) is
the stripe unit size in use for that mirror.  The number of
stripes is given by the number of elements in ffv2s_data_servers
within each ffv2_stripes4.  If the number of stripes is one,
then ffv2m_striping_unit_size <bcp14>MUST</bcp14> be zero.  The mapping scheme
(sparse or dense) is selected per mirror by ffv2m_striping and is
detailed in <xref target="sec-striping"/>.</t>
          <t>Stripe unit size and stripe count <bcp14>MAY</bcp14> differ between mirrors in
the same layout segment.  In particular, mirrors of different
encoding types (see <xref target="sec-heterogeneous-mirrors"/>) have stripe
counts determined by their respective (fdp_data, fdp_parity)
protection structures, and there is no requirement that those
structures match across mirrors.  Each mirror is self-consistent
internally; cross-mirror coherence is at the byte level (every
mirror represents the same file bytes), not at the stripe-geometry
level.</t>
          <t>The ffv2l_mirrors field represents an array of state information for
each mirrored copy of the current layout segment.  Each element is
described by a ffv2_mirror4 type.</t>
          <t>ffv2ds_deviceid provides the deviceid of the storage device holding
the data file.</t>
          <t>ffv2ds_file_info is an array of ffv2_file_info4 structures, each
pairing a filehandle (ffv2fi_fh_vers) with a stateid (ffv2fi_stateid).
There <bcp14>MUST</bcp14> be exactly as many elements in ffv2ds_file_info as there
are in ffda_versions.  Each element of the array corresponds to a
particular combination of ffdv_version, ffdv_minorversion, and
ffdv_tightly_coupled provided for the device.  The array allows for
server implementations that have different filehandles and stateids
for different combinations of version, minor version, and coupling
strength.  See <xref target="sec-version-errors"/> for how to handle versioning
issues between the client and storage devices.</t>
          <t>For tight coupling, ffv2fi_stateid provides the stateid to be used
by the client to access the file.  The metadata server registers
ffv2fi_stateid with each tight-coupling-capable storage device via
TRUST_STATEID (see <xref target="sec-tight-coupling-control"/>) before returning
the layout; the storage device validates subsequent CHUNK operations
against its trust table.</t>
          <t>For loose coupling and an NFSv4 storage device, the client <bcp14>MUST</bcp14> use
the anonymous stateid to perform I/O on the storage device, because
the metadata server stateid has no meaning to a storage device that
is not participating in the control protocol.  In this case the
metadata server <bcp14>MUST</bcp14> set ffv2fi_stateid to the anonymous stateid.</t>
          <t>For an NFSv3 storage device (ffdv_version = 3), the tight-coupling
model does not apply: <xref target="sec-ff_device_addr4"/> requires
ffdv_tightly_coupled to be FALSE whenever ffdv_version equals 3,
because NFSv3 has no wire encoding for stateids.  The corresponding
ffv2fi_stateid element in the ffv2ds_file_info array <bcp14>MUST</bcp14> therefore
be the anonymous stateid and is unused; an NFSv3 data server uses
the synthetic-uid fencing model (see <xref target="sec-Fencing-Clients"/>)
rather than a stateid-based trust table.</t>
          <t>This specification of the ffv2fi_stateid restricts both models for
NFSv4.x storage protocols:</t>
          <dl>
            <dt>loosely couple</dt>
            <dd>
              <t>the stateid has to be an anonymous stateid</t>
            </dd>
            <dt>tightly couple</dt>
            <dd>
              <t>the stateid has to be a global stateid</t>
            </dd>
          </dl>
          <t>By pairing each ffv2fi_fh_vers with its own ffv2fi_stateid inside
ffv2_file_info4, the flexible file v2 layout addresses a limitation
in the flexible file v1 layout where a single stateid was shared
across all filehandles.</t>
          <t>Whether the ffv2fi_stateid values across an ffv2_file_info4 array
are distinct depends on each entry's coupling mode per the rules
above.  Loose-coupling and NFSv3 entries <bcp14>MUST</bcp14> carry the anonymous
stateid; those entries are therefore byte-identical by mandate.
Tight-coupling entries carry stateids the metadata server assigned
and registered via TRUST_STATEID; the metadata server <bcp14>MAY</bcp14> assign
these distinctly per filehandle version or <bcp14>MAY</bcp14> reuse the same
stateid across entries.</t>
          <t>The client <bcp14>MUST</bcp14> treat each (ffv2fi_fh_vers, ffv2fi_stateid) pair as
an opaque, independent authorization unit.  The client <bcp14>MUST NOT</bcp14>
compare ffv2fi_stateid values across entries in the array and <bcp14>MUST
NOT</bcp14> infer any relationship between two entries whose stateid values
are byte-identical.  When the client selects an entry to use for
I/O, it presents that entry's stateid with that entry's filehandle;
other entries in the array are unused for that I/O.</t>
          <t>For loosely coupled storage devices, ffv2ds_user and ffv2ds_group
provide the synthetic user and group to be used in the RPC credentials
that the client presents to the storage device to access the data
files.  For tightly coupled storage devices, the user and group on
the storage device will be the same as on the metadata server; that
is, if ffdv_tightly_coupled (see <xref target="sec-ff_device_addr4"/>) is set,
then the client <bcp14>MUST</bcp14> ignore both ffv2ds_user and ffv2ds_group.</t>
          <t>The allowed values for both ffv2ds_user and ffv2ds_group are specified
as owner and owner_group, respectively, in Section 5.9 of <xref target="RFC8881"/>.
For NFSv3 compatibility, user and group strings that consist of
decimal numeric values with no leading zeros can be given a special
interpretation by clients and servers that choose to provide such
support.  The receiver may treat such a user or group string as
representing the same user as would be represented by an NFSv3 uid
or gid having the corresponding numeric value.  Note that if using
Kerberos for security, the expectation is that these values will
be a name@domain string.</t>
          <t>ffv2ds_efficiency describes the metadata server's evaluation as to
the effectiveness of each mirror.  Note that this is per layout and
not per device as the metric may change due to perceived load,
availability to the metadata server, etc.  Higher values denote
higher perceived utility.  The way the client can select the best
mirror to access is discussed in <xref target="sec-select-mirror"/>.</t>
        </section>
        <section anchor="error-codes-from-layoutget">
          <name>Error Codes from LAYOUTGET</name>
          <t><xref target="RFC8881"/> provides little guidance as to how the client is to
proceed with a LAYOUTGET that returns an error of either
NFS4ERR_LAYOUTTRYLATER, NFS4ERR_LAYOUTUNAVAILABLE, and NFS4ERR_DELAY.
Within the context of this document:</t>
          <dl>
            <dt>NFS4ERR_LAYOUTUNAVAILABLE:</dt>
            <dd>
              <t>there is no layout available and the I/O is to go to the metadata
server.  Note that it is possible to have had a layout before a
recall and not after.</t>
            </dd>
            <dt>NFS4ERR_LAYOUTTRYLATER:</dt>
            <dd>
              <t>there is some issue preventing the layout from being granted.
If the client already has an appropriate layout, it should continue
with I/O to the storage devices.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>there is some issue preventing the layout from being granted.
If the client already has an appropriate layout, it should not
continue with I/O to the storage devices.</t>
            </dd>
          </dl>
        </section>
        <section anchor="client-interactions-with-ffflagsnoiothrumds">
          <name>Client Interactions with FF_FLAGS_NO_IO_THRU_MDS</name>
          <t>Even if the metadata server provides the FF_FLAGS_NO_IO_THRU_MDS
flag, the client can still perform I/O to the metadata server.  The
flag functions as a hint.  The flag indicates to the client that
the metadata server prefers to separate the metadata I/O from the
data I/ O, most likely for performance reasons.</t>
        </section>
      </section>
      <section anchor="layoutcommit-1">
        <name>LAYOUTCOMMIT</name>
        <t>The flexible file v2 layout does not use lou_body inside the
loca_layoutupdate argument to LAYOUTCOMMIT.  If lou_type is
LAYOUT4_FLEX_FILES, the lou_body field <bcp14>MUST</bcp14> have a zero length (see
Section 18.42.1 of <xref target="RFC8881"/>).</t>
      </section>
      <section anchor="interactions-between-devices-and-layouts">
        <name>Interactions between Devices and Layouts</name>
        <t>The file layout type is defined such that the relationship between
multipathing and filehandles can result in either 0, 1, or N
filehandles (see Section 13.3 of <xref target="RFC8881"/>).  Some rationales for
this are clustered servers that share the same filehandle or allow
for multiple read-only copies of the file on the same storage device.
In the flexible file v2 layout, while there is an array of
filehandles, they are independent of the multipathing being used.
If the metadata server wants to provide multiple read-only copies
of the same file on the same storage device, then it should provide
multiple mirrored instances, each with a different ff_device_addr4.
The client can then determine that, since each of the ffv2fi_fh_vers
values within ffv2ds_file_info are different, there are multiple
copies of the file for the current layout segment available.</t>
      </section>
      <section anchor="sec-version-errors">
        <name>Handling Version Errors</name>
        <t>When the metadata server provides the ffda_versions array in the
ff_device_addr4 (see <xref target="sec-ff_device_addr4"/>), the client is able
to determine whether or not it can access a storage device with any
of the supplied combinations of ffdv_version, ffdv_minorversion,
and ffdv_tightly_coupled.  However, due to the limitations of
reporting errors in GETDEVICEINFO (see Section 18.40 in <xref target="RFC8881"/>),
the client is not able to specify which specific device it cannot
communicate with over one of the provided ffdv_version and
ffdv_minorversion combinations.  Using ffv2_ioerr4 (<xref target="sec-ffv2_ioerr4"/>)
inside either the LAYOUTRETURN (see Section 18.44 of <xref target="RFC8881"/>)
or the LAYOUTERROR (see Section 15.6 of <xref target="RFC7862"/> and <xref target="sec-LAYOUTERROR"/>
of this document), the client can isolate the problematic storage
device.</t>
        <t>The error code to return for LAYOUTRETURN and/or LAYOUTERROR is
NFS4ERR_MINOR_VERS_MISMATCH.  It does not matter whether the mismatch
is a major version (e.g., client can use NFSv3 but not NFSv4) or
minor version (e.g., client can use NFSv4.1 but not NFSv4.2), the
error indicates that for all the supplied combinations for ffdv_version
and ffdv_minorversion, the client cannot communicate with the storage
device.  The client can retry the GETDEVICEINFO to see if the
metadata server can provide a different combination, or it can fall
back to doing the I/O through the metadata server.</t>
      </section>
    </section>
    <section anchor="sec-striping">
      <name>Striping</name>
      <t>The flexible file v2 layout version 2 inherits the dense and
sparse striping dispositions defined by the file layout type in
Section 13.4 of <xref target="RFC8881"/>.  The disposition for a given
mirror is selected by the ffv2m_striping field (see
<xref target="sec-ffv2-mirror4"/>) and applies to every data server in that
mirror's ffv2s_data_servers list.  Three values are permitted:</t>
      <dl>
        <dt>FFV2_STRIPING_NONE:</dt>
        <dd>
          <t>The mirror is not striped.  ffv2m_striping_unit_size <bcp14>MUST</bcp14> be 1
and ffv2m_stripes <bcp14>MUST</bcp14> contain exactly one stripe.  The entire
mirror lives on that stripe's single data server list, with
no offset transformation.</t>
        </dd>
        <dt>FFV2_STRIPING_SPARSE:</dt>
        <dd>
          <t>Logical offsets within the file map to the same numeric
offset on each data server.  A data server that does not own
the stripe unit at a given logical offset presents a hole at
that offset.  This is the simpler model and matches the
mental picture of "the file is laid out end-to-end on each
data server, but each data server stores only its stripe
units".</t>
        </dd>
        <dt>FFV2_STRIPING_DENSE:</dt>
        <dd>
          <t>Stripe units owned by a given data server are packed
contiguously on that data server, with no holes.  The
logical offset is transformed into a compact physical offset
on the target data server.  This matches pre-existing
deployments that follow the dense layout convention of
Section 13.4.4 of <xref target="RFC8881"/>.</t>
        </dd>
      </dl>
      <t>The mapping math for sparse and dense is given in
<xref target="fig-striping-math"/>.  Common definitions apply to both.</t>
      <figure anchor="fig-striping-math">
        <name>Sparse and dense stripe mapping math</name>
        <artwork><![CDATA[
L: logical offset within the file (bytes)
U: stripe-unit size in bytes  = ffv2m_striping_unit_size
W: stripe width               = length of ffv2s_data_servers
S: stripe size in bytes       = W * U
N: stripe number              = L / S
i: index (0-based) of the data server that owns L
                              = (L / U) mod W
R: byte offset within the stripe unit
                              = L mod U

FFV2_STRIPING_SPARSE:
  physical offset on data server i:
      P_sparse(L) = L
  other data servers see a hole at offset L.

FFV2_STRIPING_DENSE:
  physical offset on data server i:
      P_dense(L) = N * U + R
             = (L / S) * U + (L mod U)
  each data server stores only the stripe units it owns,
  packed contiguously.
]]></artwork>
      </figure>
    </section>
    <section anchor="recovering-from-client-io-errors">
      <name>Recovering from Client I/O Errors</name>
      <t>The pNFS client may encounter errors when directly accessing the
storage devices.  However, it is the responsibility of the metadata
server to recover from the I/O errors.  When the LAYOUT4_FLEX_FILES
layout type is used, the client <bcp14>MUST</bcp14> report the I/O errors to the
server at LAYOUTRETURN time using the ffv2_ioerr4 structure (see
<xref target="sec-ffv2_ioerr4"/>).</t>
      <t>The metadata server analyzes the error and determines the required
recovery operations such as recovering media failures or reconstructing
missing data files.</t>
      <t>The metadata server <bcp14>MUST</bcp14> recall any outstanding layouts to allow
it exclusive write access to the stripes being recovered and to
prevent other clients from hitting the same error condition.  In
these cases, the server <bcp14>MUST</bcp14> complete recovery before handing out
any new layouts to the affected byte ranges.</t>
      <t>Although the client implementation has the option to propagate a
corresponding error to the application that initiated the I/O
operation and drop any unwritten data, the client should attempt
to retry the original I/O operation by either requesting a new
layout or sending the I/O via regular NFSv4.1+ READ or WRITE
operations to the metadata server.  The client <bcp14>SHOULD</bcp14> attempt to
retrieve a new layout and retry the I/O operation using the storage
device first and only retry the I/O operation via the metadata
server if the error persists.</t>
    </section>
    <section anchor="client-side-protection-modes">
      <name>Client-Side Protection Modes</name>
      <section anchor="sec-CSM">
        <name>Client-Side Mirroring</name>
        <t>The flexible file v2 layout has a simple model in place for the
mirroring of the file data constrained by a layout segment.  There
is no assumption that each copy of the mirror is stored identically
on the storage devices.  For example, one device might employ
compression or deduplication on the data.  However, the over-the-wire
transfer of the file contents <bcp14>MUST</bcp14> appear identical.  Note, this
is a constraint of the selected XDR representation in which each
mirrored copy of the layout segment has the same striping pattern
(see <xref target="fig-parallel-filesystem"/>).</t>
        <t>The metadata server is responsible for determining the number of
mirrored copies and the location of each mirror.  While the client
may provide a hint to how many copies it wants (see <xref target="sec-ffv2-layouthint"/>),
the metadata server can ignore that hint; in any event, the client
has no means to dictate either the storage device (which also means
the coupling and/or protocol levels to access the layout segments)
or the location of said storage device.</t>
        <t>The updating of mirrored layout segments is done via client-side
mirroring.  With this approach, the client is responsible for making
sure modifications are made on all copies of the layout segments
it is informed of via the layout.  If a layout segment is being
resilvered to a storage device, that mirrored copy will not be in
the layout.  Thus, the metadata server <bcp14>MUST</bcp14> update that copy until
the client is presented it in a layout.  If the FF_FLAGS_WRITE_ONE_MIRROR
is set in ffv2l_flags, the client need only update one of the mirrors
(see <xref target="sec-write-mirrors"/>).  If the client is writing to the layout
segments via the metadata server, then the metadata server <bcp14>MUST</bcp14>
update all copies of the mirror.  As seen in <xref target="sec-mds-resilvering"/>,
during the resilvering, the layout is recalled, and the client has
to make modifications via the metadata server.</t>
        <section anchor="sec-select-mirror">
          <name>Selecting a Mirror</name>
          <t>When the metadata server grants a layout to a client, it <bcp14>MAY</bcp14> let
the client know how fast it expects each mirror to be once the
request arrives at the storage devices via the ffv2ds_efficiency
member.  While the algorithms to calculate that value are left to
the metadata server implementations, factors that could contribute
to that calculation include speed of the storage device, physical
memory available to the device, operating system version, current
load, etc.</t>
          <t>However, what should not be involved in that calculation is a
perceived network distance between the client and the storage device.
The client is better situated for making that determination based
on past interaction with the storage device over the different
available network interfaces between the two; that is, the metadata
server might not know about a transient outage between the client
and storage device because it has no presence on the given subnet.</t>
          <t>As such, it is the client that decides which mirror to access for
reading the file.  The requirements for writing to mirrored layout
segments are presented below.</t>
        </section>
        <section anchor="sec-write-mirrors">
          <name>Writing to Mirrors</name>
          <section anchor="single-storage-device-updates-mirrors">
            <name>Single Storage Device Updates Mirrors</name>
            <t>If the FF_FLAGS_WRITE_ONE_MIRROR flag in ffv2l_flags is set, the
client <bcp14>MAY</bcp14> update just one of the copies of the layout segment.
For this case, the storage device <bcp14>MUST</bcp14> ensure that all copies of
the mirror are updated when any one of the mirrors is updated.  If
the storage device gets an error when updating one of the mirrors,
then it <bcp14>MUST</bcp14> inform the client that the original WRITE had an error.
The client then <bcp14>MUST</bcp14> inform the metadata server (see <xref target="sec-write-errors"/>).
The client's responsibility with respect to COMMIT is explained in
<xref target="sec-write-commits"/>.  The client may choose any one of the mirrors
and may use ffv2ds_efficiency as described in <xref target="sec-select-mirror"/>
when making this choice.</t>
          </section>
          <section anchor="client-updates-all-mirrors">
            <name>Client Updates All Mirrors</name>
            <t>If the FF_FLAGS_WRITE_ONE_MIRROR flag in ffv2l_flags is not set, the
client is responsible for updating all mirrored copies of the layout
segments that it is given in the layout.  A single failed update
is sufficient to fail the entire operation.  If all but one copy
is updated successfully and the last one provides an error, then
the client <bcp14>MUST</bcp14> inform the metadata server about the error.
The client can use either LAYOUTRETURN or LAYOUTERROR to inform the
metadata server that the update failed to that storage device.  If
the client is updating the mirrors serially, then it <bcp14>SHOULD</bcp14> stop
at the first error encountered and report that to the metadata
server.  If the client is updating the mirrors in parallel, then
it <bcp14>SHOULD</bcp14> wait until all storage devices respond so that it can
report all errors encountered during the update.</t>
          </section>
          <section anchor="sec-write-errors">
            <name>Handling Write Errors</name>
            <t>When the client reports a write error to the metadata server, the
metadata server is responsible for determining if it wants to remove
the errant mirror from the layout, if the mirror has recovered from
some transient error, etc.  When the client tries to get a new
layout, the metadata server informs it of the decision by the
contents of the layout.  The client <bcp14>MUST NOT</bcp14> assume that the contents
of the previous layout will match those of the new one.  If it has
updates that were not committed to all mirrors, then it <bcp14>MUST</bcp14> resend
those updates to all mirrors.</t>
            <t>There is no provision in the protocol for the metadata server to
directly determine that the client has or has not recovered from
an error.  For example, if a storage device was network partitioned
from the client and the client reported the error to the metadata
server, then the network partition would be repaired, and all of
the copies would be successfully updated.  There is no mechanism
for the client to report that fact, and the metadata server is
forced to repair the file across the mirror.</t>
            <t>If the client supports NFSv4.2, it can use LAYOUTERROR and LAYOUTRETURN
to provide hints to the metadata server about the recovery efforts.
A LAYOUTERROR on a file is for a non-fatal error.  A subsequent
LAYOUTRETURN without a ffv2_ioerr4 indicates that the client successfully
replayed the I/O to all mirrors.  Any LAYOUTRETURN with a ffv2_ioerr4
is an error that the metadata server needs to repair.  The client
<bcp14>MUST</bcp14> be prepared for the LAYOUTERROR to trigger a CB_LAYOUTRECALL
if the metadata server determines it needs to start repairing the
file.</t>
          </section>
          <section anchor="sec-write-commits">
            <name>Handling Write COMMITs</name>
            <t>When stable writes are done to the metadata server or to a single
replica (if allowed by the use of FF_FLAGS_WRITE_ONE_MIRROR), it
is the responsibility of the receiving node to propagate the written
data stably, before replying to the client.</t>
            <t>In the corresponding cases in which unstable writes are done, the
receiving node does not have any such obligation, although it may
choose to asynchronously propagate the updates.  However, once a
COMMIT is replied to, all replicas <bcp14>MUST</bcp14> reflect the writes that
have been done, and this data <bcp14>MUST</bcp14> have been committed to stable
storage on all replicas.</t>
            <t>In order to avoid situations in which stale data is read from
replicas to which writes have not been propagated:</t>
            <ul spacing="normal">
              <li>
                <t>A client that has outstanding unstable writes made to single
node (metadata server or storage device) <bcp14>MUST</bcp14> do all reads from
that same node.</t>
              </li>
              <li>
                <t>When writes are flushed to the server (for example, to implement
close-to-open semantics), a COMMIT must be done by the client
to ensure that up-to-date written data will be available
irrespective of the particular replica read.</t>
              </li>
            </ul>
          </section>
        </section>
        <section anchor="sec-mds-resilvering">
          <name>Metadata Server Resilvering of the File</name>
          <t>The metadata server may elect to create a new mirror of the layout
segments at any time.  This might be to resilver a copy on a storage
device that was down for servicing, to provide a copy of the layout
segments on storage with different storage performance characteristics,
etc.  As the client will not be aware of the new mirror and the
metadata server will not be aware of updates that the client is
making to the layout segments, the metadata server <bcp14>MUST</bcp14> recall the
writable layout segment(s) that it is resilvering.  If the client
issues a LAYOUTGET for a writable layout segment that is in the
process of being resilvered, then the metadata server can deny that
request with an NFS4ERR_LAYOUTUNAVAILABLE.  The client would then
have to perform the I/O through the metadata server.</t>
        </section>
      </section>
      <section anchor="erasure-coding">
        <name>Erasure Coding</name>
        <t>Erasure coding takes a data block and transforms it to a payload
to send to the data servers (see <xref target="fig-encoding-data-block"/>).  It
generates a metadata header and transformed block per data server.
The header is metadata information for the transformed block.  From
now on, the metadata is simply referred to as the header and the
transformed block as the chunk.  The payload of a data block is the
set of generated headers and chunks for that data block.</t>
        <t>The guard is an unique identifier generated by the client to describe
the current write transaction (see <xref target="sec-chunk_guard4"/>).  The
intent is to have a unique and non-opaque value for comparison.
The payload_id describes the position within the payload.  Finally,
the checksum carries a 32-bit CRC computed over the header and the
chunk.  Because the checksum field is itself part of the header, the
computation treats the bytes of that field as zero so that the
result is independent of the field's wire value; the writer then
stores the computed CRC into the checksum field for transmission.
To validate on the read path, the receiver saves the received
checksum, treats those bytes as zero, recomputes the CRC over the
header and chunk, and compares against the saved value.  By
combining the two parts of the payload in the CRC, integrity is
ensured for both parts.</t>
        <t>While the data block might have a length of 4kB, that does not
necessarily mean that the length of the chunk is 4kB.  That length
is determined by the erasure coding type algorithm.  For example,
Reed Solomon might have 4kB chunks with the data integrity being
compromised by parity chunks.  Another example would be the Mojette
Transformation, which might have 1kB chunk lengths.</t>
        <t>The payload contains redundancy which will allow the erasure
coding type algorithm to repair chunks in the payload as it is
transformed back to a data block (see <xref target="fig-decoding-db"/>).</t>
        <t>The protocol provides two levels of payload integrity, consumed at
different points in the read path:</t>
        <dl>
          <dt>Atomicity:</dt>
          <dd>
            <t>A payload is <strong>atomic</strong> when all of the chunks that belong
to it carry the same chunk_guard4 value (see
<xref target="sec-chunk_guard4"/>).  Atomicity alone does NOT imply the
bytes are free of corruption; it means only that every chunk in
the payload came from one write transaction.  A reader detects
a non-atomic payload (a torn read across writes) when it
assembles a payload and finds differing chunk_guard4 values
across chunks.</t>
          </dd>
          <dt>Integrity:</dt>
          <dd>
            <t>A payload has <strong>integrity</strong> when it is atomic AND every
contained chunk passes its checksum check.  Integrity is the
precondition for returning the payload's data block to the
application.</t>
          </dd>
        </dl>
        <t>The separation matters because the two checks detect different
failure modes.  Atomicity detects protocol-level failures (racing
writers, partial writes, rollback windows); the checksum detects
byte-level corruption (network errors, media errors, software bugs
in the erasure transform).  Neither subsumes the other.</t>
        <t>The two-level integrity model also reflects a deeper property of
distributed writes: <strong>last-writer-wins does not apply to a payload
spread across independent data servers.</strong>  The ordering of writes
arriving at one data server may differ from the ordering arriving
at another; the "last" write on one data server may well be the
"first" on another.  The chunk_guard4 CAS primitive (see
<xref target="sec-chunk_guard4"/>) resolves this by serializing concurrent
writers per chunk rather than by imposing a global order.</t>
        <t>The erasure coding algorithm itself might not be sufficient to
detect all byte-level errors in the chunks.  The checksum checks
allow the data server to detect chunks with integrity issues; the
erasure decoding algorithm can then reconstruct the affected
chunks from the remaining integral chunks in the payload.</t>
        <section anchor="encoding-a-data-block">
          <name>Encoding a Data Block</name>
          <figure anchor="fig-encoding-data-block">
            <name>Encoding a Data Block</name>
            <artwork><![CDATA[
                 +-------------+
                 | data block  |
                 +-------+-----+
                         |
                         |
   +---------------------+-------------------------------+
   |            Erasure Encoding (Transform Forward)     |
   +---+----------------------+---------------------+----+
       |                      |                     |
       |                      |                     |
   +---+------------+     +---+------------+     +--+-------------+
   | HEADER         | ... | HEADER         | ... | HEADER         |
   +----------------+     +----------------+     +----------------+
   | guard:         | ... | guard:         | ... | guard:         |
   |   gen_id   : 3 | ... |   gen_id   : 3 | ... |   gen_id   : 3 |
   |   client_id: 6 | ... |   client_id: 6 | ... |   client_id: 6 |
   | payload_id : 0 | ... | payload_id : M | ... | payload_id : 5 |
   | checksum   :      | ... | checksum   :      | ... | checksum   :      |
   +----------------+     +----------------+     +----------------+
   | CHUNK          | ... | CHUNK          | ... | CHUNK          |
   +----------------+     +----------------+     +----------------+
   | data: ....     | ... | data: ....     | ... | data: ....     |
   +----------------+     +----------------+     +----------------+
     Data Server 1          Data Server N          Data Server 6
]]></artwork>
          </figure>
          <t>Each data block of the file resident in the client's cache of the
file will be encoded into N different payloads to be sent to the
data servers as shown in <xref target="fig-encoding-data-block"/>.  As CHUNK_WRITE
(see <xref target="sec-CHUNK_WRITE"/>) can encode multiple write_chunk4 into a
single transaction, a more accurate description of a CHUNK_WRITE
is in <xref target="fig-example-chunk-write-args"/>.</t>
          <figure anchor="fig-example-chunk-write-args">
            <name>Example of CHUNK_WRITE_args</name>
            <artwork><![CDATA[
  +------------------------------------+
  | CHUNK_WRITEargs                    |
  +------------------------------------+
  | cwa_stateid: 0                     |
  | cwa_offset: 1                      |
  | cwa_stable: FILE_SYNC4             |
  | cwa_payload_id: 0                  |
  | cwa_owner:                         |
  |            co_guard:               |
  |                cg_gen_id   : 3     |
  |                cg_client_id: 6     |
  | cwa_chunk_size  :  1048            |
  | cwa_checksums:                        |
  |         [0]:  0x32ef89             |
  |         [1]:  0x56fa89             |
  |         [2]:  0x7693af             |
  | cwa_chunks  :  ......              |
  +------------------------------------+
]]></artwork>
          </figure>
          <t>This describes a 3 block write of data from an offset of 1 block
in the file.  As each block shares the cwa_owner, it is only presented
once.  I.e., the data server will be able to construct the header
for the i'th chunk from the cwa_chunks from the cwa_payload_id, the
cwa_owner, and the i'th checksum from the cwa_checksums.  The cwa_chunks
are sent together as a byte stream to increase performance.</t>
          <t>Assuming that there were no issues, <xref target="fig-example-chunk-write-res"/>
illustrates the results.  The payload sequence id is implicit in
the CHUNK_WRITEargs.</t>
          <figure anchor="fig-example-chunk-write-res">
            <name>Example of CHUNK_WRITE_res</name>
            <artwork><![CDATA[
  +-------------------------------+
  | CHUNK_WRITEresok              |
  +-------------------------------+
  | cwr_count: 3                  |
  | cwr_committed: FILE_SYNC4     |
  | cwr_writeverf: 0xf1234abc     |
  | cwr_owners[0]:                |
  |        co_chunk_id: 1         |
  |        co_guard:              |
  |            cg_gen_id   : 3    |
  |            cg_client_id: 6    |
  | cwr_owners[1]:                |
  |        co_chunk_id: 2         |
  |        co_guard:              |
  |            cg_gen_id   : 3    |
  |            cg_client_id: 6    |
  | cwr_owners[2]:                |
  |        co_chunk_id: 3         |
  |        co_guard:              |
  |            cg_gen_id   : 3    |
  |            cg_client_id: 6    |
  +-------------------------------+
]]></artwork>
          </figure>
          <section anchor="worked-example-calculating-the-crc32">
            <name>Worked Example: Calculating the CRC32</name>
            <t>The examples in this section and in
<xref target="sec-checking-crc32"/> illustrate checksum computation
and verification using CHECKSUM_ALG_CRC32 as the worked
algorithm.  Other registered checksum algorithms
(CHECKSUM_ALG_CRC32C, CHECKSUM_ALG_FLETCHER4,
CHECKSUM_ALG_SHA256, CHECKSUM_ALG_SHA512,
CHECKSUM_ALG_BLAKE3; see <xref target="sec-checksum4"/>) follow the same
pattern -- the algorithm names a function over the header
and chunk bytes, the writer fills cs_value with the
computed output, and the reader recomputes and compares.
Only the algorithm and the cs_value length differ.</t>
            <figure anchor="fig-calc-before">
              <name>CRC32 Before Calculation</name>
              <artwork><![CDATA[
  +--------------------+
  | HEADER             |
  +--------------------+
  | guard:             |
  |   gen_id   : 7     |
  |   client_id: 6     |
  | payload_id : 0     |
  | crc32   : 0        |
  +--------------------+
  | CHUNK              |
  +--------------------+
  | data:  ....        |
  +--------------------+
        Data Server 1
]]></artwork>
            </figure>
            <t>Assuming the header and payload as in <xref target="fig-calc-before"/>, the crc32
needs to be calculated in order to fill in the cwa_checksums entry field.  In
this case, the crc32 is calculated over the 4 fields as shown in
the header and the cw_chunk.  In this example, it is calculated to
be 0x21de8.  The resulting CHUNK_WRITE is shown in <xref target="fig-calc-crc-after"/>.</t>
            <figure anchor="fig-calc-crc-after">
              <name>CRC32 After Calculation</name>
              <artwork><![CDATA[
  +------------------------------------+
  | CHUNK_WRITEargs                    |
  +------------------------------------+
  | cwa_stateid: 0                     |
  | cwa_offset: 1                      |
  | cwa_stable: FILE_SYNC4             |
  | cwa_payload_id: 0                  |
  | cwa_owner:                         |
  |            co_guard:               |
  |                cg_gen_id   : 7     |
  |                cg_client_id: 6     |
  | cwa_chunk_size  :  1048            |
  | cwa_checksums:                        |
  |         [0]:  0x21de8              |
  | cwa_chunks  :  ......              |
  +------------------------------------+
]]></artwork>
            </figure>
          </section>
        </section>
        <section anchor="decoding-a-data-block">
          <name>Decoding a Data Block</name>
          <figure anchor="fig-decoding-db">
            <name>Decoding a Data Block</name>
            <artwork><![CDATA[
    Data Server 1          Data Server N          Data Server 6
  +----------------+     +----------------+     +----------------+
  | HEADER         | ... | HEADER         | ... | HEADER         |
  +----------------+     +----------------+     +----------------+
  | guard:         | ... | guard:         | ... | guard:         |
  |   gen_id   : 3 | ... |   gen_id   : 3 | ... |   gen_id   : 3 |
  |   client_id: 6 | ... |   client_id: 6 | ... |   client_id: 6 |
  | payload_id : 0 | ... | payload_id : M | ... | payload_id : 5 |
  | crc32   :      | ... | crc32   :      | ... | crc32   :      |
  +----------------+     +----------------+     +----------------+
  | CHUNK          | ... | CHUNK          | ... | CHUNK          |
  +----------------+     +----------------+     +----------------+
  | data: ....     | ... | data: ....     | ... | data: ....     |
  +---+------------+     +--+-------------+     +-+--------------+
      |                     |                     |
      |                     |                     |
  +---+---------------------+---------------------+-----+
  |            Erasure Decoding (Transform Reverse)     |
  +---------------------+-------------------------------+
                        |
                        |
                +-------+-----+
                | data block  |
                +-------------+
]]></artwork>
          </figure>
          <t>When reading chunks via a CHUNK_READ operation, the client will
decode them into data blocks as shown in <xref target="fig-decoding-db"/>.</t>
          <t>At this time, the client could detect issues in the integrity of
the data.  The handling and repair are out of the scope of this
document and <bcp14>MUST</bcp14> be addressed in the document describing each
erasure coding type.</t>
          <section anchor="sec-checking-crc32">
            <name>Worked Example: Checking the CRC32</name>
            <figure anchor="fig-example-chunk-read-crc">
              <name>CRC32 on the Wire</name>
              <artwork><![CDATA[
  +------------------------------------+
  | CHUNK_READresok                    |
  +------------------------------------+
  | crr_eof: false                     |
  | crr_chunks[0]:                     |
  |        cr_checksum: 0x21de8             |
  |        cr_owner:                   |
  |            co_guard:               |
  |                cg_gen_id   : 7     |
  |                cg_client_id: 6     |
  |        cr_chunk  :  ......         |
  +------------------------------------+
]]></artwork>
            </figure>
            <t>Assuming the CHUNK_READ results as in <xref target="fig-example-chunk-read-crc"/>,
the crc32 needs to be checked in order to ensure data integrity.
Conceptually, a header and payload can be built as shown in
<xref target="fig-example-crc-checked"/>.  The crc32 is calculated over the 4
fields as shown in the header and the cr_chunk.  In this example,
it is calculated to be 0x21de8.  Thus this payload for the data
server has data integrity.</t>
            <figure anchor="fig-example-crc-checked">
              <name>CRC32 Being Checked</name>
              <artwork><![CDATA[
  +--------------------+
  | HEADER             |
  +--------------------+
  | guard:             |
  |   gen_id   : 7     |
  |   client_id: 6     |
  | payload_id  : 0    |
  | crc32    : 0       |
  +--------------------+
  | CHUNK              |
  +--------------------+
  | data:  ....        |
  +--------------------+
       Data Server 1
]]></artwork>
            </figure>
          </section>
        </section>
        <section anchor="write-modes">
          <name>Write Modes</name>
          <t>There are two basic writing modes for erasure coding and they depend
on the metadata server using FFV2_FLAGS_ONLY_ONE_WRITER in the
ffv2l_flags in the ffv2_layout4 (see <xref target="fig-ffv2_layout4"/>) to inform
the client whether it is the only writer to the file or not.  If
it is the only writer, then CHUNK_WRITE with the cwa_guard not set
can be used to write chunks.  In this scenario, there is no write
contention, but write holes can occur as the client overwrites old
data.  Thus the client does not need guarded writes, but it does
need the ability to rollback writes.  If it is not the only writer,
then CHUNK_WRITE with the cwa_guard set <bcp14>MUST</bcp14> be used to write chunks.
In this scenario, the write holes can also be caused by multiple
clients writing to the same chunk.  Thus the client needs guarded
writes to prevent over writes and it does need the ability to
rollback writes.</t>
          <t>In both modes, clients <bcp14>MUST NOT</bcp14> overwrite payloads which already
contain non-atomicity.  This directly follows from <xref target="sec-reading-chunks"/>
and <bcp14>MUST</bcp14> be handled as discussed there.  Once atomicity in the
payload has been detected, the client can use those chunks as a
basis for read/modify/update.</t>
          <t>CHUNK_WRITE is a two pass operation in cooperation with CHUNK_FINALIZE
(<xref target="sec-CHUNK_FINALIZE"/>) and CHUNK_ROLLBACK (<xref target="sec-CHUNK_ROLLBACK"/>).
It writes to the data file and the data server is responsible for
retaining a copy of the old header and chunk. A subsequent CHUNK_READ
would return the new chunk. However, until either the CHUNK_FINALIZE
or CHUNK_ROLLBACK is presented, a subsequent CHUNK_WRITE <bcp14>MUST</bcp14> result
in the locking of the chunk, as if a CHUNK_LOCK (<xref target="sec-CHUNK_LOCK"/>)
had been performed on the chunk. As such, further CHUNK_WRITES by
any client <bcp14>MUST</bcp14> be denied until the chunk is unlocked by CHUNK_UNLOCK
(<xref target="sec-CHUNK_UNLOCK"/>).</t>
          <t>If the CHUNK_WRITE results in a atomic data block, then the
client will send a CHUNK_FINALIZE in a subsequent compound to inform
the data server that the chunk is finalized and can be overwritten
by another CHUNK_WRITE.</t>
          <t>If the CHUNK_WRITE results in an non-atomic data block, or if the
data server returns NFS4ERR_CHUNK_LOCKED, the client reports the
condition to the metadata server via LAYOUTERROR with an error code
of NFS4ERR_PAYLOAD_NOT_ATOMIC.</t>
        </section>
        <section anchor="sec-repair-selection">
          <name>Selecting the Repair Client</name>
          <t>The repair topology involves three actors communicating along
distinct paths, as shown in <xref target="fig-repair-topology"/>.</t>
          <figure anchor="fig-repair-topology">
            <name>Repair topology</name>
            <artwork><![CDATA[
     +-------------+      (1)         +-----------------+
     |  Reporting  | ---------------> |                 |
     |  client     |   LAYOUTERROR    |       MDS       |
     |  (detects   |                  |                 |
     |  error)     |                  |                 |
     +-------------+                  +--------+--------+
                                               |
                                               | (2b)
                                               | CB_CHUNK_REPAIR
                                               | (RACE or SCRUB)
                                               v
     +-------------+      (4)         +-----------------+
     |  Repair     | ---------------> |      DSes       |
     |  client     |    CHUNK_*       |  (mirror set    |
     |  (selected  |                  |  for affected   |
     |  per (2a),  |                  |  ranges)        |
     |  adopts     |                  |                 |
     |  lock (3))  |                  |                 |
     +-------------+                  +-----------------+

     (1)   Reporting client LAYOUTERRORs the metadata server.
     (2a)  Metadata server selects a repair client (may be same
           as the reporting client).
     (2b)  Metadata server escrows the chunk lock and issues
           CB_CHUNK_REPAIR to the selected repair client.
     (3)   Repair client adopts the lock and drives the repair.
     (4)   Repair client issues CHUNK_LOCK_ADOPT, CHUNK_WRITE_REPAIR,
           CHUNK_FINALIZE, CHUNK_COMMIT, and CHUNK_REPAIRED against
           the mirror set.
]]></artwork>
          </figure>
          <t>The metadata server is the authority that selects which client
(or, in a tightly coupled deployment, which data server) repairs
an non-atomic payload.  This is analogous to the way the
metadata server assigns per-mirror priority via ffv2ds_efficiency
(see <xref target="sec-select-mirror"/>): the protocol does not prescribe the
selection algorithm, and each deployment <bcp14>MAY</bcp14> tune its policy.</t>
          <t>Implementations <bcp14>MAY</bcp14> consider factors such as:</t>
          <ul spacing="normal">
            <li>
              <t>Whether a client holds an active write layout on the affected
payload (the client most likely to hold surviving shards in
cache).</t>
            </li>
            <li>
              <t>Whether a client has previously reported atomic shards to
the metadata server via LAYOUTSTATS or a prior LAYOUTERROR.</t>
            </li>
            <li>
              <t>Whether the layout exposes a data server carrying
FFV2_DS_FLAGS_REPAIR as a target for reconstructed shards.</t>
            </li>
            <li>
              <t>Network proximity, observed latency, or recent client load --
the same class of information that informs ffv2ds_efficiency.</t>
            </li>
          </ul>
          <t>The selection algorithm is not normative.  What is normative is
that every client <bcp14>MUST</bcp14> be prepared to:</t>
          <ol spacing="normal" type="1"><li>
              <t>Receive a repair request for a payload that the client does
not have an outstanding write layout on, and did not write;
and</t>
            </li>
            <li>
              <t>Continue its own workload after reporting
NFS4ERR_PAYLOAD_NOT_ATOMIC without itself being selected
to repair the payload it reported.</t>
            </li>
          </ol>
          <t>The metadata server signals the selected client via the
CB_CHUNK_REPAIR callback (<xref target="sec-CB_CHUNK_REPAIR"/>), which
identifies the file, the affected ranges (each with its own
triggering nfsstat4), and a wall-clock deadline.  A client that
receives CB_CHUNK_REPAIR for a file for which it does not
already hold a layout <bcp14>MUST</bcp14> acquire a layout via LAYOUTGET before
attempting the repair.</t>
          <t>Operational expectations for CB_CHUNK_REPAIR:
CB_CHUNK_REPAIR is an exceptional path, triggered only by
concurrent-writer races or data-server failures.  It is not a
steady-state operation and its frequency is a function of
racing-writer and data-server-failure rates in the deployment
rather than of normal client workload.  Implementations <bcp14>SHOULD</bcp14>
treat the CB_CHUNK_REPAIR handler as rare-path code and avoid
over-optimising it.  Implementations <bcp14>SHOULD</bcp14>, however, provision
enough client-side compute to handle a repair transaction
without stalling their foreground I/O, because foreground
throughput during repair is the externally observable cost of
this callback.</t>
        </section>
        <section anchor="repair-protocol-normative-vs-informative">
          <name>Repair Protocol: Normative vs. Informative</name>
          <t>The selection algorithm is non-normative and deployment-tunable.
The externally-observable state transitions of the repair flow
are normative.  The line between the two is drawn at what
another party on the wire -- the metadata server, another
client, a reader -- can observe.  What no other party can see
(client-internal ordering, retry policy, whether to CHUNK_READ
first to confirm the failure) is left to implementations.</t>
          <t>The following requirements are normative.  An implementation
that violates any of these can leak inconsistency or write-holes
into the cluster:</t>
          <dl>
            <dt>Final state flat:</dt>
            <dd>
              <t>Every shard in every range identified
in a CB_CHUNK_REPAIR <bcp14>MUST</bcp14> reach either the COMMITTED state
(repaired) or the EMPTY state (rolled back).  No shard is
left in PENDING or FINALIZED indefinitely.</t>
            </dd>
            <dt>Lock before write:</dt>
            <dd>
              <t>The repair client <bcp14>MUST</bcp14> adopt the
lock on every affected range via CHUNK_LOCK with
CHUNK_LOCK_FLAGS_ADOPT (<xref target="sec-CHUNK_LOCK"/>) before issuing
any CHUNK_WRITE_REPAIR, CHUNK_ROLLBACK, or CHUNK_WRITE on a
chunk in that range.  The lock on the affected chunks is
held continuously from the failure that triggered
CB_CHUNK_REPAIR through the adoption; at no point is the
range unlocked.</t>
            </dd>
            <dt>Clear the errored state:</dt>
            <dd>
              <t>On the reconstruction path,
the repair client <bcp14>MUST</bcp14> issue CHUNK_REPAIRED
(<xref target="sec-CHUNK_REPAIRED"/>) after CHUNK_COMMIT.  Without it,
readers continue to see holes regardless of on-disk state.</t>
            </dd>
            <dt>Release locks explicitly:</dt>
            <dd>
              <t>CHUNK_ROLLBACK does not
release chunk locks.  On the rollback path the client <bcp14>MUST</bcp14>
issue CHUNK_UNLOCK (<xref target="sec-CHUNK_UNLOCK"/>) on each affected
chunk.  A client that walks away without either completing
CHUNK_REPAIRED or issuing CHUNK_UNLOCK holds the locks
until lease expiry, blocking progress for other writers.</t>
            </dd>
            <dt>Deadline honored:</dt>
            <dd>
              <t>The client <bcp14>MUST</bcp14> drive every range to
its final flat state before ccra_deadline, or <bcp14>MUST</bcp14> respond
to the CB_CHUNK_REPAIR with NFS4ERR_DELAY (requesting an
extension), NFS4ERR_CODING_NOT_SUPPORTED (declining), or
NFS4ERR_PAYLOAD_LOST (declaring the data unrecoverable).
A deadline that elapses without any of these leaves the
metadata server free to re-select; the client <bcp14>MUST NOT</bcp14>
continue repair-related CHUNK operations after the
deadline without first re-verifying its layout and the
chunk lock state.</t>
            </dd>
            <dt>Terminal return codes:</dt>
            <dd>
              <t>NFS4ERR_CODING_NOT_SUPPORTED
<bcp14>MUST</bcp14> mean "decline; select another client."
NFS4ERR_PAYLOAD_LOST <bcp14>MUST</bcp14> mean "the data is not
recoverable; do not retry."  The metadata server relies on
these to decide whether to re-issue.</t>
            </dd>
          </dl>
          <t>The following aspects are informative / implementation-defined:</t>
          <ul spacing="normal">
            <li>
              <t>Choice between the reconstruction path (CHUNK_WRITE_REPAIR)
and the rollback path (CHUNK_ROLLBACK) on a given range.  The
protocol <bcp14>MUST</bcp14> support both; the client <bcp14>MAY</bcp14> use either based
on its local state and whether reconstruction is feasible
from surviving shards.</t>
            </li>
            <li>
              <t>Ordering among multiple affected ranges in a single
CB_CHUNK_REPAIR (parallel or serial).</t>
            </li>
            <li>
              <t>Whether to issue CHUNK_READ to confirm the failure mode
before reconstructing.</t>
            </li>
            <li>
              <t>Retry policy on transient CHUNK_WRITE_REPAIR errors below the
deadline cutoff.</t>
            </li>
            <li>
              <t>How the repair status is surfaced to local filesystem API
callers.</t>
            </li>
          </ul>
        </section>
        <section anchor="carrying-out-the-repair">
          <name>Carrying Out the Repair</name>
          <t>With the normative framing above, the reconstruction path is:</t>
          <ol spacing="normal" type="1"><li>
              <t>CHUNK_LOCK with CHUNK_LOCK_FLAGS_ADOPT on each affected
range (<xref target="sec-CHUNK_LOCK"/>).</t>
            </li>
            <li>
              <t>CHUNK_WRITE_REPAIR (<xref target="sec-CHUNK_WRITE_REPAIR"/>) with the
reconstructed data for each non-atomic shard.  The
client's chunk_owner4 on this and all subsequent operations
is the one it presented in the CHUNK_LOCK ADOPT above;
prior owners' generation ids are now historical.</t>
            </li>
            <li>
              <t>CHUNK_FINALIZE (<xref target="sec-CHUNK_FINALIZE"/>) and CHUNK_COMMIT
(<xref target="sec-CHUNK_COMMIT"/>) to persist the repaired shards.</t>
            </li>
            <li>
              <t>CHUNK_REPAIRED (<xref target="sec-CHUNK_REPAIRED"/>) to clear the
errored state.</t>
            </li>
          </ol>
          <t>The rollback path, when reconstruction is not possible:</t>
          <ol spacing="normal" type="1"><li>
              <t>CHUNK_LOCK with CHUNK_LOCK_FLAGS_ADOPT on each affected
range.</t>
            </li>
            <li>
              <t>CHUNK_ROLLBACK (<xref target="sec-CHUNK_ROLLBACK"/>) on each affected
shard to restore the previously committed content.</t>
            </li>
            <li>
              <t>CHUNK_UNLOCK (<xref target="sec-CHUNK_UNLOCK"/>) on each shard.</t>
            </li>
          </ol>
          <t>In both paths, the repair client <bcp14>SHOULD</bcp14> target reconstructed
shards according to the following fallback order: first, any
data server in the layout carrying FFV2_DS_FLAGS_REPAIR; then
the data server that reported the failure (the one carrying the
failing shard at the range identified by ccr_offset and ccr_count
in the CB_CHUNK_REPAIR argument); then, if both of the above are
unreachable, a data server carrying FFV2_DS_FLAGS_SPARE.  If
none of the above are available, the client <bcp14>MUST</bcp14> return
NFS4ERR_PAYLOAD_LOST on the CB_CHUNK_REPAIR response.</t>
          <section anchor="single-writer-mode">
            <name>Single Writer Mode</name>
            <t>In single writer mode, the metadata server sets FFV2_FLAGS_ONLY_ONE_WRITER
in ffv2l_flags, indicating that no other client holds a write layout for
the file.  The client sends CHUNK_WRITE with cwa_guard.cwg_check set to
FALSE, omitting the guard value.  Because only one writer is active,
there is no risk of two clients overwriting the same chunk concurrently.</t>
            <t>The single writer write sequence is:</t>
            <ol spacing="normal" type="1"><li>
                <t>The client issues CHUNK_WRITE (cwa_guard.cwg_check = FALSE) for each
shard.  The data server places the written block in the PENDING state
and retains a copy of the previous block for rollback.</t>
              </li>
              <li>
                <t>The client issues CHUNK_FINALIZE to advance the blocks from PENDING
to FINALIZED, validating the per-block checksum.</t>
              </li>
              <li>
                <t>The client issues CHUNK_COMMIT to advance the blocks from FINALIZED
to COMMITTED, persisting the block metadata to stable storage.</t>
              </li>
            </ol>
            <t>If the client detects an error after CHUNK_WRITE but before CHUNK_FINALIZE
(e.g., a CRC mismatch on a subsequent CHUNK_READ), it issues CHUNK_ROLLBACK
to restore the previous block content.  CHUNK_ROLLBACK does not lock the
chunk; the next CHUNK_WRITE is permitted immediately.</t>
          </section>
          <section anchor="repairing-single-writer-payloads">
            <name>Repairing Single Writer Payloads</name>
            <t>In single writer mode, non-atomic blocks arise from a client or data
server failure during a CHUNK_WRITE / CHUNK_FINALIZE sequence.  Because
no other writer is active, the original writer is the typical choice
for repair, but the metadata server <bcp14>MAY</bcp14> designate any client according
to the rules in <xref target="sec-repair-selection"/>.  A designated client that
did not originate the writes <bcp14>MUST</bcp14> follow the rollback path of that
section if it cannot reconstruct the payload from surviving shards.</t>
            <t>The repair sequence when the selected client is the original writer is:</t>
            <ol spacing="normal" type="1"><li>
                <t>The repair client issues CHUNK_READ to identify which blocks are in a
failed state (PENDING with a CRC mismatch, or in the errored state
set by a prior CHUNK_ERROR).</t>
              </li>
              <li>
                <t>For each errored chunk, the repair client reconstructs the correct
data using the erasure coding algorithm (RS matrix inversion or Mojette
back-projection) from the surviving atomic chunks (treating each
chunk's payload as a shard of the stripe).</t>
              </li>
              <li>
                <t>The repair client issues CHUNK_WRITE_REPAIR (<xref target="sec-CHUNK_WRITE_REPAIR"/>)
to write the reconstructed data.  CHUNK_WRITE_REPAIR bypasses the guard
check and applies different data server policies (e.g., allowing writes
to blocks in the errored state).</t>
              </li>
              <li>
                <t>The repair client issues CHUNK_FINALIZE and CHUNK_COMMIT to persist the
repaired blocks.</t>
              </li>
              <li>
                <t>The repair client issues CHUNK_REPAIRED (<xref target="sec-CHUNK_REPAIRED"/>) to
clear the errored state and make the blocks available for normal reads.</t>
              </li>
            </ol>
          </section>
          <section anchor="sec-swm-to-mwm">
            <name>Transitioning from Single Writer Mode to Multiple Writer Mode</name>
            <t>When a second writer requests a write layout for a file currently
covered by a single-writer layout (FFV2_FLAGS_ONLY_ONE_WRITER set),
the metadata server recalls the existing layout before granting
the new request.  The sequence is:</t>
            <ol spacing="normal" type="1"><li>
                <t>The metadata server issues CB_LAYOUTRECALL to the single-writer
client.</t>
              </li>
              <li>
                <t>The single-writer client drains its outstanding I/O issued
under the single-writer assumption (CHUNK_WRITE with
cwa_guard.cwg_check = FALSE).  Operations already underway
complete under the layout that authorized them: CHUNK_FINALIZE
and CHUNK_COMMIT proceed normally for blocks already written.</t>
              </li>
              <li>
                <t>Once drained, the single-writer client issues LAYOUTRETURN.</t>
              </li>
              <li>
                <t>The metadata server grants the new writer a layout without
FFV2_FLAGS_ONLY_ONE_WRITER set.  When the original writer next
issues LAYOUTGET, it also receives a layout without the flag.
Both clients then operate in multiple writer mode
(<xref target="sec-multi-writer"/>), supplying cwa_guard.cwg_check = TRUE
and a chunk_guard4 on every CHUNK_WRITE.</t>
              </li>
            </ol>
            <t>The transition uses standard NFSv4.1 layout recall semantics
(Section 12.5.5 of <xref target="RFC8881"/>).  Drained single-writer I/O does
not need to be re-issued under multiple writer rules; it
completed under the layout that authorized it.  If the
single-writer client fails to return the layout within the
recall window, the metadata server escalates to layout
revocation (Section 12.5.5.2.1 of <xref target="RFC8881"/>); any single-writer
writes that did not complete before revocation are repaired via
the multiple-writer repair path on subsequent access.</t>
          </section>
          <section anchor="sec-multi-writer">
            <name>Multiple Writer Mode</name>
            <t>In multiple writer mode, the metadata server does not set
FFV2_FLAGS_ONLY_ONE_WRITER, indicating that concurrent writers may hold
write layouts for the file.  The client sends CHUNK_WRITE with
cwa_guard.cwg_check set to TRUE, supplying a chunk_guard4 in cwa_guard.cwg_guard
that uniquely identifies this write transaction across all data servers.</t>
            <t>The multiple writer write sequence is:</t>
            <ol spacing="normal" type="1"><li>
                <t>The client selects a unique chunk_guard4 for this transaction.  The
cg_client_id identifies the client (derived from the client's
clientid4); the cg_gen_id is a per-client generation counter
incremented for each new transaction.</t>
              </li>
              <li>
                <t>The client issues CHUNK_WRITE (cwa_guard.cwg_check = TRUE) for each
chunk.  The data server checks that no other client's chunk is in the
PENDING state at this offset.  If another client's chunk is already
pending, the data server returns NFS4ERR_CHUNK_LOCKED with the
clr_owner field identifying the lock holder.</t>
              </li>
              <li>
                <t>On NFS4ERR_CHUNK_LOCKED, the client <bcp14>MUST</bcp14> back off.  It issues
CHUNK_ROLLBACK for any chunks it has already written in this
transaction, then retries after a delay.</t>
              </li>
              <li>
                <t>If all CHUNK_WRITEs succeed, the client issues CHUNK_FINALIZE and
CHUNK_COMMIT as in single writer mode.</t>
              </li>
            </ol>
            <t>The guard ensures that the chunks carrying the shards of an atomic
erasure-coded stripe all carry the same chunk_guard4.  A reader that
encounters chunks with different guard values knows the stripe is not
yet atomic and <bcp14>MUST</bcp14> either retry or report NFS4ERR_PAYLOAD_NOT_ATOMIC.</t>
          </section>
          <section anchor="sec-repair-multi-writer">
            <name>Repairing Multiple Writer Payloads</name>
            <t>In multiple writer mode, non-atomic chunks can arise from two sources:
a client failure leaving some chunks in PENDING state, or two clients
writing different data to the same chunk before one has committed.</t>
            <t>The metadata server coordinates repair by designating a repair
client according to the rules in <xref target="sec-repair-selection"/>.  The
FFV2_DS_FLAGS_REPAIR flag, when present on a data server in the
layout, identifies the target data server into which reconstructed
shards should be written; it does not by itself identify the
repair client.  The repair sequence is:</t>
            <ol spacing="normal" type="1"><li>
                <t>The repair client issues CHUNK_LOCK (<xref target="sec-CHUNK_LOCK"/>) on the
affected block range of each data server.  If any lock attempt returns
NFS4ERR_CHUNK_LOCKED, the repair client records the existing lock
holder's chunk_owner4 and proceeds; the lock holder's data is a
candidate for the winning payload.</t>
              </li>
              <li>
                <t>The repair client issues CHUNK_READ on all data servers to retrieve
the current payload.  It examines the chunk_owner4 of each shard to
identify which transaction (if any) produced a atomic set across
all k data shards.</t>
              </li>
              <li>
                <t>If a atomic set is found (all k data shards carry the same
chunk_guard4), that payload is the winner.  The repair client issues
CHUNK_WRITE_REPAIR to copy the winner's data to any data servers whose
shard is non-atomic, followed by CHUNK_FINALIZE and CHUNK_COMMIT.</t>
              </li>
              <li>
                <t>If no atomic set exists (all available payloads are partial), the
repair client selects one transaction's payload as authoritative
(typically the one with the most complete set of shards, or the most
recent cg_gen_id) and proceeds as above.</t>
              </li>
              <li>
                <t>After all data servers carry atomic, finalized, committed data, the
repair client issues CHUNK_REPAIRED to clear the errored state and
CHUNK_UNLOCK to release the locks acquired in step 1.</t>
              </li>
              <li>
                <t>The repair client reports success to the metadata server via
LAYOUTRETURN.</t>
              </li>
            </ol>
          </section>
          <section anchor="sec-mwm-to-swm">
            <name>Transitioning from Multiple Writer Mode to Single Writer Mode</name>
            <t>The reverse transition is optional.  When the metadata server
determines that only one writer holds a write layout for a file
(for example, because other writers' layouts have been returned or
their leases have expired), it <bcp14>MAY</bcp14> recall the remaining writer's
layout and grant a fresh layout with FFV2_FLAGS_ONLY_ONE_WRITER
set, restoring the single-writer optimization.  The metadata
server <bcp14>MAY</bcp14> also leave the writer in multiple writer mode
indefinitely; single writer mode is an optimization, not a
correctness requirement.</t>
            <t>The metadata server's choice of when to grant
FFV2_FLAGS_ONLY_ONE_WRITER is policy and is implementation-defined.
A metadata server that aggressively grants single writer mode and
then must recall it each time a second writer appears can produce
recall churn under workloads with irregular concurrent access:
each single-writer-to-multiple-writer transition costs a
CB_LAYOUTRECALL round trip and drain time for in-flight I/O.
Strategies to limit churn include withholding
FFV2_FLAGS_ONLY_ONE_WRITER until sustained single-writer behavior
is observed, deferring the single-writer grant after a recent
recall, or never granting single writer mode for files with a
history of concurrent access.</t>
          </section>
        </section>
        <section anchor="sec-reading-chunks">
          <name>Reading Chunks</name>
          <t>The client reads chunks from the data file via CHUNK_READ.  The
number of chunks in the payload that need to be atomic depend
on both the Erasure Coding Type and the level of protection selected.
If the client has enough atomic chunks in the payload, then it
can proceed to use them to build a data block.  If it does not have
enough atomic chunks in the payload, then it can either decide
to return a LAYOUTERROR of NFS4ERR_PAYLOAD_NOT_ATOMIC to the
metadata server or it can retry the CHUNK_READ until there are
enough atomic chunks in the payload.</t>
          <t>As another client might be writing to the chunks as they are being
read, it is entirely possible to read the chunks while they are not
atomic.  As such, it might even be the non-atomic chunks
which contain the new data and a better action than building the
data block is to retry the CHUNK_READ to see if new chunks are
overwritten.</t>
        </section>
        <section anchor="whole-file-repair">
          <name>Whole File Repair</name>
          <t>Whole-file repair is the case in which too many data servers have
failed, or too many chunks have been lost, for the per-range repair
flow defined in <xref target="sec-repair-selection"/> to reconstruct the file in
place.  In this case the metadata server <bcp14>MUST</bcp14> either:</t>
          <ol spacing="normal" type="1"><li>
              <t>Construct a new layout backed by replacement data servers and
drive the reconstruction via the <strong>Proxy Server</strong> mechanism (a
designated data server acts as the source of truth for client
I/O during the transition, pushing reconstructed content to the
replacement data servers in the background).  The Proxy Server mechanism also covers the non-repair cases where a file's layout
must change while remaining available to clients -- policy-driven layout transitions, data server maintenance evacuation,
administrative ingest, TLS coverage transition, and
filehandle-backend migration.</t>
            </li>
            <li>
              <t>If the metadata server has no proxy-server-capable data server
available, or the surviving shards are insufficient to
reconstruct any portion of the file, terminate the affected
byte ranges with NFS4ERR_PAYLOAD_LOST (see
<xref target="sec-NFS4ERR_PAYLOAD_LOST"/>).</t>
            </li>
          </ol>
          <t>The Proxy Server mechanism is specified in <xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>.</t>
          <t>Implementations that do not support the Proxy Server mechanism can
still perform recovery for cases where per-range repair suffices,
using CB_CHUNK_REPAIR (<xref target="sec-CB_CHUNK_REPAIR"/>) and the repair
client selection rules in <xref target="sec-repair-selection"/>.  Such
implementations will surface NFS4ERR_PAYLOAD_LOST on any failure
that exceeds per-range repair's reach, including the multi-data-server failure scenarios the Proxy Server mechanism is intended to
handle.</t>
        </section>
      </section>
      <section anchor="mixing-of-coding-types">
        <name>Mixing of Coding Types</name>
        <t>Multiple coding types can be present in a Flexible File Version 2
Layout Type layout.  The ffv2_layout4 has an array of ffv2_mirror4,
each of which has a ffv2_coding_type4.  Mixing coding types in a
single file's mirror set addresses several use cases:</t>
        <ul spacing="normal">
          <li>
            <t>Assimilation of a non-erasure-coded file into an erasure-coded
representation, or export of an erasure-coded file to a
non-erasure-coded representation.</t>
          </li>
          <li>
            <t>Online migration between encodings, for example from a
Reed-Solomon Vandermonde encoding to a Mojette systematic
encoding when a read-access-pattern change makes the new codec
a better fit.  Both representations remain addressable through
the layout throughout the transition.</t>
          </li>
          <li>
            <t>Cross-encoding recovery: when one encoding loses data to a
correlated failure mode (a codec implementation bug, a
memory-corruption pattern that affects parity shards
identically), a second mirror in a different encoding provides
an independent recovery surface.</t>
          </li>
          <li>
            <t>Client-capability routing: a Proxy Server
(<xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>) sees the full
mirror set and chooses between encodings on behalf of clients
that do not implement every codec the file is represented in.</t>
          </li>
        </ul>
        <t>Consider a layout that exposes a file in two encodings
simultaneously: a PASSTHROUGH mirror over the original byte
stream and a Reed-Solomon Vandermonde
(FFV2_ENCODING_RS_VANDERMONDE) mirror with 8 active data shards
(plus 2 parity and 2 spare data servers).  A layout for such a
file might appear as in <xref target="fig-example_mixing"/>.  Both
representations are active and addressable through the layout
simultaneously.  This is the transition-window pattern: a file
may transiently span encodings while it is being assimilated
from a non-FFv2 source or migrated between codecs.  Steady
state is homogeneous; the multi-encoding window is what the
protocol must accommodate.</t>
        <t>The active mirrors serve different access patterns concurrently:</t>
        <ul spacing="normal">
          <li>
            <t>A client that speaks only the file-layout READ path issues
READ (Section 18.22 of <xref target="RFC8881"/>) calls to index 0 (the
PASSTHROUGH mirror).</t>
          </li>
          <li>
            <t>A client that speaks the chunked path issues CHUNK_READ
(<xref target="sec-CHUNK_READ"/>) calls to index 1 (the RS_VANDERMONDE
mirror).</t>
          </li>
          <li>
            <t>A Proxy Server fronting legacy clients chooses between the two
encodings on the client's behalf
(<xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>).</t>
          </li>
        </ul>
        <t>All three patterns coexist during the transition.</t>
        <figure anchor="fig-example_mixing">
          <name>Example of Mixed Coding Types in a Layout</name>
          <artwork><![CDATA[
 +-----------------------------------------------------+
 | ffv2_layout4:                                       |
 +-----------------------------------------------------+
 |     ffv2l_mirrors[0]:                               |
 |         ffv2s_data_servers:                         |
 |             ffv2_data_server4[0]                    |
 |                 ffv2ds_flags: 0                     |
 |         ffv2m_coding: FFV2_ENCODING_PASSTHROUGH     |
 +-----------------------------------------------------+
 |     ffv2l_mirrors[1]:                               |
 |         ffv2s_data_servers:                         |
 |             ffv2_data_server4[0]                    |
 |                 ffv2ds_flags: FFV2_DS_FLAGS_ACTIVE  |
 |             ffv2_data_server4[1]                    |
 |                 ffv2ds_flags: FFV2_DS_FLAGS_ACTIVE  |
 |             ffv2_data_server4[2]                    |
 |                 ffv2ds_flags: FFV2_DS_FLAGS_ACTIVE  |
 |             ffv2_data_server4[3]                    |
 |                 ffv2ds_flags: FFV2_DS_FLAGS_ACTIVE  |
 |             ffv2_data_server4[4]                    |
 |                 ffv2ds_flags: FFV2_DS_FLAGS_PARITY  |
 |             ffv2_data_server4[5]                    |
 |                 ffv2ds_flags: FFV2_DS_FLAGS_PARITY  |
 |             ffv2_data_server4[6]                    |
 |                 ffv2ds_flags: FFV2_DS_FLAGS_SPARE   |
 |             ffv2_data_server4[7]                    |
 |                 ffv2ds_flags: FFV2_DS_FLAGS_SPARE   |
 |     ffv2m_coding: FFV2_ENCODING_RS_VANDERMONDE      |
 +-----------------------------------------------------+
]]></artwork>
        </figure>
        <t>When performing I/O via a FFV2<em>ENCODING_PASSTHROUGH coding type,
the non-transformed data will be used; whereas with the chunked
coding types (FFV2_ENCODING_MIRRORED, FFV2_ENCODING_MOJETTE</em>*,
FFV2_ENCODING_RS_VANDERMONDE), a metadata header and transformed
block will be sent.  Further, when reading data from the
instance files, the client <bcp14>MUST</bcp14> be prepared to have one of the
coding types supply data and the other type not to supply data.
I.e., the CHUNK_READ call to the data servers in mirror 1 might
return rlr_eof set to true (see <xref target="fig-read_chunk4"/>), which
indicates that there is no data, where the READ call to the
data server in mirror 0 might return eof to be false, which
indicates that there is data.  The client <bcp14>MUST</bcp14> determine that
there is in fact data.  An example use case is the active
assimilation of a file to ensure integrity.  As the client is
helping to translate the file to the new coding scheme, it is
actively modifying the file.  As such, it might be sequentially
reading the file in order to translate.  The READ calls to
mirror 0 would be returning data and the CHUNK_READ calls to
mirror 1 would not be returning data.  As the client overwrites
the file, the WRITE call and CHUNK_WRITE call would have data
sent to all of the data servers.  Finally, if the client reads
back a section which had been modified earlier, both the READ
and CHUNK_READ calls would return data.</t>
      </section>
      <section anchor="sec-rs-encoding">
        <name>Reed-Solomon Vandermonde Encoding (FFV2_ENCODING_RS_VANDERMONDE)</name>
        <section anchor="overview">
          <name>Overview</name>
          <t>Reed-Solomon (RS) codes are Maximum Distance Separable (MDS) codes:
for a (k+m, k) code, any k of the k+m encoded shards suffice to
recover the original data.  The code tolerates the simultaneous loss
of up to m shards.  <xref target="Plank97"/> is a tutorial treatment of RS
coding in RAID-like systems and is the recommended background
reading for implementers unfamiliar with the construction used
here.</t>
        </section>
        <section anchor="galois-field-arithmetic">
          <name>Galois Field Arithmetic</name>
          <t>All RS operations are performed over GF(2^8), the Galois field with
256 elements.  Each element is represented as a byte.</t>
          <dl>
            <dt>Irreducible Polynomial:</dt>
            <dd>
              <t>The field is constructed using the irreducible polynomial
x^8 + x^4 + x^3 + x^2 + 1 (0x11d in hexadecimal).  The primitive
element (generator) is g = 2, which has multiplicative order 255.</t>
            </dd>
            <dt>Addition:</dt>
            <dd>
              <t>Addition in GF(2^8) is bitwise XOR.</t>
            </dd>
            <dt>Multiplication:</dt>
            <dd>
              <t>Multiplication uses log/antilog tables.  For non-zero elements
a and b: a * b = exp(log(a) + log(b)), where the exp table is
doubled to 512 entries to avoid modular reduction on the index sum.</t>
            </dd>
          </dl>
          <t>These are the classical constructions from Berlekamp (1968) and
Peterson &amp; Weldon (1972).  The log/antilog table approach for GF(2^8)
multiplication predates all known patents on SIMD-accelerated GF
arithmetic.  Implementors considering SIMD acceleration of GF(2^8)
operations should be aware of US Patent 8,683,296 (StreamScale),
which covers certain SIMD-based GF multiplication techniques.</t>
        </section>
        <section anchor="encoding-matrix">
          <name>Encoding Matrix</name>
          <t>The encoding process uses a (k+m) x k Vandermonde matrix, normalized
so that its top k rows form the identity matrix:</t>
          <ol spacing="normal" type="1"><li>
              <t>Construct a (k+m) x k Vandermonde matrix V where V[i][j] = j^i
in GF(2^8).</t>
            </li>
            <li>
              <t>Extract the top k x k sub-matrix T from V.</t>
            </li>
            <li>
              <t>Compute T_inv = T^(-1) using Gaussian elimination in GF(2^8).</t>
            </li>
            <li>
              <t>Multiply: E = V * T_inv.  The result has an identity block on top
(rows 0 through k-1) and the parity generation matrix P on the
bottom (rows k through k+m-1).</t>
            </li>
          </ol>
          <t>The identity block makes the code systematic: data shards pass through
unchanged, and only the parity sub-matrix P is needed during encoding.</t>
        </section>
        <section anchor="encoding">
          <name>Encoding</name>
          <t>Given k data shards, each of shard_len bytes, encoding produces m
parity shards, each also shard_len bytes:</t>
          <artwork><![CDATA[
For each byte position j in [0, shard_len):
  For each parity shard i in [0, m):
    parity[i][j] = sum over s in [0, k) of P[i][s] * data[s][j]
]]></artwork>
          <t>where the sum and product are in GF(2^8).  All shards (data and
parity) are the same size.</t>
        </section>
        <section anchor="decoding">
          <name>Decoding</name>
          <t>When one or more shards are lost (up to m), reconstruction proceeds
by matrix inversion:</t>
          <ol spacing="normal" type="1"><li>
              <t>Select k available shards (from the k+m total).</t>
            </li>
            <li>
              <t>Form a k x k sub-matrix S of the encoding matrix E by selecting the
rows corresponding to the available shards.</t>
            </li>
            <li>
              <t>Compute S_inv = S^(-1) using Gaussian elimination in GF(2^8).</t>
            </li>
            <li>
              <t>Multiply S_inv by the vector of available shard data at each byte
position to recover the original k data shards.</t>
            </li>
            <li>
              <t>If any parity shards are also missing, regenerate them by
re-encoding from the recovered data shards.</t>
            </li>
          </ol>
          <t>The reconstruction cost is dominated by the matrix inversion, which
is O(k^2) in GF(2^8) multiplications.</t>
        </section>
        <section anchor="rs-interoperability-requirements">
          <name>RS Interoperability Requirements</name>
          <t>For two implementations of FFV2_ENCODING_RS_VANDERMONDE to
interoperate, they <bcp14>MUST</bcp14> agree on all of the following parameters.
Any deviation produces a different encoding matrix and renders
data unrecoverable by a different implementation.</t>
          <ul spacing="normal">
            <li>
              <t>Irreducible polynomial: x^8 + x^4 + x^3 + x^2 + 1 (0x11d)</t>
            </li>
            <li>
              <t>Primitive element: g = 2</t>
            </li>
            <li>
              <t>Vandermonde evaluation points: V[i][j] = j^i in GF(2^8)</t>
            </li>
            <li>
              <t>Matrix normalization: E = V * (V[0..k-1])^(-1)</t>
            </li>
          </ul>
          <t>These four parameters fully determine the encoding matrix for any
(k, m) configuration.</t>
        </section>
        <section anchor="rs-shard-sizes">
          <name>RS Shard Sizes</name>
          <t>All RS shards (data and parity) are exactly shard_len bytes.  This
simplifies the CHUNK operation protocol: chunk_size is exactly the
shard size for all mirrors.</t>
          <table anchor="tbl-rs-shards">
            <name>RS shard sizes for common configurations</name>
            <thead>
              <tr>
                <th align="left">Configuration</th>
                <th align="left">File Size</th>
                <th align="left">Shard Size</th>
                <th align="left">Total Storage</th>
                <th align="left">Overhead</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">4+2</td>
                <td align="left">4 KB</td>
                <td align="left">1 KB</td>
                <td align="left">6 KB</td>
                <td align="left">50%</td>
              </tr>
              <tr>
                <td align="left">4+2</td>
                <td align="left">1 MB</td>
                <td align="left">256 KB</td>
                <td align="left">1.5 MB</td>
                <td align="left">50%</td>
              </tr>
              <tr>
                <td align="left">8+2</td>
                <td align="left">4 KB</td>
                <td align="left">512 B</td>
                <td align="left">5 KB</td>
                <td align="left">25%</td>
              </tr>
              <tr>
                <td align="left">8+2</td>
                <td align="left">1 MB</td>
                <td align="left">128 KB</td>
                <td align="left">1.25 MB</td>
                <td align="left">25%</td>
              </tr>
            </tbody>
          </table>
        </section>
      </section>
      <section anchor="sec-mojette-encoding">
        <name>Mojette Transform Encoding (FFV2_ENCODING_MOJETTE_SYSTEMATIC, FFV2_ENCODING_MOJETTE_NON_SYSTEMATIC)</name>
        <section anchor="overview-1">
          <name>Overview</name>
          <t>The Mojette Transform is an erasure coding technique based on discrete
geometry rather than algebraic field operations.  It computes 1D
projections of a 2D grid along selected directions.  Given enough
projections, the original grid can be reconstructed exactly.</t>
          <t>The transform operates on fixed-width words combined with bitwise
XOR -- the additive group of GF(2)^W where W is the element width
in bits.  Encoders and decoders <bcp14>MUST</bcp14> use XOR; modular integer
addition is not equivalent and is not interoperable.  XOR has no
carry chain, is its own inverse (so the residual subtraction in
reconstruction is identical to the forward accumulation), and
scales straightforwardly to wider SIMD lanes (NEON, SSE, AVX, AVX-512)
without requiring multiplicative Galois field operations.  The
element width W is an implementation choice; 64-bit elements are
the conventional choice and align well with NEON, SSE2, and AVX2
vector widths.</t>
        </section>
        <section anchor="grid-structure">
          <name>Grid Structure</name>
          <t>Data is arranged as a P x Q grid of unsigned integer elements,
where P is the number of columns and Q is the number of rows.
For k data shards of S bytes each with W-byte elements:</t>
          <artwork><![CDATA[
P = S / W       (columns per row)
Q = k           (rows = data shards)
]]></artwork>
        </section>
        <section anchor="directions">
          <name>Directions</name>
          <t>A direction is a pair of coprime integers (p_i, q_i).  Implementations
<bcp14>SHOULD</bcp14> use q_i = 1 for all directions <xref target="PARREIN"/>.  For n = k + m total
shards, n directions are generated with non-zero p values symmetric
around zero:</t>
          <ul spacing="normal">
            <li>
              <t>For n = 4: p = {-2, -1, 1, 2}</t>
            </li>
            <li>
              <t>For n = 6: p = {-3, -2, -1, 1, 2, 3}</t>
            </li>
          </ul>
        </section>
        <section anchor="forward-transform-encoding">
          <name>Forward Transform (Encoding)</name>
          <t>For each direction (p_i, q_i), the forward transform computes a 1D
projection.  Each bin XORs the grid elements that lie on a discrete
line through the grid.  This specification adopts the bin
convention of <xref target="NORMAND"/>: a grid cell at (row, col) maps to bin</t>
          <artwork><![CDATA[
b = row * p + col * q - off
]]></artwork>
          <t>where off is chosen so that the smallest reachable bin index is 0
(off = min over all (row, col) in [0, Q) x [0, P) of row * p + col * q).
All implementations <bcp14>MUST</bcp14> use this convention -- the alternative
"transposed" convention <tt>b = col * p - row * q + off</tt> produces a
different bin ordering and is not interoperable.</t>
          <t>The full forward transform along direction (p, q) is then:</t>
          <artwork><![CDATA[
Projection(b, p, q) = XOR over all (row, col) where
                       row * p + col * q - off = b
                       of Grid[row][col]
]]></artwork>
          <t>The number of bins B in a projection is:</t>
          <artwork><![CDATA[
B(p, q, P, Q) = |p| * (Q - 1) + |q| * (P - 1) + 1
]]></artwork>
          <t>For q = 1, this simplifies to:</t>
          <artwork><![CDATA[
B = abs(p) * (Q - 1) + P
]]></artwork>
          <t>The byte size of the projection is B * W.</t>
        </section>
        <section anchor="katz-reconstruction-criterion">
          <name>Katz Reconstruction Criterion</name>
          <t>Reconstruction is possible if and only if the Katz criterion
<xref target="KATZ"/> holds:</t>
          <artwork><![CDATA[
SUM(i=1..n) |q_i| >= Q    OR    SUM(i=1..n) |p_i| >= P
]]></artwork>
          <t>When all q_i = 1, the q-sum simplifies to n &gt;= Q.</t>
        </section>
        <section anchor="inverse-transform-decoding">
          <name>Inverse Transform (Decoding)</name>
          <t>The choice of inverse algorithm is purely an implementer concern:
all correct inverses produce byte-identical plaintext from the same
shards and bin layout, so the choice has no on-the-wire impact.
Two well-known algorithms apply.</t>
          <t>The corner-peeling algorithm:</t>
          <ol spacing="normal" type="1"><li>
              <t>Count how many unknown elements contribute to each bin.</t>
            </li>
            <li>
              <t>Find any bin with exactly one contributor (singleton).</t>
            </li>
            <li>
              <t>Recover the element, XOR it back through all projections.</t>
            </li>
            <li>
              <t>Repeat until all elements are recovered.</t>
            </li>
          </ol>
          <t>Corner peeling runs in O(n * P * Q) and is the simplest correct
inverse.  Implementations <bcp14>MAY</bcp14> instead use the geometry-driven
inverse of <xref target="NORMAND"/>, which precomputes a recurrence over the
sorted projection slopes and walks each line once: it eliminates
the inner singleton search and runs substantially faster on the
parameter ranges typical of flexible file v2 layout deployments (high redundancy,
wide stripes), with no change to the shards or to the
reconstructed plaintext.</t>
        </section>
        <section anchor="systematic-mojette">
          <name>Systematic Mojette</name>
          <t>In the systematic form (FFV2_ENCODING_MOJETTE_SYSTEMATIC), the first
k shards are the original data rows and the remaining m shards are
projections.  Healthy reads require no decoding.</t>
          <t>Reconstruction of missing data rows proceeds via the
corner-peeling algorithm of <xref target="NORMAND"/>:</t>
          <ol spacing="normal" type="1"><li>
              <t>Load available parity projections.</t>
            </li>
            <li>
              <t>Subtract contributions of present data rows (residual).</t>
            </li>
            <li>
              <t>Corner-peel the residual to recover missing rows.</t>
            </li>
          </ol>
          <t>Reconstruction cost is O(m * k) -- a fundamental advantage over RS
at wide geometries (k &gt;= 8).</t>
        </section>
        <section anchor="non-systematic-mojette">
          <name>Non-Systematic Mojette</name>
          <t>In the non-systematic form (FFV2_ENCODING_MOJETTE_NON_SYSTEMATIC),
all k + m shards are projections.  Every read requires the full
inverse transform.  This provides constant performance regardless of
failure count, but at higher baseline read cost than systematic.</t>
        </section>
        <section anchor="mojette-shard-sizes">
          <name>Mojette Shard Sizes</name>
          <t>Unlike RS, Mojette parity shard sizes vary by direction:</t>
          <table anchor="tbl-mojette-proj-sizes">
            <name>Mojette projection sizes for 4+2, 4KB shards, 64-bit elements</name>
            <thead>
              <tr>
                <th align="left">Direction (p, q)</th>
                <th align="left">Bins (B) for P=512, Q=4</th>
                <th align="left">Size (bytes, 64-bit elements)</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">(-3, 1)</td>
                <td align="left">521</td>
                <td align="left">4168</td>
              </tr>
              <tr>
                <td align="left">(-2, 1)</td>
                <td align="left">518</td>
                <td align="left">4144</td>
              </tr>
              <tr>
                <td align="left">(-1, 1)</td>
                <td align="left">515</td>
                <td align="left">4120</td>
              </tr>
              <tr>
                <td align="left">(1, 1)</td>
                <td align="left">515</td>
                <td align="left">4120</td>
              </tr>
              <tr>
                <td align="left">(2, 1)</td>
                <td align="left">518</td>
                <td align="left">4144</td>
              </tr>
              <tr>
                <td align="left">(3, 1)</td>
                <td align="left">521</td>
                <td align="left">4168</td>
              </tr>
            </tbody>
          </table>
          <t>When using CHUNK operations, the chunk_size is a nominal stride; the
last chunk in a parity shard <bcp14>MAY</bcp14> be shorter than the stride.</t>
        </section>
      </section>
      <section anchor="comparison-of-encoding-types">
        <name>Comparison of Encoding Types</name>
        <table anchor="tbl-encoding-comparison">
          <name>Comparison of erasure encoding types</name>
          <thead>
            <tr>
              <th align="left">Property</th>
              <th align="left">Reed-Solomon</th>
              <th align="left">Mojette Systematic</th>
              <th align="left">Mojette Non-Systematic</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">MDS guarantee</td>
              <td align="left">Yes</td>
              <td align="left">Yes (Katz)</td>
              <td align="left">Yes (Katz)</td>
            </tr>
            <tr>
              <td align="left">Shard sizes</td>
              <td align="left">Uniform</td>
              <td align="left">Variable</td>
              <td align="left">Variable</td>
            </tr>
            <tr>
              <td align="left">Reconstruction cost</td>
              <td align="left">O(k^2)</td>
              <td align="left">O(m * k)</td>
              <td align="left">O(m * k)</td>
            </tr>
            <tr>
              <td align="left">Healthy read cost</td>
              <td align="left">Zero</td>
              <td align="left">Zero</td>
              <td align="left">Full decode</td>
            </tr>
            <tr>
              <td align="left">GF operations</td>
              <td align="left">Yes (GF(2^8))</td>
              <td align="left">No</td>
              <td align="left">No</td>
            </tr>
          </tbody>
        </table>
        <t>Reed-Solomon uses uniform shard sizes and GF(2^8) operations.
Mojette systematic provides zero-cost healthy reads with variable
parity shard sizes; reconstruction cost scales as O(m * k) rather
than O(k^2).  Mojette non-systematic encodes all k + m shards as
projections, providing constant decode cost regardless of failure
count at a higher baseline read cost than systematic.  The choice
among these is a deployment decision driven by workload
characteristics and operational priorities.</t>
      </section>
      <section anchor="sec-spare-substitution">
        <name>First-Line Substitution to a Spare</name>
        <t>When a client's CHUNK_WRITE to an FFV2_DS_FLAGS_ACTIVE data server
fails with a transport-level error, NFS4ERR_IO, NFS4ERR_NOSPC, or
any other code that indicates the data server cannot accept the
shard, and the layout includes a data server flagged
FFV2_DS_FLAGS_SPARE (<xref target="sec-ffv2_ds_flags4"/>) that is not already
holding a shard for the affected payload, the client <bcp14>MAY</bcp14> substitute
the spare for the failing active data server for this write.</t>
        <t>Substitution avoids the full metadata-server repair flow.  The
client issues CHUNK_WRITE to the spare in place of the failing
ACTIVE and, if successful, proceeds with CHUNK_FINALIZE and
CHUNK_COMMIT against the full set of data servers the payload
now resides on (the k-1 healthy ACTIVE plus the substituted
SPARE).  The spare becomes the i-th shard holder for the
affected payload.</t>
        <t>The client <bcp14>MUST</bcp14> inform the metadata server of the substitution
before returning the layout.  This is done via LAYOUTERROR on
the failing ACTIVE (reporting the error code the client
encountered) in the same compound as, or before, any
LAYOUTSTATS reporting of the substitution.  The metadata server
uses the LAYOUTERROR to decide whether to update the layout in
place -- promoting the spare to ACTIVE and demoting the failing
ACTIVE to a stale-or-unreachable state -- or to push new
layouts via CB_RECALL_ANY to other clients so readers do not
continue to consult the failing ACTIVE.</t>
        <t>Substitution is optional.  A client that does not implement it,
or does not have a suitable spare in the layout, falls through
to the normal write-hole handling below.  Substitution is also
not available to clients writing with cwa_stable == FILE_SYNC
unless the client is prepared to drive FILE_SYNC semantics on
the spare as well; otherwise the substitution silently
downgrades the durability contract.</t>
        <t>Substitution <bcp14>MUST NOT</bcp14> be used when the existing PENDING state
on any shard of the affected payload carries a different
chunk_guard4 than the current transaction (the range has been
adopted by a repair client already -- the normal repair flow
applies and substitution would collide).</t>
      </section>
      <section anchor="handling-write-holes">
        <name>Handling write holes</name>
        <t>A write hole occurs when a client begins writing a stripe but does not
successfully write all k+m shards before a failure.  Some data servers
will hold new data while others still hold old data, producing an
non-atomic payload.</t>
        <t>The CHUNK_WRITE / CHUNK_ROLLBACK mechanism addresses this.  When a client
issues CHUNK_WRITE, the data server retains a copy of the previous shard
and places the new data in the PENDING state.  If any shard write fails,
the client issues CHUNK_ROLLBACK to each data server that received a
CHUNK_WRITE, restoring the previous content.  The payload remains
atomic from the reader's perspective throughout, because PENDING
blocks carry the new chunk_guard4 value and CHUNK_READ returns the last
COMMITTED or FINALIZED block when a PENDING block exists.</t>
        <t>A single-shard CHUNK_WRITE failure <bcp14>MAY</bcp14> also be handled without
CHUNK_ROLLBACK by substituting the failing data server with an
FFV2_DS_FLAGS_SPARE, per <xref target="sec-spare-substitution"/>.  This
avoids engaging the metadata server's repair flow and is the
preferred path on transient single-data server failures when the layout
exposes a suitable spare.</t>
        <t>In the multiple writer model, a write hole can also arise when two clients
are racing.  The chunk_guard4 value on each chunk identifies which
transaction wrote it.  A reader that finds chunks with different guard
values detects the non-atomicity and either retries (if a concurrent write
is still in progress) or reports NFS4ERR_PAYLOAD_NOT_ATOMIC to the
metadata server to trigger repair.</t>
        <t>When substitution and CHUNK_ROLLBACK are both unavailable, and
the payload cannot be reconstructed because too many shards have
been lost (for example, a catastrophic multi-data server failure with no
spares provisioned), the repair flow ultimately terminates with
NFS4ERR_PAYLOAD_LOST; see
<xref target="sec-NFS4ERR_PAYLOAD_LOST"/>.</t>
      </section>
    </section>
    <section anchor="sec-system-model">
      <name>System Model and Correctness</name>
      <t>The design decisions in this document -- centralized coordination
through the metadata server, CAS semantics via chunk_guard4,
pessimistic lock escrow during repair, and erasure-coded reads
from any sufficient subset -- depart visibly from a classical
distributed-consensus protocol such as Paxos or Raft.  This
section states the system model those decisions rest on, the
consistency and progress guarantees the protocol provides under
that model, and how the protocol relates to (and when it relies
on) classical consensus.  It is intended as the correctness
framing for implementers and reviewers; the normative wire
behavior is defined in the preceding sections.</t>
      <section anchor="sec-system-model-wire">
        <name>Wire Semantics vs Implementation</name>
        <t>The protocol defines wire semantics, not data-server
implementation.  The operations introduced in
<xref target="sec-new-ops"/> (CHUNK_WRITE, CHUNK_FINALIZE, CHUNK_COMMIT,
CHUNK_ROLLBACK, CHUNK_LOCK / CHUNK_UNLOCK, CHUNK_READ,
CHUNK_REPAIRED, CHUNK_ERROR, CHUNK_HEADER_READ,
CHUNK_WRITE_REPAIR) together with the per-chunk state machine
(<xref target="sec-system-model-chunk-state"/>) and the chunk_guard4 CAS
(<xref target="sec-chunk_guard4"/>) are the entire surface a peer observes.
The data server's internal representation of persistent state is
not exposed on the wire, and two data-server implementations
that satisfy the same wire semantics <bcp14>MAY</bcp14> differ arbitrarily in
their internal structure.</t>
        <t>In particular, the protocol does NOT exchange:</t>
        <ul spacing="normal">
          <li>
            <t>which on-disk layout (log-structured, append-only,
in-place-overwrite, external object store, key-value store,
or any other) a data server uses to persist chunks;</t>
          </li>
          <li>
            <t>whether a data server holds PENDING and FINALIZED chunks in
a single blob or in distinct regions;</t>
          </li>
          <li>
            <t>how a data server represents the CHUNK_LOCK table, the guard
epoch, or the escrow owner;</t>
          </li>
          <li>
            <t>whether a data server's chunk retention beyond COMMIT is
implemented via shadow blocks, journals, reference counts,
or copy-on-write.</t>
          </li>
        </ul>
        <t>This decoupling is deliberate.  It lets the protocol accommodate
future smart-data server designs -- including designs that integrate more
closely with storage back-ends that already provide atomic
replace, multi-version concurrency, or internal erasure coding --
without protocol revisions, provided the wire semantics are
preserved.  Conversely, a data server implementer is free to
pick the representation that best fits the underlying storage
stack without fear that some less common implementation choice
is disallowed.</t>
        <t>The counterpart of this rule is that the wire is the entire
contract.  Any behavior a client relies on <bcp14>MUST</bcp14> be observable
via the operations listed above; any behavior that is not
observable (cache state, background scrubbing cadence,
internal retry ordering, on-disk layout) is implementation
detail and <bcp14>MUST NOT</bcp14> be depended upon.</t>
      </section>
      <section anchor="sec-system-model-chunk-not-block">
        <name>Chunks Are Not Blocks</name>
        <t>The chunk is a protocol-level primitive distinct from a block.
Throughout this document, "block" refers to a byte range in the
file's address space (the application's view); "chunk" refers to
the addressable unit carried by the CHUNK_* operations, which
has an envelope that blocks do not.</t>
        <t>A chunk carries five properties that a block does not:</t>
        <ul spacing="normal">
          <li>
            <t><strong>Atomicity.</strong>  The chunk_guard4 compare-and-swap guard
(<xref target="sec-chunk_guard4"/>) sequences concurrent writers and
rejects torn-write attempts.  Block I/O has no comparable
primitive; concurrent block writes either serialize at the
storage layer or interleave unpredictably.</t>
          </li>
          <li>
            <t><strong>Integrity.</strong>  The checksum in each chunk header is computed
over the header and payload and verified end-to-end on the
read path (<xref target="sec-CHUNK_READ"/>).  Block I/O carries no
integrity tag; data-corruption detection is delegated to
the underlying storage medium or is absent.</t>
          </li>
          <li>
            <t><strong>Provenance.</strong>  The chunk_owner4 (<xref target="sec-chunk_owner4"/>)
records which transaction produced the chunk.  Block I/O
carries no per-write provenance; a block's bytes have no
protocol-visible producer.</t>
          </li>
          <li>
            <t><strong>Lifecycle state.</strong>  A chunk progresses through PENDING
-&gt; FINALIZED -&gt; COMMITTED via CHUNK_FINALIZE / CHUNK_COMMIT
(<xref target="sec-system-model-chunk-state"/>).  Block I/O has no
lifecycle states; a block is either present or absent.</t>
          </li>
          <li>
            <t><strong>Lock continuity across revocation.</strong>  The chunk's lock
(<xref target="sec-CHUNK_LOCK"/>) is transferred to the metadata server
in escrow when a holder's stateid is revoked, and adopted
by a repair client via CHUNK_LOCK_FLAGS_ADOPT.  Block I/O
has no per-block locking and no continuity mechanism;
client failure leaves any external lock indeterminate.</t>
          </li>
        </ul>
        <t>Each of these properties is load-bearing for some part of the
flexible file v2 layout's consistency story: the chunk_guard4
CAS underlies multi-writer correctness; the checksum underlies
end-to-end integrity; lock escrow underlies repair coordination
across stateid revocation; the state machine underlies the
PENDING / FINALIZED / COMMITTED distinction that enables
rollback and repair.  Removing any one of them would change
what the protocol can guarantee.</t>
        <t>A protocol that exchanges file data as byte ranges with no
envelope -- whether described as "block I/O" or as "generic
data movement" -- is not interoperable with this specification's
CHUNK_* operations.  The CHUNK_* operations are not a byte-range
I/O surface with optional integrity bolted on; they are a
chunk-protocol surface in which the envelope is the primitive.</t>
      </section>
      <section anchor="sec-system-model-roles">
        <name>Actors and Roles</name>
        <t>Three actors participate on behalf of any given file:</t>
        <dl>
          <dt>pNFS client:</dt>
          <dd>
            <t>Issues CHUNK operations to data servers over the data path;
issues LAYOUTGET, LAYOUTRETURN, LAYOUTERROR, and SEQUENCE to
the metadata server on the control path.  Authenticates to the
metadata server via AUTH_SYS, RPCSEC_GSS, or TLS.  <bcp14>MAY</bcp14> be
selected as a repair client via CB_CHUNK_REPAIR.</t>
          </dd>
          <dt>Metadata server (MDS):</dt>
          <dd>
            <t>Is the sole coordinator for the file.  Grants, renews, and
revokes layouts; issues TRUST_STATEID / REVOKE_STATEID /
BULK_REVOKE_STATEID to each tight-coupled data server; selects
the repair client under the rules in
<xref target="sec-repair-selection"/>; owns the reserved
CHUNK_GUARD_CLIENT_ID_MDS escrow identity for in-flight repair.</t>
          </dd>
          <dt>Data server (DS):</dt>
          <dd>
            <t>Persists chunks and enforces the per-file trust table, the
per-chunk guard CAS (chunk_guard4), the per-chunk lock state
(including the MDS-escrow owner), and the chunk state machine
(EMPTY / PENDING / FINALIZED / COMMITTED).  Has no
coordinator role.  Has no knowledge of the erasure coding type
in use for any file: the erasure transform is performed
entirely at the client, and the data server stores the
resulting chunks without interpreting their contents.</t>
          </dd>
        </dl>
        <t>An entity <bcp14>MAY</bcp14> simultaneously hold more than one of these roles
with respect to a given data server, with each role bound to a
distinct session.  A metadata server that opens a control
session to a data server (presenting EXCHGID4<em>FLAG_USE_PNFS_MDS
at EXCHANGE_ID; see <xref target="sec-tight-coupling-control-session"/>)
issues TRUST_STATEID, REVOKE_STATEID, and BULK_REVOKE_STATEID on
that session; on a separate client-side session (presenting
EXCHGID4_FLAG_USE_NON_PNFS), the same metadata server <bcp14>MAY</bcp14> also
issue CHUNK</em>* operations as a data-path client.  A data server
<bcp14>MUST NOT</bcp14> assume that the metadata server is not also one of its
clients; it distinguishes MDS-only operations from client-side
operations by the EXCHANGE_ID flags of the session that carries
the operation, not by the requester's IP address or principal.</t>
        <t>A data server <bcp14>MAY</bcp14> likewise act as a client of another data
server -- for example, when selected as the repair client by an
MDS-directed CB_CHUNK_REPAIR.  Independent of the actor role,
any entity may operate as codec-aware (issuing CHUNK_*
operations directly against data servers) or codec-unaware
(operating through the proxy-server-mediated READ / WRITE path
described in <xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>).
Proxy-server registration carries the codec capability
explicitly; direct pNFS clients reveal their codec posture
implicitly through the operations they issue.</t>
        <t>The protocol does NOT mandate how a data server implements the
chunk state machine or stores PENDING chunks.  An implementation
<bcp14>MAY</bcp14> use per-client staging files, a single append-only instance
file with an index, a separate metadata-header file paired with
a blocks file, a log-structured store, or any other
representation that preserves the normative semantics (the
EMPTY / PENDING / FINALIZED / COMMITTED transitions, the
chunk_guard4 CAS, lock continuity across revocation, and the
integrity checks).  The choice is a data-server implementation
concern and is transparent to clients and the metadata server.</t>
        <t>Each file is owned by exactly one metadata server at any given
instant.  Ownership transfer between metadata servers (for
example, during metadata server failover) is implementation-defined and out
of scope for this document; see <xref target="sec-system-model-consensus"/>.</t>
      </section>
      <section anchor="sec-system-model-failures">
        <name>Failure Model</name>
        <t>The protocol assumes:</t>
        <dl>
          <dt>Crash-stop:</dt>
          <dd>
            <t>Clients, metadata servers, and data servers fail by stopping.
A restarted component rejoins the protocol with a fresh epoch
and participates in the grace / reclaim path already defined
in <xref target="RFC8881"/>.  Correct components do not exhibit arbitrary
(Byzantine) behavior.</t>
          </dd>
          <dt>Fail-silent data servers:</dt>
          <dd>
            <t>Data servers report honestly about the state of the data they
hold.  The protocol detects on-disk bit rot via checksum
(see <xref target="sec-CHUNK_WRITE"/>) but does not defend against a data
server that deliberately lies about whether a chunk is
COMMITTED or what its contents are.  Byzantine data servers
are explicitly outside the trust model; see
<xref target="sec-system-model-nongoals"/>.</t>
          </dd>
          <dt>Authenticated writers and their own data:</dt>
          <dd>
            <t>An authenticated client may write arbitrary (even
semantically-invalid) bytes into chunks it owns.  The checksum
check detects transport corruption, not adversarial content.
This matches the existing NFSv4 authorization model: once
you have write access, you may write anything.</t>
          </dd>
          <dt>Network partitions:</dt>
          <dd>
            <t>The protocol is partition-tolerant at the cost of availability
during the partition window.  A client partitioned from a
data server recovers via LAYOUTERROR and may be issued a new
layout (possibly against a spare, see
<xref target="sec-spare-substitution"/>).  An metadata server partitioned from a data
server eventually renews trust entries on reconnection; in
the interim, the data server returns NFS4ERR_DELAY for
affected stateids (see <xref target="sec-tight-coupling-mds-crash"/>).
Message loss is bounded by RPC retransmit; eventual delivery
is assumed once the partition heals.
</t>
            <t>Split-brain scenarios (in which a partitioned minority of
the data servers in a mirror set attempts to make progress
independently of the majority) cannot drive non-atomic
writes to COMMITTED state.  The chunk_guard4 CAS on each
write requires the guard value from a successor chunk to
strictly advance the guard value of its predecessor; on
partition heal, any writes attempted on the minority side
are detected by the majority because their guard values do
not satisfy the CAS precondition, and those writes are
discarded.  When reconciliation is impossible -- for example,
the erasure coding has lost too many shards across both sides
of the partition to reconstruct any single atomic
generation -- the repair flow terminates with
NFS4ERR_PAYLOAD_LOST (see <xref target="sec-NFS4ERR_PAYLOAD_LOST"/>),
which is terminal for the affected ranges.</t>
          </dd>
          <dt>Lease bound:</dt>
          <dd>
            <t>All state held by a data server on behalf of a metadata server
is bounded by the TRUST_STATEID expiry (see
<xref target="sec-tight-coupling-lease"/>).  An orphaned entry will
eventually expire even if the metadata server never returns.</t>
          </dd>
        </dl>
      </section>
      <section anchor="sec-system-model-chunk-state">
        <name>Chunk State Machine</name>
        <t>Each chunk on a data server occupies exactly one of four states.
The transitions below are the complete set; any implementation
of the data server's chunk state table <bcp14>MUST</bcp14> admit these
transitions and no others.</t>
        <figure anchor="fig-chunk-state-machine">
          <name>Chunk lifecycle on the data server</name>
          <artwork><![CDATA[
                            CHUNK_WRITE
                         (fresh cg_gen_id)
        +---------+ -------------------> +-------------+
        |  EMPTY  |                      |   PENDING   |
        +---------+ <------------------- +-------------+
             ^         CHUNK_ROLLBACK            |
             |        (discard PENDING)          |
             |                                   | CHUNK_FINALIZE
             |                                   |  (writer stops
             |                                   |   further writes)
             |                                   v
             |                            +-------------+
             |       CHUNK_ROLLBACK       |  FINALIZED  |
             |      (discard FINALIZED)   +-------------+
             |                                   |
             |                                   | CHUNK_COMMIT
             |                                   |  (make durable
             |                                   |   and globally
             |                                   |   visible)
             |                                   v
             |                            +-------------+
             +--------------------------> |  COMMITTED  |
                   CHUNK_ROLLBACK         +-------------+
                (only via repair;                 |
                 replaces with a newer            | CHUNK_WRITE with
                 COMMITTED generation             | a higher cg_gen_id
                 or discards per the              | begins a new
                 rollback invariant)              | PENDING successor;
                                                  | the prior COMMITTED
                                                  | is retained until
                                                  | its successor is
                                                  | COMMITTED (see the
                                                  v  rollback invariant
                                            (next PENDING
                                             against same chunk)
]]></artwork>
        </figure>
        <t>CHUNK_WRITE against a chunk already in PENDING from the same
writer with the same cg_gen_id is a self-transition on PENDING:
the data server replaces the PENDING payload in place and the
state does not change.  This case is not drawn in
<xref target="fig-chunk-state-machine"/> for clarity.</t>
        <t>States:</t>
        <dl>
          <dt>EMPTY:</dt>
          <dd>
            <t>The chunk has no payload.  CHUNK_READ returns a zero-filled
result; CHUNK_WRITE against an EMPTY chunk is the first write.</t>
          </dd>
          <dt>PENDING:</dt>
          <dd>
            <t>The chunk has payload accepted by CHUNK_WRITE but not yet
finalized.  Not visible to CHUNK_READ (see
<xref target="sec-system-model-consistency"/>).  Further CHUNK_WRITEs from
the same writer <bcp14>MAY</bcp14> replace the payload in place (same
cg_gen_id).</t>
          </dd>
          <dt>FINALIZED:</dt>
          <dd>
            <t>The writer has signalled via CHUNK_FINALIZE that it will send
no more CHUNK_WRITEs for this generation.  Still not visible
to CHUNK_READ, but a candidate for CHUNK_COMMIT.</t>
          </dd>
          <dt>COMMITTED:</dt>
          <dd>
            <t>The chunk is durable and globally visible.  Subsequent
CHUNK_READs return this content until a newer COMMITTED
generation replaces it.  A higher-generation PENDING successor
<bcp14>MAY</bcp14> exist concurrently; the rollback invariant in
<xref target="sec-system-model-consistency"/> requires the data server to
retain the COMMITTED content while that successor exists.</t>
          </dd>
        </dl>
        <t>Transitions are driven by the operations named on the arrows.
CHUNK_ROLLBACK against a COMMITTED chunk is used only on the
repair path (see <xref target="sec-CHUNK_ROLLBACK"/>) and replaces the chunk
with a newer COMMITTED generation chosen by the repair client,
rather than returning the chunk to EMPTY.</t>
        <t><xref target="fig-chunk-state-machine"/> covers the lifecycle of a chunk's
payload but not the lock that may be held on it.  The lock has
its own state machine, shown in <xref target="fig-chunk-lock-machine"/>.</t>
        <figure anchor="fig-chunk-lock-machine">
          <name>Chunk lock ownership on the data server</name>
          <artwork><![CDATA[
                          CHUNK_LOCK
                       (writer acquires)
        +----------+ ----------------> +-------------------+
        | UNLOCKED |                   | LOCKED by writer  |
        +----------+ <---------------- +-------------------+
             ^           CHUNK_UNLOCK            |
             |          (writer releases)        |
             |                                   | REVOKE_STATEID
             |                                   |  (MDS invalidates
             |                                   |   writer stateid;
             |                                   |   lock transfers
             |                                   |   to MDS escrow)
             |                                   v
             |        CHUNK_UNLOCK     +-------------------+
             |       or CHUNK_REPAIRED |   LOCKED by MDS   |
             |      (repair client     |       escrow      |
             |       releases after    +-------------------+
             |       repair completes)           |
             |                                   | CHUNK_LOCK with
             |                                   | CHUNK_LOCK_FLAGS_ADOPT
             |                                   |  (repair client
             |                                   |   adopts MDS-escrow
             |                                   |   ownership per
             |                                   |   CB_CHUNK_REPAIR)
             |                                   v
             |                         +-------------------+
             +------------------------ | LOCKED by repair  |
                                       +-------------------+
]]></artwork>
        </figure>
        <t>The lock state machine is orthogonal to the chunk lifecycle in
<xref target="fig-chunk-state-machine"/>: a chunk in any of EMPTY, PENDING,
FINALIZED, or COMMITTED <bcp14>MAY</bcp14> simultaneously be in any of the
four lock states.  The errored bit (set by CHUNK_ERROR, cleared
by CHUNK_REPAIRED) is a third orthogonal axis and is not drawn;
CHUNK_ERROR may set the bit in any state, and CHUNK_REPAIRED
clears it as part of completing a repair sequence.  A CHUNK_LOCK
that arrives while the chunk is already LOCKED by a different
owner returns NFS4ERR_CHUNK_LOCKED with the existing owner's
chunk_owner4 in clr_owner (<xref target="sec-CHUNK_LOCK"/>).</t>
      </section>
      <section anchor="sec-system-model-consistency">
        <name>Consistency Guarantees</name>
        <t>The protocol provides <strong>per-chunk linearizability on COMMITTED
state</strong>:</t>
        <ol spacing="normal" type="1"><li>
            <t>Once CHUNK_COMMIT returns success to a writer for a given
chunk, every subsequent CHUNK_READ whose stateid postdates
the COMMIT observes either that writer's data or the data of
a later committed write.  A reader <bcp14>MUST NOT</bcp14> observe a
rolled-back write as if it had committed.</t>
          </li>
          <li>
            <t>Concurrent writers on the same chunk in multi-writer mode
serialize via chunk_guard4.  On guard conflict one writer
succeeds; the other receives NFS4ERR_CHUNK_GUARDED and <bcp14>MUST</bcp14>
either abandon the write or re-read and retry.  At most one
generation becomes COMMITTED per serialized decision.</t>
          </li>
          <li>
            <t>During repair, the chunk's lock is held continuously -- first
by the original writer, then transferred to the MDS-escrow
owner on REVOKE_STATEID, and finally adopted by the repair
client via CHUNK_LOCK_FLAGS_ADOPT.  No writer that did not
hold the lock may observe or mutate the chunk.  The
invariant "a chunk with a live lock has exactly one logical
owner at any instant" is preserved across revocation.</t>
          </li>
        </ol>
        <t>Across multiple chunks the protocol makes <strong>no multi-chunk
atomicity or ordering guarantee</strong>.  A reader that reads chunk A
at one offset and chunk B at another <bcp14>MAY</bcp14> observe A's new value
and B's old value simultaneously.  Applications that require
multi-chunk atomicity <bcp14>MUST</bcp14> layer it above this protocol -- for
example, via file-level checksums, application-level generation
fields, or external transaction managers.</t>
        <t><strong>The chunk is the unit of atomicity.</strong>  Two properties follow:</t>
        <ol spacing="normal" type="1"><li>
            <t>Chunk-aligned writes do not interfere.  Two concurrent
writers whose writes cover disjoint chunks -- even writes
that cover adjacent chunks -- never race.  Each write
terminates independently at COMMITTED per the per-chunk
linearizability rule above.</t>
          </li>
          <li>
            <t>Sub-chunk overlapping writes from different writers
produce chunk-resolution-granularity contention.  When two
concurrent writers target overlapping byte ranges within a
single chunk, chunk_guard4 resolves them: one writer's
entire chunk-generation wins and becomes COMMITTED; the
other writer sees NFS4ERR_CHUNK_GUARDED and is expected to
re-read and retry if it wishes to apply its change on top
of the winning generation (see
<xref target="sec-NFS4ERR_CHUNK_GUARDED"/>).  The protocol does NOT
produce byte-level merges of overlapping sub-chunk writes:
the losing writer's bytes are not preserved as a partial
update within the winning generation.</t>
          </li>
        </ol>
        <t>Applications that require byte-level write merging or sub-chunk
ordering guarantees <bcp14>MUST</bcp14> serialize such writes externally, for
example via NFSv4 byte-range locks (<xref target="RFC8881"/>, Section 12).
The chunk size that bounds the atomicity unit for a given file
is the product of ffv2m_striping_unit_size and the stripe width
W in <xref target="fig-striping-math"/>; applications can query
fattr4_coding_block_size (see <xref target="sec-fattr4_coding_block_size"/>)
to learn the effective chunk size and align their writes
accordingly.</t>
        <t>This choice -- chunk-boundary atomicity rather than stripe- or
block-boundary atomicity -- is load-bearing for the rest of the
consistency story: the chunk_guard4 CAS evaluates at the chunk
level, the PENDING / FINALIZED / COMMITTED state machine is per
chunk, CHUNK_LOCK is per chunk, and repair via CB_CHUNK_REPAIR
operates on chunks.  A different atomicity boundary would
require redefining those primitives, which this revision does
not.</t>
        <dl>
          <dt>Erasure-coded reads:</dt>
          <dd>
            <t>A reader of an erasure-coded file reconstructs the plaintext
from any sufficient subset of k shards of the (k+m)-shard
stripe; the guard values on those shards <bcp14>MUST</bcp14> agree.  Shards
with stale guards are ignored.  This is not a quorum read in
the Paxos sense -- there is no voting on a value; there is
only reconstruction of the single value identified by the
current guard.</t>
          </dd>
          <dt>Rollback invariant:</dt>
          <dd>
            <t>The data server <bcp14>MUST</bcp14> retain the prior FINALIZED or COMMITTED
content of a chunk while any successor PENDING chunk exists.
A corollary of this rule is the <strong>lowest-guard-recoverable</strong>
property: as long as at least k data servers in the mirror
set retain the chunk at some generation G or lower, the
payload that was COMMITTED at generation G (or earlier) can
be reconstructed.  This is the correctness basis for
CHUNK_ROLLBACK (see <xref target="sec-CHUNK_ROLLBACK"/>): rollback does not
synthesize data, it simply selects the lowest-generation
chunks whose guards agree across the mirror set and discards
the higher-generation PENDING or FINALIZED chunks that
triggered the rollback.  The protocol never relies on locating
or reconstructing data from outside the mirror set.</t>
          </dd>
          <dt>Visibility of non-committed state:</dt>
          <dd>
            <t>PENDING and FINALIZED chunks <bcp14>MUST NOT</bcp14> be globally visible.
CHUNK_READ returns only COMMITTED content; a CHUNK_READ whose
target chunk is currently PENDING or FINALIZED sees the
predecessor COMMITTED content (or an EMPTY chunk if none
exists), not the in-progress successor.  A writer observing
its own PENDING or FINALIZED chunk <bcp14>MAY</bcp14> receive the in-progress
content on the same stateid that produced it, but no other
stateid -- on the same or a different client -- sees it.
The retention window that makes the prior COMMITTED content
available to CHUNK_READ and to CHUNK_ROLLBACK is itself
bounded; see <xref target="sec-system-model-retention-scope"/> for the
normative scoping rule.</t>
          </dd>
        </dl>
      </section>
      <section anchor="sec-system-model-retention-scope">
        <name>Ownership and Scope of Retained Prior Content</name>
        <t>The rollback invariant in <xref target="sec-system-model-consistency"/>
requires a data server to retain the prior FINALIZED or
COMMITTED content of a chunk while any successor PENDING chunk
exists.  That retained content -- sometimes informally called
the "safe buffer" -- is not global state.  It is scoped to the
stateid that wrote the PENDING successor, and its retention and
visibility are governed by that owning stateid's lease.</t>
        <dl>
          <dt>Owner:</dt>
          <dd>
            <t>The data server <bcp14>MUST</bcp14> record, alongside each PENDING chunk,
the owning stateid (the stateid presented on the CHUNK_WRITE
that produced the PENDING).  This is the owning writer's
stateid; it identifies the client and openowner/lockowner
that the data server will release the PENDING to on
CHUNK_FINALIZE or CHUNK_COMMIT, and that the metadata server will treat
as the authoritative owner for purposes of
<xref target="sec-system-model-progress"/>.</t>
          </dd>
          <dt>Visibility:</dt>
          <dd>
            <t>Before transition to COMMITTED, the PENDING content is
visible only on the owning stateid.  A CHUNK_READ presenting
any other stateid (from the same client or a different
client) <bcp14>MUST</bcp14> observe the predecessor COMMITTED or EMPTY
state, not the PENDING successor.  This is the normative
form of the "non-committed data <bcp14>MUST NOT</bcp14> be globally visible"
rule stated in the "Visibility of non-committed state"
bullet of <xref target="sec-system-model-consistency"/>.</t>
          </dd>
          <dt>Retention window:</dt>
          <dd>
            <t>The data server <bcp14>MUST</bcp14> retain the predecessor COMMITTED (or
FINALIZED) content that the PENDING is superseding for as
long as the owning stateid's lease is valid.  If the owning
stateid's lease expires without the PENDING reaching
COMMITTED, the retention obligation for that PENDING ends
(see <xref target="sec-system-model-progress"/> for the scavenger rule
that drives demotion).  If the PENDING does reach COMMITTED,
the new COMMITTED generation supersedes the prior one under
the standard rollback invariant and its own retention is
governed by any newer PENDING successor.</t>
          </dd>
        </dl>
        <t>The practical effect is that the "safe buffer" for a chunk is
not an unbounded chunk-global state but a per-writer window
bounded by that writer's lease.  The data server always has a
rule for discarding retained prior content -- it is the
owning stateid's lease expiry -- so a chunk cannot accumulate
indefinitely many retained generations even in the presence of
dropped or partitioned writers.</t>
      </section>
      <section anchor="sec-system-model-progress">
        <name>Progress and Termination</name>
        <t>Under the failure model above, the protocol guarantees the
following progress properties:</t>
        <dl>
          <dt>Data-path progress:</dt>
          <dd>
            <t>If all mirrors are reachable and none are failed, a
CHUNK_WRITE followed by CHUNK_FINALIZE followed by
CHUNK_COMMIT completes in O(1) round trips independent of
cluster size.  In particular, there is no consensus round,
no leader election, and no quorum voting on the write
itself.  The three operations <bcp14>MAY</bcp14> be amortized across
compounds: a steady-state writer sending a series of
CHUNK_WRITEs can piggyback the CHUNK_FINALIZE of the previous
write on the compound that carries the next write (for
example, <tt>SEQUENCE + PUTFH + CHUNK_FINALIZE + CHUNK_WRITE</tt>),
reducing the data-path happy case to a single round trip per
CHUNK_WRITE rather than three.  The CHUNK_COMMIT for the
final write in a sequence <bcp14>MAY</bcp14> similarly ride on the CLOSE
compound.  These compound-packing optimizations are
permitted by the normal NFSv4.2 compound rules and require
no protocol extensions.</t>
          </dd>
          <dt>Repair termination:</dt>
          <dd>
            <t>Every CB_CHUNK_REPAIR completes in bounded time.  The client
selected as the repair client either:
</t>
            <ol spacing="normal" type="1"><li>
                <t>returns NFS4_OK for every range in ccra_ranges (repair
succeeded), or</t>
              </li>
              <li>
                <t>returns NFS4ERR_PAYLOAD_LOST for one or more ranges (the
erasure coding lost too many shards to reconstruct; the
data is permanently unrecoverable), or</t>
              </li>
              <li>
                <t>fails to respond within the ccra_deadline, in which case
the metadata server <bcp14>MUST</bcp14> re-select under the rules in
<xref target="sec-repair-selection"/> or <bcp14>MUST</bcp14> declare the ranges lost.</t>
              </li>
            </ol>
            <t>NFS4ERR_PAYLOAD_LOST is terminal for the affected ranges.
The protocol makes no further attempt to recover them.</t>
          </dd>
          <dt>Eventual trust-table convergence:</dt>
          <dd>
            <t>After a metadata server restart, each data server's trust
table converges to the metadata server's view within one
metadata-server lease period.  Entries that the metadata
server does not re-issue expire naturally via tsa_expire;
entries that the metadata server does re-issue transition
from pending-revalidation back to active on the next
TRUST_STATEID (see <xref target="sec-tight-coupling-mds-crash"/>).</t>
          </dd>
          <dt>Orphaned PENDING scavenger:</dt>
          <dd>
            <t>A PENDING chunk whose owning stateid (see
<xref target="sec-system-model-retention-scope"/>) has expired without
transition to FINALIZED or COMMITTED is an orphan.  The
metadata server <bcp14>MUST</bcp14> drive demotion of orphaned PENDINGs so
that no chunk remains in a non-terminal state indefinitely:
</t>
            <ol spacing="normal" type="1"><li>
                <t>When an owning stateid's lease expires, the metadata
server identifies every PENDING chunk owned by that
stateid (either from its own bookkeeping or by query
against the data server) and issues the control-plane
operations needed to demote each PENDING.</t>
              </li>
              <li>
                <t>Demotion replaces the PENDING with the predecessor
COMMITTED (or EMPTY) content that the data server has
been retaining under
<xref target="sec-system-model-retention-scope"/>.  The data server
<bcp14>MUST NOT</bcp14> wait for a separate client action before
performing the demotion.</t>
              </li>
              <li>
                <t>Any CHUNK_LOCK held in escrow on behalf of the expired
stateid (see <xref target="sec-chunk_guard_mds"/>) is released after
an MDS-defined grace period.  The grace period exists to
let a recovering client reclaim its lock via the grace /
reclaim path defined in <xref target="RFC8881"/>; on expiry of the
grace period without reclaim, the lock becomes available
for new CHUNK_LOCK_FLAGS_ADOPT acquirers.</t>
              </li>
            </ol>
            <t>The scavenger timeout (the delay between lease expiry and
demotion) is implementation-defined but <bcp14>SHOULD</bcp14> be tied to
the metadata server lease period so that it composes
naturally with existing NFSv4 grace / reclaim semantics.  A
scavenger timeout shorter than the lease risks racing an
in-progress client reclaim; a timeout substantially longer
than the lease extends the retention budget without a
commensurate benefit.</t>
          </dd>
        </dl>
        <t>The protocol does NOT guarantee progress if the metadata server
is unavailable for longer than its lease period -- this is the
standard NFSv4 lease assumption and is inherited unchanged.</t>
      </section>
      <section anchor="sec-system-model-consensus">
        <name>Relation to Classical Consensus</name>
        <t>Classical consensus protocols (Paxos, Raft, Viewstamped
Replication) solve the problem of reaching agreement among
mutually-distrusting replicas in the absence of a trusted
coordinator.  They typically cost two or three round trips per
decision, require a majority of replicas to be live and
reachable for progress, and impose the overhead of leader
election and log replication.</t>
        <t>This protocol is not a consensus protocol and does not attempt
to be.  Its approach instead is:</t>
        <dl>
          <dt>Designated coordinator:</dt>
          <dd>
            <t>The metadata server is the
coordinator for a file.  Clients accept the metadata server's authority
for layout grants, stateid registration, repair client
selection, and revocation.  This assumption is the same one
made by <xref target="RFC8434"/> and all pNFS layout types to date.</t>
          </dd>
          <dt>Per-chunk CAS, not per-chunk voting:</dt>
          <dd>
            <t>Concurrent writes
on the same chunk serialize via chunk_guard4 as a CAS
primitive (see <xref target="sec-chunk_guard4"/>).  No replica vote is
required; the data server that owns the chunk evaluates the
guard locally and rejects stale writes with
NFS4ERR_CHUNK_GUARDED.</t>
          </dd>
          <dt>Pessimistic locks off the critical path:</dt>
          <dd>
            <t>CHUNK_LOCK is
used only during repair, never on the normal write path.
Lock escrow (see <xref target="sec-chunk_guard_mds"/>) preserves the
"exactly one owner" invariant across stateid revocation
without requiring a consensus round to elect the next owner.</t>
          </dd>
          <dt>Erasure-coded reads replace quorum reads:</dt>
          <dd>
            <t>A reader
reconstructs from any k of k+m shards with matching guards.
No voting is needed because there is no disagreement to
resolve: the guard identifies the single generation that was
committed.</t>
          </dd>
        </dl>
        <t>The result is a data path with O(1) round-trip cost independent
of the number of replicas, and a repair path whose cost is
bounded by the number of affected chunks rather than by the
cluster size.</t>
        <t>Metadata-server high availability is orthogonal.  Deployments
that require a highly-available metadata server <bcp14>MAY</bcp14> replicate
metadata-server state across multiple metadata server instances
using classical consensus (Raft, Paxos, or equivalent).  Such
replication is implementation-defined; from a pNFS client's
perspective a highly-available metadata server looks like a
single metadata server that occasionally resets its session and
triggers grace-period reclaim, and the client's behavior is
already specified by <xref target="RFC8881"/>.  This protocol neither
requires nor precludes such an implementation.</t>
      </section>
      <section anchor="sec-system-model-nongoals">
        <name>Non-Goals</name>
        <t>For clarity, the protocol explicitly does not provide:</t>
        <dl>
          <dt>Byzantine fault tolerance:</dt>
          <dd>
            <t>A data server that
deliberately misreports its state, or a client that
bypasses its own authentication, is outside the trust model.
Deployments requiring Byzantine tolerance <bcp14>MUST</bcp14> add it in a
layer above or below this protocol.</t>
          </dd>
          <dt>Metadata server high availability:</dt>
          <dd>
            <t>Single-MDS-per-file is the protocol model.  Metadata server
high availability, if deployed, is implemented below the wire
protocol and transparent to clients.</t>
          </dd>
          <dt>Cross-file atomicity:</dt>
          <dd>
            <t>Writes to multiple files are not
atomic at the protocol level.  File-system-level transactions
are not defined.</t>
          </dd>
          <dt>Multi-chunk atomicity within a single file:</dt>
          <dd>
            <t>COMMITs on
distinct chunks are independent.  A reader may observe a
partial write across chunks; applications must layer their
own consistency if they need otherwise.</t>
          </dd>
          <dt>Global linearizability across unrelated files:</dt>
          <dd>
            <t>Each
file's COMMITTED state is linearizable in isolation; no
total order is defined across files.</t>
          </dd>
          <dt>Authenticated malicious client protection:</dt>
          <dd>
            <t>An
authenticated client may write garbage into its own chunks
with a correctly computed checksum; see
<xref target="sec-security-checksum-scope"/>.  A bit-flip-class checksum
is a transport-integrity check, not an adversarial-integrity
check; cryptographic-class checksums detect adversarial
modification by anyone other than the authenticated writer.</t>
          </dd>
        </dl>
      </section>
    </section>
    <section anchor="nfsv42-operations-allowed-to-data-files">
      <name>NFSv4.2 Operations Allowed to Data Files</name>
      <t>In the Flexible File Version 1 Layout Type (<xref target="RFC8435"/>), the data path
between client and data server was NFSv3 (<xref target="RFC1813"/>); the
operations a client sent to a data file were limited to READ,
WRITE, and COMMIT, and the operations the metadata server sent on
its control plane to the data server were limited to GETATTR,
SETATTR, CREATE, and REMOVE.  An NFSv4.2 data server, as used by
the Flexible File Version 2 Layout Type, exposes a much larger
operation set.  This section defines which operations a client <bcp14>MAY</bcp14>
send to a data file, which operations the metadata server <bcp14>MAY</bcp14>
send, and which operations a data server <bcp14>MUST</bcp14> reject.</t>
      <t>The restrictions below apply only to operations directed at a data
file on a data server.  Clients retain the full NFSv4.2 operation
set for files visible through the metadata server, including the
operations prohibited below (RENAME, LINK, CLONE, COPY, ACL-scoped
SETATTR, and so on).  The metadata server <bcp14>MAY</bcp14> internally use
operations on data files that clients <bcp14>MUST NOT</bcp14> send, as part of
its control-plane duties for the file (see
<xref target="sec-system-model-roles"/>).</t>
      <section anchor="sec-ops-mds">
        <name>Control Plane: Metadata Server to Data Server</name>
        <t>When the metadata server acts as a client to a data server, it is
managing the data file on behalf of the metadata file's namespace.
A data server <bcp14>MUST</bcp14> support the following operations on data files
when issued by the metadata server:</t>
        <ul spacing="normal">
          <li>
            <t>SEQUENCE, PUTFH, PUTROOTFH, GETFH (<xref target="RFC8881"/> Sections 18.46,
18.19, 18.21, 18.8): session and filehandle plumbing.</t>
          </li>
          <li>
            <t>LOOKUP (<xref target="RFC8881"/> Section 18.15): runway pool directory
traversal.</t>
          </li>
          <li>
            <t>GETATTR (<xref target="RFC8881"/> Section 18.7): reflected GETATTR after a
write layout is returned, and any other attribute queries the
metadata server needs to reconcile its cached view.</t>
          </li>
          <li>
            <t>SETATTR (<xref target="RFC8881"/> Section 18.30): data file truncate for
MDS-level SETATTR(size) fan-out, synthetic uid/gid rotation
for fencing, and mode-bit initialisation on runway assignment.</t>
          </li>
          <li>
            <t>CREATE (<xref target="RFC8881"/> Section 18.4): runway pool file creation.</t>
          </li>
          <li>
            <t>REMOVE (<xref target="RFC8881"/> Section 18.25): cleanup on metadata server file
unlink.</t>
          </li>
          <li>
            <t>OPEN, CLOSE (<xref target="RFC8881"/> Sections 18.16, 18.2): used by the
metadata server when it acts as a client to the data server
for InBand or proxy I/O.</t>
          </li>
          <li>
            <t>EXCHANGE_ID, CREATE_SESSION, DESTROY_SESSION,
BIND_CONN_TO_SESSION, DESTROY_CLIENTID (<xref target="RFC8881"/> Sections
18.35, 18.36, 18.37, 18.34, 18.50): control-session
management.  The metadata server sets
EXCHGID4_FLAG_USE_PNFS_MDS in its EXCHANGE_ID.  A data
server that supports the tight-coupling control protocol
(see <xref target="sec-tight-coupling-control-session"/>) identifies the
metadata server's session by EXCHGID4_FLAG_USE_PNFS_MDS and
accepts TRUST_STATEID, REVOKE_STATEID, and
BULK_REVOKE_STATEID on that session.</t>
          </li>
          <li>
            <t>TRUST_STATEID (<xref target="sec-TRUST_STATEID"/>), REVOKE_STATEID
(<xref target="sec-REVOKE_STATEID"/>), BULK_REVOKE_STATEID
(<xref target="sec-BULK_REVOKE_STATEID"/>): the MDS-to-DS tight-coupling
trust-table control operations.</t>
          </li>
        </ul>
        <t>The metadata server <bcp14>MAY</bcp14> also use other NFSv4.2 operations on data
files as implementation-defined control-plane actions (for
example, COPY or CLONE to migrate a data file between data
servers during a proxy server operation).  The list above is the
minimum set a flexible file v2 layout data server <bcp14>MUST</bcp14> support for the
metadata server's use.</t>
      </section>
      <section anchor="sec-ops-client">
        <name>Data Path: Client to Data Server</name>
        <t>A pNFS client with an active flexible file v2 layout <bcp14>MUST</bcp14> restrict
the operations it issues against data files to the operations
defined below.  A data server <bcp14>MUST</bcp14> reject any other operation on
a data file with NFS4ERR_NOTSUPP.</t>
        <section anchor="session-and-identity-plumbing">
          <name>Session and Identity Plumbing</name>
          <t>Required for all protection modes:</t>
          <ul spacing="normal">
            <li>
              <t>SEQUENCE, PUTFH, GETFH, PUTROOTFH (<xref target="RFC8881"/> Sections 18.46,
18.19, 18.8, 18.21).</t>
            </li>
            <li>
              <t>EXCHANGE_ID, CREATE_SESSION, DESTROY_SESSION,
BIND_CONN_TO_SESSION, DESTROY_CLIENTID (<xref target="RFC8881"/> Sections
18.35, 18.36, 18.37, 18.34, 18.50).</t>
            </li>
            <li>
              <t>RECLAIM_COMPLETE (<xref target="RFC8881"/> Section 18.51).</t>
            </li>
            <li>
              <t>SECINFO, SECINFO_NO_NAME (<xref target="RFC8881"/> Sections 18.29, 18.45):
discovery of acceptable security flavours on the data
server.</t>
            </li>
          </ul>
          <t>These operations are baseline NFSv4.2 session plumbing and are
supported on data files as on any NFSv4.2 file.</t>
        </section>
        <section anchor="sec-ds-stateid-model">
          <name>Stateid Model on the Data Server</name>
          <t>The stateid presented on a CHUNK_* operation is a <strong>layout
stateid</strong> returned by a prior LAYOUTGET against the metadata
server (see Section 18.43 of <xref target="RFC8881"/>), NOT an open
stateid, byte-range lock stateid, or delegation stateid.  A
pNFS client does NOT issue OPEN against the data server.
This is a meaningful departure from the stateid model in
Section 18.32 of <xref target="RFC8881"/> (which states that the WRITE
stateid "represents a value returned from a previous
byte-range LOCK or OPEN request or the stateid associated
with a delegation"), and clients implementing
Flexible File Version 2 <bcp14>MUST NOT</bcp14> carry over those
expectations to the data path.</t>
          <t>The three roles the RFC 8881 stateid plays on a regular
NFSv4 server split apart in the Flexible File Version 2
data-server model:</t>
          <dl>
            <dt>Open and share-mode tracking:</dt>
            <dd>
              <t>Lives at the metadata server, established by OPEN
(<xref target="RFC8881"/> Section 18.16) on the metadata-server
filehandle.  The metadata server's open stateid is NOT
exposed to data servers; share-mode conflicts are
resolved at the metadata server before LAYOUTGET grants
a layout.</t>
            </dd>
            <dt>Byte-range lock tracking:</dt>
            <dd>
              <t>Does not apply at the data server.  Locking on the data
path is chunk-range rather than byte-range, expressed
via CHUNK_LOCK (<xref target="sec-CHUNK_LOCK"/>), and the lock holder
is identified by chunk_owner4 (the {cg_client_id,
cg_gen_id} pair) rather than by a lock stateid.  A
client wanting byte-range locks on a file <bcp14>MUST</bcp14> acquire
them on the metadata-server filehandle, where standard
<xref target="RFC8881"/> Section 12 byte-range locking applies.</t>
            </dd>
            <dt>I/O authorization on the data server:</dt>
            <dd>
              <t>The layout stateid carried on CHUNK_* operations.  Under
tight coupling (<xref target="sec-tight-coupling-control"/>), the
metadata server registers each issued layout stateid
with the data server via TRUST_STATEID
(<xref target="sec-TRUST_STATEID"/>) and the data server validates
subsequent CHUNK_* stateids against the trust table.
Under loose coupling, the data server treats the layout
stateid as an opaque per-client token and authorizes by
the synthetic uid/gid the layout carries (see
<xref target="sec-Fencing-Clients"/>).</t>
            </dd>
          </dl>
          <t>Because the layout stateid does authorization but does not
identify a per-open or per-lock owner, a single client may
present the same layout stateid on many CHUNK_* operations
across many parallel writers within the client, without any
of the open-owner ordering constraints <xref target="RFC8881"/>
Section 8.2.2 imposes on regular NFSv4 stateids.  Chunk-
level write ordering and contention are resolved by the
per-chunk chunk_guard4 CAS (<xref target="sec-chunk_guard4"/>) and the
chunk-range CHUNK_LOCK, not by stateid-owner sequencing.</t>
        </section>
        <section anchor="getattr-on-a-data-file">
          <name>GETATTR on a Data File</name>
          <t>GETATTR <bcp14>MAY</bcp14> be issued by a client against a data file.  The
primary use case is repair: a repair client selected by
CB_CHUNK_REPAIR (<xref target="sec-CB_CHUNK_REPAIR"/>) may need to query the
per-server file size or allocation state when reconstructing a
payload, and the proxy server described informally in
<xref target="sec-system-model-roles"/> similarly benefits from attribute
queries on surviving mirrors.  Diagnostic use is also permitted.</t>
          <t>Clients <bcp14>MUST NOT</bcp14> treat GETATTR values returned by a data server as
authoritative for any file attribute (size, timestamps, owner,
mode, ACL, and so on).  The metadata server is the sole authority
for file attributes.  Values returned by a data server reflect the
per-server data file instance only and <bcp14>MAY</bcp14> diverge from the
metadata server's view, particularly during a write layout's
lifetime or during a proxy server transition.  A client that uses a
data-server GETATTR result to determine the file's visible size
will observe inconsistencies.</t>
        </section>
        <section anchor="sec-setattr-on-data-file">
          <name>SETATTR on a Data File</name>
          <t>Clients <bcp14>MUST NOT</bcp14> issue SETATTR against a data file.  A data server
<bcp14>MUST</bcp14> reject a client SETATTR with NFS4ERR_NOTSUPP.</t>
          <t>Attribute changes on data files <bcp14>MUST</bcp14> be reconciled with the
metadata server's view and cannot be applied unilaterally by a
client.  A client that wants to truncate, change the mode, change
ownership, or otherwise modify attributes on a file <bcp14>MUST</bcp14> issue
SETATTR to the metadata server for the file's metadata server handle; the
metadata server fans the change out to the data files as a
control-plane operation.</t>
          <t>This rule explicitly covers truncate (SETATTR with size in the
bitmap): a client <bcp14>MUST NOT</bcp14> truncate a data file directly.  See
<xref target="sec-mds-truncate-ec"/> for how the metadata server handles
truncate on erasure-coded files.  Similarly, a client <bcp14>MUST NOT</bcp14>
issue DEALLOCATE against a data file; see the next subsection.</t>
        </section>
        <section anchor="sec-mds-truncate-ec">
          <name>MDS-Driven Truncate on Erasure-Coded Files</name>
          <t>A client that wants to truncate an erasure-coded file <bcp14>MUST</bcp14>
issue SETATTR(FATTR4_SIZE) to the metadata-server filehandle
(see <xref target="sec-setattr-on-data-file"/>).  The metadata server
translates the logical truncate into per-shard size changes
across the data servers in each mirror.</t>
          <dl>
            <dt>Stripe-aligned truncate:</dt>
            <dd>
              <t>When the new size lies on a stripe boundary (including
zero), no chunk re-encoding is required.  The metadata
server computes per-shard sizes from the codec geometry it
issued in the layout (k, m, and the projection parameters
for Mojette; see <xref target="sec-mojette-encoding"/>) and issues
per-data-server SETATTR(FATTR4_SIZE) with the computed
per-shard size.  Geometry parameters are sufficient
arithmetic; no codec implementation is required at the
metadata server.</t>
            </dd>
            <dt>Non-stripe-aligned truncate:</dt>
            <dd>
              <t>When the new size falls within a stripe, the data shards
covering the partial stripe must be truncated and the
parity shards re-encoded from the truncated data.  Because
re-encoding requires running the erasure transform, the
metadata server <bcp14>MUST</bcp14> delegate this case to a codec-aware
actor: either a Proxy Server
(<xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>) for
proxy-mediated truncate, or a codec-aware client selected
per <xref target="sec-repair-selection"/> via CB_CHUNK_REPAIR with the
affected partial-stripe chunks as the repair target.  If
neither path is available, the metadata server <bcp14>MUST</bcp14> return
NFS4ERR_NOTSUPP to the originating SETATTR.</t>
            </dd>
          </dl>
          <t>The metadata server knows codec geometry from the layout but
is not required to include a codec implementation.  The
delegation rule above accommodates a metadata server that has
geometry knowledge only.</t>
        </section>
        <section anchor="passthrough-data-files-ffv2encodingpassthrough">
          <name>PASSTHROUGH Data Files (FFV2_ENCODING_PASSTHROUGH)</name>
          <t>For a mirror whose ffv2m_coding_type_data is
FFV2_ENCODING_PASSTHROUGH (see <xref target="sec-encoding-passthrough"/>),
client operations on the data file follow the same pattern as
the File Layout Type in <xref target="RFC8881"/> Section 13.6 and the
Flexible File Version 1 Layout Type in <xref target="RFC8435"/>:</t>
          <t>Required:</t>
          <ul spacing="normal">
            <li>
              <t>READ (<xref target="RFC8881"/> Section 18.22).</t>
            </li>
            <li>
              <t>WRITE (<xref target="RFC8881"/> Section 18.32).</t>
            </li>
            <li>
              <t>COMMIT (<xref target="RFC8881"/> Section 18.3).</t>
            </li>
          </ul>
          <t>Optional (the client <bcp14>MAY</bcp14> send, and the data server <bcp14>MAY</bcp14> support):</t>
          <ul spacing="normal">
            <li>
              <t>READ_PLUS (<xref target="RFC7862"/> Section 15.10): hole-aware reads.</t>
            </li>
            <li>
              <t>SEEK (<xref target="RFC7862"/> Section 15.11): hole and data detection.</t>
            </li>
            <li>
              <t>ALLOCATE (<xref target="RFC7862"/> Section 15.1): space reservation hint.</t>
            </li>
          </ul>
          <t>The client <bcp14>MUST NOT</bcp14> send:</t>
          <ul spacing="normal">
            <li>
              <t>DEALLOCATE (<xref target="RFC7862"/> Section 15.4): hole punching is a
metadata-server responsibility; the client issues DEALLOCATE
on the metadata-server filehandle, and the metadata server
fans out to the data servers as a control-plane operation.</t>
            </li>
          </ul>
        </section>
        <section anchor="chunked-data-files-ffv2encodingmirrored-ffv2encodingmojette-ffv2encodingrsvandermonde">
          <name>Chunked Data Files (FFV2<em>ENCODING_MIRRORED, FFV2_ENCODING_MOJETTE</em>*, FFV2_ENCODING_RS_VANDERMONDE)</name>
          <t>For a mirror whose ffv2m_coding_type_data is any of the chunked
coding types defined in this document
(FFV2<em>ENCODING_MIRRORED, FFV2_ENCODING_MOJETTE_SYSTEMATIC,
FFV2_ENCODING_MOJETTE_NON_SYSTEMATIC,
FFV2_ENCODING_RS_VANDERMONDE), client operations use the CHUNK</em>*
operations rather than READ / WRITE / COMMIT.</t>
          <t>Required for all erasure-coded clients:</t>
          <ul spacing="normal">
            <li>
              <t>CHUNK_WRITE (<xref target="sec-CHUNK_WRITE"/>).</t>
            </li>
            <li>
              <t>CHUNK_READ (<xref target="sec-CHUNK_READ"/>).</t>
            </li>
            <li>
              <t>CHUNK_FINALIZE (<xref target="sec-CHUNK_FINALIZE"/>).</t>
            </li>
            <li>
              <t>CHUNK_COMMIT (<xref target="sec-CHUNK_COMMIT"/>).</t>
            </li>
            <li>
              <t>CHUNK_HEADER_READ (<xref target="sec-CHUNK_HEADER_READ"/>).</t>
            </li>
            <li>
              <t>CHUNK_LOCK (<xref target="sec-CHUNK_LOCK"/>) and CHUNK_UNLOCK
(<xref target="sec-CHUNK_UNLOCK"/>).</t>
            </li>
            <li>
              <t>CHUNK_ROLLBACK (<xref target="sec-CHUNK_ROLLBACK"/>).</t>
            </li>
          </ul>
          <t>Required for clients that participate in repair:</t>
          <ul spacing="normal">
            <li>
              <t>CHUNK_ERROR (<xref target="sec-CHUNK_ERROR"/>).</t>
            </li>
            <li>
              <t>CHUNK_REPAIRED (<xref target="sec-CHUNK_REPAIRED"/>).</t>
            </li>
            <li>
              <t>CHUNK_WRITE_REPAIR (<xref target="sec-CHUNK_WRITE_REPAIR"/>).</t>
            </li>
          </ul>
          <t>Clients <bcp14>MUST NOT</bcp14> send:</t>
          <ul spacing="normal">
            <li>
              <t>READ, WRITE, COMMIT against an erasure-coded data file.  A
data server <bcp14>MUST</bcp14> reject these with NFS4ERR_NOTSUPP and <bcp14>MAY</bcp14>
log the client for operator attention; this case is almost
always a client bug in which the client did not inspect the
mirror's ffv2m_coding_type_data before issuing I/O.</t>
            </li>
            <li>
              <t>READ_PLUS, SEEK, ALLOCATE, DEALLOCATE against an erasure-coded data file.  Chunk-level allocation is a
metadata-server responsibility.</t>
            </li>
            <li>
              <t>SETATTR against an erasure-coded data file (the general
prohibition in <xref target="sec-setattr-on-data-file"/> applies to all
data files; truncate in particular is handled by the
metadata server per <xref target="sec-mds-truncate-ec"/>).</t>
            </li>
          </ul>
        </section>
        <section anchor="operations-that-must-not-be-sent-to-a-data-file">
          <name>Operations That MUST NOT Be Sent to a Data File</name>
          <t>Clients <bcp14>MUST NOT</bcp14> send the following operations to a data server
on a data file, regardless of protection mode.  A data server
<bcp14>MUST</bcp14> return NFS4ERR_NOTSUPP:</t>
          <ul spacing="normal">
            <li>
              <t>OPEN, CLOSE, OPEN_DOWNGRADE, OPEN_CONFIRM (<xref target="RFC8881"/>
Sections 18.16, 18.2, 18.18, 18.20).  Opens occur on the
metadata server; the stateid obtained there is used on the
data path.</t>
            </li>
            <li>
              <t>LOCK, LOCKU, LOCKT, RELEASE_LOCKOWNER (<xref target="RFC8881"/> Sections
18.10, 18.11, 18.13, 18.24).  Byte-range locks on data files
are not supported; erasure-coded files use CHUNK_LOCK, and
mirrored files rely on metadata-server coordination.</t>
            </li>
            <li>
              <t>DELEGPURGE, DELEGRETURN, WANT_DELEGATION (<xref target="RFC8881"/> Sections
18.5, 18.6 and <xref target="RFC7862"/> Section 15.3).  Delegations are
issued by the metadata server.</t>
            </li>
            <li>
              <t>Any operation whose purpose is to manipulate the file's
namespace: RENAME, LINK, SYMLINK, CREATE (at the file-creation use, not metadata server runway creation), REMOVE.  Namespace
operations belong on the metadata server.</t>
            </li>
            <li>
              <t>Any ACL-scoped SETATTR or GETATTR bit (FATTR4_ACL,
FATTR4_DACL, FATTR4_SACL).  Access control on data files is
delegated to the metadata server.</t>
            </li>
            <li>
              <t>CLONE, COPY, COPY_NOTIFY, OFFLOAD_CANCEL, OFFLOAD_STATUS
(<xref target="RFC7862"/> Sections 15.13, 15.2, 15.3, 15.8, 15.9).
File-level data migration is a metadata-server responsibility.</t>
            </li>
            <li>
              <t>LAYOUTGET, LAYOUTCOMMIT, LAYOUTRETURN, LAYOUTSTATS,
LAYOUTERROR, GETDEVICEINFO, GETDEVICELIST (<xref target="RFC8881"/>
Sections 18.43, 18.42, 18.44, <xref target="RFC7862"/> Sections 15.7,
15.6, <xref target="RFC8881"/> Sections 18.40, 18.41).  Layout operations
belong on the metadata server.</t>
            </li>
            <li>
              <t>TRUST_STATEID, REVOKE_STATEID, BULK_REVOKE_STATEID
(<xref target="sec-TRUST_STATEID"/>, <xref target="sec-REVOKE_STATEID"/>,
<xref target="sec-BULK_REVOKE_STATEID"/>).  These are MDS-to-DS
control-plane operations; a data server rejects them with
NFS4ERR_PERM when received on a client session (see
<xref target="sec-tight-coupling-control-session"/>).</t>
            </li>
          </ul>
        </section>
      </section>
      <section anchor="callback-path-data-server-to-client">
        <name>Callback Path: Data Server to Client</name>
        <t>A data server does not call back directly to pNFS clients.
Recall notifications and repair coordination flow through the
metadata server's backchannel session with the client.  The
callbacks a client will observe that affect its data files are:</t>
        <ul spacing="normal">
          <li>
            <t>CB_LAYOUTRECALL (<xref target="RFC8881"/> Section 20.3).</t>
          </li>
          <li>
            <t>CB_NOTIFY_DEVICEID (<xref target="RFC8881"/> Section 20.12).</t>
          </li>
          <li>
            <t>CB_RECALL_ANY (<xref target="RFC8881"/> Section 20.6).</t>
          </li>
          <li>
            <t>CB_CHUNK_REPAIR (<xref target="sec-CB_CHUNK_REPAIR"/>).</t>
          </li>
        </ul>
        <t>A data server influences these callbacks only indirectly, via
LAYOUTERROR reports the client issues to the metadata server or
by returning error codes that prompt the client to report.  A
data server <bcp14>MUST NOT</bcp14> attempt to send CB_* operations to clients
directly.</t>
      </section>
      <section anchor="summary-table">
        <name>Summary Table</name>
        <t>The classification below adapts the operation taxonomy of
<xref target="RFC8881"/> Section 17 (<bcp14>REQUIRED</bcp14> / <bcp14>RECOMMENDED</bcp14> / <bcp14>OPTIONAL</bcp14> /
<bcp14>MUST NOT</bcp14> IMPLEMENT) to the two-direction per-operation view a
Flexible File Version 2 data server requires.  Two of the four
labels in the table below match <xref target="RFC8881"/> usage; the other
two are extensions specific to this document.</t>
        <dl>
          <dt><bcp14>REQUIRED</bcp14>:</dt>
          <dd>
            <t>The data server <bcp14>MUST</bcp14> support the operation on this path.
Matches <xref target="RFC8881"/> Section 17 REQ.</t>
          </dd>
          <dt><bcp14>OPTIONAL</bcp14>:</dt>
          <dd>
            <t>The data server <bcp14>MAY</bcp14> support the operation; if it does, the
actor in this column <bcp14>MUST</bcp14> tolerate the absence of support.
Matches <xref target="RFC8881"/> Section 17 OPT.</t>
          </dd>
          <dt><bcp14>MUST NOT</bcp14>:</dt>
          <dd>
            <t>The actor in this column <bcp14>MUST NOT</bcp14> send the operation, and
the data server <bcp14>MUST</bcp14> reject it with NFS4ERR_NOTSUPP.  This
per-direction prohibition extends <xref target="RFC8881"/> Section 17's
single-axis <bcp14>MUST NOT</bcp14> IMPLEMENT classification: an operation
may be forbidden on one path (client to data server) while
required on another (metadata server to data server).
SETATTR is the canonical example.</t>
          </dd>
          <dt><bcp14>MAY</bcp14>:</dt>
          <dd>
            <t>The metadata server <bcp14>MAY</bcp14> use the operation as an
implementation-defined control-plane action.  Not in
<xref target="RFC8881"/> Section 17; specific to the metadata-server-to-
data-server path in this document.</t>
          </dd>
        </dl>
        <table anchor="tbl-ops-allowed">
          <name>NFSv4.2 operations allowed on data files</name>
          <thead>
            <tr>
              <th align="left">Operation</th>
              <th align="left">Client -&gt; data server</th>
              <th align="left">metadata server -&gt; data server</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">SEQUENCE, PUTFH, GETFH, PUTROOTFH</td>
              <td align="left">
                <bcp14>REQUIRED</bcp14></td>
              <td align="left">
                <bcp14>REQUIRED</bcp14></td>
            </tr>
            <tr>
              <td align="left">EXCHANGE_ID, CREATE_SESSION, DESTROY_SESSION, BIND_CONN_TO_SESSION, DESTROY_CLIENTID</td>
              <td align="left">
                <bcp14>REQUIRED</bcp14></td>
              <td align="left">
                <bcp14>REQUIRED</bcp14></td>
            </tr>
            <tr>
              <td align="left">RECLAIM_COMPLETE</td>
              <td align="left">
                <bcp14>REQUIRED</bcp14></td>
              <td align="left">
                <bcp14>REQUIRED</bcp14></td>
            </tr>
            <tr>
              <td align="left">SECINFO, SECINFO_NO_NAME</td>
              <td align="left">
                <bcp14>REQUIRED</bcp14></td>
              <td align="left">
                <bcp14>MAY</bcp14></td>
            </tr>
            <tr>
              <td align="left">GETATTR</td>
              <td align="left">
                <bcp14>OPTIONAL</bcp14> (non-authoritative)</td>
              <td align="left">
                <bcp14>REQUIRED</bcp14></td>
            </tr>
            <tr>
              <td align="left">SETATTR</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>REQUIRED</bcp14></td>
            </tr>
            <tr>
              <td align="left">LOOKUP, CREATE, REMOVE</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>REQUIRED</bcp14></td>
            </tr>
            <tr>
              <td align="left">READ, WRITE, COMMIT</td>
              <td align="left">
                <bcp14>REQUIRED</bcp14> (mirrored); <bcp14>MUST NOT</bcp14> (erasure-coded)</td>
              <td align="left">
                <bcp14>MAY</bcp14></td>
            </tr>
            <tr>
              <td align="left">READ_PLUS, SEEK, ALLOCATE</td>
              <td align="left">
                <bcp14>OPTIONAL</bcp14> (mirrored); <bcp14>MUST NOT</bcp14> (erasure-coded)</td>
              <td align="left">
                <bcp14>MAY</bcp14></td>
            </tr>
            <tr>
              <td align="left">DEALLOCATE</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>MAY</bcp14></td>
            </tr>
            <tr>
              <td align="left">CHUNK_WRITE, CHUNK_READ, CHUNK_FINALIZE, CHUNK_COMMIT, CHUNK_HEADER_READ, CHUNK_LOCK, CHUNK_UNLOCK, CHUNK_ROLLBACK</td>
              <td align="left">
                <bcp14>REQUIRED</bcp14> (erasure-coded); <bcp14>MUST NOT</bcp14> (mirrored)</td>
              <td align="left">not used</td>
            </tr>
            <tr>
              <td align="left">CHUNK_ERROR, CHUNK_REPAIRED, CHUNK_WRITE_REPAIR</td>
              <td align="left">
                <bcp14>REQUIRED</bcp14> (erasure-coded repair clients); <bcp14>MUST NOT</bcp14> (mirrored)</td>
              <td align="left">not used</td>
            </tr>
            <tr>
              <td align="left">OPEN, CLOSE, OPEN_DOWNGRADE, OPEN_CONFIRM</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>OPTIONAL</bcp14> (proxy I/O)</td>
            </tr>
            <tr>
              <td align="left">LOCK, LOCKU, LOCKT, RELEASE_LOCKOWNER</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
            </tr>
            <tr>
              <td align="left">DELEGPURGE, DELEGRETURN, WANT_DELEGATION</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
            </tr>
            <tr>
              <td align="left">RENAME, LINK, SYMLINK</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
            </tr>
            <tr>
              <td align="left">CLONE, COPY, COPY_NOTIFY, OFFLOAD_CANCEL, OFFLOAD_STATUS</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>MAY</bcp14> (data migration)</td>
            </tr>
            <tr>
              <td align="left">LAYOUTGET, LAYOUTCOMMIT, LAYOUTRETURN, LAYOUTSTATS, LAYOUTERROR, GETDEVICEINFO, GETDEVICELIST</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
            </tr>
            <tr>
              <td align="left">ACL-scoped GETATTR/SETATTR bits</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>MAY</bcp14></td>
            </tr>
            <tr>
              <td align="left">TRUST_STATEID, REVOKE_STATEID, BULK_REVOKE_STATEID</td>
              <td align="left">
                <bcp14>MUST NOT</bcp14></td>
              <td align="left">
                <bcp14>REQUIRED</bcp14> (tight coupling)</td>
            </tr>
          </tbody>
        </table>
      </section>
    </section>
    <section anchor="sec-layouthint">
      <name>Flexible File Version 2 Layout Type Return</name>
      <t>layoutreturn_file4 is used in the LAYOUTRETURN operation to convey
layout-type-specific information to the server.  It is defined in
Section 18.44.1 of <xref target="RFC8881"/> (also shown in <xref target="fig-LAYOUTRETURN"/>).</t>
      <figure anchor="fig-LAYOUTRETURN">
        <name>Layout Return XDR</name>
        <sourcecode type="xdr"><![CDATA[
      /* Constants used for LAYOUTRETURN and CB_LAYOUTRECALL */
      const LAYOUT4_RET_REC_FILE      = 1;
      const LAYOUT4_RET_REC_FSID      = 2;
      const LAYOUT4_RET_REC_ALL       = 3;

      enum layoutreturn_type4 {
              LAYOUTRETURN4_FILE = LAYOUT4_RET_REC_FILE,
              LAYOUTRETURN4_FSID = LAYOUT4_RET_REC_FSID,
              LAYOUTRETURN4_ALL  = LAYOUT4_RET_REC_ALL
      };

   struct layoutreturn_file4 {
           offset4         lrf_offset;
           length4         lrf_length;
           stateid4        lrf_stateid;
           /* layouttype4 specific data */
           opaque          lrf_body<>;
   };

   union layoutreturn4 switch(layoutreturn_type4 lr_returntype) {
           case LAYOUTRETURN4_FILE:
                   layoutreturn_file4      lr_layout;
           default:
                   void;
   };

   struct LAYOUTRETURN4args {
           /* CURRENT_FH: file */
           bool                    lora_reclaim;
           layouttype4             lora_layout_type;
           layoutiomode4           lora_iomode;
           layoutreturn4           lora_layoutreturn;
   };
]]></sourcecode>
      </figure>
      <t>If the lora_layout_type layout type is LAYOUT4_FLEX_FILES and the
lr_returntype is LAYOUTRETURN4_FILE, then the lrf_body opaque value
is defined by ffv2_layoutreturn4 (see <xref target="sec-ffv2_layoutreturn4"/>).  This
allows the client to report I/O error information or layout usage
statistics back to the metadata server as defined below.  Note that
while the data structures are built on concepts introduced in
NFSv4.2, the effective discriminated union (lora_layout_type combined
with ffv2_layoutreturn4) allows for an NFSv4.1 metadata server to
utilize the data.</t>
      <section anchor="sec-io-error">
        <name>I/O Error Reporting</name>
        <section anchor="sec-ffv2_ioerr4">
          <name>ffv2_ioerr4</name>
          <figure anchor="fig-ffv2_ioerr4">
            <name>ffv2_ioerr4</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_ioerr4 {
   ///         offset4        ffv2ie_offset;
   ///         length4        ffv2ie_length;
   ///         stateid4       ffv2ie_stateid;
   ///         device_error4  ffv2ie_errors<>;
   /// };
   ///
]]></sourcecode>
          </figure>
          <t>Recall that <xref target="RFC7862"/> defines device_error4 as in <xref target="fig-device_error4"/>:</t>
          <figure anchor="fig-device_error4">
            <name>device_error4</name>
            <sourcecode type="xdr"><![CDATA[
   struct device_error4 {
           deviceid4       de_deviceid;
           nfsstat4        de_status;
           nfs_opnum4      de_opnum;
   };
]]></sourcecode>
          </figure>
          <t>The ffv2_ioerr4 structure is used to return error indications for
data files that generated errors during data transfers.  These are
hints to the metadata server that there are problems with that file.
For each error, ffv2ie_errors.de_deviceid, ffv2ie_offset, and ffv2ie_length
represent the storage device and byte range within the file in which
the error occurred; ffv2ie_errors represents the operation and type
of error.  The use of device_error4 is described in Section 15.6
of <xref target="RFC7862"/>.</t>
          <t>Even though the storage device might be accessed via NFSv3 and
reports back NFSv3 errors to the client, the client is responsible
for mapping these to appropriate NFSv4 status codes as de_status.
Likewise, the NFSv3 operations need to be mapped to equivalent NFSv4
operations.</t>
        </section>
      </section>
      <section anchor="sec-layout-stats">
        <name>Layout Usage Statistics</name>
        <section anchor="ffiolatency4">
          <name>ff_io_latency4</name>
          <figure anchor="fig-ff_io_latency4">
            <name>ff_io_latency4</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_io_latency4 {
   ///         uint64_t       ffv2il_ops_requested;
   ///         uint64_t       ffv2il_bytes_requested;
   ///         uint64_t       ffv2il_ops_completed;
   ///         uint64_t       ffv2il_bytes_completed;
   ///         uint64_t       ffv2il_bytes_not_delivered;
   ///         nfstime4       ffv2il_total_busy_time;
   ///         nfstime4       ffv2il_aggregate_completion_time;
   /// };
   ///
]]></sourcecode>
          </figure>
          <t>Both operation counts and bytes transferred are kept in the
ff_io_latency4 (see <xref target="fig-ff_io_latency4"/>).  As seen in ff_layoutupdate4
(see <xref target="sec-ff_layoutupdate4"/>), READ and WRITE operations are
aggregated separately.  READ operations are used for the ff_io_latency4
ffv2l_read.  Both WRITE and COMMIT operations are used for the
ff_io_latency4 ffv2l_write.  "Requested" counters track what the
client is attempting to do, and "completed" counters track what was
done.  There is no requirement that the client only report completed
results that have matching requested results from the reported
period.</t>
          <t>ffv2il_bytes_not_delivered is used to track the aggregate number of
bytes requested but not fulfilled due to error conditions.
ffv2il_total_busy_time is the aggregate time spent with outstanding
RPC calls. ffv2il_aggregate_completion_time is the sum of all round-trip
times for completed RPC calls.</t>
          <t>In Section 3.3.1 of <xref target="RFC8881"/>, the nfstime4 is defined as the
number of seconds and nanoseconds since midnight or zero hour January
1, 1970 Coordinated Universal Time (UTC).  The use of nfstime4 in
ff_io_latency4 is to store time since the start of the first I/O
from the client after receiving the layout.  In other words, these
are to be decoded as duration and not as a date and time.</t>
          <t>Note that LAYOUTSTATS are cumulative, i.e., not reset each time the
operation is sent.  If two LAYOUTSTATS operations for the same file
and layout stateid originate from the same NFS client and are
processed at the same time by the metadata server, then the one
containing the larger values contains the most recent time series
data.</t>
        </section>
        <section anchor="sec-ff_layoutupdate4">
          <name>ff_layoutupdate4</name>
          <figure anchor="fig-ff_layoutupdate4">
            <name>ff_layoutupdate4</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_layoutupdate4 {
   ///         netaddr4         ffv2l_addr;
   ///         nfs_fh4          ffv2l_fhandle;
   ///         ffv2_io_latency4 ffv2l_read;
   ///         ffv2_io_latency4 ffv2l_write;
   ///         nfstime4         ffv2l_duration;
   ///         bool             ffv2l_local;
   /// };
   ///
]]></sourcecode>
          </figure>
          <t>ffv2l_addr differentiates which network address the client is connected
to on the storage device.  In the case of multipathing, ffv2l_fhandle
indicates which read-only copy was selected. ffv2l_read and ffv2l_write
convey the latencies for both READ and WRITE operations, respectively.
ffv2l_duration is used to indicate the time period over which the
statistics were collected.  If true, ffv2l_local indicates that the
I/O was serviced by the client's cache.  This flag allows the client
to inform the metadata server about "hot" access to a file it would
not normally be allowed to report on.</t>
        </section>
        <section anchor="ffiostats4">
          <name>ff_iostats4</name>
          <figure anchor="fig-ff_iostats4">
            <name>ff_iostats4</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_iostats4 {
   ///         offset4            ffv2is_offset;
   ///         length4            ffv2is_length;
   ///         stateid4           ffv2is_stateid;
   ///         io_info4           ffv2is_read;
   ///         io_info4           ffv2is_write;
   ///         deviceid4          ffv2is_deviceid;
   ///         ffv2_layoutupdate4 ffv2is_layoutupdate;
   /// };
   ///
]]></sourcecode>
          </figure>
          <t><xref target="RFC7862"/> defines io_info4 as in <xref target="fig-ff_iostats4"/>.</t>
          <figure anchor="fig-io_info4">
            <name>io_info4</name>
            <sourcecode type="xdr"><![CDATA[
   struct io_info4 {
           uint64_t        ii_count;
           uint64_t        ii_bytes;
   };
]]></sourcecode>
          </figure>
          <t>With pNFS, data transfers are performed directly between the pNFS
client and the storage devices.  Therefore, the metadata server has
no direct knowledge of the I/O operations being done and thus cannot
create on its own statistical information about client I/O to
optimize the data storage location.  ff_iostats4 <bcp14>MAY</bcp14> be used by the
client to report I/O statistics back to the metadata server upon
returning the layout.</t>
          <t>Since it is not feasible for the client to report every I/O that
used the layout, the client <bcp14>MAY</bcp14> identify "hot" byte ranges for which
to report I/O statistics.  The definition and/or configuration
mechanism of what is considered "hot" and the size of the reported
byte range are out of the scope of this document.  For client
implementation, providing reasonable default values and an optional
run-time management interface to control these parameters is
suggested.  For example, a client can define the default byte-range
resolution to be 1 MB in size and the thresholds for reporting to
be 1 MB/second or 10 I/O operations per second.</t>
          <t>For each byte range, ffv2is_offset and ffv2is_length represent the
starting offset of the range and the range length in bytes.
ffv2is_read.ii_count, ffv2is_read.ii_bytes, ffv2is_write.ii_count, and
ffv2is_write.ii_bytes represent the number of contiguous READ and
WRITE I/Os and the respective aggregate number of bytes transferred
within the reported byte range.</t>
          <t>The combination of ffv2is_deviceid and ffv2l_addr uniquely identifies
both the storage path and the network route to it.  Finally,
ffv2l_fhandle allows the metadata server to differentiate between
multiple read-only copies of the file on the same storage device.</t>
        </section>
      </section>
      <section anchor="sec-ffv2_layoutreturn4">
        <name>ffv2_layoutreturn4</name>
        <figure anchor="fig-ffv2_layoutreturn4">
          <name>ffv2_layoutreturn4</name>
          <sourcecode type="xdr"><![CDATA[
   /// struct ffv2_layoutreturn4 {
   ///         ffv2_ioerr4     ffv2lr_ioerr_report<>;
   ///         ffv2_iostats4   ffv2lr_iostats_report<>;
   /// };
   ///
]]></sourcecode>
        </figure>
        <t>When data file I/O operations fail, ffv2lr_ioerr_report&lt;&gt; is used to
report these errors to the metadata server as an array of elements
of type ffv2_ioerr4.  Each element in the array represents an error
that occurred on the data file identified by ffv2ie_errors.de_deviceid.
If no errors are to be reported, the size of the ffv2lr_ioerr_report&lt;&gt;
array is set to zero.  The client <bcp14>MAY</bcp14> also use ffv2lr_iostats_report&lt;&gt;
to report a list of I/O statistics as an array of elements of type
ff_iostats4.  Each element in the array represents statistics for
a particular byte range.  Byte ranges are not guaranteed to be
disjoint and <bcp14>MAY</bcp14> repeat or intersect.</t>
      </section>
    </section>
    <section anchor="sec-LAYOUTERROR">
      <name>Flexible File Version 2 Layout Type LAYOUTERROR</name>
      <t>If the client is using NFSv4.2 to communicate with the metadata
server, then instead of waiting for a LAYOUTRETURN to send error
information to the metadata server (see <xref target="sec-io-error"/>), it <bcp14>MAY</bcp14>
use LAYOUTERROR (see Section 15.6 of <xref target="RFC7862"/>) to communicate
that information.  For the flexible file v2 layout, this means
that LAYOUTERROR4args is treated the same as ffv2_ioerr4.</t>
    </section>
    <section anchor="flexible-file-version-2-layout-type-layoutstats">
      <name>Flexible File Version 2 Layout Type LAYOUTSTATS</name>
      <t>If the client is using NFSv4.2 to communicate with the metadata
server, then instead of waiting for a LAYOUTRETURN to send I/O
statistics to the metadata server (see <xref target="sec-layout-stats"/>), it
<bcp14>MAY</bcp14> use LAYOUTSTATS (see Section 15.7 of <xref target="RFC7862"/>) to communicate
that information.  For the flexible file v2 layout, this means
that LAYOUTSTATS4args.lsa_layoutupdate is overloaded with the same
contents as in ffv2is_layoutupdate.</t>
    </section>
    <section anchor="flexible-file-version-2-layout-type-creation-hint">
      <name>Flexible File Version 2 Layout Type Creation Hint</name>
      <t>The layouthint4 type is defined in the <xref target="RFC8881"/> as in
<xref target="fig-layouthint4-v1"/>.</t>
      <figure anchor="fig-layouthint4-v1">
        <name>layouthint4 v1</name>
        <sourcecode type="xdr"><![CDATA[
   struct layouthint4 {
       layouttype4        loh_type;
       opaque             loh_body<>;
   };
]]></sourcecode>
      </figure>
      <artwork><![CDATA[
                          {{fig-layouthint4-v1}}
]]></artwork>
      <t>The layouthint4 structure is used by the client to pass a hint about
the type of layout it would like created for a particular file.  If
the loh_type layout type is LAYOUT4_FLEX_FILES, then the loh_body
opaque value is defined by the ff_layouthint4 type.</t>
    </section>
    <section anchor="fflayouthint4">
      <name>ff_layouthint4</name>
      <figure anchor="fig-ff_layouthint4-v2">
        <name>ff_layouthint4 (v1 compatibility)</name>
        <sourcecode type="xdr"><![CDATA[
   union ff_mirrors_hint switch (bool ffmc_valid) {
       case TRUE:
           uint32_t    ffmc_mirrors;
       case FALSE:
           void;
   };

   struct ff_layouthint4 {
       ff_mirrors_hint    fflh_mirrors_hint;
   };
]]></sourcecode>
      </figure>
      <t>The ff_layouthint4 is retained for backwards compatibility with
flexible file v1 layouts.  For flexible file v2 layouts, clients
<bcp14>SHOULD</bcp14> use ffv2_layouthint4 (<xref target="fig-ffv2_layouthint4"/>) instead,
which provides coding type selection and data protection geometry
hints via ffv2_data_protection4 (<xref target="fig-ffv2_data_protection4"/>).</t>
    </section>
    <section anchor="recalling-a-layout">
      <name>Recalling a Layout</name>
      <t>While Section 12.5.5 of <xref target="RFC8881"/> discusses reasons independent
of layout type for recalling a layout, the flexible file v2 layout
type metadata server should recall outstanding layouts in the
following cases:</t>
      <ul spacing="normal">
        <li>
          <t>When the file's security policy changes, i.e., ACLs or permission
mode bits are set.</t>
        </li>
        <li>
          <t>When the file's layout changes, rendering outstanding layouts
invalid.</t>
        </li>
        <li>
          <t>When existing layouts are inconsistent with the need to enforce
locking constraints.</t>
        </li>
        <li>
          <t>When existing layouts are inconsistent with the requirements
regarding resilvering as described in <xref target="sec-mds-resilvering"/>.</t>
        </li>
      </ul>
      <section anchor="cbrecallany">
        <name>CB_RECALL_ANY</name>
        <t>The metadata server can use the CB_RECALL_ANY callback operation
to notify the client to return some or all of its layouts.  Section
22.3 of <xref target="RFC8881"/> defines the allowed types of the "NFSv4 Recallable
Object Types Registry".</t>
        <figure anchor="fig-new-rca4">
          <name>RCA4 masks for v2</name>
          <sourcecode type="xdr"><![CDATA[
   /// const RCA4_TYPE_MASK_FF2_LAYOUT_MIN     = 20;
   /// const RCA4_TYPE_MASK_FF2_LAYOUT_MAX     = 21;
   ///
]]></sourcecode>
        </figure>
        <figure anchor="fig-CB_RECALL_ANY4args">
          <name>CB_RECALL_ANY4args XDR</name>
          <sourcecode type="xdr"><![CDATA[
   struct  CB_RECALL_ANY4args      {
       uint32_t        craa_layouts_to_keep;
       bitmap4         craa_type_mask;
   };
]]></sourcecode>
        </figure>
        <t>Typically, CB_RECALL_ANY will be used to recall client state when
the server needs to reclaim resources.  The craa_type_mask bitmap
specifies the type of resources that are recalled, and the
craa_layouts_to_keep value specifies how many of the recalled
flexible file v2 layouts the client is allowed to keep.  The mask flags
for the flexible file v2 layout are defined as in <xref target="fig-mask-flags"/>.</t>
        <figure anchor="fig-mask-flags">
          <name>Recall Mask Flags for v2</name>
          <sourcecode type="xdr"><![CDATA[
   /// enum ffv2_cb_recall_any_mask {
   ///     PNFS_FF_RCA4_TYPE_MASK_READ = 20,
   ///     PNFS_FF_RCA4_TYPE_MASK_RW   = 21
   /// };
   ///
]]></sourcecode>
        </figure>
        <t>The flags represent the iomode of the recalled layouts.  In response,
the client <bcp14>SHOULD</bcp14> return layouts of the recalled iomode that it
needs the least, keeping at most craa_layouts_to_keep flexible file
layouts.</t>
        <t>The PNFS_FF_RCA4_TYPE_MASK_READ flag notifies the client to return
layouts of iomode LAYOUTIOMODE4_READ.  Similarly, the
PNFS_FF_RCA4_TYPE_MASK_RW flag notifies the client to return layouts
of iomode LAYOUTIOMODE4_RW.  When both mask flags are set, the
client is notified to return layouts of either iomode.</t>
      </section>
    </section>
    <section anchor="layout-revocation-and-fencing">
      <name>Layout Revocation and Fencing</name>
      <t>In cases where clients are uncommunicative and their lease has
expired, or when clients fail to return recalled layouts within
a lease period, the metadata server <bcp14>MAY</bcp14> revoke client layouts
and reassign these resources to other clients (see Section
12.5.5 of <xref target="RFC8881"/>).  To avoid data corruption from a
revoked client continuing to issue I/O, the metadata server
<bcp14>MUST</bcp14> fence the revoked client from the affected data files.
The mechanism varies by coupling model and by whether the
client's layout stateid has been registered with the data
servers via TRUST_STATEID:</t>
      <dl>
        <dt>Loosely coupled, untrusted stateid:</dt>
        <dd>
          <t>The metadata server rotates the synthetic uid/gid on the
affected data files per <xref target="sec-Fencing-Clients"/>.  The
revoked client presents stale RPC credentials and receives
NFS4ERR_ACCESS from the data server.  This is the
FFv1-style fencing mechanism; it operates per data file and
does not distinguish between clients that hold layouts on
the same file.</t>
        </dd>
        <dt>Tightly coupled, trusted stateid:</dt>
        <dd>
          <t>When the metadata server has registered a client's layout
stateid with the data servers via TRUST_STATEID
(<xref target="sec-TRUST_STATEID"/>), it can revoke per-client access
without rotating credentials by issuing REVOKE_STATEID
(<xref target="sec-REVOKE_STATEID"/>) to each affected data server, or
BULK_REVOKE_STATEID (<xref target="sec-BULK_REVOKE_STATEID"/>) when
revoking all stateids belonging to a single clientid4
across a data server.  Subsequent I/O from the revoked
client carrying the revoked stateid receives
NFS4ERR_BAD_STATEID.  This is the preferred mechanism for
erasure-coded layouts because it is per-client and avoids
the FFv1 limitation of fencing all clients on a data file
when only one needs to be revoked.</t>
        </dd>
        <dt>Mixed:</dt>
        <dd>
          <t>A metadata server <bcp14>MAY</bcp14> combine the two mechanisms when a
file's layout includes both PASSTHROUGH mirrors (where
stateid registration is not in play) and erasure-coded
mirrors with trusted stateids.  The metadata server rotates
synthetic ids for the PASSTHROUGH mirror's data file and
issues REVOKE_STATEID for the erasure-coded mirror's data
servers.</t>
        </dd>
      </dl>
    </section>
    <section anchor="new-nfsv42-error-values">
      <name>New NFSv4.2 Error Values</name>
      <figure anchor="fig-errors-xdr">
        <name>Errors XDR</name>
        <sourcecode type="xdr"><![CDATA[
   ///
   /// /* Erasure Coding error constants; added to nfsstat4 enum */
   ///
   /// const NFS4ERR_CODING_NOT_SUPPORTED         = 10097;
   /// const NFS4ERR_PAYLOAD_NOT_ATOMIC           = 10098;
   /// const NFS4ERR_CHUNK_LOCKED                 = 10099;
   /// const NFS4ERR_CHUNK_GUARDED                = 10100;
   /// const NFS4ERR_PAYLOAD_LOST                 = 10101;
   /// const NFS4ERR_LAYOUT_CHECKSUM_NOT_SUPPORTED = 10102;
   ///
]]></sourcecode>
      </figure>
      <t>The new error codes are shown in <xref target="fig-errors-xdr"/>.</t>
      <section anchor="error-definitions">
        <name>Error Definitions</name>
        <table anchor="tbl-protocol-errors">
          <name>Error Definitions</name>
          <thead>
            <tr>
              <th align="left">Error</th>
              <th align="left">Number</th>
              <th align="left">Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">NFS4ERR_CODING_NOT_SUPPORTED</td>
              <td align="left">10097</td>
              <td align="left">
                <xref target="sec-NFS4ERR_CODING_NOT_SUPPORTED"/></td>
            </tr>
            <tr>
              <td align="left">NFS4ERR_PAYLOAD_NOT_ATOMIC</td>
              <td align="left">10098</td>
              <td align="left">
                <xref target="sec-NFS4ERR_PAYLOAD_NOT_ATOMIC"/></td>
            </tr>
            <tr>
              <td align="left">NFS4ERR_CHUNK_LOCKED</td>
              <td align="left">10099</td>
              <td align="left">
                <xref target="sec-NFS4ERR_CHUNK_LOCKED"/></td>
            </tr>
            <tr>
              <td align="left">NFS4ERR_CHUNK_GUARDED</td>
              <td align="left">10100</td>
              <td align="left">
                <xref target="sec-NFS4ERR_CHUNK_GUARDED"/></td>
            </tr>
            <tr>
              <td align="left">NFS4ERR_PAYLOAD_LOST</td>
              <td align="left">10101</td>
              <td align="left">
                <xref target="sec-NFS4ERR_PAYLOAD_LOST"/></td>
            </tr>
            <tr>
              <td align="left">NFS4ERR_LAYOUT_CHECKSUM_NOT_SUPPORTED</td>
              <td align="left">10102</td>
              <td align="left">
                <xref target="sec-NFS4ERR_LAYOUT_CHECKSUM_NOT_SUPPORTED"/></td>
            </tr>
          </tbody>
        </table>
        <section anchor="sec-NFS4ERR_CODING_NOT_SUPPORTED">
          <name>NFS4ERR_CODING_NOT_SUPPORTED (Error Code 10097)</name>
          <t>The client requested a ffv2_coding_type4 which the metadata server
does not support.  I.e., if the client sends a layout_hint requesting
an erasure coding type that the metadata server does not support,
this error code can be returned.  The client might have to send the
layout_hint several times to determine the overlapping set of
supported erasure coding types.</t>
        </section>
        <section anchor="sec-NFS4ERR_PAYLOAD_NOT_ATOMIC">
          <name>NFS4ERR_PAYLOAD_NOT_ATOMIC (Error Code 10098)</name>
          <t>The client encountered a payload in which the blocks were non-atomic
and stay non-atomic.  As the client can not tell if another
client is actively writing, it informs the metadata server of this
error via LAYOUTERROR.  The metadata server can then arrange for
repair of the file.</t>
        </section>
        <section anchor="sec-NFS4ERR_CHUNK_LOCKED">
          <name>NFS4ERR_CHUNK_LOCKED (Error Code 10099)</name>
          <t>The client tried an operation on a chunk which resulted in the data
server reporting that the chunk was locked. The client will then
inform the metadata server of this error via LAYOUTERROR.  The
metadata server can then arrange for repair of the file.</t>
        </section>
        <section anchor="sec-NFS4ERR_CHUNK_GUARDED">
          <name>NFS4ERR_CHUNK_GUARDED (Error Code 10100)</name>
          <t>The client tried a guarded CHUNK_WRITE on a chunk which did not match
the guard on the chunk in the data file. As such, the CHUNK_WRITE was
rejected and the client should refresh the chunk it has cached.</t>
        </section>
        <section anchor="sec-NFS4ERR_PAYLOAD_LOST">
          <name>NFS4ERR_PAYLOAD_LOST (Error Code 10101)</name>
          <t>Returned by a repair client on the CB_CHUNK_REPAIR response
(ccrr_status) to indicate that the identified ranges cannot be
repaired and the underlying data is no longer recoverable.
Causes include: too few surviving shards to meet the
reconstruction threshold (Katz criterion for Mojette, any
k-of-(k+m) subset for Reed-Solomon Vandermonde), inability to
roll back to a previously committed payload because that payload
is also lost, or exhaustion of all FFV2_DS_FLAGS_SPARE and
FFV2_DS_FLAGS_REPAIR data servers available in the layout.</t>
          <t>On receipt, the metadata server <bcp14>MUST NOT</bcp14> retry the repair by
selecting a different client -- the payload is damaged and the
metadata server transitions the affected file or byte range into
an implementation-defined damaged state.  Operator notification
and restore-from-snapshot are out of scope for this specification.</t>
          <t>NFS4ERR_PAYLOAD_LOST is distinct from NFS4ERR_DELAY (transient;
metadata server <bcp14>MAY</bcp14> extend the deadline or re-select) and from
NFS4ERR_IO (per-operation failure; metadata server <bcp14>MAY</bcp14> retry or
re-select).  Only NFS4ERR_PAYLOAD_LOST is terminal.</t>
        </section>
        <section anchor="sec-NFS4ERR_LAYOUT_CHECKSUM_NOT_SUPPORTED">
          <name>NFS4ERR_LAYOUT_CHECKSUM_NOT_SUPPORTED (Error Code 10102)</name>
          <t>Returned by the client on LAYOUTRETURN to indicate that the
layout's ffv2m_checksum_algorithm
(<xref target="sec-ffv2-mirror4"/>) names a checksum_algorithm4
(<xref target="sec-checksum4"/>) that the client does not implement.
The client returns the layout with this error code rather
than attempting CHUNK_* operations it cannot validate.</t>
          <t>On receipt, the metadata server <bcp14>MAY</bcp14>:</t>
          <ul spacing="normal">
            <li>
              <t>issue a new layout for the same file naming a different
checksum_algorithm4 that the client supports (if the
file's policy permits any of the algorithms the client
does support); or</t>
            </li>
            <li>
              <t>deny the layout request, in which case the client <bcp14>MUST</bcp14>
either fall back to MDS-mediated I/O or report an I/O
error to the application.</t>
            </li>
          </ul>
          <t>NFS4ERR_LAYOUT_CHECKSUM_NOT_SUPPORTED is distinct from
NFS4ERR_BADLAYOUT (generic "this layout shape is unusable"):
the explicit per-checksum-algorithm signal lets the metadata
server discriminate "client can't read this layout because
of the checksum algorithm" from "client can't read this
layout for some other reason" and respond accordingly.</t>
        </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>
        <table anchor="tbl-ops-and-errors">
          <name>Operations and Their Valid Errors</name>
          <thead>
            <tr>
              <th align="left">Operation</th>
              <th align="left">Errors</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">CHUNK_COMMIT</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_DELAY, NFS4ERR_FHEXPIRED, NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_NOTSUPP, NFS4ERR_SERVERFAULT, NFS4ERR_STALE</td>
            </tr>
            <tr>
              <td align="left">CHUNK_ERROR</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_INVAL, NFS4ERR_NOTSUPP, NFS4ERR_SERVERFAULT</td>
            </tr>
            <tr>
              <td align="left">CHUNK_FINALIZE</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_DELAY, NFS4ERR_FHEXPIRED, NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_NOTSUPP, NFS4ERR_SERVERFAULT, NFS4ERR_STALE</td>
            </tr>
            <tr>
              <td align="left">CHUNK_HEADER_READ</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_DELAY, NFS4ERR_FHEXPIRED, NFS4ERR_IO, NFS4ERR_NOTSUPP, NFS4ERR_SERVERFAULT, NFS4ERR_STALE</td>
            </tr>
            <tr>
              <td align="left">CHUNK_LOCK</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_CHUNK_LOCKED, NFS4ERR_INVAL, NFS4ERR_NOTSUPP, NFS4ERR_SERVERFAULT</td>
            </tr>
            <tr>
              <td align="left">CHUNK_READ</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_DELAY, NFS4ERR_FHEXPIRED, NFS4ERR_IO, NFS4ERR_NOTSUPP, NFS4ERR_PAYLOAD_NOT_ATOMIC, NFS4ERR_SERVERFAULT, NFS4ERR_STALE</td>
            </tr>
            <tr>
              <td align="left">CHUNK_REPAIRED</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_INVAL, NFS4ERR_NOTSUPP, NFS4ERR_SERVERFAULT</td>
            </tr>
            <tr>
              <td align="left">CHUNK_ROLLBACK</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_INVAL, NFS4ERR_NOTSUPP, NFS4ERR_SERVERFAULT</td>
            </tr>
            <tr>
              <td align="left">CHUNK_UNLOCK</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_INVAL, NFS4ERR_NOTSUPP, NFS4ERR_SERVERFAULT</td>
            </tr>
            <tr>
              <td align="left">CHUNK_WRITE</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_CHUNK_GUARDED, NFS4ERR_CHUNK_LOCKED, NFS4ERR_DELAY, NFS4ERR_FHEXPIRED, NFS4ERR_IO, NFS4ERR_NOSPC, NFS4ERR_NOTSUPP, NFS4ERR_SERVERFAULT, NFS4ERR_STALE</td>
            </tr>
            <tr>
              <td align="left">CHUNK_WRITE_REPAIR</td>
              <td align="left">NFS4_OK, NFS4ERR_ACCESS, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_DELAY, NFS4ERR_FHEXPIRED, NFS4ERR_IO, NFS4ERR_NOSPC, NFS4ERR_NOTSUPP, NFS4ERR_SERVERFAULT, NFS4ERR_STALE</td>
            </tr>
            <tr>
              <td align="left">TRUST_STATEID</td>
              <td align="left">NFS4_OK, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_DELAY, NFS4ERR_INVAL, NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP, NFS4ERR_PERM, NFS4ERR_SERVERFAULT</td>
            </tr>
            <tr>
              <td align="left">REVOKE_STATEID</td>
              <td align="left">NFS4_OK, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_DELAY, NFS4ERR_INVAL, NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP, NFS4ERR_PERM, NFS4ERR_SERVERFAULT</td>
            </tr>
            <tr>
              <td align="left">BULK_REVOKE_STATEID</td>
              <td align="left">NFS4_OK, NFS4ERR_BADXDR, NFS4ERR_DELAY, NFS4ERR_NOTSUPP, NFS4ERR_PERM, NFS4ERR_SERVERFAULT</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="callback-operations-and-their-valid-errors">
        <name>Callback Operations and Their Valid Errors</name>
        <t>The callback operations and their valid errors are presented in
<xref target="tbl-cb-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>
        <table anchor="tbl-cb-ops-and-errors">
          <name>Callback Operations and Their Valid Errors</name>
          <thead>
            <tr>
              <th align="left">Callback Operation</th>
              <th align="left">Errors</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">CB_CHUNK_REPAIR</td>
              <td align="left">NFS4_OK, NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID, NFS4ERR_DEADSESSION, NFS4ERR_DELAY, NFS4ERR_CODING_NOT_SUPPORTED, NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_ISDIR, NFS4ERR_LOCKED, NFS4ERR_NOTSUPP, NFS4ERR_OLD_STATEID, NFS4ERR_PAYLOAD_LOST, NFS4ERR_SERVERFAULT, NFS4ERR_STALE</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="errors-and-the-operations-that-use-them">
        <name>Errors and the Operations That Use Them</name>
        <t>The operations and their valid errors are presented in
<xref target="tbl-errors-and-ops"/>.  All operations not defined in this document
are defined in Section 18 of <xref target="RFC8881"/> and Section 15 of <xref target="RFC7862"/>.</t>
        <table anchor="tbl-errors-and-ops">
          <name>Errors and the Operations That Use Them</name>
          <thead>
            <tr>
              <th align="left">Error</th>
              <th align="left">Operations</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">NFS4ERR_CODING_NOT_SUPPORTED</td>
              <td align="left">CB_CHUNK_REPAIR, LAYOUTGET</td>
            </tr>
            <tr>
              <td align="left">NFS4ERR_PAYLOAD_LOST</td>
              <td align="left">CB_CHUNK_REPAIR</td>
            </tr>
          </tbody>
        </table>
      </section>
    </section>
    <section anchor="exchgid4flaguseerasureds">
      <name>EXCHGID4_FLAG_USE_ERASURE_DS</name>
      <figure anchor="fig-EXCHGID4_FLAG_USE_ERASURE_DS">
        <name>The EXCHGID4_FLAG_USE_ERASURE_DS</name>
        <sourcecode type="xdr"><![CDATA[
   /// const EXCHGID4_FLAG_USE_ERASURE_DS      = 0x00100000;
]]></sourcecode>
      </figure>
      <t>When a data server connects to a metadata server it can via
EXCHANGE_ID (see Section 18.35 of <xref target="RFC8881"/>) state its pNFS role.
The data server can use EXCHGID4_FLAG_USE_ERASURE_DS (see
<xref target="fig-EXCHGID4_FLAG_USE_ERASURE_DS"/>) to indicate that it supports the
new NFSv4.2 operations introduced in this document.  Section 13.1
of <xref target="RFC8881"/> describes the interaction of the various pNFS roles
masked by EXCHGID4_FLAG_MASK_PNFS.  However, that does not mask out
EXCHGID4_FLAG_USE_ERASURE_DS.  I.e., EXCHGID4_FLAG_USE_ERASURE_DS can
be used in combination with all of the pNFS flags.</t>
      <t>If the data server sets EXCHGID4_FLAG_USE_ERASURE_DS during the
EXCHANGE_ID operation, then it <bcp14>MUST</bcp14> support all of the operations
in <xref target="tbl-protocol-ops"/>.  Further, this support is orthogonal to the
Erasure Coding Type selected.  The data server is unaware of which type
is driving the I/O.</t>
    </section>
    <section anchor="new-nfsv42-attributes">
      <name>New NFSv4.2 Attributes</name>
      <section anchor="sec-fattr4_coding_block_size">
        <name>Attribute 89: fattr4_coding_block_size</name>
        <figure anchor="fig-fattr4_coding_block_size">
          <name>XDR for fattr4_coding_block_size</name>
          <sourcecode type="xdr"><![CDATA[
   /// typedef uint64_t                  fattr4_coding_block_size;
   ///
   /// const FATTR4_CODING_BLOCK_SIZE  = 89;
   ///
]]></sourcecode>
        </figure>
        <t>The new attribute fattr4_coding_block_size (see
<xref target="fig-fattr4_coding_block_size"/>) is an <bcp14>OPTIONAL</bcp14> to NFSv4.2 attribute
which <bcp14>MUST</bcp14> be supported if the metadata server supports the Flexible
File Version 2 Layout Type.  By querying it, the client can determine
the data block size it is to use when coding the data blocks to
chunks.</t>
      </section>
    </section>
    <section anchor="new-nfsv42-common-data-structures">
      <name>New NFSv4.2 Common Data Structures</name>
      <section anchor="sec-chunk_guard4">
        <name>chunk_guard4</name>
        <figure anchor="fig-chunk_guard4">
          <name>XDR for chunk_guard4</name>
          <sourcecode type="xdr"><![CDATA[
   /// const CHUNK_GUARD_CLIENT_ID_NONE = 0x00000000;
   /// const CHUNK_GUARD_CLIENT_ID_MDS  = 0xFFFFFFFF;
   ///
   /// struct chunk_guard4 {
   ///     uint32_t   cg_gen_id;
   ///     uint32_t   cg_client_id;
   /// };
]]></sourcecode>
        </figure>
        <t>On the wire, a single CHUNK_WRITE carries the 8-byte
chunk_guard4 header followed by the tagged checksum4 and
then the opaque payload, as shown in
<xref target="fig-chunk-wire-layout"/>.  The payload length is carried
separately in the CHUNK_WRITE4args cwa_chunks&lt;&gt; slot; the
diagram shows the per-chunk framing only.</t>
        <figure anchor="fig-chunk-wire-layout">
          <name>Per-chunk wire layout</name>
          <artwork><![CDATA[
    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                          cg_gen_id                            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                         cg_client_id                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       cs_algorithm                            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        cs_value_len                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    cs_value ... (variable)                    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    opaque payload ...                         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   Bytes 0-3:    cg_gen_id      (per-chunk generation counter)
   Bytes 4-7:    cg_client_id   (owning-client short id)
   Bytes 8-11:   cs_algorithm   (checksum_algorithm4)
   Bytes 12-15:  cs_value_len   (XDR opaque length prefix)
   Bytes 16-N:   cs_value       (checksum bytes; length per
                                 cs_algorithm's registered output)
   Bytes N+1-M:  opaque payload (encoded shard; variable length)

   The checksum block (cs_algorithm + cs_value_len + cs_value)
   is the XDR encoding of one checksum4 ({{fig-checksum4}}).
   For CHECKSUM_ALG_NONE the cs_value_len is zero and the
   payload follows immediately after byte 15.
]]></artwork>
        </figure>
        <t>The chunk_guard4 (see <xref target="fig-chunk_guard4"/>) is effectively a 64-bit
value identifying a specific write transaction on a specific chunk.
It has two fields:</t>
        <dl>
          <dt>cg_gen_id:</dt>
          <dd>
            <t>A per-chunk monotonic generation counter.  Each chunk's gen_id
starts at 0 when the chunk is first written and is incremented
on each successful write by any client.  cg_gen_id is NOT a
timestamp -- the protocol does not rely on a global clock,
and no interpretation of cg_gen_id as a wall-clock value is
supported.  cg_gen_id values are NOT comparable across distinct
chunks; a given cg_gen_id is only meaningful within the scope
of a single chunk on a single file.</t>
          </dd>
          <dt>cg_client_id:</dt>
          <dd>
            <t>A 32-bit value established by the metadata server at the time
the client's layout is granted (see <xref target="sec-ffv2-mirror4"/> and
ffv2m_client_id).  The metadata server <bcp14>MUST</bcp14> assign distinct
cg_client_id values to distinct clients that hold concurrent
write layouts on the same file.  cg_client_id is opaque with
respect to client identity -- a data server <bcp14>MUST NOT</bcp14>
interpret its bits as naming or ordering clients in any
external sense.  The value supports two operations only:
equality comparison (to detect whether two chunks were written
by the same transaction) and numeric comparison (to implement
the tiebreaker rule below).</t>
          </dd>
          <dt>Uniqueness contract:</dt>
          <dd>
            <t>The pair (cg_gen_id, cg_client_id) uniquely identifies a write
transaction on a chunk.  Neither field alone is globally
unique; two clients <bcp14>MAY</bcp14> independently write with the same
cg_gen_id on the same chunk (in particular, both may write
with cg_gen_id equal to some prior value + 1), and the
cg_client_id is what makes the resulting transactions
distinguishable.</t>
          </dd>
          <dt>Deterministic tiebreaker for concurrent writers:</dt>
          <dd>
            <t>When two or more clients race on the same chunk in the
multi-writer mode, the client whose cg_client_id compares
numerically lowest wins the race.  A data server enforces this
by accepting the first CHUNK_WRITE whose guard check succeeds
and rejecting later writers with NFS4ERR_CHUNK_GUARDED; across
the mirror set, the subset of data servers on which each
client wins will vary, but the deterministic tiebreaker
ensures all clients agree on which client's write ultimately
becomes COMMITTED.  A client that lost the race on at least
one data server <bcp14>MUST</bcp14> re-read the chunk and <bcp14>MAY</bcp14> retry its write
with a refreshed cg_gen_id.  A client that detects no forward
progress after a bounded number of retries <bcp14>MUST</bcp14> escalate via
LAYOUTERROR and the repair coordination flow in
<xref target="sec-repair-selection"/>.</t>
          </dd>
        </dl>
        <t>The numeric ordering of cg_client_id values is arbitrary with
respect to the clients' external identities -- it is a
deterministic total order over the opaque 32-bit values, not a
preference ordering over the clients themselves.  A deployment
that requires a specific client to win a race <bcp14>MUST</bcp14> arrange
cg_client_id assignment at the metadata server; the protocol does
not provide a preference mechanism at layout-grant time.</t>
        <section anchor="metadata-server-assignment-rules-for-cgclientid">
          <name>Metadata-Server Assignment Rules for cg_client_id</name>
          <t>To uphold the uniqueness contract, the metadata server <bcp14>MUST</bcp14>
follow these rules when assigning cg_client_id (that is, when
populating ffv2m_client_id at layout-grant time):</t>
          <ul spacing="normal">
            <li>
              <t>Two clients holding concurrent write layouts on the same
file <bcp14>MUST</bcp14> receive distinct cg_client_id values.  A client
that holds only a read layout need not be assigned a
distinct value.</t>
            </li>
            <li>
              <t>The reserved sentinel CHUNK_GUARD_CLIENT_ID_NONE (0x00000000)
<bcp14>MUST NOT</bcp14> be assigned to any client.  Reserving 0 prevents an
uninitialized cg_client_id field from passing as a real
client and ensures the deterministic tiebreaker (numerically
lowest wins) does not encode an implicit priority via
assignment of 0.</t>
            </li>
            <li>
              <t>The reserved sentinel CHUNK_GUARD_CLIENT_ID_MDS (0xFFFFFFFF)
<bcp14>MUST NOT</bcp14> be assigned to any client.</t>
            </li>
            <li>
              <t>A cg_client_id <bcp14>MAY</bcp14> be reused by the metadata server after
the prior holder's layout has been fully returned (via
LAYOUTRETURN or revocation).  The metadata server <bcp14>SHOULD</bcp14>
avoid reusing a cg_client_id within a single lease period
to simplify diagnosis of stale writes.</t>
            </li>
            <li>
              <t>cg_client_id values do not persist across metadata-server
restart.  Clients reclaiming layouts during the grace period
receive freshly assigned values; the protocol does not rely
on any pre-restart assignment surviving.</t>
            </li>
          </ul>
        </section>
        <section anchor="data-server-collision-handling">
          <name>Data-Server Collision Handling</name>
          <t>A (cg_gen_id, cg_client_id) pair that the uniqueness contract
would otherwise render unique can nonetheless collide if a
client and the metadata server disagree about which
cg_client_id the client currently holds, or if a client
presents a spoofed cg_client_id.  The data server enforces the
contract locally:</t>
          <ul spacing="normal">
            <li>
              <t>If the data server receives a CHUNK_WRITE whose
chunk_guard4 has the same (cg_gen_id, cg_client_id) as a
chunk already in PENDING, FINALIZED, or COMMITTED state
AND the presented payload differs from the retained
payload, the data server <bcp14>MUST</bcp14> reject the write with
NFS4ERR_CHUNK_GUARDED and <bcp14>SHOULD</bcp14> report the collision to
the metadata server via LAYOUTERROR.  This situation is a
protocol violation on one side of the conversation; the
metadata server resolves it by revoking the offending
client's layout and selecting a repair client under
<xref target="sec-repair-selection"/>.</t>
            </li>
            <li>
              <t>If a client presents CHUNK_GUARD_CLIENT_ID_MDS as
cg_client_id in any client-originated operation, the data
server <bcp14>MUST</bcp14> reject the operation with NFS4ERR_INVAL (see
<xref target="sec-chunk_guard_mds"/>).</t>
            </li>
            <li>
              <t>A cg_client_id that does not match any layout the data
server has been told about (via TRUST_STATEID) <bcp14>MUST</bcp14> be
rejected.  Unknown cg_client_id values are treated as stale
layouts; the data server returns the error specified in
<xref target="sec-tight-coupling-control"/> for unknown stateids.</t>
            </li>
          </ul>
        </section>
        <section anchor="sec-chunk_guard_none">
          <name>Reserved cg_client_id Value: CHUNK_GUARD_CLIENT_ID_NONE</name>
          <t>The value <tt>CHUNK_GUARD_CLIENT_ID_NONE</tt> (0x00000000) is reserved.
It does not denote any client.  Reserving 0 prevents an
uninitialized cg_client_id field from passing as a real client
and ensures the deterministic tiebreaker (numerically lowest
wins, see <xref target="sec-chunk_guard4"/>) does not encode an implicit
priority via assignment of 0.</t>
          <t>Clients <bcp14>MUST NOT</bcp14> present CHUNK_GUARD_CLIENT_ID_NONE as the
cg_client_id of any client-originated chunk_guard4 or
chunk_owner4.  A data server that receives such a value from
a client <bcp14>MUST</bcp14> reject the operation with NFS4ERR_INVAL.</t>
        </section>
        <section anchor="sec-chunk_guard_mds">
          <name>Reserved cg_client_id Value: CHUNK_GUARD_CLIENT_ID_MDS</name>
          <t>The value <tt>CHUNK_GUARD_CLIENT_ID_MDS</tt> (0xFFFFFFFF) is reserved.
It denotes that the chunk lock is held by the metadata server
itself, in escrow during a repair coordination sequence (see
<xref target="sec-repair-selection"/>).  The data server produces a
chunk_guard4 with this cg_client_id when the metadata server
revokes the prior holder's stateid while that holder still holds
chunk locks; the locks <bcp14>MUST NOT</bcp14> be dropped and are transferred to
the MDS-escrow owner instead.</t>
          <t>The metadata server does not originate CHUNK_LOCK or CHUNK_WRITE
traffic on its own session.  Clients <bcp14>MUST NOT</bcp14> present
CHUNK_GUARD_CLIENT_ID_MDS as the cg_client_id of any
client-originated chunk_guard4 or chunk_owner4.  A data server
that receives such a value from a client <bcp14>MUST</bcp14> reject the
operation with NFS4ERR_INVAL.</t>
          <t>The MDS-escrow owner is released only by a CHUNK_LOCK from the
client selected via CB_CHUNK_REPAIR, carrying
CHUNK_LOCK_FLAGS_ADOPT.  See <xref target="sec-CHUNK_LOCK"/>.</t>
        </section>
      </section>
      <section anchor="sec-chunk_owner4">
        <name>chunk_owner4</name>
        <figure anchor="fig-chunk_owner4">
          <name>XDR for chunk_owner4</name>
          <sourcecode type="xdr"><![CDATA[
   /// struct chunk_owner4 {
   ///     chunk_guard4   co_guard;
   ///     uint32_t       co_chunk_id;
   /// };
]]></sourcecode>
        </figure>
        <t>The chunk_owner4 (see <xref target="fig-chunk_owner4"/>) is used to determine
when and by whom a block was written.  The co_chunk_id is used
to identify the chunk and <bcp14>MUST</bcp14> be the index of the chunk within
the file.  I.e., it is the offset of the start of the chunk
divided by the chunk length.  The co_guard is a chunk_guard4
(see <xref target="sec-chunk_guard4"/>), used to identify a given
transaction.</t>
        <t>The co_guard is like the change attribute (see Section 5.8.1.4 of
<xref target="RFC8881"/>) in that each chunk write by a given client has to have
an unique co_guard.  I.e., it can be determined which transaction
across all data files that a chunk corresponds.</t>
      </section>
      <section anchor="sec-checksum4">
        <name>checksum4</name>
        <figure anchor="fig-checksum4">
          <name>XDR for checksum4</name>
          <sourcecode type="xdr"><![CDATA[
   /// typedef uint32_t   checksum_algorithm4;
   ///
   /// const CHECKSUM_ALG_NONE      = 0;
   /// const CHECKSUM_ALG_CRC32     = 1;
   /// const CHECKSUM_ALG_CRC32C    = 2;
   /// const CHECKSUM_ALG_FLETCHER4 = 3;
   /// const CHECKSUM_ALG_SHA256    = 4;
   /// const CHECKSUM_ALG_SHA512    = 5;
   /// const CHECKSUM_ALG_BLAKE3    = 6;
   /// /* Additional values registered with IANA;
   ///    see Section "Checksum Algorithm Registry" in
   ///    the IANA Considerations. */
   ///
   /// struct checksum4 {
   ///     checksum_algorithm4   cs_algorithm;
   ///     opaque                cs_value<>;
   /// };
]]></sourcecode>
        </figure>
        <t>The checksum4 (see <xref target="fig-checksum4"/>) is a tagged
checksum value used to detect transport corruption and
on-disk bit rot of chunk payloads.  Every chunk on the
wire and at rest carries a checksum4 alongside its
chunk_owner4.</t>
        <dl>
          <dt>cs_algorithm:</dt>
          <dd>
            <t>identifies the checksum algorithm.  The values
listed above are registered by this document; additional
values are managed by the IANA registry (see
"Checksum Algorithm Registry" in the IANA
Considerations section).  CHECKSUM_ALG_NONE indicates
the deployment relies on transport-layer (TLS, IPsec)
or storage-layer integrity instead of a protocol-level
per-chunk checksum.</t>
          </dd>
          <dt>cs_value:</dt>
          <dd>
            <t>the checksum bytes.  The length is fixed per registered
algorithm:
</t>
            <ul spacing="normal">
              <li>
                <t>CHECKSUM_ALG_NONE: 0 bytes.</t>
              </li>
              <li>
                <t>CHECKSUM_ALG_CRC32: 4 bytes.</t>
              </li>
              <li>
                <t>CHECKSUM_ALG_CRC32C: 4 bytes.</t>
              </li>
              <li>
                <t>CHECKSUM_ALG_FLETCHER4: 32 bytes (four 64-bit
accumulators, matching the ZFS Fletcher4 layout).</t>
              </li>
              <li>
                <t>CHECKSUM_ALG_SHA256: 32 bytes.</t>
              </li>
              <li>
                <t>CHECKSUM_ALG_SHA512: 64 bytes.</t>
              </li>
              <li>
                <t>CHECKSUM_ALG_BLAKE3: 32 bytes (BLAKE3 standard
output length).</t>
              </li>
            </ul>
            <t>A checksum4 whose cs_value length does not match the
registered length for cs_algorithm <bcp14>MUST</bcp14> be rejected
with NFS4ERR_INVAL.</t>
          </dd>
        </dl>
        <t>The checksum algorithm for a given file is selected by
the metadata server at LAYOUTGET time and carried in
the layout (see <xref target="sec-ffv2-mirror4"/>).  A client that
does not implement the algorithm a layout names returns
the layout with NFS4ERR_LAYOUT_CHECKSUM_NOT_SUPPORTED
(<xref target="sec-NFS4ERR_LAYOUT_CHECKSUM_NOT_SUPPORTED"/>); the
metadata server may then offer a layout with a
different algorithm.</t>
      </section>
    </section>
    <section anchor="sec-new-ops">
      <name>New NFSv4.2 Operations</name>
      <figure anchor="fig-ops-xdr">
        <name>Operations XDR</name>
        <sourcecode type="xdr"><![CDATA[
   ///
   /// /* New operations for Erasure Coding start here */
   ///
   ///  OP_CHUNK_COMMIT        = 78,
   ///  OP_CHUNK_ERROR         = 79,
   ///  OP_CHUNK_FINALIZE      = 80,
   ///  OP_CHUNK_HEADER_READ   = 81,
   ///  OP_CHUNK_LOCK          = 82,
   ///  OP_CHUNK_READ          = 83,
   ///  OP_CHUNK_REPAIRED      = 84,
   ///  OP_CHUNK_ROLLBACK      = 85,
   ///  OP_CHUNK_UNLOCK        = 86,
   ///  OP_CHUNK_WRITE         = 87,
   ///  OP_CHUNK_WRITE_REPAIR  = 88,
   ///
   /// /* MDS-to-DS control-plane operations for tight coupling */
   ///
   ///  OP_TRUST_STATEID       = 89,
   ///  OP_REVOKE_STATEID      = 90,
   ///  OP_BULK_REVOKE_STATEID = 91,
   ///
]]></sourcecode>
      </figure>
      <t>The following amendment blocks extend the nfs_argop4 and
nfs_resop4 dispatch unions defined in <xref target="RFC7863"/> with arms for
each of the new operations defined in this document.  A consumer
that combines this document's extracted XDR with the RFC 7863
XDR applies these amendments at the union's extension point.</t>
      <figure anchor="fig-nfs_argop4-amend">
        <name>nfs_argop4 amendment block</name>
        <sourcecode type="xdr"><![CDATA[
   /// /* nfs_argop4 amendment block */
   ///
   /// case OP_CHUNK_COMMIT: CHUNK_COMMIT4args opchunkcommit;
   /// case OP_CHUNK_ERROR: CHUNK_ERROR4args opchunkerror;
   /// case OP_CHUNK_FINALIZE: CHUNK_FINALIZE4args opchunkfinalize;
   /// case OP_CHUNK_HEADER_READ:
   ///     CHUNK_HEADER_READ4args opchunkheaderread;
   /// case OP_CHUNK_LOCK: CHUNK_LOCK4args opchunklock;
   /// case OP_CHUNK_READ: CHUNK_READ4args opchunkread;
   /// case OP_CHUNK_REPAIRED: CHUNK_REPAIRED4args opchunkrepaired;
   /// case OP_CHUNK_ROLLBACK: CHUNK_ROLLBACK4args opchunkrollback;
   /// case OP_CHUNK_UNLOCK: CHUNK_UNLOCK4args opchunkunlock;
   /// case OP_CHUNK_WRITE: CHUNK_WRITE4args opchunkwrite;
   /// case OP_CHUNK_WRITE_REPAIR:
   ///     CHUNK_WRITE_REPAIR4args opchunkwriterepair;
   /// case OP_TRUST_STATEID: TRUST_STATEID4args optruststateid;
   /// case OP_REVOKE_STATEID: REVOKE_STATEID4args oprevokestateid;
   /// case OP_BULK_REVOKE_STATEID:
   ///     BULK_REVOKE_STATEID4args opbulkrevokestateid;
]]></sourcecode>
      </figure>
      <figure anchor="fig-nfs_resop4-amend">
        <name>nfs_resop4 amendment block</name>
        <sourcecode type="xdr"><![CDATA[
   /// /* nfs_resop4 amendment block */
   ///
   /// case OP_CHUNK_COMMIT: CHUNK_COMMIT4res opchunkcommit;
   /// case OP_CHUNK_ERROR: CHUNK_ERROR4res opchunkerror;
   /// case OP_CHUNK_FINALIZE: CHUNK_FINALIZE4res opchunkfinalize;
   /// case OP_CHUNK_HEADER_READ:
   ///     CHUNK_HEADER_READ4res opchunkheaderread;
   /// case OP_CHUNK_LOCK: CHUNK_LOCK4res opchunklock;
   /// case OP_CHUNK_READ: CHUNK_READ4res opchunkread;
   /// case OP_CHUNK_REPAIRED: CHUNK_REPAIRED4res opchunkrepaired;
   /// case OP_CHUNK_ROLLBACK: CHUNK_ROLLBACK4res opchunkrollback;
   /// case OP_CHUNK_UNLOCK: CHUNK_UNLOCK4res opchunkunlock;
   /// case OP_CHUNK_WRITE: CHUNK_WRITE4res opchunkwrite;
   /// case OP_CHUNK_WRITE_REPAIR:
   ///     CHUNK_WRITE_REPAIR4res opchunkwriterepair;
   /// case OP_TRUST_STATEID: TRUST_STATEID4res optruststateid;
   /// case OP_REVOKE_STATEID: REVOKE_STATEID4res oprevokestateid;
   /// case OP_BULK_REVOKE_STATEID:
   ///     BULK_REVOKE_STATEID4res opbulkrevokestateid;
]]></sourcecode>
      </figure>
      <t>Operations 78 through 88 (the CHUNK_* operations) are sent by
clients to storage devices on the data path.  Operations 89
through 91 (TRUST_STATEID, REVOKE_STATEID, BULK_REVOKE_STATEID)
are sent by the metadata server to storage devices on the
MDS-to-DS control session (see
<xref target="sec-tight-coupling-control-session"/>); they <bcp14>MUST NOT</bcp14> be sent by
pNFS clients.</t>
      <t>All CHUNK_* operations <bcp14>MUST</bcp14> be issued under an active flexible
file v2 layout obtained via LAYOUTGET against the metadata
server.  A data server receiving a CHUNK_* operation from a
client that does not hold a current layout stateid for the
target file <bcp14>MUST</bcp14> reject the operation with NFS4ERR_BAD_STATEID.
In trusted-stateid tight coupling, the stateid presented <bcp14>MUST</bcp14> be
present in the data server's trust table; an unknown stateid
<bcp14>MUST</bcp14> be rejected with NFS4ERR_BAD_STATEID per
<xref target="sec-TRUST_STATEID"/>.</t>
      <t>The chunk envelope's safety properties (atomicity via
chunk_guard4 CAS, integrity via checksum, lock continuity across
revocation) depend on metadata-server coordination of layout
grants, guard generation, and lock escrow.  A client that issues
CHUNK_* operations outside an active layout is operating outside
this specification; the data server's behaviour in that case is
undefined.  See <xref target="sec-system-model-chunk-not-block"/> for the
distinction between the CHUNK_* surface and a generic block I/O
interface.</t>
      <table anchor="tbl-protocol-ops">
        <name>Protocol OPs</name>
        <thead>
          <tr>
            <th align="left">Operation</th>
            <th align="left">Number</th>
            <th align="left">Target Server</th>
            <th align="left">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">CHUNK_COMMIT</td>
            <td align="left">78</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_COMMIT"/></td>
          </tr>
          <tr>
            <td align="left">CHUNK_ERROR</td>
            <td align="left">79</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_ERROR"/></td>
          </tr>
          <tr>
            <td align="left">CHUNK_FINALIZE</td>
            <td align="left">80</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_FINALIZE"/></td>
          </tr>
          <tr>
            <td align="left">CHUNK_HEADER_READ</td>
            <td align="left">81</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_HEADER_READ"/></td>
          </tr>
          <tr>
            <td align="left">CHUNK_LOCK</td>
            <td align="left">82</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_LOCK"/></td>
          </tr>
          <tr>
            <td align="left">CHUNK_READ</td>
            <td align="left">83</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_READ"/></td>
          </tr>
          <tr>
            <td align="left">CHUNK_REPAIRED</td>
            <td align="left">84</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_REPAIRED"/></td>
          </tr>
          <tr>
            <td align="left">CHUNK_ROLLBACK</td>
            <td align="left">85</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_ROLLBACK"/></td>
          </tr>
          <tr>
            <td align="left">CHUNK_UNLOCK</td>
            <td align="left">86</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_UNLOCK"/></td>
          </tr>
          <tr>
            <td align="left">CHUNK_WRITE</td>
            <td align="left">87</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_WRITE"/></td>
          </tr>
          <tr>
            <td align="left">CHUNK_WRITE_REPAIR</td>
            <td align="left">88</td>
            <td align="left">data server (client)</td>
            <td align="left">
              <xref target="sec-CHUNK_WRITE_REPAIR"/></td>
          </tr>
          <tr>
            <td align="left">TRUST_STATEID</td>
            <td align="left">89</td>
            <td align="left">data server (metadata server control)</td>
            <td align="left">
              <xref target="sec-TRUST_STATEID"/></td>
          </tr>
          <tr>
            <td align="left">REVOKE_STATEID</td>
            <td align="left">90</td>
            <td align="left">data server (metadata server control)</td>
            <td align="left">
              <xref target="sec-REVOKE_STATEID"/></td>
          </tr>
          <tr>
            <td align="left">BULK_REVOKE_STATEID</td>
            <td align="left">91</td>
            <td align="left">data server (metadata server control)</td>
            <td align="left">
              <xref target="sec-BULK_REVOKE_STATEID"/></td>
          </tr>
        </tbody>
      </table>
      <section anchor="sec-CHUNK_COMMIT">
        <name>Operation 78: CHUNK_COMMIT - Activate Cached Chunk Data</name>
        <section anchor="arguments">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CHUNK_COMMIT4args">
            <name>XDR for CHUNK_COMMIT4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_COMMIT4args {
   ///     /* CURRENT_FH: file */
   ///     offset4         cca_offset;
   ///     count4          cca_count;
   ///     chunk_owner4    cca_chunks<>;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results">
          <name>RESULTS</name>
          <figure anchor="fig-CHUNK_COMMIT4resok">
            <name>XDR for CHUNK_COMMIT4resok</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_COMMIT4resok {
   ///     verifier4       ccr_writeverf;
   ///     nfsstat4        ccr_status<>;
   /// };
]]></sourcecode>
          </figure>
          <figure anchor="fig-CHUNK_COMMIT4res">
            <name>XDR for CHUNK_COMMIT4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union CHUNK_COMMIT4res switch (nfsstat4 ccr_status) {
   ///     case NFS4_OK:
   ///         CHUNK_COMMIT4resok   ccr_resok4;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description">
          <name>DESCRIPTION</name>
          <t>The CHUNK_COMMIT operation is based upon the NFSv4.1 COMMIT
operation (see Section 18.3 of <xref target="RFC8881"/>) and similarly
commits previously written data to stable storage on the
regular file identified by the current filehandle, with the
difference that CHUNK_COMMIT operates on the chunk
coordinate system used by Flexible File Version 2 layouts
rather than on the byte coordinate system, and that
CHUNK_COMMIT advances each named chunk through the chunk
state machine from FINALIZED to COMMITTED
(<xref target="fig-chunk-state-machine"/>) rather than acting on a byte
range without a state-machine context.</t>
          <t>The client provides cca_offset and cca_count to bound the
chunk range, and cca_chunks to name the specific
(chunk_owner4) generations within that range to commit:</t>
          <dl>
            <dt>cca_offset:</dt>
            <dd>
              <t>starting chunk index in the file (not a byte offset).</t>
            </dd>
            <dt>cca_count:</dt>
            <dd>
              <t>number of chunks the range covers, starting at
cca_offset.  A zero cca_count, or a cca_offset beyond
the data server's highest chunk, is not an error; the
data server returns NFS4_OK with an empty ccr_status
array.</t>
            </dd>
            <dt>cca_chunks:</dt>
            <dd>
              <t>an array of chunk_owner4 entries
(<xref target="fig-chunk_owner4"/>) naming the specific
(cg_gen_id, cg_client_id, co_id) generations to
commit.  Each entry's co_id <bcp14>MUST</bcp14> fall within
[cca_offset, cca_offset + cca_count); an entry whose
co_id is outside the range is rejected with
NFS4ERR_INVAL in the corresponding ccr_status slot.
The reserved sentinels CHUNK_GUARD_CLIENT_ID_NONE and
CHUNK_GUARD_CLIENT_ID_MDS <bcp14>MUST NOT</bcp14> appear as the
cg_client_id of any cca_chunks entry; see
<xref target="sec-chunk_guard_none"/> and <xref target="sec-chunk_guard_mds"/>.</t>
            </dd>
          </dl>
          <t>cca_offset and cca_count would appear redundant given
cca_chunks contains explicit co_id values, but they exist
because a chunk index <bcp14>MAY</bcp14> have multiple persisted
generations at the moment CHUNK_COMMIT arrives -- an
older COMMITTED generation retained for the rollback
invariant (<xref target="sec-system-model-consistency"/>) alongside a
newer FINALIZED successor.  cca_chunks selects which
(cg_gen_id, cg_client_id) generation to advance to
COMMITTED; cca_offset and cca_count bound the work scope
so the data server can reject malformed requests that
name chunks outside the intended commit window.</t>
          <t>The CHUNK_COMMIT result reports the outcome per chunk in
the same order as cca_chunks:</t>
          <dl>
            <dt>ccr_writeverf:</dt>
            <dd>
              <t>a verifier identifying the data server's incarnation
at the time the commit completed.  A client compares
ccr_writeverf to the cwr_writeverf returned by the
prior CHUNK_WRITE (<xref target="sec-CHUNK_WRITE"/>) to detect a
data server restart that lost UNSTABLE4 writes
between the write and the commit; on a mismatch the
client <bcp14>MUST</bcp14> re-issue the CHUNK_WRITE before any
committed bytes are considered durable.
ccr_writeverf changes on every data server restart
that loses uncommitted state.</t>
            </dd>
            <dt>ccr_status:</dt>
            <dd>
              <t>per-chunk commit status, one entry per cca_chunks
entry, co-indexed.  NFS4_OK indicates that the named
chunk is COMMITTED on return.  Other per-entry
failure codes are described in
"Interaction with CHUNK_FINALIZE" and "Interaction
with a Locked Chunk" below.  The top-level
CHUNK_COMMIT status is NFS4_OK as long as the data
server could evaluate each cca_chunks entry;
per-chunk failures are reported in ccr_status rather
than by failing the whole operation.  The top-level
status returns a non-OK code only when the request
could not be evaluated at all (for example,
NFS4ERR_BADXDR, NFS4ERR_SERVERFAULT).</t>
            </dd>
          </dl>
          <t>Unlike CHUNK_READ (<xref target="sec-CHUNK_READ"/>) and CHUNK_WRITE
(<xref target="sec-CHUNK_WRITE"/>), CHUNK_COMMIT has no explicit
stateid field in its arguments.  The data server
authorizes CHUNK_COMMIT against the stateid context the
compound has already established, typically the stateid
carried on an immediately preceding PUTFH or an earlier
CHUNK_* operation in the same compound.  Under
trusted-stateid tight coupling (<xref target="sec-TRUST_STATEID"/>),
the data server applies the trust-table check to
whichever layout stateid the compound has presented; if
no layout stateid has been presented or the presented
stateid is not in the trust table, the data server
rejects CHUNK_COMMIT with NFS4ERR_BAD_STATEID.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned.  If the current filehandle
represents an object of type NF4DIR, NFS4ERR_ISDIR is
returned.  If the current filehandle designates a
symbolic link, NFS4ERR_SYMLINK is returned.  In all
other cases of non-regular-file filehandles,
NFS4ERR_WRONG_TYPE is returned.</t>
          <section anchor="interaction-with-chunkfinalize">
            <name>Interaction with CHUNK_FINALIZE</name>
            <t>CHUNK_COMMIT transitions a chunk from FINALIZED to COMMITTED
(see <xref target="sec-system-model-chunk-state"/>).  A chunk <bcp14>MUST</bcp14> have
previously been transitioned from PENDING to FINALIZED via
CHUNK_FINALIZE before CHUNK_COMMIT is accepted:</t>
            <ul spacing="normal">
              <li>
                <t>If the target chunk is PENDING (i.e., the writer never
issued CHUNK_FINALIZE), the data server <bcp14>MUST</bcp14> reject the
CHUNK_COMMIT entry for that chunk with
NFS4ERR_PAYLOAD_NOT_ATOMIC in the corresponding
ccr_status slot.  The writer is expected to either issue
CHUNK_FINALIZE to advance the state or CHUNK_ROLLBACK to
abandon the PENDING generation.</t>
              </li>
              <li>
                <t>If the target chunk is EMPTY (no generation to commit), the
data server <bcp14>MUST</bcp14> reject with NFS4ERR_PAYLOAD_NOT_ATOMIC
for that chunk.</t>
              </li>
              <li>
                <t>If the target chunk is already COMMITTED at the generation
identified by the cca_chunks entry's cg_gen_id, the
CHUNK_COMMIT is idempotent and <bcp14>MUST</bcp14> succeed.  Idempotence
preserves the NFSv4 COMMIT contract for duplicate-request
retransmission.</t>
              </li>
              <li>
                <t>If the target chunk is FINALIZED at a different generation
than the one named in the cca_chunks entry, the data server
<bcp14>MUST</bcp14> reject with NFS4ERR_CHUNK_GUARDED.  A client that sees
this has lost a race and <bcp14>SHOULD</bcp14> re-read the chunk (see
<xref target="sec-chunk_guard4"/>).</t>
              </li>
            </ul>
          </section>
          <section anchor="pipelining-considerations">
            <name>Pipelining Considerations</name>
            <t>The three-step CHUNK_WRITE -&gt; CHUNK_FINALIZE -&gt; CHUNK_COMMIT
sequence <bcp14>MAY</bcp14> be pipelined within a single NFSv4.2 compound
(see Section 12.8 of <xref target="RFC8881"/>) in single-writer mode, where
no other writer can race the client's per-chunk transitions
and the CHUNK_WRITE per-block status array reports only
local-failure cases (NFS4ERR_NOSPC, NFS4ERR_IO, and so on).</t>
            <t>Same-compound pipelining is <bcp14>NOT RECOMMENDED</bcp14> in multiple-writer
mode.  CHUNK_WRITE reports per-block outcomes in cwr_status
(<xref target="sec-CHUNK_WRITE"/>); a partial-success outcome (some chunks
accepted, others rejected with NFS4ERR_CHUNK_GUARDED on a lost
race) leaves the client without an opportunity to react before
a same-compound CHUNK_FINALIZE / CHUNK_COMMIT proceeds against
whichever chunks happen to be PENDING.  The compound-level
status is NFS4_OK in this case because per-block failures are
reported in the per-op status array rather than as a compound-
level error, so NFSv4 compound short-circuit (Section 2.10.6.4
of <xref target="RFC8881"/>) does not stop the trailing ops.  A client that
wants atomic-or-none semantics across multiple chunks <bcp14>MUST</bcp14>
examine the per-block status returned by each CHUNK_WRITE
before issuing the corresponding CHUNK_FINALIZE.</t>
            <t>For multi-chunk pipelines in multiple-writer mode, the
recommended pattern is to stagger the three steps across
compounds so each trailing operation acts only on chunks whose
preceding operation's status the client has already inspected:</t>
            <figure anchor="fig-staggered-chunk-pipeline">
              <name>Staggered three-stage chunk pipeline (multiple-writer mode)</name>
              <artwork><![CDATA[
Compound A:  SEQUENCE PUTFH CHUNK_WRITE(a)
Compound B:  SEQUENCE PUTFH CHUNK_WRITE(b) CHUNK_FINALIZE(a)
Compound C:  SEQUENCE PUTFH CHUNK_WRITE(c) CHUNK_FINALIZE(b)
                              CHUNK_COMMIT(a)
Compound D:  SEQUENCE PUTFH CHUNK_WRITE(d) CHUNK_FINALIZE(c)
                              CHUNK_COMMIT(b)
...
]]></artwork>
            </figure>
            <t>In each compound, the CHUNK_WRITE acts on the trailing chunk
the client wants to enqueue next; the CHUNK_FINALIZE operates
on a chunk whose CHUNK_WRITE the client has already inspected
in a previous compound; the CHUNK_COMMIT operates on a chunk
whose CHUNK_FINALIZE the client has already inspected.  If
any per-block status in compound N reports a guard loss or
other failure, the client abandons the affected chunk (via
CHUNK_ROLLBACK in compound N+1 or later) without ever issuing
the trailing FINALIZE / COMMIT for it.</t>
            <t>This pattern adds two compounds of latency between a chunk's
write and its commit (one for the FINALIZE wait, one for the
COMMIT wait), but provides the client with the per-step
inspection point required for atomic-or-none multi-chunk
writes under contention.</t>
          </section>
          <section anchor="interaction-with-a-locked-chunk">
            <name>Interaction with a Locked Chunk</name>
            <t>When a chunk is locked via CHUNK_LOCK (see <xref target="sec-CHUNK_LOCK"/>),
CHUNK_COMMIT is permitted only when the submitter owns the
lock -- that is, when the stateid carried on the compound
matches the lock holder's stateid (or is an
CHUNK_LOCK_FLAGS_ADOPT-transferred continuation):</t>
            <ul spacing="normal">
              <li>
                <t>The owning writer <bcp14>MAY</bcp14> issue CHUNK_COMMIT; the chunk
transitions from FINALIZED to COMMITTED normally.</t>
              </li>
              <li>
                <t>A non-owning client <bcp14>MUST</bcp14> receive NFS4ERR_CHUNK_LOCKED in
the corresponding ccr_status slot.  The chunk's state is
not changed.</t>
              </li>
              <li>
                <t>During repair, the MDS-escrow owner
(CHUNK_GUARD_CLIENT_ID_MDS, see <xref target="sec-chunk_guard_mds"/>)
holds the lock while the repair client adopts it via
CHUNK_LOCK_FLAGS_ADOPT.  CHUNK_COMMIT during the escrow
window is permitted only to the holder of the adopted
lock.</t>
              </li>
            </ul>
            <t>This rule is what <xref target="sec-system-model-consistency"/> calls
"lock continuity across revocation": the COMMIT privilege
follows the lock without gaps in which a non-owner could race.</t>
          </section>
        </section>
        <section anchor="response-codes">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>every named chunk transitioned to COMMITTED.</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to commit on this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>the data server is temporarily unable to process
the request.</t>
            </dd>
            <dt>NFS4ERR_FHEXPIRED:</dt>
            <dd>
              <t>the current filehandle has expired.</t>
            </dd>
            <dt>NFS4ERR_INVAL:</dt>
            <dd>
              <t>arguments named chunks outside the file's mirror
set or in a non-atomic state.</t>
            </dd>
            <dt>NFS4ERR_IO:</dt>
            <dd>
              <t>an I/O error occurred while persisting the commit.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement CHUNK_COMMIT.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
            <dt>NFS4ERR_STALE:</dt>
            <dd>
              <t>the current filehandle no longer identifies a
valid file.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-CHUNK_ERROR">
        <name>Operation 79: CHUNK_ERROR - Report Error on Cached Chunk Data</name>
        <section anchor="arguments-1">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CHUNK_ERROR4args">
            <name>XDR for CHUNK_ERROR4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_ERROR4args {
   ///     /* CURRENT_FH: file */
   ///     stateid4        cea_stateid;
   ///     offset4         cea_offset;
   ///     count4          cea_count;
   ///     nfsstat4        cea_error;
   ///     chunk_owner4    cea_owner;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-1">
          <name>RESULTS</name>
          <figure anchor="fig-CHUNK_ERROR4res">
            <name>XDR for CHUNK_ERROR4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_ERROR4res {
   ///     nfsstat4        cer_status;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-1">
          <name>DESCRIPTION</name>
          <t>CHUNK_ERROR allows a client that has detected corruption or
inconsistency in a chunk to report the condition to the data
server, so that the data server can mark the affected chunks
as errored.  Errored chunks are excluded from subsequent
CHUNK_READ responses until they are repaired via
CHUNK_WRITE_REPAIR (<xref target="sec-CHUNK_WRITE_REPAIR"/>) and the
repair is confirmed via CHUNK_REPAIRED (<xref target="sec-CHUNK_REPAIRED"/>).</t>
          <t>CHUNK_ERROR has no direct analog in <xref target="RFC8881"/>.  The closest
parallel is LAYOUTERROR (<xref target="RFC7862"/> Section 15.6), which
reports layout-level errors to the metadata server.
CHUNK_ERROR is the data-path counterpart: it reports a
chunk-level integrity finding directly to the data server so
that the corrupted chunks are quarantined before the
metadata server has had time to coordinate repair.  A client
<bcp14>SHOULD</bcp14> issue CHUNK_ERROR to the data server holding the bad
chunks before issuing LAYOUTERROR to the metadata server.</t>
          <t>The client provides:</t>
          <dl>
            <dt>cea_stateid:</dt>
            <dd>
              <t>the layout stateid the metadata server granted for
this file.  Under trusted-stateid tight coupling
(<xref target="sec-TRUST_STATEID"/>), this stateid <bcp14>MUST</bcp14> be in the
data server's trust table; otherwise the data server
rejects the operation with NFS4ERR_BAD_STATEID.</t>
            </dd>
            <dt>cea_offset:</dt>
            <dd>
              <t>starting chunk index of the affected range (not a byte
offset).</t>
            </dd>
            <dt>cea_count:</dt>
            <dd>
              <t>number of chunks the affected range covers, starting at
cea_offset.</t>
            </dd>
            <dt>cea_error:</dt>
            <dd>
              <t>the nfsstat4 error code that describes the integrity
finding.  Typical values include
NFS4ERR_PAYLOAD_NOT_ATOMIC (the chunk's persisted checksum
or guard did not match the value the client expected),
NFS4ERR_IO (the client's CHUNK_READ returned an I/O
error from this data server), and NFS4ERR_INVAL (the
chunk's chunk_owner4 did not match the expected
generation across mirrors).  The data server <bcp14>MAY</bcp14> record
the supplied error code in operator logs but does not
otherwise interpret it; the chunk-level effect (mark
errored) is the same for any cea_error value.</t>
            </dd>
            <dt>cea_owner:</dt>
            <dd>
              <t>the chunk_owner4 (<xref target="fig-chunk_owner4"/>) the client read
when it observed the error, so the data server can
record which (cg_gen_id, cg_client_id) generation was
reported as corrupted.  The reserved sentinels
CHUNK_GUARD_CLIENT_ID_NONE and
CHUNK_GUARD_CLIENT_ID_MDS <bcp14>MUST NOT</bcp14> appear in
cea_owner; see <xref target="sec-chunk_guard_none"/> and
<xref target="sec-chunk_guard_mds"/>.</t>
            </dd>
          </dl>
          <t>CHUNK_ERROR returns a single top-level status in cer_status;
there is no per-chunk status array because the data server
either accepts the report for the whole range or returns a
top-level error.  Once a CHUNK_ERROR has been accepted, the
affected chunks transition into the errored state described
in <xref target="sec-system-model-chunk-state"/>; subsequent CHUNK_READ
operations against those chunks return
NFS4ERR_PAYLOAD_NOT_ATOMIC in the per-chunk cr_status slot
until a successful CHUNK_REPAIRED sequence clears the
errored flag.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned (NFS4ERR_ISDIR / NFS4ERR_SYMLINK /
NFS4ERR_WRONG_TYPE).</t>
        </section>
        <section anchor="response-codes-1">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the client's chunk error report has been recorded.</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to report errors on this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_INVAL:</dt>
            <dd>
              <t>the reported chunk range or error code was not
recognized.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement CHUNK_ERROR.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-CHUNK_FINALIZE">
        <name>Operation 80: CHUNK_FINALIZE - Transition Chunks from Pending to Finalized</name>
        <section anchor="arguments-2">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CHUNK_FINALIZE4args">
            <name>XDR for CHUNK_FINALIZE4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_FINALIZE4args {
   ///     /* CURRENT_FH: file */
   ///     offset4         cfa_offset;
   ///     count4          cfa_count;
   ///     chunk_owner4    cfa_chunks<>;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-2">
          <name>RESULTS</name>
          <figure anchor="fig-CHUNK_FINALIZE4resok">
            <name>XDR for CHUNK_FINALIZE4resok</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_FINALIZE4resok {
   ///     verifier4       cfr_writeverf;
   ///     nfsstat4        cfr_status<>;
   /// };
]]></sourcecode>
          </figure>
          <figure anchor="fig-CHUNK_FINALIZE4res">
            <name>XDR for CHUNK_FINALIZE4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union CHUNK_FINALIZE4res switch (nfsstat4 cfr_status) {
   ///     case NFS4_OK:
   ///         CHUNK_FINALIZE4resok   cfr_resok4;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-2">
          <name>DESCRIPTION</name>
          <t>CHUNK_FINALIZE transitions chunks from the PENDING state (set
by CHUNK_WRITE, see <xref target="sec-CHUNK_WRITE"/>) to the FINALIZED
state in the chunk state machine (<xref target="fig-chunk-state-machine"/>).
A FINALIZED chunk is visible on the owning stateid for reads
(<xref target="sec-system-model-consistency"/>) and is eligible for
CHUNK_COMMIT (<xref target="sec-CHUNK_COMMIT"/>); the FINALIZED transition
is the writer's signal that it will issue no further
CHUNK_WRITEs for the named (cg_gen_id, cg_client_id)
generation of each chunk.</t>
          <t>CHUNK_FINALIZE has no direct analog in <xref target="RFC8881"/>: the COMMIT
operation in <xref target="RFC8881"/> Section 18.3 combines the "no more
writes" signal and the "make durable and globally visible"
step into one operation; the Flexible File Version 2 chunk
lifecycle separates them so a writer in multiple-writer mode
can validate the per-chunk acceptance status reported by
CHUNK_WRITE before committing any chunk to durable storage
(see "Pipelining Considerations" in
<xref target="sec-CHUNK_COMMIT"/>).</t>
          <t>The client provides cfa_offset and cfa_count to bound the
chunk range, and cfa_chunks to name the specific
(chunk_owner4) generations within that range to finalize:</t>
          <dl>
            <dt>cfa_offset:</dt>
            <dd>
              <t>starting chunk index in the file (not a byte offset).</t>
            </dd>
            <dt>cfa_count:</dt>
            <dd>
              <t>number of chunks the range covers, starting at
cfa_offset.  A zero cfa_count, or a cfa_offset beyond
the data server's highest chunk, is not an error; the
data server returns NFS4_OK with an empty cfr_status
array.</t>
            </dd>
            <dt>cfa_chunks:</dt>
            <dd>
              <t>an array of chunk_owner4 entries
(<xref target="fig-chunk_owner4"/>) naming the specific
(cg_gen_id, cg_client_id, co_id) generations to
finalize.  Each entry's co_id <bcp14>MUST</bcp14> fall within
[cfa_offset, cfa_offset + cfa_count); an entry whose
co_id is outside the range is rejected with
NFS4ERR_INVAL in the corresponding cfr_status slot.
The reserved sentinels CHUNK_GUARD_CLIENT_ID_NONE and
CHUNK_GUARD_CLIENT_ID_MDS <bcp14>MUST NOT</bcp14> appear as the
cg_client_id of any cfa_chunks entry; see
<xref target="sec-chunk_guard_none"/> and <xref target="sec-chunk_guard_mds"/>.</t>
            </dd>
          </dl>
          <t>The CHUNK_FINALIZE result reports the outcome per chunk in
the same order as cfa_chunks:</t>
          <dl>
            <dt>cfr_writeverf:</dt>
            <dd>
              <t>a verifier identifying the data server's incarnation
at the time the finalization completed.  Semantics
match cwr_writeverf in CHUNK_WRITE
(<xref target="sec-CHUNK_WRITE"/>): a client that observes a
different writeverf on a subsequent CHUNK_COMMIT <bcp14>MUST</bcp14>
re-issue the CHUNK_WRITE before treating any of the
finalized chunks as durable.</t>
            </dd>
            <dt>cfr_status:</dt>
            <dd>
              <t>per-chunk finalization status, one entry per
cfa_chunks entry, co-indexed.  NFS4_OK indicates that
the named chunk is FINALIZED on return.  Other
per-entry failure cases:
</t>
              <ul spacing="normal">
                <li>
                  <t>NFS4ERR_INVAL -- the named generation is not in the
PENDING state at this offset (the chunk is EMPTY,
FINALIZED at a different generation, or COMMITTED),
or the entry's co_id is outside the
[cfa_offset, cfa_offset + cfa_count) range.</t>
                </li>
                <li>
                  <t>NFS4ERR_CHUNK_GUARDED -- the chunk is PENDING but
at a different (cg_gen_id, cg_client_id) than the
one named in the cfa_chunks entry.  A client that
sees this has lost a race; see <xref target="sec-chunk_guard4"/>.</t>
                </li>
                <li>
                  <t>NFS4ERR_CHUNK_LOCKED -- the chunk is locked by a
CHUNK_LOCK (<xref target="sec-CHUNK_LOCK"/>) held by a different
stateid; the finalize is rejected.</t>
                </li>
              </ul>
              <t>The top-level CHUNK_FINALIZE status is NFS4_OK as long
as the data server could evaluate each cfa_chunks
entry; per-chunk failures are reported in cfr_status
rather than by failing the whole operation.  The
top-level status returns a non-OK code only when the
request could not be evaluated at all (for example,
NFS4ERR_BADXDR, NFS4ERR_SERVERFAULT).</t>
            </dd>
          </dl>
          <t>CHUNK_FINALIZE serves as the CRC validation checkpoint for
the chunk lifecycle.  The data server <bcp14>SHOULD</bcp14> have validated
each chunk's checksum against the value supplied in cwa_checksums
at CHUNK_WRITE time; the FINALIZE transition persists the
chunk metadata (CRC, owner, state) to stable storage so it
survives a data server restart.  An implementation <bcp14>MAY</bcp14>
defer some metadata persistence to CHUNK_COMMIT instead of
CHUNK_FINALIZE; in that case the FINALIZED state is
recovered by replay of the data server's local journal on
restart.</t>
          <t>A chunk that has been FINALIZED but not yet COMMITTED <bcp14>MAY</bcp14>
be rolled back via CHUNK_ROLLBACK (<xref target="sec-CHUNK_ROLLBACK"/>),
which returns the chunk to the EMPTY state (or to the
prior COMMITTED generation, if one exists).</t>
          <t>Like CHUNK_COMMIT, CHUNK_FINALIZE has no explicit stateid
field in its arguments.  The data server authorizes
CHUNK_FINALIZE against the stateid context the compound
has already established, typically the stateid carried on
an immediately preceding PUTFH or an earlier CHUNK_*
operation in the same compound.  Under trusted-stateid
tight coupling (<xref target="sec-TRUST_STATEID"/>), the data server
applies the trust-table check to whichever layout stateid
the compound has presented; if no layout stateid has been
presented or the presented stateid is not in the trust
table, the data server rejects CHUNK_FINALIZE with
NFS4ERR_BAD_STATEID.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned.  If the current filehandle
represents an object of type NF4DIR, NFS4ERR_ISDIR is
returned.  If the current filehandle designates a
symbolic link, NFS4ERR_SYMLINK is returned.  In all
other cases of non-regular-file filehandles,
NFS4ERR_WRONG_TYPE is returned.</t>
        </section>
        <section anchor="response-codes-2">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>every named chunk transitioned from PENDING to
FINALIZED.</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to finalize on this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>the data server is temporarily unable to process
the request.</t>
            </dd>
            <dt>NFS4ERR_FHEXPIRED:</dt>
            <dd>
              <t>the current filehandle has expired.</t>
            </dd>
            <dt>NFS4ERR_INVAL:</dt>
            <dd>
              <t>arguments named chunks not in PENDING or outside
the file's mirror set.</t>
            </dd>
            <dt>NFS4ERR_IO:</dt>
            <dd>
              <t>an I/O error occurred while persisting the
transition.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement
CHUNK_FINALIZE.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
            <dt>NFS4ERR_STALE:</dt>
            <dd>
              <t>the current filehandle no longer identifies a
valid file.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-CHUNK_HEADER_READ">
        <name>Operation 81: CHUNK_HEADER_READ - Read Chunk Header from File</name>
        <section anchor="arguments-3">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CHUNK_HEADER_READ4args">
            <name>XDR for CHUNK_HEADER_READ4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_HEADER_READ4args {
   ///     /* CURRENT_FH: file */
   ///     stateid4    chra_stateid;
   ///     offset4     chra_offset;
   ///     count4      chra_count;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-3">
          <name>RESULTS</name>
          <figure anchor="fig-CHUNK_HEADER_READ4resok">
            <name>XDR for CHUNK_HEADER_READ4resok</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_HEADER_READ4resok {
   ///     bool            chrr_eof;
   ///     nfsstat4        chrr_status<>;
   ///     bool            chrr_locked<>;
   ///     chunk_owner4    chrr_chunks<>;
   /// };
]]></sourcecode>
          </figure>
          <figure anchor="fig-CHUNK_HEADER_READ4res">
            <name>XDR for CHUNK_HEADER_READ4resok</name>
            <sourcecode type="xdr"><![CDATA[
   /// union CHUNK_HEADER_READ4res switch (nfsstat4 chrr_status) {
   ///     case NFS4_OK:
   ///         CHUNK_HEADER_READ4resok     chrr_resok4;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-3">
          <name>DESCRIPTION</name>
          <t>CHUNK_HEADER_READ returns the per-chunk metadata
(chunk_owner4, lock state, and per-chunk status) for a
range of chunks in the target data file without returning
the chunk payloads.  The operation enables clients and
repair coordinators to inspect chunk lifecycle and
ownership cheaply, without the data-transfer cost of
CHUNK_READ (<xref target="sec-CHUNK_READ"/>).  CHUNK_HEADER_READ has
no direct analog in <xref target="RFC8881"/>; it is the chunk-protocol
counterpart of a stat-like fast probe and exists because
chunks are first-class state-bearing objects whose
ownership, lock state, and lifecycle status are not
recoverable from a byte-offset query.</t>
          <t>The client provides:</t>
          <dl>
            <dt>chra_stateid:</dt>
            <dd>
              <t>the layout stateid the metadata server granted for
this file.  Under trusted-stateid tight coupling
(<xref target="sec-TRUST_STATEID"/>), this stateid <bcp14>MUST</bcp14> be in the
data server's trust table; otherwise the data server
rejects the operation with NFS4ERR_BAD_STATEID.</t>
            </dd>
            <dt>chra_offset:</dt>
            <dd>
              <t>starting chunk index of the range to inspect (not a
byte offset).</t>
            </dd>
            <dt>chra_count:</dt>
            <dd>
              <t>number of chunks the inspection range covers,
starting at chra_offset.</t>
            </dd>
          </dl>
          <t>The CHUNK_HEADER_READ result returns four co-indexed
arrays, one entry per chunk in the requested range in
chunk-offset order from chra_offset:</t>
          <dl>
            <dt>chrr_eof:</dt>
            <dd>
              <t>TRUE if the requested range extended at or past the
data server's last chunk for this file.  Same
per-data-server semantics as crr_eof in CHUNK_READ
(<xref target="sec-CHUNK_READ"/>).</t>
            </dd>
            <dt>chrr_status:</dt>
            <dd>
              <t>per-chunk lifecycle state encoded as an nfsstat4
(see "Per-Chunk Status Encoding" below).</t>
            </dd>
            <dt>chrr_locked:</dt>
            <dd>
              <t>per-chunk boolean.  TRUE if the chunk currently has a
CHUNK_LOCK (<xref target="sec-CHUNK_LOCK"/>) held by some
chunk_owner4; FALSE otherwise.  Lock state is
reported orthogonally to chrr_status so that a locked
chunk still surfaces its lifecycle state and
chunk_owner4 to the inspector.</t>
            </dd>
            <dt>chrr_chunks:</dt>
            <dd>
              <t>per-chunk chunk_owner4 (<xref target="fig-chunk_owner4"/>).  For a
chunk whose chrr_status is NFS4_OK the field is the
COMMITTED generation's owner.  For
NFS4ERR_PAYLOAD_NOT_ATOMIC the field is the writer of
the in-progress (PENDING or FINALIZED) generation.
For NFS4ERR_NOENT (EMPTY chunk) the chunk_owner4 is
unspecified.</t>
            </dd>
          </dl>
          <t>The operation has several uses:</t>
          <dl>
            <dt>Whole-file repair scan:</dt>
            <dd>
              <t>A repair client selected via CB_CHUNK_REPAIR
(<xref target="sec-CB_CHUNK_REPAIR"/>) walks the affected chunk
range and uses the per-chunk chunk_owner4 returned by
each mirror's data server to identify which chunks
carry an atomic stripe (all k data shards share the
same chunk_guard4) and which require reconstruction.
CHUNK_HEADER_READ is the discovery primitive that
drives the per-chunk decisions described in
<xref target="sec-repair-multi-writer"/>; without it, a repair
client would have to issue CHUNK_READ to retrieve the
full payload of every chunk merely to inspect its
guard.</t>
            </dd>
            <dt>Client-side recovery from partial writes:</dt>
            <dd>
              <t>After a network disruption or client restart, a writer
that holds the file's layout <bcp14>MAY</bcp14> issue
CHUNK_HEADER_READ to learn which of its prior
CHUNK_WRITEs reached the data server.  Chunks whose
chunk_owner4 reports the writer's own (cg_client_id,
cg_gen_id) pair are PENDING or FINALIZED and
recoverable; chunks absent from the response or
carrying another writer's owner are not.  The writer
can then re-issue CHUNK_WRITE for the missing chunks
or CHUNK_ROLLBACK for the abandoned ones without
reading payloads it has already committed locally.</t>
            </dd>
            <dt>Read-side atomicity check:</dt>
            <dd>
              <t>Before issuing a multi-chunk CHUNK_READ in
multiple-writer mode, a client <bcp14>MAY</bcp14> issue
CHUNK_HEADER_READ to verify that the chunks in the
target range share a common chunk_guard4 (the
cohort-atomicity property in
<xref target="sec-system-model-consistency"/>).  If the guards
diverge, the client knows the read will not be atomic
and can wait for a writer to commit, retry, or report
NFS4ERR_PAYLOAD_NOT_ATOMIC via LAYOUTERROR.  This is
a hint rather than a guarantee: a concurrent writer
<bcp14>MAY</bcp14> advance a chunk's state between the
CHUNK_HEADER_READ response and the subsequent
CHUNK_READ.</t>
            </dd>
            <dt>Lock probe before write:</dt>
            <dd>
              <t>A client <bcp14>MAY</bcp14> issue CHUNK_HEADER_READ and inspect the
chrr_locked array to discover whether any chunk in
the target range is currently held by a CHUNK_LOCK
(<xref target="sec-CHUNK_LOCK"/>) before attempting CHUNK_WRITE,
avoiding the round-trip cost of receiving
NFS4ERR_CHUNK_LOCKED.  As above, this is a hint; a
lock <bcp14>MAY</bcp14> be acquired between the header read and the
write.</t>
            </dd>
          </dl>
          <t>CHUNK_HEADER_READ does not change any chunk state.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned (NFS4ERR_ISDIR / NFS4ERR_SYMLINK /
NFS4ERR_WRONG_TYPE).</t>
          <section anchor="per-chunk-status-encoding">
            <name>Per-Chunk Status Encoding</name>
            <t>The per-chunk chrr_status field reports the chunk's
lifecycle state encoded as an nfsstat4:</t>
            <dl>
              <dt>NFS4_OK:</dt>
              <dd>
                <t>the chunk is COMMITTED and the chunk_owner4 in the
corresponding chrr_chunks slot is the COMMITTED
generation's owner.</t>
              </dd>
              <dt>NFS4ERR_PAYLOAD_NOT_ATOMIC:</dt>
              <dd>
                <t>the chunk is PENDING or FINALIZED (a non-globally-
visible generation is in progress).  The
chunk_owner4 in the corresponding chrr_chunks slot
names the writer of that in-progress generation.</t>
              </dd>
              <dt>NFS4ERR_NOENT:</dt>
              <dd>
                <t>the chunk is EMPTY (no COMMITTED generation has been
written at this offset).  The chunk_owner4 in the
corresponding chrr_chunks slot is unspecified.</t>
              </dd>
            </dl>
            <t>CHUNK_HEADER_READ never returns NFS4ERR_CHUNK_LOCKED in
chrr_status; lock state is reported orthogonally via
chrr_locked so that locked chunks still surface their
chunk_owner4 to the inspector.</t>
          </section>
        </section>
        <section anchor="response-codes-3">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the chunk headers have been returned.</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to read chunk headers on this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>the data server is temporarily unable to process
the request.</t>
            </dd>
            <dt>NFS4ERR_FHEXPIRED:</dt>
            <dd>
              <t>the current filehandle has expired.</t>
            </dd>
            <dt>NFS4ERR_IO:</dt>
            <dd>
              <t>an I/O error occurred while reading chunk headers.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement
CHUNK_HEADER_READ.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
            <dt>NFS4ERR_STALE:</dt>
            <dd>
              <t>the current filehandle no longer identifies a
valid file.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-CHUNK_LOCK">
        <name>Operation 82: CHUNK_LOCK - Lock Cached Chunk Data</name>
        <section anchor="arguments-4">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CHUNK_LOCK4args">
            <name>XDR for CHUNK_LOCK4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// const CHUNK_LOCK_FLAGS_ADOPT  = 0x00000001;
   ///
   /// struct CHUNK_LOCK4args {
   ///     /* CURRENT_FH: file */
   ///     stateid4        cla_stateid;
   ///     offset4         cla_offset;
   ///     count4          cla_count;
   ///     uint32_t        cla_flags;
   ///     chunk_owner4    cla_owner;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-4">
          <name>RESULTS</name>
          <figure anchor="fig-CHUNK_LOCK4res">
            <name>XDR for CHUNK_LOCK4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union CHUNK_LOCK4res switch (nfsstat4 clr_status) {
   ///     case NFS4_OK:
   ///         void;
   ///     case NFS4ERR_CHUNK_LOCKED:
   ///         chunk_owner4    clr_owner;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-4">
          <name>DESCRIPTION</name>
          <t>CHUNK_LOCK acquires an exclusive chunk-range lock on the
range specified by cla_offset and cla_count.  While the
lock is held, CHUNK_WRITE, CHUNK_WRITE_REPAIR,
CHUNK_FINALIZE, CHUNK_COMMIT, CHUNK_ROLLBACK, and
CHUNK_UNLOCK (<xref target="sec-CHUNK_UNLOCK"/>) operations on any of
the locked chunks from any other chunk_owner4 receive
NFS4ERR_CHUNK_LOCKED in the corresponding per-chunk
status slot.  The lock is associated with the
chunk_owner4 in cla_owner.</t>
          <t>CHUNK_LOCK is loosely analogous to LOCK (<xref target="RFC8881"/>
Section 18.10) in that it acquires an exclusive
guard against concurrent modification, but the two
operate on different coordinate systems and use
different naming: LOCK is byte-range and stateid-based;
CHUNK_LOCK is chunk-range and chunk_owner4-based.
CHUNK_LOCK is used in multiple-writer mode
(<xref target="sec-multi-writer"/>) to serialize racing writers on a
common chunk range, and in the repair flow
(<xref target="sec-repair-selection"/>) to transfer lock ownership
to a repair client via CHUNK_LOCK_FLAGS_ADOPT.</t>
          <t>The client provides:</t>
          <dl>
            <dt>cla_stateid:</dt>
            <dd>
              <t>the layout stateid the metadata server granted for
this file.  Under trusted-stateid tight coupling
(<xref target="sec-TRUST_STATEID"/>), this stateid <bcp14>MUST</bcp14> be in the
data server's trust table; otherwise the data server
rejects the operation with NFS4ERR_BAD_STATEID.</t>
            </dd>
            <dt>cla_offset:</dt>
            <dd>
              <t>starting chunk index of the lock range (not a byte
offset).</t>
            </dd>
            <dt>cla_count:</dt>
            <dd>
              <t>number of chunks the lock range covers, starting at
cla_offset.</t>
            </dd>
            <dt>cla_flags:</dt>
            <dd>
              <t>bitmask of CHUNK_LOCK_FLAGS_* values.  Currently
defined: CHUNK_LOCK_FLAGS_ADOPT (lock-ownership
transfer; see "Lock Transfer via
CHUNK_LOCK_FLAGS_ADOPT" below).  Unknown bits <bcp14>MUST</bcp14> be
rejected with NFS4ERR_INVAL.</t>
            </dd>
            <dt>cla_owner:</dt>
            <dd>
              <t>the chunk_owner4 (<xref target="fig-chunk_owner4"/>) that will hold
the lock on success.  The reserved sentinels
CHUNK_GUARD_CLIENT_ID_NONE and
CHUNK_GUARD_CLIENT_ID_MDS <bcp14>MUST NOT</bcp14> appear as the
cg_client_id of cla_owner; see
<xref target="sec-chunk_guard_none"/> and <xref target="sec-chunk_guard_mds"/>.
(A client requesting CHUNK_LOCK_FLAGS_ADOPT <bcp14>MUST</bcp14> use
its own cg_client_id, not the MDS-escrow sentinel,
even when adopting from an MDS-escrow holder.)</t>
            </dd>
          </dl>
          <t>The CHUNK_LOCK result returns:</t>
          <dl>
            <dt>clr_status:</dt>
            <dd>
              <t>NFS4_OK if the lock was acquired (or transferred via
ADOPT).  NFS4ERR_CHUNK_LOCKED if one or more chunks
in the range are already locked and the request does
not carry CHUNK_LOCK_FLAGS_ADOPT.</t>
            </dd>
            <dt>clr_owner (NFS4ERR_CHUNK_LOCKED case only):</dt>
            <dd>
              <t>the chunk_owner4 of the current lock holder, so the
caller can identify the blocking writer.</t>
            </dd>
          </dl>
          <t>The lock is released by CHUNK_UNLOCK
(<xref target="sec-CHUNK_UNLOCK"/>) or implicitly when the holder's
lease expires; on lease expiry without explicit
release, the data server transitions the lock to the
MDS-escrow owner if the metadata server has revoked
the holder's stateid via REVOKE_STATEID
(<xref target="sec-REVOKE_STATEID"/>), per the lock-continuity-
across-revocation invariant in
<xref target="sec-system-model-consistency"/>.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned (NFS4ERR_ISDIR / NFS4ERR_SYMLINK /
NFS4ERR_WRONG_TYPE).</t>
          <section anchor="lock-transfer-via-chunklockflagsadopt">
            <name>Lock Transfer via CHUNK_LOCK_FLAGS_ADOPT</name>
            <t>The CHUNK_LOCK_FLAGS_ADOPT flag in cla_flags requests an atomic
transfer of lock ownership to cla_owner for every chunk in
[cla_offset, cla_offset+cla_count).  The data server <bcp14>MUST</bcp14> perform
the transfer as a single atomic step per chunk: there is no window
in which the chunk is unlocked.  After a successful ADOPT, subsequent
CHUNK_WRITE, CHUNK_WRITE_REPAIR, CHUNK_ROLLBACK, and CHUNK_UNLOCK
operations <bcp14>MUST</bcp14> present cla_owner as their chunk_owner4.</t>
            <t>CHUNK_LOCK_FLAGS_ADOPT is the sole mechanism by which a chunk lock
can change hands without first being released.  The lock ordering
invariant -- that every chunk in a payload transitioning through
repair is held by exactly one owner continuously from failure
detection to repair completion -- depends on it.</t>
            <t>CHUNK_LOCK_FLAGS_ADOPT is valid only when the caller has been
selected as the repair client for the range by the metadata server,
typically via CB_CHUNK_REPAIR (<xref target="sec-CB_CHUNK_REPAIR"/>).  A data
server that receives CHUNK_LOCK with the ADOPT flag from a client
that has not been so designated <bcp14>MAY</bcp14> reject the operation with
NFS4ERR_ACCESS.  The mechanism by which the data server determines
designation is coupling-model dependent:</t>
            <ul spacing="normal">
              <li>
                <t>In a tightly coupled deployment, the metadata server notifies the
data server via the control protocol (e.g., TRUST_STATEID with
the new client's stateid or a similar facility).</t>
              </li>
              <li>
                <t>In a loosely coupled deployment, the data server <bcp14>MAY</bcp14> rely on the
metadata server's authentication of the client and accept ADOPT
from any authenticated client holding a current layout that
includes the range.  The write-hole exposure cost is that a misbehaving
client can trigger spurious ownership transfers; the write-hole
exposure is bounded by the chunk_guard4 checks that subsequent
CHUNK_WRITEs from displaced writers experience.</t>
              </li>
            </ul>
            <t>The current lock holder at the moment of ADOPT <bcp14>MAY</bcp14> be:</t>
            <ol spacing="normal" type="1"><li>
                <t>Another client whose stateid remains valid (for example, a
client that has stopped making progress but has not yet lost
its lease).  The prior owner's PENDING or FINALIZED shards
remain on disk until the new owner issues CHUNK_WRITE_REPAIR,
CHUNK_ROLLBACK, or CHUNK_COMMIT.</t>
              </li>
              <li>
                <t>The metadata server itself, acting through the
CHUNK_GUARD_CLIENT_ID_MDS escrow owner
(<xref target="sec-chunk_guard_mds"/>).  This occurs when the metadata
server has revoked the prior holder's stateid in a tightly
coupled deployment.</t>
              </li>
            </ol>
            <t>In either case, ADOPT's effect from the repair client's
perspective is the same: after the successful return the caller
holds the lock and may drive the range to consistency.</t>
            <t>The data server <bcp14>MUST</bcp14> reject CHUNK_LOCK with
CHUNK_LOCK_FLAGS_ADOPT if cla_owner's cg_client_id equals
CHUNK_GUARD_CLIENT_ID_MDS -- that value is reserved for server
production and <bcp14>MUST NOT</bcp14> be presented by a client.  The operation
returns NFS4ERR_INVAL in that case.</t>
          </section>
        </section>
        <section anchor="response-codes-4">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the requested chunk range has been locked.</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to lock chunks on this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_CHUNK_LOCKED:</dt>
            <dd>
              <t>one or more chunks in the requested
range are already locked by another writer.</t>
            </dd>
            <dt>NFS4ERR_INVAL:</dt>
            <dd>
              <t>the requested range was malformed or outside
the file's mirror set.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement CHUNK_LOCK.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-CHUNK_READ">
        <name>Operation 83: CHUNK_READ - Read Chunks from File</name>
        <section anchor="arguments-5">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CHUNK_READ4args">
            <name>XDR for CHUNK_READ4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_READ4args {
   ///     /* CURRENT_FH: file */
   ///     stateid4    cra_stateid;
   ///     offset4     cra_offset;
   ///     count4      cra_count;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-5">
          <name>RESULTS</name>
          <figure anchor="fig-read_chunk4">
            <name>XDR for read_chunk4</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct read_chunk4 {
   ///     checksum4       cr_checksum;
   ///     uint32_t        cr_effective_len;
   ///     chunk_owner4    cr_owner;
   ///     uint32_t        cr_payload_id;
   ///     bool            cr_locked;
   ///     nfsstat4        cr_status;
   ///     opaque          cr_chunk<>;
   /// };
]]></sourcecode>
          </figure>
          <figure anchor="fig-CHUNK_READ4resok">
            <name>XDR for CHUNK_READ4resok</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_READ4resok {
   ///     bool        crr_eof;
   ///     read_chunk4 crr_chunks<>;
   /// };
]]></sourcecode>
          </figure>
          <figure anchor="fig-CHUNK_READ4res">
            <name>XDR for CHUNK_READ4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union CHUNK_READ4res switch (nfsstat4 crr_status) {
   ///     case NFS4_OK:
   ///          CHUNK_READ4resok     crr_resok4;
   ///     default:
   ///          void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-5">
          <name>DESCRIPTION</name>
          <t>The CHUNK_READ operation is based upon the NFSv4.1 READ
operation (see Section 18.22 of <xref target="RFC8881"/>) and similarly
reads data from the regular file identified by the current
filehandle, with the difference that CHUNK_READ operates on
the chunk coordinate system used by Flexible File Version 2
layouts rather than on the byte coordinate system.</t>
          <t>The client provides a cra_offset of where the CHUNK_READ is
to start and a cra_count of how many chunks are to be read.
cra_offset is the starting chunk index in the file (not a
byte offset); the chunk at index N occupies the bytes
[N * chunk_size, (N + 1) * chunk_size) for codecs with a
uniform chunk size, where chunk_size is taken from
ffv2m_striping_unit_size in the file's layout
(<xref target="sec-ffv2-mirror4"/>).  For codecs whose parity shards
have variable sizes (the Mojette family), the parity-shard
chunks on a given data server may use a smaller per-shard
chunk size; see <xref target="sec-mojette-encoding"/>.  cra_count is a
count of chunks to read and not bytes to read.</t>
          <t>A cra_offset of zero starts reading at the first chunk of
the file.  If cra_offset is greater than or equal to the
number of chunks the data server holds for this file, the
status NFS4_OK is returned with crr_chunks empty and
crr_eof set to TRUE.</t>
          <t>If cra_count is zero, the CHUNK_READ succeeds and returns
zero chunks.  In all situations the data server <bcp14>MAY</bcp14> choose
to return fewer chunks than the client requested; the
client must be prepared to handle a short read and reissue
CHUNK_READ for the remaining chunks.</t>
          <t>The CHUNK_READ result is comprised of an array of
read_chunk4, each describing the metadata and payload of
one chunk.  The array entries are in chunk-index order
starting from cra_offset.  Within each read_chunk4
(<xref target="fig-read_chunk4"/>):</t>
          <dl>
            <dt>cr_checksum:</dt>
            <dd>
              <t>the checksum4 (<xref target="sec-checksum4"/>) the data server
computed over the chunk payload (cr_chunk) at
CHUNK_FINALIZE or CHUNK_COMMIT time and persisted with
the chunk metadata.  The cs_algorithm field matches the
layout's ffv2m_checksum_algorithm (<xref target="sec-ffv2-mirror4"/>);
the cs_value carries the computed bytes at the length
registered for that algorithm.  The client uses
cr_checksum to detect transport corruption between the
data server and the client; see
<xref target="sec-security-checksum-scope"/> for the scope and limits
of checksum protection per algorithm class.</t>
            </dd>
            <dt>cr_effective_len:</dt>
            <dd>
              <t>the byte length of cr_chunk.  This may be smaller than
the layout's chunk_size when the chunk is the final
chunk of a file whose size is not chunk-aligned, or
when the chunk belongs to a variable-size Mojette
parity shard.</t>
            </dd>
            <dt>cr_owner:</dt>
            <dd>
              <t>the chunk_owner4 carrying the chunk_guard4 and chunk-id
of the COMMITTED generation being returned.  A client
reading from multiple data servers in an erasure-coded
layout <bcp14>MUST</bcp14> compare cr_owner.co_guard across data
servers; agreement of the chunk_guard4 across the k
data shards is the atomicity invariant on which
reconstruction depends.  See
<xref target="sec-system-model-consistency"/>.</t>
            </dd>
            <dt>cr_payload_id:</dt>
            <dd>
              <t>the payload-id the writer associated with the chunk at
CHUNK_WRITE time, used by repair coordinators to
correlate chunks across mirrors.</t>
            </dd>
            <dt>cr_locked:</dt>
            <dd>
              <t>TRUE if the chunk currently has a CHUNK_LOCK
(<xref target="sec-CHUNK_LOCK"/>) held against it; FALSE otherwise.
Lock state does not block the read.</t>
            </dd>
            <dt>cr_status:</dt>
            <dd>
              <t>per-chunk status.  NFS4_OK indicates that cr_chunk is
the COMMITTED payload.  NFS4ERR_PAYLOAD_NOT_ATOMIC
indicates the chunk's persisted checksum or guard check
failed at read time, in which case cr_chunk content
is undefined; see <xref target="sec-NFS4ERR_PAYLOAD_NOT_ATOMIC"/>.
NFS4ERR_NOENT indicates the chunk is EMPTY (no
COMMITTED generation has been written at this offset).</t>
            </dd>
            <dt>cr_chunk:</dt>
            <dd>
              <t>the chunk payload bytes.  Empty for cr_status values
other than NFS4_OK.</t>
            </dd>
          </dl>
          <t>A chunk that is EMPTY at the requested offset is returned
as a synthetic zero-filled chunk: cr_status is
NFS4ERR_NOENT, cr_chunk is zero-filled to the layout's
chunk_size, cr_owner is set to all-zeros (with cg_client_id
= CHUNK_GUARD_CLIENT_ID_NONE, see <xref target="sec-chunk_guard_none"/>),
and cr_checksum is the checksum of the synthetic zero-filled
payload.  This lets a client reconstruct holes without a
special-casing path.</t>
          <t>The data server <bcp14>MAY</bcp14> signal end-of-file by setting crr_eof
to TRUE.  If the CHUNK_READ ended at the last chunk that
exists on this data server (the read returned chunks up to
and including the data server's last chunk) or extended
beyond it, crr_eof <bcp14>MUST</bcp14> be TRUE.  Otherwise crr_eof is
FALSE.  A successful CHUNK_READ of an empty file always
returns crr_eof as TRUE with crr_chunks empty.  Note that
crr_eof reflects the state at the data server only; in a
multi-data-server erasure-coded layout the file's logical
size is reconstructed at the client from the surviving
shards' chunk_owner4 values, not from any single data
server's crr_eof.</t>
          <t>Except when special stateids are used, the cra_stateid
value represents a layout stateid returned by a prior
LAYOUTGET against the metadata server (see Section 18.43
of <xref target="RFC8881"/>).  The data server uses cra_stateid to
verify that the client holds a valid layout that
authorizes reading this file.  Under trusted-stateid tight
coupling (<xref target="sec-TRUST_STATEID"/>), the data server
additionally checks that the metadata server has
registered the stateid via TRUST_STATEID; an unregistered
stateid (other than a special stateid) returns
NFS4ERR_BAD_STATEID.</t>
          <t>For a CHUNK_READ with a cra_stateid value of all bits
equal to zero, the data server <bcp14>MAY</bcp14> allow the CHUNK_READ
to be serviced subject to the chunk-lock state recorded in
cr_locked.  For a CHUNK_READ with a cra_stateid value of
all bits equal to one, the data server <bcp14>MAY</bcp14> allow CHUNK_READ
to bypass lock-state reporting at the data server.  These
special-stateid behaviours mirror the corresponding READ
semantics in <xref target="RFC8881"/> adapted to the chunk-locking
model (<xref target="sec-CHUNK_LOCK"/>) rather than the byte-range
locking model of <xref target="RFC8881"/> Section 12.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned.  If the current filehandle
represents an object of type NF4DIR, NFS4ERR_ISDIR is
returned.  If the current filehandle designates a symbolic
link, NFS4ERR_SYMLINK is returned.  In all other cases of
non-regular-file filehandles, NFS4ERR_WRONG_TYPE is
returned.</t>
          <t><xref target="fig-example-CHUNK_READ4args"/> shows a client requesting
4 chunks starting at chunk index 2.  Data Server 2
responds as in <xref target="fig-example-CHUNK_READ4resok"/>: there is
valid data for chunks 2 and 4, a synthetic zero-filled
hole at chunk 3, and no data for chunk 5 (the data server's
last chunk is chunk 4, so crr_eof is TRUE).  The data
server calculates a valid cr_checksum for chunk 3 based on the
synthetic zero-filled payload.</t>
          <figure anchor="fig-example-CHUNK_READ4args">
            <name>Example: CHUNK_READ4args parameters</name>
            <artwork><![CDATA[
        Data Server 2
  +--------------------------------+
  | CHUNK_READ4args                |
  +--------------------------------+
  | cra_stateid: 0                 |
  | cra_offset: 2                  |
  | cra_count: 4                   |
  +--------------------------------+
]]></artwork>
          </figure>
          <figure anchor="fig-example-CHUNK_READ4resok">
            <name>Example: Resulting CHUNK_READ4resok reply</name>
            <artwork><![CDATA[
        Data Server 2
  +--------------------------------+
  | CHUNK_READ4resok               |
  +--------------------------------+
  | crr_eof: true                  |
  | crr_chunks[0]:                 |
  |     cr_checksum: 0x3faddace         |
  |     cr_owner:                  |
  |         co_chunk_id: 2         |
  |         co_guard:              |
  |             cg_gen_id   : 3    |
  |             cg_client_id: 6    |
  |     cr_payload_id: 1           |
  |     cr_chunk: ....             |
  | crr_chunks[0]:                 |
  |     cr_checksum: 0xdeade4e5         |
  |     cr_owner:                  |
  |         co_chunk_id: 3         |
  |         co_guard:              |
  |             cg_gen_id   : 0    |
  |             cg_client_id: 0    |
  |     cr_payload_id: 1           |
  |     cr_chunk: 0000...00000     |
  | crr_chunks[0]:                 |
  |     cr_checksum: 0x7778abcd         |
  |     cr_owner:                  |
  |         co_chunk_id: 4         |
  |         co_guard:              |
  |             cg_gen_id   : 3    |
  |             cg_client_id: 6    |
  |     cr_payload_id: 1           |
  |     cr_chunk: ....             |
  +--------------------------------+
]]></artwork>
          </figure>
        </section>
        <section anchor="response-codes-5">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the requested chunks have been returned.</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to read this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>the data server is temporarily unable to process
the request.</t>
            </dd>
            <dt>NFS4ERR_FHEXPIRED:</dt>
            <dd>
              <t>the current filehandle has expired.</t>
            </dd>
            <dt>NFS4ERR_IO:</dt>
            <dd>
              <t>an I/O error occurred while reading the chunks.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement CHUNK_READ.</t>
            </dd>
            <dt>NFS4ERR_PAYLOAD_NOT_ATOMIC:</dt>
            <dd>
              <t>one or more chunks failed their
persisted guard or CRC check.  See <xref target="sec-NFS4ERR_PAYLOAD_NOT_ATOMIC"/>.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
            <dt>NFS4ERR_STALE:</dt>
            <dd>
              <t>the current filehandle no longer identifies a
valid file.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-CHUNK_REPAIRED">
        <name>Operation 84: CHUNK_REPAIRED - Confirm Repair of Errored Chunk Data</name>
        <section anchor="arguments-6">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CHUNK_REPAIRED4args">
            <name>XDR for CHUNK_REPAIRED4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_REPAIRED4args {
   ///     /* CURRENT_FH: file */
   ///     stateid4        cra_stateid;
   ///     offset4         cra_offset;
   ///     count4          cra_count;
   ///     chunk_owner4    cra_owner;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-6">
          <name>RESULTS</name>
          <figure anchor="fig-CHUNK_REPAIRED4res">
            <name>XDR for CHUNK_REPAIRED4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union CHUNK_REPAIRED4res switch (nfsstat4 crr_status) {
   ///     case NFS4_OK:
   ///         void;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-6">
          <name>DESCRIPTION</name>
          <t>CHUNK_REPAIRED signals that chunks previously marked as
errored (via CHUNK_ERROR, see <xref target="sec-CHUNK_ERROR"/>) have been
repaired and the errored state can be cleared.  The repair
client writes replacement data via CHUNK_WRITE_REPAIR
(<xref target="sec-CHUNK_WRITE_REPAIR"/>), advances the new chunks
through CHUNK_FINALIZE (<xref target="sec-CHUNK_FINALIZE"/>) and
CHUNK_COMMIT (<xref target="sec-CHUNK_COMMIT"/>), and only then issues
CHUNK_REPAIRED to make the repaired chunks visible to
normal CHUNK_READ traffic again.</t>
          <t>CHUNK_REPAIRED has no direct analog in <xref target="RFC8881"/>; it is
the chunk-protocol equivalent of clearing a "needs scrub"
flag after a RAID controller has rewritten a parity stripe.
Together with CHUNK_ERROR it forms the data-server-side
state-bit pair that quarantines damaged chunks from
ordinary reads during the repair window.</t>
          <t>The client provides:</t>
          <dl>
            <dt>cra_stateid:</dt>
            <dd>
              <t>the layout stateid the metadata server granted to the
repair client.  Under trusted-stateid tight coupling
(<xref target="sec-TRUST_STATEID"/>), this stateid <bcp14>MUST</bcp14> be in the
data server's trust table; otherwise the data server
rejects the operation with NFS4ERR_BAD_STATEID.</t>
            </dd>
            <dt>cra_offset:</dt>
            <dd>
              <t>starting chunk index of the repaired range (not a byte
offset).</t>
            </dd>
            <dt>cra_count:</dt>
            <dd>
              <t>number of chunks the repaired range covers, starting
at cra_offset.  The cra_offset / cra_count range <bcp14>MUST</bcp14>
match the range named in the original CHUNK_ERROR that
marked these chunks errored; mismatched ranges are
rejected with NFS4ERR_INVAL.</t>
            </dd>
            <dt>cra_owner:</dt>
            <dd>
              <t>the chunk_owner4 (<xref target="fig-chunk_owner4"/>) identifying the
repair client.  The data server uses this to record
which actor cleared the errored state.  The reserved
sentinels CHUNK_GUARD_CLIENT_ID_NONE and
CHUNK_GUARD_CLIENT_ID_MDS <bcp14>MUST NOT</bcp14> appear in cra_owner;
see <xref target="sec-chunk_guard_none"/> and <xref target="sec-chunk_guard_mds"/>.</t>
            </dd>
          </dl>
          <t>CHUNK_REPAIRED returns a single top-level status; there is
no per-chunk status array because the data server either
accepts the confirmation for the whole range or returns a
top-level error.</t>
          <t>The data server <bcp14>MUST</bcp14> verify before accepting the
confirmation that:</t>
          <ul spacing="normal">
            <li>
              <t>every chunk in [cra_offset, cra_offset + cra_count) is
currently in the errored state, and</t>
            </li>
            <li>
              <t>every chunk in the range has been advanced to COMMITTED
by a CHUNK_WRITE_REPAIR / CHUNK_FINALIZE / CHUNK_COMMIT
sequence since the CHUNK_ERROR that marked them errored.</t>
            </li>
          </ul>
          <t>If either precondition fails, the data server returns
NFS4ERR_INVAL and the errored state is left in place.  A
repair client that sees NFS4ERR_INVAL <bcp14>SHOULD</bcp14> verify the
chunks via CHUNK_HEADER_READ (<xref target="sec-CHUNK_HEADER_READ"/>)
before retrying.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned (NFS4ERR_ISDIR / NFS4ERR_SYMLINK /
NFS4ERR_WRONG_TYPE).</t>
        </section>
        <section anchor="response-codes-6">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the repair confirmation has been recorded.</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to confirm repair on this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_INVAL:</dt>
            <dd>
              <t>the chunks named were not in an errored state,
or the repair did not match the recorded error.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement
CHUNK_REPAIRED.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-CHUNK_ROLLBACK">
        <name>Operation 85: CHUNK_ROLLBACK - Rollback Changes on Cached Chunk Data</name>
        <section anchor="arguments-7">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CHUNK_ROLLBACK4args">
            <name>XDR for CHUNK_ROLLBACK4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_ROLLBACK4args {
   ///     /* CURRENT_FH: file */
   ///     offset4         cra_offset;
   ///     count4          cra_count;
   ///     chunk_owner4    cra_chunks<>;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-7">
          <name>RESULTS</name>
          <figure anchor="fig-CHUNK_ROLLBACK4resok">
            <name>XDR for CHUNK_ROLLBACK4resok</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_ROLLBACK4resok {
   ///     verifier4       crr_writeverf;
   /// };
]]></sourcecode>
          </figure>
          <figure anchor="fig-CHUNK_ROLLBACK4res">
            <name>XDR for CHUNK_ROLLBACK4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union CHUNK_ROLLBACK4res switch (nfsstat4 crr_status) {
   ///     case NFS4_OK:
   ///         CHUNK_ROLLBACK4resok   crr_resok4;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-7">
          <name>DESCRIPTION</name>
          <t>CHUNK_ROLLBACK reverts chunks from the PENDING or
FINALIZED state to their previous state, effectively
undoing a CHUNK_WRITE (<xref target="sec-CHUNK_WRITE"/>) that has not
yet reached COMMITTED via CHUNK_COMMIT
(<xref target="sec-CHUNK_COMMIT"/>).  The reversion target is the
prior COMMITTED generation, if one exists for the
affected chunk; otherwise the chunk returns to the EMPTY
state (<xref target="fig-chunk-state-machine"/>).  CHUNK_ROLLBACK
against a chunk already in the COMMITTED state is
permitted only on the repair path; see "Rollback of
COMMITTED Chunks" below.</t>
          <t>CHUNK_ROLLBACK has no direct analog in <xref target="RFC8881"/>: NFS
WRITE has no separate finalization or commit step that a
client could undo without contacting other components.
CHUNK_ROLLBACK exists because the chunk state machine
exposes the PENDING and FINALIZED states explicitly, and
the writer needs a way to abandon a non-committed
generation without committing it.</t>
          <t>The client provides cra_offset and cra_count to bound the
chunk range, and cra_chunks to name the specific
(chunk_owner4) generations within that range to roll back:</t>
          <dl>
            <dt>cra_offset:</dt>
            <dd>
              <t>starting chunk index in the file (not a byte offset).</t>
            </dd>
            <dt>cra_count:</dt>
            <dd>
              <t>number of chunks the range covers, starting at
cra_offset.</t>
            </dd>
            <dt>cra_chunks:</dt>
            <dd>
              <t>an array of chunk_owner4 entries
(<xref target="fig-chunk_owner4"/>) naming the specific
(cg_gen_id, cg_client_id, co_id) generations to roll
back.  Each entry's co_id <bcp14>MUST</bcp14> fall within
[cra_offset, cra_offset + cra_count); entries outside
the range are rejected with NFS4ERR_INVAL in the
corresponding crr_status slot (the result struct is
sized to match cra_chunks).  The reserved sentinels
CHUNK_GUARD_CLIENT_ID_NONE and
CHUNK_GUARD_CLIENT_ID_MDS <bcp14>MUST NOT</bcp14> appear as the
cg_client_id of any cra_chunks entry; see
<xref target="sec-chunk_guard_none"/> and <xref target="sec-chunk_guard_mds"/>.</t>
            </dd>
          </dl>
          <t>The CHUNK_ROLLBACK result returns:</t>
          <dl>
            <dt>crr_writeverf:</dt>
            <dd>
              <t>a verifier identifying the data server's incarnation.
Semantics match cwr_writeverf in CHUNK_WRITE.</t>
            </dd>
          </dl>
          <t>CHUNK_ROLLBACK has two principal scenarios:</t>
          <ol spacing="normal" type="1"><li>
              <t>A writer in multiple-writer mode that observed
per-chunk failures in the CHUNK_WRITE response (e.g.,
NFS4ERR_CHUNK_GUARDED on a subset of chunks) needs to
abandon the partial write before issuing CHUNK_FINALIZE
on the chunks that did succeed.  CHUNK_ROLLBACK on the
abandoned chunks releases their PENDING generation
cleanly.</t>
            </li>
            <li>
              <t>A repair client that wrote reconstructed data via
CHUNK_WRITE_REPAIR (<xref target="sec-CHUNK_WRITE_REPAIR"/>) and
subsequently discovered the reconstruction was wrong
(for example, a CRC mismatch detected during
cross-mirror verification) needs to abandon the
repair before any client commits it.</t>
            </li>
          </ol>
          <t>The data server effects the rollback as follows:</t>
          <ul spacing="normal">
            <li>
              <t>Chunks in PENDING with a matching chunk_owner4: the
data server deletes the PENDING payload and restores
the chunk to its prior state (EMPTY, or the prior
COMMITTED generation if the rollback invariant in
<xref target="sec-system-model-consistency"/> required retention).</t>
            </li>
            <li>
              <t>Chunks in FINALIZED with a matching chunk_owner4: the
data server deletes the FINALIZED payload and the
persisted finalization metadata, restoring the chunk
to its prior state.</t>
            </li>
            <li>
              <t>Chunks not in PENDING or FINALIZED at the named
generation, or whose chunk_owner4 does not match: the
corresponding crr_status slot reports NFS4ERR_INVAL
and the chunk is left unchanged.</t>
            </li>
          </ul>
          <section anchor="rollback-of-committed-chunks">
            <name>Rollback of COMMITTED Chunks</name>
            <t>CHUNK_ROLLBACK against a COMMITTED chunk is permitted
ONLY on the repair path, when a repair client is
restoring a prior COMMITTED generation that another
client incorrectly advanced.  In this case the data
server replaces the current COMMITTED generation with
the chunk_owner4 named in the cra_chunks entry, which
<bcp14>MUST</bcp14> itself name a generation already persisted at the
data server (typically the prior COMMITTED kept under
the rollback invariant).  A non-repair CHUNK_ROLLBACK
against a COMMITTED chunk is rejected with
NFS4ERR_INVAL.</t>
          </section>
          <section anchor="stateid-and-authorization">
            <name>Stateid and Authorization</name>
            <t>Like CHUNK_COMMIT, CHUNK_ROLLBACK has no explicit
stateid field in its arguments.  The data server
authorizes CHUNK_ROLLBACK against the stateid context
the compound has already established, typically the
stateid carried on an immediately preceding PUTFH or an
earlier CHUNK_* operation.  Under trusted-stateid tight
coupling (<xref target="sec-TRUST_STATEID"/>), the data server
applies the trust-table check to whichever layout
stateid the compound has presented; if no layout
stateid has been presented or the presented stateid is
not in the trust table, the data server rejects
CHUNK_ROLLBACK with NFS4ERR_BAD_STATEID.</t>
            <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned (NFS4ERR_ISDIR / NFS4ERR_SYMLINK /
NFS4ERR_WRONG_TYPE).</t>
          </section>
        </section>
        <section anchor="response-codes-7">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the named chunks have been rolled back.</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to roll back chunks on this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_INVAL:</dt>
            <dd>
              <t>arguments named chunks not eligible for rollback
or outside the file's mirror set.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement
CHUNK_ROLLBACK.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-CHUNK_UNLOCK">
        <name>Operation 86: CHUNK_UNLOCK - Unlock Cached Chunk Data</name>
        <section anchor="arguments-8">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CHUNK_UNLOCK4args">
            <name>XDR for CHUNK_UNLOCK4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_UNLOCK4args {
   ///     /* CURRENT_FH: file */
   ///     stateid4        cua_stateid;
   ///     offset4         cua_offset;
   ///     count4          cua_count;
   ///     chunk_owner4    cua_owner;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-8">
          <name>RESULTS</name>
          <figure anchor="fig-CHUNK_UNLOCK4res">
            <name>XDR for CHUNK_UNLOCK4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union CHUNK_UNLOCK4res switch (nfsstat4 cur_status) {
   ///     case NFS4_OK:
   ///         void;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-8">
          <name>DESCRIPTION</name>
          <t>CHUNK_UNLOCK releases the exclusive chunk-range lock
previously acquired by CHUNK_LOCK (<xref target="sec-CHUNK_LOCK"/>).
CHUNK_UNLOCK is loosely analogous to LOCKU (<xref target="RFC8881"/>
Section 18.12) in that it releases an exclusive guard,
but it operates on chunk-range coordinates and is
matched against the chunk_owner4 that acquired the
lock rather than against an open / lock stateid.</t>
          <t>The client provides:</t>
          <dl>
            <dt>cua_stateid:</dt>
            <dd>
              <t>the layout stateid the metadata server granted for
this file.  Under trusted-stateid tight coupling
(<xref target="sec-TRUST_STATEID"/>), this stateid <bcp14>MUST</bcp14> be in the
data server's trust table; otherwise the data server
rejects the operation with NFS4ERR_BAD_STATEID.</t>
            </dd>
            <dt>cua_offset:</dt>
            <dd>
              <t>starting chunk index of the range to unlock (not a
byte offset).</t>
            </dd>
            <dt>cua_count:</dt>
            <dd>
              <t>number of chunks the unlock range covers, starting at
cua_offset.  The range <bcp14>MUST</bcp14> match exactly the range
of an outstanding CHUNK_LOCK held by cua_owner;
partial-range unlock is not supported.</t>
            </dd>
            <dt>cua_owner:</dt>
            <dd>
              <t>the chunk_owner4 (<xref target="fig-chunk_owner4"/>) that holds
the lock.  The cg_client_id <bcp14>MUST</bcp14> match the
chunk_owner4 that was supplied on the CHUNK_LOCK that
acquired the lock (including the case of a lock
transferred via CHUNK_LOCK_FLAGS_ADOPT, in which the
adopter's chunk_owner4 is the current holder).  The
reserved sentinels CHUNK_GUARD_CLIENT_ID_NONE and
CHUNK_GUARD_CLIENT_ID_MDS <bcp14>MUST NOT</bcp14> appear as the
cg_client_id of cua_owner; see
<xref target="sec-chunk_guard_none"/> and <xref target="sec-chunk_guard_mds"/>.
In particular, a repair client releasing a lock it
adopted from the MDS-escrow owner uses its own
cg_client_id in cua_owner, not
CHUNK_GUARD_CLIENT_ID_MDS.</t>
            </dd>
          </dl>
          <t>The CHUNK_UNLOCK result returns a single top-level
status; there is no per-chunk status array because the
unlock either succeeds for the whole range or returns a
top-level error.</t>
          <t>CHUNK_UNLOCK is idempotent in the sense that releasing
chunks that are not currently locked returns NFS4_OK
without effect.  Releasing chunks that are locked by a
different cua_owner returns NFS4ERR_INVAL and leaves the
lock in place.</t>
          <t>A client <bcp14>SHOULD</bcp14> issue CHUNK_UNLOCK promptly after
completing the write, write-repair, or commit sequence
that the lock guarded.  Locks not explicitly released
are released implicitly when the holder's lease expires;
if the metadata server has revoked the holder's stateid
via REVOKE_STATEID (<xref target="sec-REVOKE_STATEID"/>) before the
lease lapses, the lock transitions to the MDS-escrow
owner per the lock-continuity invariant in
<xref target="sec-system-model-consistency"/> rather than being
released outright.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned (NFS4ERR_ISDIR / NFS4ERR_SYMLINK /
NFS4ERR_WRONG_TYPE).</t>
        </section>
        <section anchor="response-codes-8">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the named chunks have been unlocked, or no lock was
held (idempotent).</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to unlock chunks on this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_INVAL:</dt>
            <dd>
              <t>arguments named chunks not in a locked state
owned by this caller.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement
CHUNK_UNLOCK.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-CHUNK_WRITE">
        <name>Operation 87: CHUNK_WRITE - Write Chunks to File</name>
        <section anchor="arguments-9">
          <name>ARGUMENTS</name>
          <figure anchor="fig-write_chunk_guard4">
            <name>XDR for write_chunk_guard4</name>
            <sourcecode type="xdr"><![CDATA[
   /// union write_chunk_guard4 switch (bool cwg_check) {
   ///     case TRUE:
   ///         chunk_guard4   cwg_guard;
   ///     case FALSE:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
          <figure anchor="fig-CHUNK_WRITE4args">
            <name>XDR for CHUNK_WRITE4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// const CHUNK_WRITE_FLAGS_ACTIVATE_IF_EMPTY = 0x00000001;
   ///
   /// struct CHUNK_WRITE4args {
   ///     /* CURRENT_FH: file */
   ///     stateid4           cwa_stateid;
   ///     offset4            cwa_offset;
   ///     stable_how4        cwa_stable;
   ///     chunk_owner4       cwa_owner;
   ///     uint32_t           cwa_payload_id;
   ///     uint32_t           cwa_flags;
   ///     write_chunk_guard4 cwa_guard;
   ///     uint32_t           cwa_chunk_size;
   ///     checksum4          cwa_checksums<>;
   ///     opaque             cwa_chunks<>;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-9">
          <name>RESULTS</name>
          <figure anchor="fig-CHUNK_WRITE4resok">
            <name>XDR for CHUNK_WRITE4resok</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_WRITE4resok {
   ///     count4          cwr_count;
   ///     stable_how4     cwr_committed;
   ///     verifier4       cwr_writeverf;
   ///     nfsstat4        cwr_block_status<>;
   ///     bool            cwr_block_activated<>;
   ///     chunk_owner4    cwr_owners<>;
   /// };
]]></sourcecode>
          </figure>
          <figure anchor="fig-CHUNK_WRITE4res">
            <name>XDR for CHUNK_WRITE4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union CHUNK_WRITE4res switch (nfsstat4 cwr_status) {
   ///     case NFS4_OK:
   ///         CHUNK_WRITE4resok    cwr_resok4;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-9">
          <name>DESCRIPTION</name>
          <t>The CHUNK_WRITE operation is based upon the NFSv4.1 WRITE
operation (see Section 18.32 of <xref target="RFC8881"/>) and similarly
writes data to the regular file identified by the current
filehandle, with the difference that CHUNK_WRITE operates
on the chunk coordinate system used by Flexible File
Version 2 layouts rather than on the byte coordinate
system.  Successful chunk writes initially enter the
PENDING state in the chunk state machine
(<xref target="fig-chunk-state-machine"/>); a subsequent CHUNK_FINALIZE
(<xref target="sec-CHUNK_FINALIZE"/>) and CHUNK_COMMIT
(<xref target="sec-CHUNK_COMMIT"/>) (or the activation shortcut
described below) progress them to COMMITTED.</t>
          <t>The client provides a cwa_offset of where the CHUNK_WRITE
is to start and a payload consisting of one or more chunks
packed into the cwa_chunks opaque field.  cwa_offset is
the starting chunk index in the file (not a byte offset);
each chunk occupies cwa_chunk_size bytes within cwa_chunks
except the last, which <bcp14>MAY</bcp14> be shorter when the file size
is not chunk-aligned or when the payload encodes a
variable-size Mojette parity shard
(<xref target="sec-mojette-encoding"/>).  The number of chunks in the
payload is ceil(len(cwa_chunks) / cwa_chunk_size).</t>
          <t>cwa_owner (<xref target="fig-chunk_owner4"/>) names the writer's
chunk_owner4: cg_gen_id is the writer's per-chunk
generation counter, cg_client_id is the writer's
metadata-server-assigned client identifier (the reserved
sentinels CHUNK_GUARD_CLIENT_ID_NONE and
CHUNK_GUARD_CLIENT_ID_MDS <bcp14>MUST NOT</bcp14> appear in cwa_owner;
see <xref target="sec-chunk_guard_none"/> and <xref target="sec-chunk_guard_mds"/>),
and co_id is the chunk-index identifier of the first
chunk in the payload (redundant with cwa_offset for a
single-chunk write; the data server <bcp14>MUST</bcp14> treat them as
the same value and <bcp14>MAY</bcp14> reject a mismatch with
NFS4ERR_INVAL).</t>
          <t>cwa_payload_id is a writer-chosen identifier that lets a
repair coordinator correlate chunks of the same logical
write across data servers.</t>
          <t>cwa_checksums, when non-empty, <bcp14>MUST</bcp14> contain one checksum
entry per chunk in the payload.  Each entry's cs_algorithm
<bcp14>MUST</bcp14> match ffv2m_checksum_algorithm of the mirror named in
the layout (see <xref target="sec-ffv2-mirror4"/>); a mismatch is rejected
with NFS4ERR_INVAL.  The data server validates each chunk's
checksum at CHUNK_WRITE time and rejects mismatched chunks
with NFS4ERR_IO in the corresponding cwr_block_status slot.
An empty cwa_checksums array (cwa_checksums_len == 0)
indicates the client did not supply per-chunk checksums; the
data server still computes and persists per-chunk checksums
from the payload bytes for later integrity verification but
cannot detect transport corruption at CHUNK_WRITE time
without the client's
reference values.</t>
          <t>cwa_flags carries CHUNK_WRITE_FLAGS_ACTIVATE_IF_EMPTY (see
"Stability and Activation" below).</t>
          <t>cwa_guard (<xref target="fig-write_chunk_guard4"/>) controls the chunk-
guard CAS check (see "Guarding the Write" below).</t>
          <t>A cwa_offset of zero starts writing at the first chunk of
the file.  Unlike READ in <xref target="RFC8881"/>, a CHUNK_WRITE whose
cwa_offset extends beyond the current end of the file is
not an error: the data server extends the file's chunk
store to cover the new chunks, with intervening offsets
remaining EMPTY (<xref target="sec-system-model-chunk-state"/>) until
they too are written.  If the cwa_chunks payload is empty
(zero bytes), the CHUNK_WRITE succeeds and writes zero
chunks (cwr_count == 0).</t>
          <t>In all situations the data server <bcp14>MAY</bcp14> choose to write
fewer chunks than the client requested; the client must be
prepared to handle a short write and reissue CHUNK_WRITE
for the remaining chunks.</t>
          <t>The CHUNK_WRITE result includes per-chunk outcomes in
cwr_block_status, cwr_block_activated, and cwr_owners, all
co-indexed and one entry per chunk in the payload:</t>
          <dl>
            <dt>cwr_count:</dt>
            <dd>
              <t>the number of chunks the data server successfully
accepted.  Chunks that failed their guard check, checksum
check, or any other local precondition do not
contribute to cwr_count.</t>
            </dd>
            <dt>cwr_committed:</dt>
            <dd>
              <t>the stable_how4 level the data server actually applied
for accepted chunks.  This <bcp14>MUST</bcp14> be at least as durable
as cwa_stable; see "Stability and Activation" below.</t>
            </dd>
            <dt>cwr_writeverf:</dt>
            <dd>
              <t>a verifier identifying the data server's incarnation.
A client uses cwr_writeverf to detect a data server
restart that lost UNSTABLE4 writes: if the client's
subsequent CHUNK_COMMIT returns a different writeverf
than was returned by an UNSTABLE4 CHUNK_WRITE earlier,
the chunks may have been lost and the client <bcp14>SHOULD</bcp14>
re-issue CHUNK_WRITE.  cwr_writeverf changes on every
data server restart that loses uncommitted state.</t>
            </dd>
            <dt>cwr_block_status:</dt>
            <dd>
              <t>per-chunk acceptance status; see "Per-Block Acceptance
Semantics" below.</t>
            </dd>
            <dt>cwr_block_activated:</dt>
            <dd>
              <t>per-chunk activation flag.  TRUE indicates that the
chunk is COMMITTED on return from CHUNK_WRITE -- the
activation shortcut described under "Stability and
Activation" below.  FALSE indicates that the chunk is
in the PENDING state and requires a subsequent
CHUNK_FINALIZE and CHUNK_COMMIT to become COMMITTED.</t>
            </dd>
            <dt>cwr_owners:</dt>
            <dd>
              <t>per-chunk chunk_owner4 the data server recorded.  In
normal operation this matches cwa_owner with cg_gen_id
incremented for each chunk; the field is reported
explicitly so a client that lost track of its
per-chunk gen counter can recover the data server's
view.</t>
            </dd>
          </dl>
          <t>Except when special stateids are used, cwa_stateid
represents a layout stateid returned by a prior LAYOUTGET
against the metadata server (see Section 18.43 of
<xref target="RFC8881"/>) that authorizes write access to this file.
Under trusted-stateid tight coupling
(<xref target="sec-TRUST_STATEID"/>), the data server additionally
checks that the metadata server has registered the
stateid via TRUST_STATEID; an unregistered stateid (other
than a special stateid) returns NFS4ERR_BAD_STATEID.</t>
          <t>For a CHUNK_WRITE with a cwa_stateid value of all bits
equal to zero, the data server <bcp14>MAY</bcp14> allow the CHUNK_WRITE
to be serviced subject to any CHUNK_LOCK currently held
on the target chunks.  For a CHUNK_WRITE with a
cwa_stateid value of all bits equal to one, the data
server <bcp14>MAY</bcp14> allow CHUNK_WRITE to bypass lock-state
checking at the data server.  These special-stateid
behaviours mirror the corresponding WRITE semantics in
<xref target="RFC8881"/> adapted to the chunk-locking model
(<xref target="sec-CHUNK_LOCK"/>) rather than the byte-range locking
model of <xref target="RFC8881"/> Section 12.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned.  If the current filehandle
represents an object of type NF4DIR, NFS4ERR_ISDIR is
returned.  If the current filehandle designates a
symbolic link, NFS4ERR_SYMLINK is returned.  In all other
cases of non-regular-file filehandles, NFS4ERR_WRONG_TYPE
is returned.</t>
          <section anchor="stability-and-activation">
            <name>Stability and Activation</name>
            <t>The cwa_stable field controls the durability level the
data server guarantees before returning:</t>
            <dl>
              <dt>FILE_SYNC4:</dt>
              <dd>
                <t>The data server <bcp14>MUST</bcp14> commit all written chunks plus
all chunk-store metadata to stable storage before
returning.</t>
              </dd>
              <dt>DATA_SYNC4:</dt>
              <dd>
                <t>The data server <bcp14>MUST</bcp14> commit all written chunk payloads
to stable storage and enough of the chunk-store
metadata to retrieve the data before returning.  An
implementation <bcp14>MAY</bcp14> treat DATA_SYNC4 identically to
FILE_SYNC4 at a possible performance cost.</t>
              </dd>
              <dt>UNSTABLE4:</dt>
              <dd>
                <t>The data server is free to commit any portion of the
chunk payload and metadata to stable storage before
returning, including all or none.  The data server
makes only two guarantees: it will not destroy any
chunk payload it accepted without changing
cwr_writeverf, and the durability level it ultimately
applies will not be less than that requested.</t>
              </dd>
            </dl>
            <t>The CHUNK_WRITE_FLAGS_ACTIVATE_IF_EMPTY flag in cwa_flags
requests an activation shortcut for first-time writes: a
chunk that was EMPTY before the CHUNK_WRITE and whose
write reaches FILE_SYNC4 or DATA_SYNC4 durability <bcp14>MAY</bcp14> be
transitioned directly to COMMITTED by the data server,
with the corresponding cwr_block_activated entry set to
TRUE in the response.
Without the flag, or for chunks that were not EMPTY
before the write, or for writes at UNSTABLE4 durability,
the chunk enters the PENDING state and reaches COMMITTED
only after a subsequent CHUNK_FINALIZE and CHUNK_COMMIT.</t>
            <t>The activation shortcut interacts with concurrent writers
and unstable writes in subtle ways:</t>
            <ul spacing="normal">
              <li>
                <t>A chunk written with cwa_stable == UNSTABLE4 cannot be
activated by CHUNK_WRITE_FLAGS_ACTIVATE_IF_EMPTY
because the payload has not been committed to stable
storage; the chunk enters the PENDING state regardless
of the flag.</t>
              </li>
              <li>
                <t>Two clients racing on a chunk in multiple-writer mode
each see chunk_guard4 contention.  One client wins the
per-chunk CAS; if its CHUNK_WRITE had
CHUNK_WRITE_FLAGS_ACTIVATE_IF_EMPTY set and stable was
FILE_SYNC4 or DATA_SYNC4, the winning chunk becomes
COMMITTED.  The losing client sees NFS4ERR_CHUNK_GUARDED
in the corresponding cwr_block_status slot.</t>
              </li>
              <li>
                <t>A client that issues an UNSTABLE4 CHUNK_WRITE and
observes a FALSE entry in cwr_block_activated for a
chunk <bcp14>MAY</bcp14> still find that chunk COMMITTED on a
subsequent CHUNK_READ -- another client could have
activated it via the shortcut after this one's
response was sent.  cwr_block_activated reflects the
state at the moment the CHUNK_WRITE result was
constructed, not a commitment to that state's
persistence.</t>
              </li>
            </ul>
          </section>
          <section anchor="guarding-the-write">
            <name>Guarding the Write</name>
            <t>A guarded CHUNK_WRITE is when the writing of a block <bcp14>MUST</bcp14> fail if
cwa_guard.cwg_check is TRUE and the target chunk does not have the
same cg_gen_id as cwa_guard.cwg_guard.cg_gen_id.  This is
useful in read-update-write scenarios.  The client reads a block,
updates it, and is prepared to write it back.  It guards the write
such that if another writer has modified the block, the data server
will reject the modification.</t>
            <t>As the chunk_guard4 (see <xref target="fig-chunk_guard4"/>) does not have a
chunk_id and the CHUNK_WRITE applies to all blocks in the range of
cwa_offset to the length of cwa_data, then each of the target blocks
<bcp14>MUST</bcp14> have the same cg_gen_id and cg_client_id.  The client <bcp14>SHOULD</bcp14>
present the smallest set of blocks as possible to meet this
requirement.</t>
          </section>
          <section anchor="per-block-acceptance-semantics">
            <name>Per-Block Acceptance Semantics</name>
            <t>A CHUNK_WRITE targets a contiguous range of blocks on a single
data server.  The data server evaluates each block independently
and reports the outcome per block in cwr_block_status (see
<xref target="fig-CHUNK_WRITE4resok"/>):</t>
            <ul spacing="normal">
              <li>
                <t>Each block is subjected to the guard check (when
cwa_guard.cwg_check is TRUE), the cg_client_id validation
(see <xref target="sec-chunk_guard4"/>), and any other local preconditions
(storage-space limits, tight-coupling trust-table state,
etc.).</t>
              </li>
              <li>
                <t>Blocks that pass their preconditions are written and their
cwr_block_status entry is NFS4_OK.  Blocks that fail produce
the appropriate error code
(NFS4ERR_CHUNK_GUARDED, NFS4ERR_NOSPC, etc.) in the
corresponding cwr_block_status slot, and their data is
NOT persisted.</t>
              </li>
              <li>
                <t>cwr_count reflects only the blocks that were written
successfully; failed blocks do not contribute.</t>
              </li>
              <li>
                <t>The top-level cwr_status is NFS4_OK when the call itself was
structurally valid and the data server could evaluate each
block.  Per-block failures are reported in cwr_block_status,
not by failing the whole operation.  The data server returns
a top-level error only if it could not evaluate the request
at all (for example, NFS4ERR_BADXDR, NFS4ERR_SERVERFAULT).</t>
              </li>
            </ul>
            <t>This is the "continue and report" discipline.  It is
intentionally not all-or-none: atomicity is already per-chunk
(see <xref target="sec-system-model-consistency"/>), so there is no
file-level correctness reason to reject the entire compound
because of a single chunk guard failure.  Per-block reporting
gives the client the information it needs to construct a
targeted CHUNK_ROLLBACK or CHUNK_WRITE retry that covers only
the blocks that failed.</t>
            <t>The data server does not hold a file-wide lock across the
per-block evaluation.  The chunk_guard4 CAS is evaluated
atomically per chunk at the point the data server updates that
chunk's state, so an interleaving CHUNK_WRITE from a different
client that arrives mid-compound will either win its own CAS
race (and the losing client sees NFS4ERR_CHUNK_GUARDED for the
contested block) or be rejected itself, without introducing
data-server-level locking beyond the per-chunk scope.</t>
          </section>
        </section>
        <section anchor="response-codes-9">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the chunks have been written and are in the PENDING
state.</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to write to this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_CHUNK_GUARDED:</dt>
            <dd>
              <t>the chunk_guard4 condition supplied by
the client did not match the persisted state.</t>
            </dd>
            <dt>NFS4ERR_CHUNK_LOCKED:</dt>
            <dd>
              <t>one or more chunks in the requested
range are locked by another writer.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>the data server is temporarily unable to process
the request.</t>
            </dd>
            <dt>NFS4ERR_FHEXPIRED:</dt>
            <dd>
              <t>the current filehandle has expired.</t>
            </dd>
            <dt>NFS4ERR_IO:</dt>
            <dd>
              <t>an I/O error occurred while persisting the chunks.</t>
            </dd>
            <dt>NFS4ERR_NOSPC:</dt>
            <dd>
              <t>there is insufficient space at the data server.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement CHUNK_WRITE.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
            <dt>NFS4ERR_STALE:</dt>
            <dd>
              <t>the current filehandle no longer identifies a
valid file.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-CHUNK_WRITE_REPAIR">
        <name>Operation 88: CHUNK_WRITE_REPAIR - Write Repaired Cached Chunk Data</name>
        <section anchor="arguments-10">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CHUNK_WRITE_REPAIR4args">
            <name>XDR for CHUNK_WRITE_REPAIR4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_WRITE_REPAIR4args {
   ///     /* CURRENT_FH: file */
   ///     stateid4           cwra_stateid;
   ///     offset4            cwra_offset;
   ///     stable_how4        cwra_stable;
   ///     chunk_owner4       cwra_owner;
   ///     uint32_t           cwra_payload_id;
   ///     uint32_t           cwra_chunk_size;
   ///     checksum4          cwra_checksums<>;
   ///     opaque             cwra_chunks<>;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-10">
          <name>RESULTS</name>
          <figure anchor="fig-CHUNK_WRITE_REPAIR4resok">
            <name>XDR for CHUNK_WRITE_REPAIR4resok</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CHUNK_WRITE_REPAIR4resok {
   ///     count4          cwrr_count;
   ///     stable_how4     cwrr_committed;
   ///     verifier4       cwrr_writeverf;
   ///     nfsstat4        cwrr_status<>;
   /// };
]]></sourcecode>
          </figure>
          <figure anchor="fig-CHUNK_WRITE_REPAIR4res">
            <name>XDR for CHUNK_WRITE_REPAIR4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union CHUNK_WRITE_REPAIR4res switch (nfsstat4 cwrr_status) {
   ///     case NFS4_OK:
   ///         CHUNK_WRITE_REPAIR4resok   cwrr_resok4;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-10">
          <name>DESCRIPTION</name>
          <t>CHUNK_WRITE_REPAIR is the repair-path variant of CHUNK_WRITE
(<xref target="sec-CHUNK_WRITE"/>).  It writes reconstructed chunk data
to a data server whose chunks have been reported errored
(via CHUNK_ERROR, see <xref target="sec-CHUNK_ERROR"/>) or to a
replacement data server selected during whole-file repair.
The data server applies repair-specific policies to the
write that are not appropriate for normal client writes:
the chunk_guard4 CAS check is bypassed (the repair client
is writing a reconstructed value rather than competing in
a multiple-writer race), and the data server <bcp14>MAY</bcp14> log the
repair separately for operator audit.</t>
          <t>CHUNK_WRITE_REPAIR has no direct analog in <xref target="RFC8881"/>; it
is the chunk-protocol equivalent of writing reconstructed
data into a RAID stripe whose other members are known
healthy.  The reconstructed data is produced by the repair
client from surviving shards via the erasure-coding
algorithm of the file's layout (RS matrix inversion or
Mojette corner-peeling, see <xref target="sec-rs-encoding"/> and
<xref target="sec-mojette-encoding"/>).</t>
          <t>The repair workflow that invokes CHUNK_WRITE_REPAIR is:</t>
          <ol spacing="normal" type="1"><li>
              <t>The repair client (selected per
<xref target="sec-repair-selection"/>) reads surviving chunks from
the remaining data servers via CHUNK_READ
(<xref target="sec-CHUNK_READ"/>).</t>
            </li>
            <li>
              <t>The repair client reconstructs the missing chunks
using the erasure-coding algorithm of the file's
layout.</t>
            </li>
            <li>
              <t>The repair client acquires a CHUNK_LOCK
(<xref target="sec-CHUNK_LOCK"/>) on the target data server to
prevent concurrent writes during repair.  For repair
that adopts an MDS-escrow lock, the CHUNK_LOCK
carries CHUNK_LOCK_FLAGS_ADOPT
(<xref target="sec-chunk_guard_mds"/>).</t>
            </li>
            <li>
              <t>The repair client writes the reconstructed data via
CHUNK_WRITE_REPAIR.</t>
            </li>
            <li>
              <t>The repair client issues CHUNK_FINALIZE
(<xref target="sec-CHUNK_FINALIZE"/>) and CHUNK_COMMIT
(<xref target="sec-CHUNK_COMMIT"/>) to persist the repair.</t>
            </li>
            <li>
              <t>The repair client issues CHUNK_REPAIRED
(<xref target="sec-CHUNK_REPAIRED"/>) to clear the errored state.</t>
            </li>
            <li>
              <t>The repair client releases the lock via CHUNK_UNLOCK
(<xref target="sec-CHUNK_UNLOCK"/>).</t>
            </li>
          </ol>
          <t>The arguments mirror CHUNK_WRITE except that
CHUNK_WRITE_REPAIR has no cwa_flags field (the
activation-shortcut behaviour is not offered on the repair
path) and no cwa_guard field (the guard CAS is bypassed
by construction):</t>
          <dl>
            <dt>cwra_stateid:</dt>
            <dd>
              <t>the layout stateid the metadata server granted to the
repair client.  Under trusted-stateid tight coupling
(<xref target="sec-TRUST_STATEID"/>), this stateid <bcp14>MUST</bcp14> be in the
data server's trust table; otherwise the data server
rejects the operation with NFS4ERR_BAD_STATEID.</t>
            </dd>
            <dt>cwra_offset:</dt>
            <dd>
              <t>starting chunk index in the file (not a byte offset).</t>
            </dd>
            <dt>cwra_stable:</dt>
            <dd>
              <t>the stable_how4 durability level the data server <bcp14>MUST</bcp14>
apply before returning.  Semantics match cwa_stable in
CHUNK_WRITE (see <xref target="sec-CHUNK_WRITE"/> "Stability and
Activation").</t>
            </dd>
            <dt>cwra_owner:</dt>
            <dd>
              <t>the chunk_owner4 (<xref target="fig-chunk_owner4"/>) the repair
client uses for the reconstructed payload.  The
cg_client_id <bcp14>MUST</bcp14> be the repair client's own
ffv2m_client_id (not CHUNK_GUARD_CLIENT_ID_MDS); the
cg_gen_id is the repair client's locally chosen
per-chunk generation counter.  The reserved sentinels
CHUNK_GUARD_CLIENT_ID_NONE and
CHUNK_GUARD_CLIENT_ID_MDS <bcp14>MUST NOT</bcp14> appear in
cwra_owner; see <xref target="sec-chunk_guard_none"/> and
<xref target="sec-chunk_guard_mds"/>.</t>
            </dd>
            <dt>cwra_payload_id:</dt>
            <dd>
              <t>the payload-id the repair client associates with the
reconstructed payload, used by the repair coordinator
to correlate this repair across mirrors.</t>
            </dd>
            <dt>cwra_chunk_size:</dt>
            <dd>
              <t>the nominal chunk size of the reconstructed payload,
in bytes.</t>
            </dd>
            <dt>cwra_checksums:</dt>
            <dd>
              <t>per-chunk checksum4 (<xref target="sec-checksum4"/>) array.  Semantics
match cwa_checksums in CHUNK_WRITE: each entry's
cs_algorithm <bcp14>MUST</bcp14> match ffv2m_checksum_algorithm of the
mirror named in the layout
(<xref target="sec-ffv2-mirror4"/>), with NFS4ERR_INVAL on mismatch.</t>
            </dd>
            <dt>cwra_chunks:</dt>
            <dd>
              <t>the reconstructed chunk payload as an opaque blob,
packed identically to cwa_chunks in CHUNK_WRITE.</t>
            </dd>
          </dl>
          <t>The CHUNK_WRITE_REPAIR result reports per-chunk outcomes:</t>
          <dl>
            <dt>cwrr_count:</dt>
            <dd>
              <t>the number of chunks the data server successfully
accepted.</t>
            </dd>
            <dt>cwrr_committed:</dt>
            <dd>
              <t>the stable_how4 level the data server actually applied.
<bcp14>MUST</bcp14> be at least as durable as cwra_stable.</t>
            </dd>
            <dt>cwrr_writeverf:</dt>
            <dd>
              <t>a verifier identifying the data server's incarnation.
Semantics match cwr_writeverf in CHUNK_WRITE.</t>
            </dd>
            <dt>cwrr_status:</dt>
            <dd>
              <t>per-chunk acceptance status, one entry per chunk in
the payload, co-indexed.  The top-level
CHUNK_WRITE_REPAIR status is NFS4_OK as long as the
data server could evaluate each chunk; per-chunk
failures are reported in cwrr_status rather than by
failing the whole operation.</t>
            </dd>
          </dl>
          <t>The target chunks <bcp14>SHOULD</bcp14> be in the errored state (set by
a prior CHUNK_ERROR) or EMPTY.  If a target chunk is
COMMITTED with valid data, the data server <bcp14>MAY</bcp14> reject the
repair-write with NFS4ERR_INVAL in the corresponding
cwrr_status slot to prevent overwriting good data; the
repair client <bcp14>SHOULD</bcp14> re-verify the chunk before
attempting another repair-write on the same range.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned (NFS4ERR_ISDIR / NFS4ERR_SYMLINK /
NFS4ERR_WRONG_TYPE).</t>
        </section>
        <section anchor="response-codes-10">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the repair-write succeeded.</t>
            </dd>
            <dt>NFS4ERR_ACCESS:</dt>
            <dd>
              <t>the layout stateid or credentials are not
permitted to write repair data to this file.</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>no active layout stateid for this file (or, in trusted-stateid
tight coupling, the stateid is not in the trust table).  See
<xref target="sec-new-ops"/>.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>the data server is temporarily unable to process
the request.</t>
            </dd>
            <dt>NFS4ERR_FHEXPIRED:</dt>
            <dd>
              <t>the current filehandle has expired.</t>
            </dd>
            <dt>NFS4ERR_IO:</dt>
            <dd>
              <t>an I/O error occurred while persisting the repair
data.</t>
            </dd>
            <dt>NFS4ERR_NOSPC:</dt>
            <dd>
              <t>there is insufficient space at the data server.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement
CHUNK_WRITE_REPAIR.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
            <dt>NFS4ERR_STALE:</dt>
            <dd>
              <t>the current filehandle no longer identifies a
valid file.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-TRUST_STATEID">
        <name>Operation 89: TRUST_STATEID - Register Layout Stateid on Data Server</name>
        <section anchor="arguments-11">
          <name>ARGUMENTS</name>
          <figure anchor="fig-TRUST_STATEID4args">
            <name>XDR for TRUST_STATEID4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct TRUST_STATEID4args {
   ///     /* CURRENT_FH: file */
   ///     stateid4        tsa_layout_stateid;
   ///     layoutiomode4   tsa_iomode;
   ///     nfstime4        tsa_expire;
   ///     utf8str_cs      tsa_principal;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-11">
          <name>RESULTS</name>
          <figure anchor="fig-TRUST_STATEID4res">
            <name>XDR for TRUST_STATEID4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union TRUST_STATEID4res switch (nfsstat4 tsr_status) {
   ///     case NFS4_OK:
   ///         void;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-11">
          <name>DESCRIPTION</name>
          <t>TRUST_STATEID registers a layout stateid with the data
server so that subsequent CHUNK_* operations presenting that
stateid can be validated against the data server's per-file
trust table.  It is the mechanism by which tight coupling
(see <xref target="sec-tight-coupling-control"/>) is established between
the metadata server and the data server for a particular
layout.</t>
          <t>TRUST_STATEID has no analog in <xref target="RFC8881"/>: pNFS layouts in
RFC 8881 do not register the layout stateid with data
servers; data servers in the loose-coupling model trust the
synthetic uid/gid the metadata server inserts on each I/O
(<xref target="sec-Fencing-Clients"/>).  TRUST_STATEID is the new MDS-
to-DS control-plane operation that replaces synthetic-uid
fencing with per-client stateid-table validation for
deployments that opt into tight coupling.</t>
          <t>TRUST_STATEID is an MDS-to-DS operation; pNFS clients <bcp14>MUST
NOT</bcp14> send it.  The data server <bcp14>MUST</bcp14> verify that the
operation arrived on a session whose owning client presented
EXCHGID4_FLAG_USE_PNFS_MDS at EXCHANGE_ID and reject any
TRUST_STATEID received on a regular client session with
NFS4ERR_PERM.  TRUST_STATEID operates on the current
filehandle; a PUTFH naming the data server's file <bcp14>MUST</bcp14>
precede it in the same compound (except in the capability
probe case, where the current filehandle is the root).</t>
          <t>The metadata server provides:</t>
          <dl>
            <dt>tsa_layout_stateid:</dt>
            <dd>
              <t>the stateid the metadata server issued in the
LAYOUTGET that produced this layout.  <bcp14>MUST NOT</bcp14> be a
special stateid (anonymous, invalid, read-bypass, or
current).  The sole exception is the capability probe
described in <xref target="sec-tight-coupling-probe"/>: when the
metadata server sends TRUST_STATEID with
tsa_layout_stateid set to the anonymous stateid
against the root filehandle, the data server <bcp14>MUST</bcp14>
reject the request with NFS4ERR_INVAL -- that
rejection is the positive response to the probe.</t>
            </dd>
            <dt>tsa_iomode:</dt>
            <dd>
              <t>the iomode of the layout (LAYOUTIOMODE4<em>READ or
LAYOUTIOMODE4_RW).  The data server <bcp14>MAY</bcp14> enforce this
against the CHUNK</em>* operation presented later: a
READ-iomode trust entry does not authorize
CHUNK_WRITE.</t>
            </dd>
            <dt>tsa_expire:</dt>
            <dd>
              <t>the absolute wall-clock time at which the trust
entry becomes invalid if not renewed (see
<xref target="sec-tight-coupling-lease"/>).  The data server <bcp14>MUST</bcp14>
reject a TRUST_STATEID whose tsa_expire has
tv_nseconds &gt;= 10^9 with NFS4ERR_INVAL.</t>
            </dd>
            <dt>tsa_principal:</dt>
            <dd>
              <t>the client's authenticated identity as verified by
the metadata server at LAYOUTGET time.  For
RPCSEC_GSS clients this is the GSS display name
(e.g., "alice@REALM").  For AUTH_SYS and TLS
clients, tsa_principal <bcp14>MUST</bcp14> be the empty string,
indicating that no principal binding is enforced on
subsequent CHUNK operations.  See
<xref target="sec-tight-coupling-principal"/>.</t>
            </dd>
          </dl>
          <t>If a trust entry already exists for the same
tsa_layout_stateid on the same current filehandle,
TRUST_STATEID atomically updates tsa_expire and
tsa_principal; this is the renewal path (see
<xref target="sec-tight-coupling-lease"/>).</t>
          <t>At registration time the data server tags the new trust
entry with the identity of the metadata server, derived
from the clientid of the owning client of the control
session on which TRUST_STATEID arrived.  This tag is
consulted by REVOKE_STATEID (<xref target="sec-REVOKE_STATEID"/>) and
BULK_REVOKE_STATEID (<xref target="sec-BULK_REVOKE_STATEID"/>) so that
revocation only affects entries registered by the same
metadata server.  In a multi-metadata-server deployment
sharing a single data server, each metadata server
registers and revokes only its own entries; the tag is
opaque to pNFS clients and is not carried on the wire.</t>
          <t>TRUST_STATEID returns only a top-level status; there is
no result body beyond the nfsstat4 discriminant.</t>
          <t>If the current filehandle is not an ordinary file
(except in the capability-probe case, where the current
filehandle is the root and the operation is expected to
be rejected with NFS4ERR_INVAL), an error <bcp14>MUST</bcp14> be
returned (NFS4ERR_ISDIR / NFS4ERR_SYMLINK /
NFS4ERR_WRONG_TYPE).</t>
        </section>
        <section anchor="response-codes-11">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the trust entry is registered (or updated).</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>tsa_layout_stateid was a special stateid
other than the anonymous stateid on the root filehandle.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>the data server is temporarily unable to process
the request; the metadata server <bcp14>SHOULD</bcp14> retry.</t>
            </dd>
            <dt>NFS4ERR_INVAL:</dt>
            <dd>
              <t>tsa_layout_stateid was the anonymous stateid
and the current filehandle is not the root filehandle;
tsa_expire is malformed; or the current filehandle is a
directory (except in the capability-probe case).</t>
            </dd>
            <dt>NFS4ERR_NOFILEHANDLE:</dt>
            <dd>
              <t>no current filehandle is set.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement
TRUST_STATEID.  This is the capability-probe response (see
<xref target="sec-tight-coupling-probe"/>).</t>
            </dd>
            <dt>NFS4ERR_PERM:</dt>
            <dd>
              <t>the request arrived on a session whose owning
client did not present EXCHGID4_FLAG_USE_PNFS_MDS.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-REVOKE_STATEID">
        <name>Operation 90: REVOKE_STATEID - Revoke Registered Stateid on Data Server</name>
        <section anchor="arguments-12">
          <name>ARGUMENTS</name>
          <figure anchor="fig-REVOKE_STATEID4args">
            <name>XDR for REVOKE_STATEID4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct REVOKE_STATEID4args {
   ///     /* CURRENT_FH: file */
   ///     stateid4        rsa_layout_stateid;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-12">
          <name>RESULTS</name>
          <figure anchor="fig-REVOKE_STATEID4res">
            <name>XDR for REVOKE_STATEID4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union REVOKE_STATEID4res switch (nfsstat4 rsr_status) {
   ///     case NFS4_OK:
   ///         void;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-12">
          <name>DESCRIPTION</name>
          <t>REVOKE_STATEID invalidates a single trust entry on the
data server.  Subsequent CHUNK_* operations that present
the revoked stateid <bcp14>MUST</bcp14> fail with NFS4ERR_BAD_STATEID.
REVOKE_STATEID is the per-file revoke counterpart to
TRUST_STATEID (<xref target="sec-TRUST_STATEID"/>) -- registration and
revocation form the matched pair that drives the per-file
trust table for a tightly coupled deployment.</t>
          <t>REVOKE_STATEID has no analog in <xref target="RFC8881"/>.  RFC 8881
revokes pNFS layouts via LAYOUTRETURN with a special
all-files marker or via implicit lease expiry;
REVOKE_STATEID is the new MDS-to-DS surface that lets the
metadata server force per-client invalidation at the data
server without waiting for tsa_expire and without
unsetting other clients' trust entries.</t>
          <t>REVOKE_STATEID is an MDS-to-DS operation; pNFS clients
<bcp14>MUST NOT</bcp14> send it.  The data server <bcp14>MUST</bcp14> verify that the
operation arrived on a session whose owning client
presented EXCHGID4_FLAG_USE_PNFS_MDS at EXCHANGE_ID and
reject any REVOKE_STATEID received on a regular client
session with NFS4ERR_PERM.  REVOKE_STATEID operates on
the current filehandle; a PUTFH naming the data server's
file <bcp14>MUST</bcp14> precede it in the same compound.</t>
          <t>The metadata server provides:</t>
          <dl>
            <dt>rsa_layout_stateid:</dt>
            <dd>
              <t>the stateid to revoke.  Together with the current
filehandle this identifies the trust entry to remove.
<bcp14>MUST NOT</bcp14> be a special stateid; the anonymous stateid
is rejected with NFS4ERR_INVAL and other special
stateids with NFS4ERR_BAD_STATEID.</t>
            </dd>
          </dl>
          <t>The metadata server calls REVOKE_STATEID in any of the
following situations:</t>
          <ul spacing="normal">
            <li>
              <t>CB_LAYOUTRECALL timeout: the client did not return the
layout within the recall timeout.  REVOKE_STATEID
terminates the client's ability to issue further I/O
to the data server without waiting for tsa_expire.</t>
            </li>
            <li>
              <t>LAYOUTERROR with NFS4ERR_ACCESS or NFS4ERR_PERM: the
data server rejected the client's I/O; the trust
entry is stale and must be removed.  This mirrors the
fencing case in the loose-coupled model
(<xref target="sec-Fencing-Clients"/>).</t>
            </li>
            <li>
              <t>Explicit LAYOUTRETURN: the client returned the layout
cleanly.  The metadata server <bcp14>MAY</bcp14> issue REVOKE_STATEID
at this time or <bcp14>MAY</bcp14> rely on tsa_expire; either is
correct.</t>
            </li>
          </ul>
          <t>In-flight CHUNK_* operations that arrived before
REVOKE_STATEID completes <bcp14>MAY</bcp14> be allowed to finish.  The
data server <bcp14>MUST NOT</bcp14> process new CHUNK_* operations
presenting rsa_layout_stateid after REVOKE_STATEID
returns.</t>
          <t>Lock state (see <xref target="sec-CHUNK_LOCK"/>) held by the revoked
stateid is NOT released as part of REVOKE_STATEID; the
data server <bcp14>MUST</bcp14> transfer each held lock to the
MDS-escrow owner (see <xref target="sec-chunk_guard_mds"/>).
Dropping a chunk lock during revocation would permit a
write hole and is prohibited; the repair coordination
sequence in <xref target="sec-repair-selection"/> assumes that locks
held by a revoked writer remain held until a repair
client adopts them via CHUNK_LOCK with
CHUNK_LOCK_FLAGS_ADOPT.</t>
          <t>REVOKE_STATEID is scoped to the issuing metadata
server's entries (see the tagging rule in
<xref target="sec-TRUST_STATEID"/>).  The data server <bcp14>MUST NOT</bcp14>
remove an entry that was registered by a different
metadata server, even if rsa_layout_stateid happens to
match.  In a multi-metadata-server deployment, one
metadata server therefore cannot revoke another
metadata server's entries.</t>
          <t>REVOKE_STATEID is idempotent: revoking a stateid that
has no matching trust entry (either no entry exists, or
the entry was registered by a different metadata
server) returns NFS4_OK.  The metadata server therefore
does not need to track precisely which entries are
currently live on which data server in order to revoke
safely.</t>
          <t>REVOKE_STATEID returns only a top-level status; there
is no result body beyond the nfsstat4 discriminant.</t>
          <t>If the current filehandle is not an ordinary file, an
error <bcp14>MUST</bcp14> be returned (NFS4ERR_ISDIR / NFS4ERR_SYMLINK /
NFS4ERR_WRONG_TYPE).</t>
        </section>
        <section anchor="response-codes-12">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the trust entry was removed, or no matching entry
existed (idempotent).</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_BAD_STATEID:</dt>
            <dd>
              <t>rsa_layout_stateid was a special stateid.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>the data server is temporarily unable to process
the request.</t>
            </dd>
            <dt>NFS4ERR_INVAL:</dt>
            <dd>
              <t>rsa_layout_stateid was the anonymous stateid.</t>
            </dd>
            <dt>NFS4ERR_NOFILEHANDLE:</dt>
            <dd>
              <t>no current filehandle is set.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement
REVOKE_STATEID.</t>
            </dd>
            <dt>NFS4ERR_PERM:</dt>
            <dd>
              <t>the request arrived on a session whose owning
client did not present EXCHGID4_FLAG_USE_PNFS_MDS.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
          </dl>
        </section>
      </section>
      <section anchor="sec-BULK_REVOKE_STATEID">
        <name>Operation 91: BULK_REVOKE_STATEID - Revoke All Stateids for a Client</name>
        <section anchor="arguments-13">
          <name>ARGUMENTS</name>
          <figure anchor="fig-BULK_REVOKE_STATEID4args">
            <name>XDR for BULK_REVOKE_STATEID4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct BULK_REVOKE_STATEID4args {
   ///     clientid4       brsa_clientid;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-13">
          <name>RESULTS</name>
          <figure anchor="fig-BULK_REVOKE_STATEID4res">
            <name>XDR for BULK_REVOKE_STATEID4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// union BULK_REVOKE_STATEID4res switch (nfsstat4 brsr_status) {
   ///     case NFS4_OK:
   ///         void;
   ///     default:
   ///         void;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-13">
          <name>DESCRIPTION</name>
          <t>BULK_REVOKE_STATEID removes every trust entry on the data
server that was registered on behalf of a single named
client.  Unlike REVOKE_STATEID (<xref target="sec-REVOKE_STATEID"/>),
which removes one entry identified by a (filehandle,
stateid) pair, BULK_REVOKE_STATEID does not target a
specific filehandle or stateid; it instructs the data
server to scan its trust table and remove every entry
whose owning pNFS client matches brsa_clientid (and whose
issuing metadata server matches the calling MDS).</t>
          <t>BULK_REVOKE_STATEID has no analog in <xref target="RFC8881"/>.  RFC 8881
recall-all is expressed at the layout layer
(CB_LAYOUTRECALL with LAYOUTRECALL4_ALL); the per-client
trust-table sweep introduced here is the data-server-side
complement, replacing the N per-file REVOKE_STATEID
compounds that per-entry revocation would require with a
single round-trip.</t>
          <t>BULK_REVOKE_STATEID is an MDS-to-DS operation; pNFS
clients <bcp14>MUST NOT</bcp14> send it.  The data server <bcp14>MUST</bcp14> verify
that the operation arrived on a session whose owning
client presented EXCHGID4_FLAG_USE_PNFS_MDS at EXCHANGE_ID
and reject any BULK_REVOKE_STATEID received on a regular
client session with NFS4ERR_PERM.  BULK_REVOKE_STATEID
does not operate on the current filehandle; no PUTFH is
required in the compound.</t>
          <t>The metadata server provides:</t>
          <dl>
            <dt>brsa_clientid:</dt>
            <dd>
              <t>the clientid of the pNFS client whose trust entries
are to be removed.  The special all-zeros value means
"remove every trust entry owned by the calling
metadata server, regardless of which pNFS client
registered it"; the data server <bcp14>MUST</bcp14> interpret this
value as a sweep of its own entries only, NOT as the
pNFS client whose clientid happens to be zero and NOT
as a global cross-MDS table clear.</t>
            </dd>
          </dl>
          <t>The metadata server calls BULK_REVOKE_STATEID in any of
the following situations:</t>
          <ul spacing="normal">
            <li>
              <t>Client lease expiry: when a client's lease on the
metadata server expires, the metadata server revokes
all of that client's layouts.  A single
BULK_REVOKE_STATEID with brsa_clientid set to the
expired client's clientid sweeps every per-file trust
entry the metadata server had registered for that
client.</t>
            </li>
            <li>
              <t>CB_LAYOUTRECALL with LAYOUTRECALL4_ALL: the metadata
server is recalling all layouts for a client.
BULK_REVOKE_STATEID is the data-server-side
complement.</t>
            </li>
            <li>
              <t>Metadata server restart cleanup: after the metadata
server reconnects to a data server, it <bcp14>MAY</bcp14> issue
BULK_REVOKE_STATEID with brsa_clientid set to
all-zeros to clear the prior trust table before
re-issuing TRUST_STATEID as clients reclaim.  See
<xref target="sec-tight-coupling-mds-crash"/>.</t>
            </li>
          </ul>
          <t>BULK_REVOKE_STATEID is scoped to the issuing metadata
server's entries (see the tagging rule in
<xref target="sec-TRUST_STATEID"/>).  The data server <bcp14>MUST NOT</bcp14> affect
entries registered by a different metadata server.
Consequently, in a multi-metadata-server deployment
sharing a single data server, one metadata server cannot
clear another metadata server's entries via
BULK_REVOKE_STATEID.</t>
          <t>Like REVOKE_STATEID, BULK_REVOKE_STATEID is idempotent
(no error is returned if there are no matching entries)
and preserves chunk locks held under any revoked stateid
by transferring them to the MDS-escrow owner (see
<xref target="sec-chunk_guard_mds"/>), rather than dropping them.
Subsequent CHUNK_* operations from the revoked client
fail with NFS4ERR_BAD_STATEID; locks held under those
revoked stateids remain until adopted by a repair
client via CHUNK_LOCK with CHUNK_LOCK_FLAGS_ADOPT
(<xref target="sec-CHUNK_LOCK"/>).</t>
          <t>BULK_REVOKE_STATEID returns only a top-level status;
there is no result body beyond the nfsstat4 discriminant.</t>
        </section>
        <section anchor="response-codes-13">
          <name>RESPONSE CODES</name>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>the matching entries were removed, or there were
none (idempotent).</t>
            </dd>
            <dt>NFS4ERR_BADXDR:</dt>
            <dd>
              <t>arguments could not be decoded.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>the data server is temporarily unable to process
the request.</t>
            </dd>
            <dt>NFS4ERR_NOTSUPP:</dt>
            <dd>
              <t>the data server does not implement
BULK_REVOKE_STATEID.</t>
            </dd>
            <dt>NFS4ERR_PERM:</dt>
            <dd>
              <t>the request arrived on a session whose owning
client did not present EXCHGID4_FLAG_USE_PNFS_MDS.</t>
            </dd>
            <dt>NFS4ERR_SERVERFAULT:</dt>
            <dd>
              <t>the data server failed while processing
the request.</t>
            </dd>
          </dl>
        </section>
      </section>
    </section>
    <section anchor="new-nfsv42-callback-operations">
      <name>New NFSv4.2 Callback Operations</name>
      <figure anchor="fig-cb-ops-xdr">
        <name>Callback Operations XDR</name>
        <sourcecode type="xdr"><![CDATA[
   ///
   /// /* New callback operations for Erasure Coding start here */
   ///
   ///  OP_CB_CHUNK_REPAIR     = 16,
   ///
]]></sourcecode>
      </figure>
      <t>The following amendment blocks extend the nfs_cb_argop4 and
nfs_cb_resop4 dispatch unions defined in <xref target="RFC7863"/> with arms
for the new callback operation defined in this document.</t>
      <figure anchor="fig-nfs_cb_argop4-amend">
        <name>nfs_cb_argop4 amendment block</name>
        <sourcecode type="xdr"><![CDATA[
   /// /* nfs_cb_argop4 amendment block */
   ///
   /// case OP_CB_CHUNK_REPAIR: CB_CHUNK_REPAIR4args opcbchunkrepair;
]]></sourcecode>
      </figure>
      <figure anchor="fig-nfs_cb_resop4-amend">
        <name>nfs_cb_resop4 amendment block</name>
        <sourcecode type="xdr"><![CDATA[
   /// /* nfs_cb_resop4 amendment block */
   ///
   /// case OP_CB_CHUNK_REPAIR: CB_CHUNK_REPAIR4res opcbchunkrepair;
]]></sourcecode>
      </figure>
      <section anchor="sec-CB_CHUNK_REPAIR">
        <name>Callback Operation 16: CB_CHUNK_REPAIR - Request Repair of Inconsistent Chunk Ranges</name>
        <section anchor="arguments-14">
          <name>ARGUMENTS</name>
          <figure anchor="fig-CB_CHUNK_REPAIR4args">
            <name>XDR for CB_CHUNK_REPAIR4args</name>
            <sourcecode type="xdr"><![CDATA[
   /// enum cb_chunk_repair_reason4 {
   ///     CB_REPAIR_REASON_RACE  = 1,
   ///     CB_REPAIR_REASON_SCRUB = 2
   /// };
   ///
   /// struct cb_chunk_range4 {
   ///     offset4         ccr_offset;
   ///     count4          ccr_count;
   ///     nfsstat4        ccr_error;
   /// };
   ///
   /// struct CB_CHUNK_REPAIR4args {
   ///     nfs_fh4                     ccra_fh;
   ///     stateid4                    ccra_layout_stateid;
   ///     nfstime4                    ccra_deadline;
   ///     cb_chunk_repair_reason4     ccra_reason;
   ///     cb_chunk_range4             ccra_ranges<>;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="results-14">
          <name>RESULTS</name>
          <figure anchor="fig-CB_CHUNK_REPAIR4res">
            <name>XDR for CB_CHUNK_REPAIR4res</name>
            <sourcecode type="xdr"><![CDATA[
   /// struct CB_CHUNK_REPAIR4res {
   ///     nfsstat4           ccrr_status;
   /// };
]]></sourcecode>
          </figure>
        </section>
        <section anchor="description-14">
          <name>DESCRIPTION</name>
          <t>CB_CHUNK_REPAIR is sent by the metadata server to a
selected pNFS client to request that the client repair one
or more non-atomic chunk ranges on the file's data
servers.  CB_CHUNK_REPAIR is the back-channel companion to
the chunk repair flow: the metadata server selects a
repair client per <xref target="sec-repair-selection"/> (those rules
are normative for how the client <bcp14>MUST</bcp14> respond on receipt
of this callback) and uses CB_CHUNK_REPAIR to deliver the
work item.</t>
          <t>CB_CHUNK_REPAIR has no analog in <xref target="RFC8881"/>.  RFC 8881
back-channel callbacks operate at the layout layer
(CB_LAYOUTRECALL) or the file-state layer (CB_RECALL,
CB_NOTIFY); CB_CHUNK_REPAIR is the new chunk-layer
callback that drives reconstruction or rollback of
non-atomic chunks without requiring a full layout return.</t>
          <t>The metadata server provides:</t>
          <dl>
            <dt>ccra_fh:</dt>
            <dd>
              <t>the filehandle of the file whose chunks are non-atomic.
The callback compound carries the filehandle directly;
there is no preceding PUTFH in callback compounds.</t>
            </dd>
            <dt>ccra_layout_stateid:</dt>
            <dd>
              <t>the recipient client's current layout stateid for the
file if one is held.  A client that does not hold a
layout on ccra_fh <bcp14>MUST</bcp14> ignore ccra_layout_stateid (it
will be the anonymous stateid in that case) and <bcp14>MUST</bcp14>
acquire one via LAYOUTGET before issuing any CHUNK_*
operation on the ranges.</t>
            </dd>
            <dt>ccra_deadline:</dt>
            <dd>
              <t>a wall-clock nfstime4 (seconds and nanoseconds since
the epoch, as defined in Section 3.3.1 of <xref target="RFC8881"/>)
by which the client is expected to have driven every
range to completion (CHUNK_REPAIRED on the
reconstruction path, or CHUNK_UNLOCK on the rollback
path).  Missing the deadline does not corrupt state --
the metadata server <bcp14>MAY</bcp14> re-select another repair
client after the deadline elapses -- but a client that
has missed the deadline <bcp14>MUST</bcp14> re-verify its layout and
the chunk lock state before continuing any
repair-related CHUNK_* operation.</t>
            </dd>
            <dt>ccra_reason:</dt>
            <dd>
              <t>distinguishes the two flows that cause the metadata
server to issue a repair callback:
</t>
              <dl>
                <dt>CB_REPAIR_REASON_RACE:</dt>
                <dd>
                  <t>A live-race repair.  A client (not necessarily the
recipient of this callback) detected a chunk-level
non-atomicity at write or read time and reported it
via LAYOUTERROR.  The metadata server is driving
repair synchronously because the affected chunk is
on the critical path of some I/O.  The recipient
<bcp14>SHOULD</bcp14> prioritise the callback over background
work.</t>
                </dd>
                <dt>CB_REPAIR_REASON_SCRUB:</dt>
                <dd>
                  <t>A background scrub.  The metadata server has
detected stale or non-atomic payloads during a
scheduled integrity sweep and is opportunistically
driving repair.  No client is currently blocked on
these ranges.  The recipient <bcp14>MAY</bcp14> schedule the
callback at lower priority than
CB_REPAIR_REASON_RACE, and <bcp14>MAY</bcp14> return NFS4ERR_DELAY
to defer repair to a more convenient time; the
metadata server will retry.</t>
                </dd>
              </dl>
              <t>The two reasons share all other semantics: the same
ccra_ranges encoding, the same response codes, the same
deadline contract.  Only the priority and retry
behaviour differs.</t>
            </dd>
            <dt>ccra_ranges:</dt>
            <dd>
              <t>the list of every chunk range the metadata server
requests the client to repair.  Each entry carries its
own ccr_error describing the failure mode the client
is being asked to remedy.  The repair strategy depends
on the error code; see <xref target="sec-repair-selection"/> for
the normative and guidance split.</t>
            </dd>
          </dl>
          <t>The metadata server <bcp14>SHOULD</bcp14> keep each CB_CHUNK_REPAIR
compound within the back-channel maximum
(ca_maxrequestsize) negotiated in CREATE_SESSION (see
Section 18.36.3 of <xref target="RFC8881"/>).  If the set of affected
ranges would exceed that maximum, the metadata server <bcp14>MAY</bcp14>
issue multiple CB_CHUNK_REPAIR callbacks to the same
client.  Each callback is independent; the client drives
each to completion before the deadline on that callback's
ranges.</t>
          <t>The fact that a range appears in ccra_ranges implies the
data server holds a chunk lock on the range (the failure
occurred in or around a PENDING or FINALIZED state that
established the lock).  The repair client <bcp14>MUST</bcp14> use
CHUNK_LOCK with CHUNK_LOCK_FLAGS_ADOPT
(<xref target="sec-CHUNK_LOCK"/>) to take ownership of the lock before
issuing CHUNK_WRITE_REPAIR, CHUNK_ROLLBACK, or CHUNK_WRITE
on any chunk in a requested range.</t>
          <t>CB_CHUNK_REPAIR returns only a top-level status in
ccrr_status; see "RESPONSE CODES" below for the normative
meanings the metadata server attaches to each returned
nfsstat4.</t>
        </section>
        <section anchor="response-codes-14">
          <name>RESPONSE CODES</name>
          <t>The ccrr_status value returned by the client has the following
normative meanings to the metadata server:</t>
          <dl>
            <dt>NFS4_OK:</dt>
            <dd>
              <t>The client has accepted the request and driven every range in
this callback to completion (CHUNK_REPAIRED or CHUNK_UNLOCK on
every affected chunk).  The metadata server clears the repair
queue entry.</t>
            </dd>
            <dt>NFS4ERR_DELAY:</dt>
            <dd>
              <t>The client has accepted the request but requires more time.
The metadata server <bcp14>MAY</bcp14> extend the deadline by issuing a new
CB_CHUNK_REPAIR with a later ccra_deadline, or <bcp14>MAY</bcp14> re-select
another client.  The client continues to hold any locks it has
adopted until the original or extended deadline.</t>
            </dd>
            <dt>NFS4ERR_CODING_NOT_SUPPORTED:</dt>
            <dd>
              <t>The client does not implement the encoding type of the layout
and cannot reconstruct.  The metadata server <bcp14>MUST NOT</bcp14> retry with
the same client and <bcp14>SHOULD</bcp14> select a different client.</t>
            </dd>
            <dt>NFS4ERR_PAYLOAD_LOST:</dt>
            <dd>
              <t>The client has concluded that the identified ranges cannot
be repaired -- there are not enough surviving shards to
reconstruct and rollback is also impossible.  The metadata
server <bcp14>MUST NOT</bcp14> retry the repair and transitions the affected
ranges into an implementation-defined damaged state.  See
<xref target="sec-NFS4ERR_PAYLOAD_LOST"/>.</t>
            </dd>
          </dl>
          <t>All other error codes listed in <xref target="tbl-cb-ops-and-errors"/> are
treated by the metadata server as retriable: the metadata server
<bcp14>MAY</bcp14> issue a subsequent CB_CHUNK_REPAIR to the same or a
different client.  If the client becomes unreachable (no
response within the deadline), the metadata server re-selects
per <xref target="sec-repair-selection"/>.</t>
        </section>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>The combination of components in a pNFS system is required to
preserve the security properties of NFSv4.1+ with respect to an
entity accessing data via a client.  The pNFS feature partitions
the NFSv4.1+ file system protocol into two parts: the control
protocol and the data protocol.  As the control protocol in this
document is NFS, the security properties are equivalent to the
version of NFS being used.  The flexible file v2 layout further divides
the data protocol into metadata and data paths.  The security
properties of the metadata path are equivalent to those of NFSv4.1x
(see Sections 1.7.1 and 2.2.1 of <xref target="RFC8881"/>).  And the security
properties of the data path are equivalent to those of the version
of NFS used to access the storage device, with the provision that
the metadata server is responsible for authenticating client access
to the data file.  The metadata server provides appropriate credentials
to the client to access data files on the storage device.  It is
also responsible for revoking access for a client to the storage
device.</t>
      <t>The metadata server enforces the file access control policy at
LAYOUTGET time.  The client <bcp14>MUST</bcp14> use RPC authorization credentials
for getting the layout for the requested iomode (LAYOUTIOMODE4_READ
or LAYOUTIOMODE4_RW), and the server verifies the permissions and
ACL for these credentials, possibly returning NFS4ERR_ACCESS if the
client is not allowed the requested iomode.  If the LAYOUTGET
operation succeeds, the client receives, as part of the layout, a
set of credentials allowing it I/O access to the specified data
files corresponding to the requested iomode.  When the client acts
on I/O operations on behalf of its local users, it <bcp14>MUST</bcp14> authenticate
and authorize the user by issuing respective OPEN and ACCESS calls
to the metadata server, similar to having NFSv4 data delegations.</t>
      <t>The combination of filehandle, synthetic uid, and gid in the layout
is the way that the metadata server enforces access control to the
data server.  The client only has access to filehandles of file
objects and not directory objects.  Thus, given a filehandle in a
layout, it is not possible to guess the parent directory filehandle.
Further, as the data file permissions only allow the given synthetic
uid read/write permission and the given synthetic gid read permission,
knowing the synthetic ids of one file does not necessarily allow
access to any other data file on the storage device.</t>
      <t>The metadata server can also deny access at any time by fencing the
data file, which means changing the synthetic ids.  In turn, that
forces the client to return its current layout and get a new layout
if it wants to continue I/O to the data file.</t>
      <t>If access is allowed, the client uses the corresponding (read-only
or read/write) credentials to perform the I/O operations at the
data file's storage devices.  When the metadata server receives a
request to change a file's permissions or ACL, it <bcp14>SHOULD</bcp14> recall all
layouts for that file and then <bcp14>MUST</bcp14> fence off any clients still
holding outstanding layouts for the respective files by implicitly
invalidating the previously distributed credential on all data file
comprising the file in question.  It is <bcp14>REQUIRED</bcp14> that this be done
before committing to the new permissions and/or ACL.  By requesting
new layouts, the clients will reauthorize access against the modified
access control metadata.  Recalling the layouts in this case is
intended to prevent clients from getting an error on I/Os done after
the client was fenced off.</t>
      <section anchor="sec-security-checksum-scope">
        <name>Checksum Integrity Scope</name>
        <t>The checksum values carried in CHUNK_WRITE and returned from
CHUNK_READ defend against accidental data corruption during
storage or transmission -- bit flips on storage media, network
errors, software bugs in the erasure transform.  The threat
model an individual deployment achieves depends on which
checksum_algorithm4 (<xref target="sec-checksum4"/>) the metadata server
selects for the file's mirrors via ffv2m_checksum_algorithm
(<xref target="sec-ffv2-mirror4"/>):</t>
        <dl>
          <dt>Bit-flip-class algorithms (CRC32, CRC32C, Fletcher4):</dt>
          <dd>
            <t>Detect accidental bit-level corruption with high
probability.  Do NOT defend against an adversary who can
modify the payload and recompute a valid checksum, because
these algorithms are not cryptographic and the algorithm
identifier and parameters are public.  Suitable when the
threat model excludes adversaries on the wire and at rest.</t>
          </dd>
          <dt>Cryptographic algorithms (SHA-256, SHA-512, BLAKE3):</dt>
          <dd>
            <t>Detect accidental corruption AND defend against adversarial
modification, provided that (a) the algorithm choice itself
is communicated over a trusted channel (typically the
layout from the MDS) and (b) the integrity-protected
recomputation happens at trust boundaries the deployment
controls.  Suitable when chunks may be at rest on storage
the deployment does not fully control, or when transit may
cross hostile network segments.</t>
          </dd>
          <dt>CHECKSUM_ALG_NONE:</dt>
          <dd>
            <t>No protocol-level integrity check.  The deployment is
relying on transport-layer integrity (RPC-over-TLS
<xref target="RFC9289"/>, RPCSEC_GSS_KRB5I) or storage-layer integrity
(filesystem checksums on the data server, RAID-level
integrity) instead.  Suitable when those other layers are
reliably present end-to-end and the per-chunk wire
protection would be redundant.</t>
          </dd>
        </dl>
        <t>Deployments requiring protection against active attackers
<bcp14>SHOULD</bcp14> select one of the cryptographic algorithms, OR use
CHECKSUM_ALG_NONE in conjunction with RPC-over-TLS
(<xref target="sec-tls"/>) or RPCSEC_GSS, whichever fits the deployment's
existing security architecture.</t>
        <t>An authenticated client is in the "active attacker" role with
respect to its own chunks, in a restricted sense.  The data
server validates the checksum against the bytes the client
provided, so an authenticated client that chooses to send
semantically-invalid bytes with a correctly computed checksum will
have those bytes accepted.  The residual surface differs per
authentication model:</t>
        <ul spacing="normal">
          <li>
            <t>Under AUTH_SYS with loose coupling, the residual surface is
essentially the pre-existing attack surface of NFSv3 writes:
any host that can reach the data server with a valid uid can
write nonsense to chunks that uid owns.  This is the Flex
Files v1 authorization model, which flexible file v2 layout inherits
without modification for this path.</t>
          </li>
          <li>
            <t>Under RPCSEC_GSS or TLS with mutual authentication, the
residual surface reduces to: only the authenticated client
can write nonsense into chunks it owns.  Cross-client
corruption is prevented because the data server verifies the
principal before accepting the write.  The remaining attack
surface is the client's own integrity: any deployment that
relies on data integrity above the wire <bcp14>MUST</bcp14> apply
application-level content validation.</t>
          </li>
        </ul>
        <t>Flexible file v2 layout does not attempt to defend against this
authenticated-but-malicious case.  The checksum mechanism is a
transport-integrity check, not a content-integrity check; the
system trust model assumes that an authenticated principal is
entitled to destroy the content of chunks it owns.</t>
      </section>
      <section anchor="chunk-lock-and-lease-expiry">
        <name>Chunk Lock and Lease Expiry</name>
        <t>When a client holds a chunk lock (acquired via CHUNK_LOCK) and its
lease expires or the client crashes, the lock is released implicitly
by the data server.  This opens a window in which another client
may write to the previously locked range before the original client's
repair is complete.  Implementations <bcp14>SHOULD</bcp14> ensure that the lease
period for chunk locks is sufficient to complete repair operations,
and <bcp14>SHOULD</bcp14> implement CHUNK_UNLOCK explicitly on abort paths.  The
metadata server's LAYOUTERROR and LAYOUTRETURN mechanisms provide
the coordination point for detecting and resolving such races.</t>
      </section>
      <section anchor="error-code-information-disclosure">
        <name>Error Code Information Disclosure</name>
        <t>The new error codes NFS4ERR_CHUNK_LOCKED (10099) and
NFS4ERR_PAYLOAD_NOT_ATOMIC (10098) convey information about
chunk state to the caller.  Both of these errors <bcp14>MAY</bcp14> be returned
to callers whose credentials have not been verified by the data
server (e.g., when the AUTH_SYS uid presented does not match the
synthetic uid on the data file).  The information they reveal --
that a chunk is locked, or that a CRC mismatch occurred -- does
not directly disclose file contents but may indicate concurrent
write activity.  Implementations that are concerned about this
level of disclosure <bcp14>SHOULD</bcp14> require that CHUNK operations
only succeed after credential verification and return
NFS4ERR_ACCESS for unverified callers rather than the more
specific error codes.</t>
      </section>
      <section anchor="sec-tls">
        <name>Transport Layer Security</name>
        <t>RPC-over-TLS <xref target="RFC9289"/> <bcp14>MAY</bcp14> be used to protect traffic between the
client and the metadata server and between the client and data servers.
When RPC-over-TLS is in use on the data server path, the synthetic
uid/gid credentials carried in AUTH_SYS remain the access control
mechanism; TLS provides confidentiality and integrity for the transport
but does not replace the fencing model described in <xref target="sec-Fencing-Clients"/>.
Servers that require transport security <bcp14>SHOULD</bcp14> advertise this via the
SECINFO mechanism rather than silently dropping connections.</t>
      </section>
      <section anchor="rpcsecgss-and-security-services">
        <name>RPCSEC_GSS and Security Services</name>
        <t>This document does not specify how RPCSEC_GSS <xref target="RFC7861"/> is
used between the client and a storage device in the loosely
coupled model, and the reasons differ between the two coupling
models.  Because the loosely coupled model uses synthetic
credentials that are managed by the metadata server rather than
shared with the storage device, a full RPCSEC_GSS integration
would require protocol work (RPCSEC_GSSv3 structured privilege
assertions, per <xref target="RFC7861"/>) on all three of the metadata
server, the storage device, and the client.  In the tightly
coupled model the principal used to access the data file is the
same as the one used to access the metadata file, so
RPCSEC_GSS applies unchanged.  The two subsections below treat
each model in turn.</t>
        <section anchor="loosely-coupled">
          <name>Loosely Coupled</name>
          <t>RPCSEC_GSS version 3 (RPCSEC_GSSv3) <xref target="RFC7861"/> contains facilities
that would allow it to be used to authorize the client to the storage
device on behalf of the metadata server.  Doing so would require
that each of the metadata server, storage device, and client would
need to implement RPCSEC_GSSv3 using an RPC-application-defined
structured privilege assertion in a manner described in Section
4.9.1 of <xref target="RFC7862"/>.  The specifics necessary to do so are not
described in this document.  This is principally because any such
specification would require extensive implementation work on a wide
range of storage devices, which would be unlikely to result in a
widely usable specification for a considerable time.</t>
          <t>As a result, the layout type described in this document will not
provide support for use of RPCSEC_GSS together with the loosely
coupled model.  However, future layout types could be specified,
which would allow such support, either through the use of RPCSEC_GSSv3
or in other ways.</t>
        </section>
        <section anchor="tightly-coupled">
          <name>Tightly Coupled</name>
          <t>With tight coupling, the principal used to access the metadata file
is exactly the same as used to access the data file.  The storage
device can use the control protocol to validate any RPC credentials.
As a result, there are no security issues related to using RPCSEC_GSS
with a tightly coupled system.  For example, if Kerberos V5 Generic
Security Service Application Program Interface (GSS-API) <xref target="RFC4121"/>
is used as the security mechanism, then the storage device could
use a control protocol to validate the RPC credentials to the
metadata server.</t>
        </section>
      </section>
      <section anchor="sec-security-trust-stateid">
        <name>Trusted Stateids</name>
        <t>The TRUST_STATEID, REVOKE_STATEID, and BULK_REVOKE_STATEID
operations (<xref target="sec-TRUST_STATEID"/>, <xref target="sec-REVOKE_STATEID"/>,
<xref target="sec-BULK_REVOKE_STATEID"/>) introduce a per-stateid
authorization channel between the metadata server and the
data server.  The security implications of that channel are
distinct from those of the loosely coupled synthetic-uid
model (<xref target="sec-Fencing-Clients"/>) and warrant their own
treatment.</t>
        <section anchor="interaction-with-kerberos-and-rpcsecgss">
          <name>Interaction with Kerberos and RPCSEC_GSS</name>
          <t>Trusted stateids decouple the credential the data server
uses to authorize I/O from the credential the client uses
to authenticate to the data server.  Under loose coupling
(<xref target="sec-Fencing-Clients"/>), the metadata server inserts a
synthetic uid/gid into the layout and the client presents
that synthetic credential on every data-server RPC; the
data server has no independent verification of the
client's identity, and a client that learns another
client's synthetic uid/gid can impersonate it on the data
path.  Tight coupling via TRUST_STATEID changes this in
three ways:</t>
          <ul spacing="normal">
            <li>
              <t>The metadata server records the client's authenticated
principal in the trust entry via tsa_principal at
TRUST_STATEID time (<xref target="sec-TRUST_STATEID"/>).  Under
RPCSEC_GSS (typically Kerberos V5 GSS-API per
<xref target="RFC4121"/>), tsa_principal is the GSS display name
(for example, "alice@REALM"); under AUTH_SYS and TLS,
tsa_principal is the empty string.</t>
            </li>
            <li>
              <t>The client presents its own RPCSEC_GSS context on each
CHUNK_* operation against the data server.  Under
tight coupling with GSS, the data server <bcp14>MUST</bcp14> verify
that the principal carried in the inbound RPC's
RPCSEC_GSS context matches the tsa_principal recorded
for the stateid in its trust table; a mismatch returns
NFS4ERR_ACCESS.  A client that learned another
client's layout stateid (from a log file, a packet
capture of cleartext RPC, or any other leak) cannot
use it because their own GSS principal would not
match.</t>
            </li>
            <li>
              <t>The data server does NOT need its own Kerberos keytab
to validate each client principal individually.  In a
loose-coupling Kerberos deployment the data server
would have to be a service principal in every realm
it serves clients from; under tight coupling the data
server's keytab is only required for its session with
the metadata server (the control session,
<xref target="sec-tight-coupling-control"/>).  Operational
complexity of Kerberos deployment is meaningfully
reduced.</t>
            </li>
          </ul>
          <t>The mechanism does not authenticate the metadata server
to the client; it authenticates the client to the data
server using credentials the metadata server vouched for
at LAYOUTGET time.  Compromise of the metadata server
allows an attacker to register arbitrary trust entries;
the metadata server is the trust anchor for the layout
grant, unchanged from the existing pNFS layout-issuance
model.</t>
        </section>
        <section anchor="attack-surfaces-and-mitigations">
          <name>Attack Surfaces and Mitigations</name>
          <dl>
            <dt>Compromised metadata server:</dt>
            <dd>
              <t>An attacker controlling the metadata server can issue
TRUST_STATEID for any (layout stateid, principal)
pair.  This is the same trust assumption pNFS already
makes -- the metadata server grants layouts and the
data servers honour them.  Deployment defence is the
same: restrict administrative access to the metadata
server, require RPCSEC_GSS or RPC-over-TLS
(<xref target="RFC9289"/>) with mutual authentication on the
control session (<xref target="sec-tight-coupling-control"/>), and
monitor for anomalous TRUST_STATEID volume.</t>
            </dd>
            <dt>Compromised data server:</dt>
            <dd>
              <t>A compromised data server sees plaintext chunk
payloads at rest and on the wire (subject to whatever
the deployment uses for at-rest encryption and
transport security).  It can return arbitrary content
on CHUNK_READ with a correctly computed checksum; the
checksum protects against transport corruption, not
adversarial content (<xref target="sec-security-checksum-scope"/>).
This is the same as the RAID-stripe trust model:
each shard host can lie about its shard.  Deployment
defences are encryption at rest, an integrity-
protected transport (RPCSEC_GSS_KRB5I or TLS), and
physical or logical isolation of data servers.</t>
            </dd>
            <dt>Stateid leak from client to attacker:</dt>
            <dd>
              <t>Under tight coupling with RPCSEC_GSS, a leaked
stateid is not exploitable: the attacker's own RPC
principal will not match tsa_principal in the trust
table, and the data server returns NFS4ERR_ACCESS.
Under tight coupling with AUTH_SYS over TLS (where
tsa_principal is empty), a leaked stateid is
exploitable by any attacker who can also forge the
source-address binding the data server's TLS session
expects; this is the standard AUTH_SYS-over-TLS
trust model, unchanged.</t>
            </dd>
            <dt>Replay of revoked stateid:</dt>
            <dd>
              <t>After REVOKE_STATEID or BULK_REVOKE_STATEID the data
server removes the trust entry and subsequent CHUNK_*
operations presenting the revoked stateid fail with
NFS4ERR_BAD_STATEID (<xref target="sec-REVOKE_STATEID"/>).  An
in-flight CHUNK_* operation that arrived before the
revoke completed <bcp14>MAY</bcp14> be allowed to finish; the
chunk_guard4 CAS (<xref target="sec-chunk_guard4"/>) bounds the
worst-case damage from such in-flight I/O to the
chunks already PENDING at revocation time, and the
lock-transfer-to-MDS-escrow rule
(<xref target="sec-chunk_guard_mds"/>) prevents a write hole from
opening during revocation.</t>
            </dd>
            <dt>Compromised control session:</dt>
            <dd>
              <t>An attacker who controls the metadata-server-to-data-
server control session can register or revoke
arbitrary trust entries.  The control session is the
most security-sensitive surface introduced by tight
coupling.  Deployment <bcp14>MUST</bcp14> protect it with RPCSEC_GSS
(<xref target="RFC7861"/>) using a service principal both sides
trust, or with RPC-over-TLS (<xref target="RFC9289"/>) using
mutual authentication and allowlisted certificates.
The data server enforces that TRUST_STATEID,
REVOKE_STATEID, and BULK_REVOKE_STATEID only arrive
on sessions whose owning client presented
EXCHGID4_FLAG_USE_PNFS_MDS at EXCHANGE_ID
(<xref target="sec-TRUST_STATEID"/>), but that flag alone does not
authenticate the metadata server.</t>
            </dd>
            <dt>Resource exhaustion via trust-table flood:</dt>
            <dd>
              <t>A misbehaving metadata server could register an
unbounded number of TRUST_STATEID entries to exhaust
the data server's trust-table memory.  The mechanism
defending against this is the tsa_expire lease on
each entry: trust entries that are not renewed
before expiry are reaped by the data server.  A data
server under memory pressure <bcp14>MAY</bcp14> also return
NFS4ERR_DELAY on new TRUST_STATEID requests, forcing
the metadata server to back off.</t>
            </dd>
            <dt>Cross-metadata-server isolation:</dt>
            <dd>
              <t>In a deployment where two metadata servers share a
single data server, the per-entry metadata-server
tag (derived from the control session's owning
client; see <xref target="sec-TRUST_STATEID"/>) ensures that
REVOKE_STATEID and BULK_REVOKE_STATEID from one
metadata server cannot remove entries registered by
the other.  A compromised metadata server can,
however, register entries against any filehandle the
data server exposes to it.  Deployments concerned
about cross-metadata-server isolation <bcp14>MUST</bcp14> partition
the data server's filesystem namespace into
per-metadata-server exports at the data server,
rather than rely on the trust table alone to enforce
file-level boundaries between metadata servers.</t>
            </dd>
          </dl>
        </section>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t><xref target="RFC8881"/> introduced the "pNFS Layout Types Registry"; new layout
type numbers in this registry need to be assigned by IANA.  This
document defines a new layout type number: LAYOUT4_FLEX_FILES_V2
(see <xref target="tbl_layout_types"/>).</t>
      <table anchor="tbl_layout_types">
        <name>Layout Type Assignments</name>
        <thead>
          <tr>
            <th align="left">Layout Type Name</th>
            <th align="left">Value</th>
            <th align="left">RFC</th>
            <th align="left">How</th>
            <th align="left">Minor Versions</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">LAYOUT4_FLEX_FILES_V2</td>
            <td align="left">0x6</td>
            <td align="left">RFCTBD10</td>
            <td align="left">L</td>
            <td align="left">1</td>
          </tr>
        </tbody>
      </table>
      <t><xref target="RFC8881"/> also introduced the "NFSv4 Recallable Object Types
Registry".  This document defines new recallable objects for
RCA4_TYPE_MASK_FF2_LAYOUT_MIN and RCA4_TYPE_MASK_FF2_LAYOUT_MAX
(see <xref target="tbl_recallables"/>).</t>
      <table anchor="tbl_recallables">
        <name>Recallable Object Type Assignments</name>
        <thead>
          <tr>
            <th align="left">Recallable Object Type Name</th>
            <th align="left">Value</th>
            <th align="left">RFC</th>
            <th align="left">How</th>
            <th align="left">Minor Versions</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">RCA4_TYPE_MASK_FF2_LAYOUT_MIN</td>
            <td align="left">20</td>
            <td align="left">RFCTBD10</td>
            <td align="left">L</td>
            <td align="left">1</td>
          </tr>
          <tr>
            <td align="left">RCA4_TYPE_MASK_FF2_LAYOUT_MAX</td>
            <td align="left">21</td>
            <td align="left">RFCTBD10</td>
            <td align="left">L</td>
            <td align="left">1</td>
          </tr>
        </tbody>
      </table>
      <t>This document introduces the 'Flexible File Version 2 Layout Type
Erasure Coding Type Registry'.  The registry uses a 32-bit value
space partitioned into ranges based on the intended scope of the
encoding type (see <xref target="tbl-coding-ranges"/>).</t>
      <table anchor="tbl-coding-ranges">
        <name>Erasure Coding Type Value Ranges</name>
        <thead>
          <tr>
            <th align="left">Range</th>
            <th align="left">Purpose</th>
            <th align="left">Allocation Policy</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">0x0000-0x00FF</td>
            <td align="left">Standards Track</td>
            <td align="left">IETF Review</td>
          </tr>
          <tr>
            <td align="left">0x0100-0x0FFF</td>
            <td align="left">Experimental</td>
            <td align="left">Expert Review</td>
          </tr>
          <tr>
            <td align="left">0x1000-0x7FFF</td>
            <td align="left">Vendor (open)</td>
            <td align="left">First Come First Served</td>
          </tr>
          <tr>
            <td align="left">0x8000-0xFFFE</td>
            <td align="left">Private/proprietary</td>
            <td align="left">No registration required</td>
          </tr>
          <tr>
            <td align="left">0xFFFF</td>
            <td align="left">Reserved</td>
            <td align="left">--</td>
          </tr>
        </tbody>
      </table>
      <dl>
        <dt>Standards Track (0x0000-0x00FF):</dt>
        <dd>
          <t>Encoding types intended for broad interoperability.  The
specification <bcp14>MUST</bcp14> include a complete mathematical description
sufficient for independent interoperable implementations (see
<xref target="encoding-type-interoperability"/>).  Allocated by IETF Review.</t>
        </dd>
        <dt>Experimental (0x0100-0x0FFF):</dt>
        <dd>
          <t>Encoding types under development or evaluation.  An Internet-Draft
is sufficient for allocation.  The specification <bcp14>SHOULD</bcp14> include
enough detail for interoperability testing.  Allocated by Expert
Review.</t>
        </dd>
        <dt>Vendor (open) (0x1000-0x7FFF):</dt>
        <dd>
          <t>Encoding types with a published specification or patent reference.
Interoperability is expected among implementations that license or
implement the specification.  The registration <bcp14>MUST</bcp14> include either a
math specification or a patent reference.  Allocated First Come
First Served.</t>
        </dd>
        <dt>Private/proprietary (0x8000-0xFFFE):</dt>
        <dd>
          <t>Encoding types for use within a single vendor's ecosystem.
No IANA registration is required.  Interoperability with other
implementations is not expected.  To reduce the likelihood of
accidental codepoint collisions between independent vendors,
implementations <bcp14>SHOULD</bcp14> derive the low-order 15 bits of any value
in this range from that vendor's Private Enterprise Number
<xref target="IANA-PEN"/> (for example, by hashing the PEN into the 15-bit
space and reserving one well-known offset per codec).  The
encoding type name <bcp14>SHOULD</bcp14> include an organizational identifier
(e.g., FFV2_ENCODING_ACME_FOOBAR).  A client that encounters a
value in this range from an unrecognized server <bcp14>SHOULD</bcp14> treat
it as an unsupported encoding type.</t>
        </dd>
      </dl>
      <t>This partitioning prevents contention for small numbers in the
Standards Track range and provides a clear signal to clients about
what level of interoperability to expect.</t>
      <t>This document defines five encoding types: the flexible file v1 layout-compatible
PASSTHROUGH (see <xref target="sec-encoding-passthrough"/>), the chunked
MIRRORED (see <xref target="sec-encoding-mirrored"/>), and three chunked
erasure coding types (see <xref target="tbl-coding-types"/>).</t>
      <table anchor="tbl-coding-types">
        <name>Flexible File Version 2 Layout Type Encoding Type Assignments</name>
        <thead>
          <tr>
            <th align="left">Encoding Type Name</th>
            <th align="left">Value</th>
            <th align="left">RFC</th>
            <th align="left">How</th>
            <th align="left">Minor Versions</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">FFV2_ENCODING_PASSTHROUGH</td>
            <td align="left">1</td>
            <td align="left">RFCTBD10</td>
            <td align="left">L</td>
            <td align="left">2</td>
          </tr>
          <tr>
            <td align="left">FFV2_ENCODING_MOJETTE_SYSTEMATIC</td>
            <td align="left">2</td>
            <td align="left">RFCTBD10</td>
            <td align="left">L</td>
            <td align="left">2</td>
          </tr>
          <tr>
            <td align="left">FFV2_ENCODING_MOJETTE_NON_SYSTEMATIC</td>
            <td align="left">3</td>
            <td align="left">RFCTBD10</td>
            <td align="left">L</td>
            <td align="left">2</td>
          </tr>
          <tr>
            <td align="left">FFV2_ENCODING_RS_VANDERMONDE</td>
            <td align="left">4</td>
            <td align="left">RFCTBD10</td>
            <td align="left">L</td>
            <td align="left">2</td>
          </tr>
          <tr>
            <td align="left">FFV2_ENCODING_MIRRORED</td>
            <td align="left">5</td>
            <td align="left">RFCTBD10</td>
            <td align="left">L</td>
            <td align="left">2</td>
          </tr>
        </tbody>
      </table>
      <section anchor="iana-checksum-algorithms">
        <name>Checksum Algorithm Registry</name>
        <t>This document introduces the "Flexible File Version 2
Layout Type Checksum Algorithm Registry".  Values in this
registry name the checksum_algorithm4
(<xref target="sec-checksum4"/>) carried in checksum4 on the wire and
selected per-mirror via ffv2m_checksum_algorithm
(<xref target="sec-ffv2-mirror4"/>).</t>
        <t>The registry uses a 32-bit value space.  Registration
policy is Specification Required <xref target="RFC8126"/>; the Designated
Expert reviews each request for:</t>
        <ul spacing="normal">
          <li>
            <t>a complete and publicly available specification of the
algorithm sufficient for independent interoperable
implementations;</t>
          </li>
          <li>
            <t>the exact length of the cs_value field for this
algorithm (a single registered length per algorithm;
variable-length variants register separately);</t>
          </li>
          <li>
            <t>collision risk against existing registrations (the
Expert <bcp14>MAY</bcp14> decline to register an algorithm whose
output overlaps substantially with an existing
registration).</t>
          </li>
        </ul>
        <t>Initial registrations are listed in
<xref target="tbl-checksum-algorithms"/>.</t>
        <table anchor="tbl-checksum-algorithms">
          <name>Initial Checksum Algorithm Registrations</name>
          <thead>
            <tr>
              <th align="left">Name</th>
              <th align="left">Value</th>
              <th align="left">cs_value bytes</th>
              <th align="left">Class</th>
              <th align="left">RFC</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">CHECKSUM_ALG_NONE</td>
              <td align="left">0</td>
              <td align="left">0</td>
              <td align="left">none</td>
              <td align="left">RFCTBD10</td>
            </tr>
            <tr>
              <td align="left">CHECKSUM_ALG_CRC32</td>
              <td align="left">1</td>
              <td align="left">4</td>
              <td align="left">bit-flip</td>
              <td align="left">RFCTBD10</td>
            </tr>
            <tr>
              <td align="left">CHECKSUM_ALG_CRC32C</td>
              <td align="left">2</td>
              <td align="left">4</td>
              <td align="left">bit-flip</td>
              <td align="left">RFCTBD10</td>
            </tr>
            <tr>
              <td align="left">CHECKSUM_ALG_FLETCHER4</td>
              <td align="left">3</td>
              <td align="left">32</td>
              <td align="left">bit-flip</td>
              <td align="left">RFCTBD10</td>
            </tr>
            <tr>
              <td align="left">CHECKSUM_ALG_SHA256</td>
              <td align="left">4</td>
              <td align="left">32</td>
              <td align="left">cryptographic</td>
              <td align="left">RFCTBD10</td>
            </tr>
            <tr>
              <td align="left">CHECKSUM_ALG_SHA512</td>
              <td align="left">5</td>
              <td align="left">64</td>
              <td align="left">cryptographic</td>
              <td align="left">RFCTBD10</td>
            </tr>
            <tr>
              <td align="left">CHECKSUM_ALG_BLAKE3</td>
              <td align="left">6</td>
              <td align="left">32</td>
              <td align="left">cryptographic</td>
              <td align="left">RFCTBD10</td>
            </tr>
          </tbody>
        </table>
        <t>CHECKSUM_ALG_NONE (value 0) indicates that no
protocol-level checksum is computed.  The deployment relies
on transport-layer integrity (RPC-over-TLS, RPCSEC_GSS_KRB5I)
or storage-layer integrity instead; see
<xref target="sec-security-checksum-scope"/>.</t>
        <t>CHECKSUM_ALG_CRC32 (value 1) is the CRC32 algorithm used
in this draft's predecessor revisions.  It is registered
for backward conceptual compatibility; deployments
<bcp14>SHOULD</bcp14> prefer CHECKSUM_ALG_CRC32C for new files since
CRC32C is hardware-accelerated on every modern CPU.</t>
        <t>CHECKSUM_ALG_CRC32C (value 2) is the CRC32 with the
Castagnoli polynomial (0x1EDC6F41), as used in iSCSI,
SCTP, and the SSE4.2 / ARMv8 / RISC-V hardware-acceleration
instructions.</t>
        <t>CHECKSUM_ALG_FLETCHER4 (value 3) is the Fletcher's
checksum variant used in ZFS, comprising four 64-bit
accumulators concatenated to produce a 32-byte output.
Other Fletcher4 implementations that truncate to a
shorter output register separately.</t>
        <t>CHECKSUM_ALG_SHA256 (value 4), CHECKSUM_ALG_SHA512 (value
5), and CHECKSUM_ALG_BLAKE3 (value 6) are cryptographic
hashes with standard outputs at the lengths listed.
BLAKE3 is registered at its standard 32-byte output;
extended-output BLAKE3 (the algorithm's XOF mode at other
lengths) registers separately.</t>
        <t>A checksum4 whose cs_value length does not match the
registered cs_value bytes for its cs_algorithm <bcp14>MUST</bcp14> be
rejected with NFS4ERR_INVAL.</t>
        <t>The "Class" column in <xref target="tbl-checksum-algorithms"/> is
informational and indicates the threat model the algorithm
supports; see <xref target="sec-security-checksum-scope"/>.</t>
      </section>
    </section>
    <section anchor="xdr-description-of-the-flexible-file-version-2-layout-type">
      <name>XDR Description of the Flexible File Version 2 Layout Type</name>
      <t>This document contains the External Data Representation (XDR)
<xref target="RFC4506"/> description of the flexible file v2 layout.  The XDR
description is embedded in this document in a way that makes it simple
for the reader to extract into a ready-to-compile form.  The reader can
feed this document into the shell script in <xref target="fig-extract"/> to produce
the machine-readable XDR description of the flexible file v2 layout.</t>
      <figure anchor="fig-extract">
        <name>extract.sh</name>
        <sourcecode type="shell"><![CDATA[
#!/bin/sh
grep '^ *///' $* | sed 's?^ */// ??' | sed 's?^ *///$??'
]]></sourcecode>
      </figure>
      <t>That is, if the above script is stored in a file called "extract.sh"
and this document is in a file called "spec.txt", then the reader can
run the script as in <xref target="fig-extract-example"/>.</t>
      <figure anchor="fig-extract-example">
        <name>Example use of extract.sh</name>
        <sourcecode type="shell"><![CDATA[
sh extract.sh < spec.txt > flex_files2_prot.x
]]></sourcecode>
      </figure>
      <t>The effect of the script is to remove leading blank space from each
line, plus a sentinel sequence of "///".</t>
      <t>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.1 nfs4_prot.x file <xref target="RFC5662"/>.  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 various
code snippets belong in their respective areas of that XDR.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC4121">
          <front>
            <title>The Kerberos Version 5 Generic Security Service Application Program Interface (GSS-API) Mechanism: Version 2</title>
            <author fullname="L. Zhu" initials="L." surname="Zhu"/>
            <author fullname="K. Jaganathan" initials="K." surname="Jaganathan"/>
            <author fullname="S. Hartman" initials="S." surname="Hartman"/>
            <date month="July" year="2005"/>
            <abstract>
              <t>This document defines protocols, procedures, and conventions to be employed by peers implementing the Generic Security Service Application Program Interface (GSS-API) when using the Kerberos Version 5 mechanism.</t>
              <t>RFC 1964 is updated and incremental changes are proposed in response to recent developments such as the introduction of Kerberos cryptosystem framework. These changes support the inclusion of new cryptosystems, by defining new per-message tokens along with their encryption and checksum algorithms based on the cryptosystem profiles. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="4121"/>
          <seriesInfo name="DOI" value="10.17487/RFC4121"/>
        </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="RFC5531">
          <front>
            <title>RPC: Remote Procedure Call Protocol Specification Version 2</title>
            <author fullname="R. Thurlow" initials="R." surname="Thurlow"/>
            <date month="May" year="2009"/>
            <abstract>
              <t>This document describes the Open Network Computing (ONC) Remote Procedure Call (RPC) version 2 protocol as it is currently deployed and accepted. This document obsoletes RFC 1831. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5531"/>
          <seriesInfo name="DOI" value="10.17487/RFC5531"/>
        </reference>
        <reference anchor="RFC5662">
          <front>
            <title>Network File System (NFS) Version 4 Minor Version 1 External Data Representation Standard (XDR) Description</title>
            <author fullname="S. Shepler" initials="S." role="editor" surname="Shepler"/>
            <author fullname="M. Eisler" initials="M." role="editor" surname="Eisler"/>
            <author fullname="D. Noveck" initials="D." role="editor" surname="Noveck"/>
            <date month="January" year="2010"/>
            <abstract>
              <t>This document provides the External Data Representation Standard (XDR) description for Network File System version 4 (NFSv4) minor version 1. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5662"/>
          <seriesInfo name="DOI" value="10.17487/RFC5662"/>
        </reference>
        <reference anchor="RFC7530">
          <front>
            <title>Network File System (NFS) Version 4 Protocol</title>
            <author fullname="T. Haynes" initials="T." role="editor" surname="Haynes"/>
            <author fullname="D. Noveck" initials="D." role="editor" surname="Noveck"/>
            <date month="March" year="2015"/>
            <abstract>
              <t>The Network File System (NFS) version 4 protocol is a distributed file system protocol that builds on the heritage of NFS protocol version 2 (RFC 1094) and version 3 (RFC 1813). Unlike earlier versions, the NFS version 4 protocol supports traditional file access while integrating support for file locking and the MOUNT protocol. In addition, support for strong security (and its negotiation), COMPOUND operations, client caching, and internationalization has been added. Of course, attention has been applied to making NFS version 4 operate well in an Internet environment.</t>
              <t>This document, together with the companion External Data Representation (XDR) description document, RFC 7531, obsoletes RFC 3530 as the definition of the NFS version 4 protocol.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7530"/>
          <seriesInfo name="DOI" value="10.17487/RFC7530"/>
        </reference>
        <reference anchor="RFC7861">
          <front>
            <title>Remote Procedure Call (RPC) Security Version 3</title>
            <author fullname="A. Adamson" initials="A." surname="Adamson"/>
            <author fullname="N. Williams" initials="N." surname="Williams"/>
            <date month="November" year="2016"/>
            <abstract>
              <t>This document specifies version 3 of the Remote Procedure Call (RPC) security protocol (RPCSEC_GSS). This protocol provides support for multi-principal authentication of client hosts and user principals to a server (constructed by generic composition), security label assertions for multi-level security and type enforcement, structured privilege assertions, and channel bindings. This document updates RFC 5403.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7861"/>
          <seriesInfo name="DOI" value="10.17487/RFC7861"/>
        </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="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="RFC8434">
          <front>
            <title>Requirements for Parallel NFS (pNFS) Layout Types</title>
            <author fullname="T. Haynes" initials="T." surname="Haynes"/>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document defines the requirements that individual Parallel NFS (pNFS) layout types need to meet in order to work within the pNFS framework as defined in RFC 5661. In so doing, this document aims to clearly distinguish between requirements for pNFS as a whole and those specifically directed to the pNFS file layout. The lack of a clear separation between the two sets of requirements has been troublesome for those specifying and evaluating new layout types. In this regard, this document updates RFC 5661.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8434"/>
          <seriesInfo name="DOI" value="10.17487/RFC8434"/>
        </reference>
        <reference anchor="RFC8435">
          <front>
            <title>Parallel NFS (pNFS) Flexible File Layout</title>
            <author fullname="B. Halevy" initials="B." surname="Halevy"/>
            <author fullname="T. Haynes" initials="T." surname="Haynes"/>
            <date month="August" year="2018"/>
            <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 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. Client-side mirroring is also added to provide replication of files.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8435"/>
          <seriesInfo name="DOI" value="10.17487/RFC8435"/>
        </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>
        <reference anchor="RFC9289">
          <front>
            <title>Towards Remote Procedure Call Encryption by Default</title>
            <author fullname="T. Myklebust" initials="T." surname="Myklebust"/>
            <author fullname="C. Lever" initials="C." role="editor" surname="Lever"/>
            <date month="September" year="2022"/>
            <abstract>
              <t>This document describes a mechanism that, through the use of opportunistic Transport Layer Security (TLS), enables encryption of Remote Procedure Call (RPC) transactions while they are in transit. The proposed mechanism interoperates with Open Network Computing (ONC) RPC implementations that do not support it. This document updates RFC 5531.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9289"/>
          <seriesInfo name="DOI" value="10.17487/RFC9289"/>
        </reference>
        <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="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>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="Plank97">
          <front>
            <title>A Tutorial on Reed-Solomon Coding for Fault-Tolerance in RAID-like System</title>
            <author initials="J." surname="Plank" fullname="J. Plank">
              <organization/>
            </author>
            <date year="1997" month="September"/>
          </front>
        </reference>
        <reference anchor="IANA-PEN" target="https://www.iana.org/assignments/enterprise-numbers/">
          <front>
            <title>Private Enterprise Numbers</title>
            <author>
              <organization>IANA</organization>
            </author>
            <date/>
          </front>
        </reference>
        <reference anchor="RFC1813">
          <front>
            <title>NFS Version 3 Protocol Specification</title>
            <author fullname="B. Callaghan" initials="B." surname="Callaghan"/>
            <author fullname="B. Pawlowski" initials="B." surname="Pawlowski"/>
            <author fullname="P. Staubach" initials="P." surname="Staubach"/>
            <date month="June" year="1995"/>
            <abstract>
              <t>This paper describes the NFS version 3 protocol. This paper is provided so that people can write compatible implementations. This memo provides information for the Internet community. This memo does not specify an Internet standard of any kind.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="1813"/>
          <seriesInfo name="DOI" value="10.17487/RFC1813"/>
        </reference>
        <reference anchor="RFC4519">
          <front>
            <title>Lightweight Directory Access Protocol (LDAP): Schema for User Applications</title>
            <author fullname="A. Sciberras" initials="A." role="editor" surname="Sciberras"/>
            <date month="June" year="2006"/>
            <abstract>
              <t>This document is an integral part of the Lightweight Directory Access Protocol (LDAP) technical specification. It provides a technical specification of attribute types and object classes intended for use by LDAP directory clients for many directory services, such as White Pages. These objects are widely used as a basis for the schema in many LDAP directories. This document does not cover attributes used for the administration of directory servers, nor does it include directory objects defined for specific uses in other documents. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="4519"/>
          <seriesInfo name="DOI" value="10.17487/RFC4519"/>
        </reference>
        <reference anchor="RFC7942">
          <front>
            <title>Improving Awareness of Running Code: The Implementation Status Section</title>
            <author fullname="Y. Sheffer" initials="Y." surname="Sheffer"/>
            <author fullname="A. Farrel" initials="A." surname="Farrel"/>
            <date month="July" year="2016"/>
            <abstract>
              <t>This document describes a simple process that allows authors of Internet-Drafts to record the status of known implementations by including an Implementation Status section. This will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature.</t>
              <t>This process is not mandatory. Authors of Internet-Drafts are encouraged to consider using the process for their documents, and working groups are invited to think about applying the process to all of their protocol specifications. This document obsoletes RFC 6982, advancing it to a Best Current Practice.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="205"/>
          <seriesInfo name="RFC" value="7942"/>
          <seriesInfo name="DOI" value="10.17487/RFC7942"/>
        </reference>
        <reference anchor="RFC8126">
          <front>
            <title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
            <author fullname="M. Cotton" initials="M." surname="Cotton"/>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <author fullname="T. Narten" initials="T." surname="Narten"/>
            <date month="June" year="2017"/>
            <abstract>
              <t>Many protocols make use of points of extensibility that use constants to identify various protocol parameters. To ensure that the values in these fields do not have conflicting uses and to promote interoperability, their allocations are often coordinated by a central record keeper. For IETF protocols, that role is filled by the Internet Assigned Numbers Authority (IANA).</t>
              <t>To make assignments in a given registry prudently, guidance describing the conditions under which new values should be assigned, as well as when and how modifications to existing values can be made, is needed. This document defines a framework for the documentation of these guidelines by specification authors, in order to assure that the provided guidance for the IANA Considerations is clear and addresses the various issues that are likely in the operation of a registry.</t>
              <t>This is the third edition of this document; it obsoletes RFC 5226.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="26"/>
          <seriesInfo name="RFC" value="8126"/>
          <seriesInfo name="DOI" value="10.17487/RFC8126"/>
        </reference>
        <reference anchor="PARREIN">
          <front>
            <title>Multiple Description Coding Using Exact Discrete Radon Transform</title>
            <author initials="B." surname="Parrein" fullname="B. Parrein">
              <organization/>
            </author>
            <author initials="N." surname="Normand" fullname="N. Normand">
              <organization/>
            </author>
            <author initials="J.-P." surname="Guedon" fullname="J.-P. Guedon">
              <organization/>
            </author>
            <date year="2001"/>
          </front>
          <seriesInfo name="IEEE" value="Data Compression Conference (DCC)"/>
        </reference>
        <reference anchor="NORMAND">
          <front>
            <title>A Geometry Driven Reconstruction Algorithm for the Mojette Transform</title>
            <author initials="N." surname="Normand" fullname="N. Normand">
              <organization/>
            </author>
            <author initials="A." surname="Kingston" fullname="A. Kingston">
              <organization/>
            </author>
            <author initials="P." surname="Evenou" fullname="P. Evenou">
              <organization/>
            </author>
            <date year="2006"/>
          </front>
          <seriesInfo name="LNCS" value="4245, pp. 122-133, DGCI 2006"/>
        </reference>
        <reference anchor="KATZ">
          <front>
            <title>Questions of Uniqueness and Resolution in Reconstruction from Projections</title>
            <author initials="M." surname="Katz" fullname="M. Katz">
              <organization/>
            </author>
            <date year="1978"/>
          </front>
          <seriesInfo name="Springer" value=""/>
        </reference>
        <reference anchor="I-D.haynes-nfsv4-flexfiles-v2-proxy-server">
          <front>
            <title>Proxy-Driven Server for Flexible Files Version 2</title>
            <author fullname="Thomas Haynes" initials="T." surname="Haynes">
              <organization>Hammerspace</organization>
            </author>
            <date day="28" month="April" year="2026"/>
            <abstract>
              <t>   Parallel NFS (pNFS) with the Flexible Files Version 2 layout type
   supports client-side erasure coding and per-chunk repair between
   clients and data servers.  This document extends that architecture
   with a proxy server (PS) role: a registered peer of the metadata
   server that polls the metadata server for work assignments and
   carries them out -- moving a file from one layout to another,
   reconstructing a whole file from surviving shards, or translating
   between codecs for clients that cannot participate in the file's
   native encoding (including NFSv3 clients).  All PS-MDS coordination
   is fore-channel: the metadata server returns work assignments inline
   in the response to a PS-initiated PROXY_PROGRESS poll, and the PS
   reports completion via a fore-channel PROXY_DONE.  No callback
   operations are required for the PS protocol.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-haynes-nfsv4-flexfiles-v2-proxy-server-00"/>
        </reference>
      </references>
    </references>
    <?line 10214?>

<section numbered="false" removeInRFC="true" anchor="sec-implementation-status">
      <name>Implementation Status</name>
      <t>This appendix records the implementation status of this
specification at the time of writing.  The purpose, per
<xref target="RFC7942"/>, is to help reviewers evaluate the protocol
against running code and to document which parts have
been validated end-to-end versus specified on paper.
This appendix is reviewer-aid material and is removed
from the final RFC.</t>
      <section numbered="false" anchor="reffs-metadata-server-and-data-server-and-ecdemo-client">
        <name>reffs (metadata server and data server) and ec_demo (Client)</name>
        <dl>
          <dt>Organization:</dt>
          <dd>
            <t>Independent / open source.</t>
          </dd>
          <dt>License:</dt>
          <dd>
            <t>AGPL-3.0-or-later.</t>
          </dd>
          <dt>Source:</dt>
          <dd>
            <t><eref target="https://github.com/loghyr/reffs">https://github.com/loghyr/reffs</eref>.</t>
          </dd>
          <dt>Implementation:</dt>
          <dd>
            <t><tt>reffs</tt> is an NFSv4.2 server written in C that acts as both a
metadata server (MDS) and a data server (DS) in a flexible file v2 layout
deployment.  <tt>ec_demo</tt> is a client-side library with a
demonstration driver that exercises the flexible file v2 layout data path
over NFSv4.2 with all three erasure coding types defined in this
document.</t>
          </dd>
        </dl>
        <t>Coverage:</t>
        <ul spacing="normal">
          <li>
            <t>CHUNK_WRITE, CHUNK_READ, CHUNK_FINALIZE, and CHUNK_COMMIT (the
happy-path data-plane operations) are implemented end-to-end and
have been exercised against the three codec families (Reed-Solomon
Vandermonde, Mojette systematic, Mojette non-systematic).</t>
          </li>
          <li>
            <t>The chunk_guard4 CAS primitive, including the conflict-detection
and deterministic-tiebreaker rules in <xref target="sec-chunk_guard4"/>, is
implemented on both the client and the data server.</t>
          </li>
          <li>
            <t>Per-chunk checksum integrity checking (see
<xref target="sec-security-checksum-scope"/>) is implemented end-to-end.</t>
          </li>
          <li>
            <t>Per-inode persistent storage of chunk state (PENDING / FINALIZED
/ COMMITTED) is implemented using write-temp / fdatasync / rename
for crash safety.</t>
          </li>
          <li>
            <t>The repair data path (CHUNK_LOCK with CHUNK_LOCK_FLAGS_ADOPT,
CHUNK_WRITE_REPAIR, CHUNK_REPAIRED, CHUNK_ROLLBACK, and
CB_CHUNK_REPAIR) is <strong>specified but not yet implemented</strong> in the
prototype.  The corresponding operations currently return
NFS4ERR_NOTSUPP.  A fault-injection test harness is in place to
drive the repair path once it is implemented.</t>
          </li>
          <li>
            <t>The tight-coupling control protocol (TRUST_STATEID,
REVOKE_STATEID, BULK_REVOKE_STATEID) is <strong>specified but not yet
implemented</strong>.  Data servers advertise loose coupling via
<tt>ffdv_tightly_coupled = false</tt>, and synthetic AUTH_SYS
credentials with fencing are used for access control.</t>
          </li>
        </ul>
        <dl>
          <dt>Level of maturity:</dt>
          <dd>
            <t>Research-quality prototype.  The implementation demonstrates the
protocol and has produced the benchmark data summarised below.
It is not production-ready; in particular, it does not yet
implement the repair path required to tolerate concurrent-writer
races or multi-data server failure reconstruction.</t>
          </dd>
          <dt>Contact:</dt>
          <dd>
            <t>loghyr@gmail.com.</t>
          </dd>
          <dt>Last update:</dt>
          <dd>
            <t>April 2026.</t>
          </dd>
        </dl>
      </section>
      <section numbered="false" anchor="interoperability-and-benchmarks">
        <name>Interoperability and Benchmarks</name>
        <t>The reffs + ec_demo implementation has been benchmarked against
itself (no second flexible file v2 layout implementation is known to the
authors at the time of writing).  The benchmark suite exercises
four I/O strategies -- plain mirroring, pure striping, Reed-Solomon
Vandermonde, Mojette systematic, and Mojette non-systematic -- at
five file sizes (4 KB, 16 KB, 64 KB, 256 KB, and 1 MB), at two
parity geometries (4+2 and 8+2), and on two platforms (an Apple M4
host running macOS with a Rocky Linux 8.10 Docker container, and a
Fedora 43 native Linux host on aarch64).  Each data point is the
mean of five measured runs.  Data servers run as Docker containers
on a single-host bridge network, so absolute latency numbers
reflect encoding and RPC fan-out cost with near-zero network
latency; real deployments will see higher absolute values but
similar overhead ratios.</t>
        <t>Selected findings:</t>
        <dl>
          <dt>Erasure-coded write overhead is modest at small and mid sizes:</dt>
          <dd>
            <t>At 4 KB to 64 KB payloads, all three codecs add 14% to 21%
write latency relative to plain mirroring.  Above 64 KB the
encoding cost begins to dominate; at 1 MB Reed-Solomon and Mojette
systematic reach approximately +54%, Mojette non-systematic
approximately +62%.</t>
          </dd>
          <dt>The dominant write cost is encoding, not fan-out:</dt>
          <dd>
            <t>A pure-striping variant (6 data shards, no parity) isolates the two
costs.  At 1 MB, plain mirroring writes in 64 ms, striping in
71 ms (+11%), Reed-Solomon in 103 ms (+60%).  Of the 39 ms
Reed-Solomon penalty, only 7 ms comes from parallel fan-out; the
remaining 32 ms is encoding plus two additional parity RPCs.</t>
          </dd>
          <dt>Reconstruction of a missing data shard is essentially free for systematic codecs at 4+2:</dt>
          <dd>
            <t>Reed-Solomon and Mojette systematic
add 1% to 6% to read latency in degraded-1 mode (one data shard
missing, reconstructed from the remaining five).  A client that
discovers a failed data server at read time can reconstruct transparently
with no user-visible latency impact.</t>
          </dd>
          <dt>At 8+2, systematic-codec reconstruction diverges:</dt>
          <dd>
            <t>Mojette
systematic reconstruction overhead stays at approximately +4% at
1 MB, while Reed-Solomon grows to approximately +54% due to the
O(k^2) cost of inverting a k x k matrix in GF(2^8).  Mojette
systematic's back-projection algorithm scales with m (parity
count) rather than k (data count), so its reconstruction
overhead does not exhibit the same growth at wider geometries.</t>
          </dd>
          <dt>Mojette non-systematic applies a full inverse transform on every read:</dt>
          <dd>
            <t>Regardless of whether any shard is missing.  At
1 MB this produces approximately 4x read overhead at 4+2 and
approximately 7x at 8+2.  The read cost is independent of
failure count, which is the algorithmic trade-off of the
non-systematic form.</t>
          </dd>
          <dt>Results are platform-independent:</dt>
          <dd>
            <t>The largest absolute
latency delta between macOS M4 and Fedora 43 at 1 MB is 20 ms
on writes.  Codec ordering, overhead percentages, and
qualitative scaling behavior are reproducible across operating
systems and Docker implementations.</t>
          </dd>
        </dl>
        <t>The benchmarks confirm that the protocol's central design claims
hold in practice: client-side erasure coding is affordable at
typical payload sizes; systematic codecs reconstruct missing
shards cheaply; and the scaling properties of the three codec
families follow directly from their published algorithmic
complexities.</t>
        <t>The benchmarks quantify the algorithmic trade-offs each codec
family makes: Mojette non-systematic's constant decode cost comes
at a higher baseline read cost, and Reed-Solomon's matrix-
inversion reconstruction grows as O(k^2) at wider geometries.
The choice of default codec and geometry in a given deployment
follows from these properties applied to the workload's read /
write mix, fault-tolerance target, and acceptable encoding cost.</t>
        <t>A full benchmark report with per-size tables, figures, and the
platform comparison is available alongside the source code.</t>
      </section>
      <section numbered="false" anchor="sec-architectural-implication">
        <name>Architectural Implication: Cost of Fault Tolerance</name>
        <t>The headline question every storage audience asks of an
erasure-coding protocol is: "what does it cost when something goes
wrong?"  At the systematic-codec operating points measured
(Mojette systematic at 4+2 and 8+2), the benchmark answer is
<strong>essentially zero</strong>.  Mojette systematic at 4+2 reconstructs a
missing data shard with read-latency overhead within run-to-run
noise of healthy operation.  Mojette systematic at 8+2 holds at
approximately +4%.</t>
        <t>This shifts the deployment conversation away from "is erasure
coding cheap enough to enable" and toward "which codec and
geometry minimise the compromise."  The compromise that remains is
not the cost of fault tolerance; it is the cost of write-time
encoding, which is bounded (under 60% at 1 MB, under 25% at 64 KB),
and the cost of crash-safe durability via the chunk state machine
(see <xref target="sec-system-model-consistency"/>), which is +7% to +22% on
writes and +2% to +10% on reads.</t>
        <t>Wire-format performance objections raised earlier in the working
group's review of this work are addressed in
<xref target="sec-rejected-alternatives"/>: the per-RPC byte-shuffling cost of
the original Mojette-specific projection header has been replaced
with XDR-encoded chunk metadata (see <xref target="sec-chunk_guard4"/>), so the
remaining wire-format cost is the XDR-encoded chunk header itself,
which is identical for every codec and is part of the +7% to +22%
v2 write overhead measured above.</t>
      </section>
    </section>
    <section numbered="false" anchor="sec-rejected-alternatives">
      <name>Design Rationale: Rejected Alternatives</name>
      <t>This appendix records design alternatives that were
considered and rejected during the development of this
specification.  It is reviewer-aid material in this draft
and is retained in the final RFC as design-history
context for future implementers; the alternatives below
are not part of the normative specification.</t>
      <t>The design of flexible file v2 layout went through several iterations between
2024 and 2026 that are recorded here for the benefit of future
reviewers and implementers.  Each alternative below was considered
and rejected, with the specific concern that led to its rejection.
Understanding why these approaches were rejected may help reviewers
evaluate the current design against a fuller space of possibilities
and may guide future extensions or replacements.</t>
      <section numbered="false" anchor="proprietary-projection-header-inside-opaque-payload">
        <name>Proprietary Projection Header Inside Opaque Payload</name>
        <t>The earliest iteration placed a 16-byte Mojette-specific header at
the start of the READ/WRITE opaque payload, interpreted in the
endianness of the writer's host.  The motivation was concrete:
NFSv3 READ and WRITE arguments carry data as <tt>opaque data&lt;&gt;</tt> and
provide no XDR room for per-write structured metadata such as
codec geometry, integrity, or write-ordering tiebreakers.  An
NFSv3 server cannot be extended; if a flexible file v2 layout deployment
wanted an NFSv3 server to participate as a data server in an
erasure-coded layout, the only place to put codec metadata was
inside that opaque payload, prepended to the data bytes.  The data server
stored the entire opaque blob without interpreting it; the reader
peeled the 16-byte prefix off and acted on it.</t>
        <t>This was rejected because:</t>
        <ul spacing="normal">
          <li>
            <t>It embedded a specific erasure coding type (Mojette) into the
generic replication-method framework, preventing alternate
codings from reusing the same wire format.</t>
          </li>
          <li>
            <t>The header bytes were not XDR-aligned, which required every
implementation to handle endianness explicitly rather than
relying on XDR's natural byte order.</t>
          </li>
          <li>
            <t>Carrying integrity and identification data inside an opaque
disrespected the XDR self-description model that the rest of
NFSv4 relies on.  A generic NFSv3 inspector watching the wire
could not tell those bytes apart from application data, which
among other things made debugging, traffic analysis, and
middlebox processing rely on out-of-band knowledge.</t>
          </li>
        </ul>
        <t>The endianness objection raised at IETF 120 (July 2024) was the
surface complaint; the structural objection -- that smuggling
structured fields through an opaque type bypasses XDR's
self-description -- was the deeper reason the working group
declined the approach.  Once the design accepted that data
servers in a flexible file v2 layout deployment would speak
NFSv4.2 (with new ops in this document), the constraint that
forced the smuggling disappeared: chunk metadata could be
expressed as proper XDR fields in CHUNK_WRITE / CHUNK_READ /
chunk_guard4, visible to every observer of the wire.</t>
      </section>
      <section numbered="false" anchor="per-client-swap-files-with-metadata-server-mappingrecall">
        <name>Per-Client Swap Files with metadata server MAPPING_RECALL</name>
        <t>One proposal split logical and physical chunk addressing: the
metadata server maintained a mapping from logical offset to
physical location, and the client appended new chunks to a
per-client staging file on each data server before asking the
metadata server to atomically remap the file to the new chunks.
This was rejected because:</t>
        <ul spacing="normal">
          <li>
            <t>The MAPPING_RECALL operation required to atomically update the
mapping would, in a multi-writer deployment, have to recall all
outstanding read/write layouts on the file -- grinding the
application to a halt during every remap.</t>
          </li>
          <li>
            <t>Each client required its own staging file on every data server,
producing N clients * M data servers staging files that had to
be reconciled on client restart.</t>
          </li>
          <li>
            <t>The approach was biased toward correctness at the expense of
throughput, which inverted the expected workload mix where
single-writer cases dominate.</t>
          </li>
        </ul>
      </section>
      <section numbered="false" anchor="server-side-byte-range-lock-manager-per-file">
        <name>Server-Side Byte-Range Lock Manager per File</name>
        <t>Another proposal relied on byte-range locks obtained by clients
before writing, with the lock manager state spread across the data
servers.  This was rejected because:</t>
        <ul spacing="normal">
          <li>
            <t>A failed lock holder required a lock manager to arbitrate
recovery, effectively reintroducing a centralized decision
point for each chunk.</t>
          </li>
          <li>
            <t>The lock recall path for HPC checkpoint workloads (many ranks
writing disjoint regions) would have required thousands of
locks per file, with recall storms on every phase transition.</t>
          </li>
          <li>
            <t>The design did not specify how the lock manager itself would
be replicated for high availability, deferring the hardest
part of the problem.</t>
          </li>
        </ul>
        <t>The current design uses CHUNK_LOCK (see <xref target="sec-CHUNK_LOCK"/>) but
only on the repair path, not on the normal write path.</t>
      </section>
      <section numbered="false" anchor="modified-two-touch-paxos-on-each-chunk">
        <name>Modified Two-Touch Paxos on Each Chunk</name>
        <t>A fully distributed-consensus proposal placed a lightweight
(modified two-touch) Paxos round on each chunk write, reaching
agreement among the data servers holding the mirror set.  This was
rejected because:</t>
        <ul spacing="normal">
          <li>
            <t>The constant-factor cost per write (two or three round trips,
leader election overhead, majority quorum requirement) was
unacceptable for workloads where single-writer throughput
dominates the deployment mix.</t>
          </li>
          <li>
            <t>The approach demanded that data servers be peers in a
consensus protocol, which is a substantially heavier
requirement than being independent chunk stores.</t>
          </li>
          <li>
            <t>A majority of (k+m) data servers must be reachable for any
progress, which is a strictly stronger availability requirement
than the k-of-(k+m) needed for erasure-coded reads.</t>
          </li>
        </ul>
        <t>Working-group feedback on this proposal was uniformly negative.
The current design retains the option -- nothing in this
specification prevents an implementation from running classical
consensus internally among metadata server replicas (see
<xref target="sec-system-model-consensus"/>) -- but does not require it per
write.</t>
      </section>
      <section numbered="false" anchor="automatic-commit-of-empty-chunks">
        <name>Automatic Commit of Empty Chunks</name>
        <t>An earlier version included a WRITE_BLOCK_FLAGS_COMMIT_IF_EMPTY
flag (later renamed CHUNK_WRITE_FLAGS_ACTIVATE_IF_EMPTY) that
automatically committed a write to a previously-empty chunk
without a separate CHUNK_COMMIT round trip.  The flag is retained
in the current design but its scope was narrowed: it is
performant in the exclusive-writer case but produces blocks that
cannot be rolled back if a racing writer appears concurrently,
requiring either hole-punching or an extension of CHUNK_ROLLBACK
to work on committed blocks.  The narrow scope is documented in
the flag's definition; a broader version was rejected because it
created rollback liabilities that were disproportionate to the
single-RTT savings.</t>
      </section>
      <section numbered="false" anchor="global-clock-or-wall-clock-based-generation-counter">
        <name>Global Clock or Wall-Clock-Based Generation Counter</name>
        <t>An early design used a wall-clock timestamp as the cg_gen_id.
This was rejected because:</t>
        <ul spacing="normal">
          <li>
            <t>No global clock exists among the many clients of a
multi-rack deployment.  Clock skew can cause a newer write
to appear to have an earlier timestamp than an older one.</t>
          </li>
          <li>
            <t>Timestamps at millisecond or microsecond resolution are not
fine-grained enough to disambiguate bursty writes from the
same client.</t>
          </li>
          <li>
            <t>Mixing client identity bits into the low-order bits of a
timestamp (to make it unique) reduces effective timestamp
resolution without providing a useful total ordering.</t>
          </li>
        </ul>
        <t>The current design uses a per-chunk monotonic counter scoped to
the chunk on the data server, with cg_client_id as the
disambiguator across clients.  See <xref target="sec-chunk_guard4"/>.</t>
      </section>
      <section numbered="false" anchor="layout-level-generation-counter">
        <name>Layout-Level Generation Counter</name>
        <t>An alternative raised at IETF 122 (March 2025) was adding a
generation counter to the layout itself, transmitted to the
data servers alongside each I/O, so that the metadata server
could redirect writes to new data servers without issuing a
full CB_LAYOUTRECALL storm across every holder of the file.
This is a natural extension of the per-chunk cg_gen_id: where
cg_gen_id disambiguates successive writes to the same chunk, a
layout-level counter would disambiguate successive placements
of the same data.  This was rejected because:</t>
        <ul spacing="normal">
          <li>
            <t>The use case is already covered.  CB_CHUNK_REPAIR (see
<xref target="sec-CB_CHUNK_REPAIR"/>) and the Proxy Server
mechanism (see <xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>) together
handle mid-layout remap without requiring a layout-level
epoch on the wire.  CB_CHUNK_REPAIR reaches the specific
chunks that need redirection; the proxy server reaches the
broader re-placement case; between them the full remap
space is covered.</t>
          </li>
          <li>
            <t>Adding a layout-level counter introduces a second,
potentially-conflicting epoch alongside cg_gen_id.  The CAS
semantics on the data server would have to compose the two
generations (per-chunk and per-layout), which multiplies
the states the data server must reason about without
strengthening any guarantee the protocol offers today.</t>
          </li>
          <li>
            <t>The CB_LAYOUTRECALL storm that motivated the proposal is a
worst-case cost that the current design pays only during a
genuine data-server retirement or full re-placement.
Partial remaps -- the common case -- already flow through
CB_CHUNK_REPAIR + layout refresh on LAYOUTGET without
disturbing other holders.</t>
          </li>
        </ul>
        <t>If a future revision determines that layout-level generation is
needed, it can be added as a protocol extension: the on-wire
surface is additive rather than a replacement, because
cg_gen_id's semantics are independent of any outer layout
epoch.</t>
      </section>
      <section numbered="false" anchor="declustered-raid-with-dynamic-parity-mapping">
        <name>Declustered RAID with Dynamic Parity Mapping</name>
        <t>An alternative raised at IETF 121 (November 2024) was
borrowing from declustered RAID designs: the
metadata server maintains, for every fixed-size region of each
file, a mapping from logical address to the specific data
servers that currently hold that region's data and parity
shards; writes do not update chunks in place but instead produce
a new parity stripe on a freshly allocated set of data servers,
and the mapping is atomically swapped on the metadata server
once the new stripe is durable.  The attraction is that
overwrite is replaced by remap, eliminating the write-hole
problem entirely at the cost of moving consistency into the
mapping table.  This was rejected because:</t>
        <ul spacing="normal">
          <li>
            <t>The mapping load scales with the file's chunk count, not with
the file count.  A single large file with billions of chunks
produces a billion-entry mapping that the metadata server
must maintain with transactional semantics; the overhead is
inverted from the usual "a few large files" regime that
pNFS is designed for.</t>
          </li>
          <li>
            <t>Remapping storms during rebalancing, data-server addition, or
data-server failure require atomic updates to many mapping
entries at once.  Providing those updates with the
reasonable-latency bounds required by HPC checkpoint
workloads is an open research problem, not a specifiable
protocol.</t>
          </li>
          <li>
            <t>The approach reintroduces the metadata-server scale bottleneck
that client-side erasure coding is designed to avoid: every
write traverses the mapping table, and the mapping table is
the hot-spot under concurrent writes.</t>
          </li>
          <li>
            <t>The mapping table becomes the single point of failure that
the rest of the flexible file v2 layout architecture works hard to avoid;
replicating it with strong consistency requires a consensus
protocol on the metadata server, which the current design
deliberately does not require (see <xref target="sec-system-model-consensus"/>).</t>
          </li>
        </ul>
        <t>The current design uses fixed per-file chunk placement decided
at LAYOUTGET time plus chunk_guard4 CAS for writes, which
localises consistency decisions to the chunks being written
rather than to a global mapping table.</t>
      </section>
    </section>
    <section numbered="false" removeInRFC="true" anchor="sec-wg-concern-codec-on-client">
      <name>Working Group Concern: Codec on Every Client</name>
      <t>This appendix captures a working-group concern raised
during the review of an earlier revision of this draft:
the source of the concern, the question as the working
group asked it, the authors' understanding of what was
being asked, and how the current specification addresses
it.  This appendix is reviewer-aid material and is
removed from the final RFC.</t>
      <section numbered="false" anchor="source">
        <name>Source</name>
        <t>Christoph Hellwig, IETF 120, NFSv4 Working Group session, during the
discussion of the original Flexible File Version 2 erasure-coding
proposal.</t>
      </section>
      <section numbered="false" anchor="the-question-as-asked">
        <name>The Question as Asked</name>
        <t>Christoph stated that he was "very scared of the implications of
having every client be a full participant in a distributed storage
system."  He pointed out that any erasure-coding or replication
protocol that runs at the client requires every client implementation
to understand the codec, and that codecs evolve over time as new
algorithms appear in the storage research literature.  He observed
that the same problem appears with replication ("simple two-, three-,
four-way replication"): a client power-failure event mid-write leaves
the participating data servers in inconsistent states, and the
recovery machinery (mirrored logs, write-ahead replay, partial-write
detection) is "a bit of overkill for simple replication."</t>
        <t>David Black seconded the concern in the same session, stating that
"it's better to have the data protection algorithm be inside the
boundary of what you think the storage system is than outside."</t>
      </section>
      <section numbered="false" anchor="what-we-believe-is-being-asked">
        <name>What We Believe Is Being Asked</name>
        <t>Two coupled requirements:</t>
        <ol spacing="normal" type="1"><li>
            <t>Codec correctness and codec evolution must not be a per-client
burden.  An ecosystem in which every client must ship and update
every supported codec does not interoperate at scale: an
organisation cannot upgrade its storage system's encoding without
coordinating an upgrade across every client.</t>
          </li>
          <li>
            <t>The expensive recovery paths (partial writes, durable shard
placement, mirrored logging) must not live at the client either.
A protocol that exposes those paths to the client forces every
client implementation to carry the failure-recovery machinery,
which is precisely what RAID controllers and distributed storage
systems put behind a service boundary so that hosts do not have
to reason about it.</t>
          </li>
        </ol>
        <t>In short: the data-protection algorithm and its recovery story
belong inside a storage boundary, not at the client.</t>
      </section>
      <section numbered="false" anchor="how-the-proxy-server-addresses-this">
        <name>How the Proxy Server Addresses This</name>
        <t>The Proxy Server role, defined in
<xref target="I-D.haynes-nfsv4-flexfiles-v2-proxy-server"/>, is the storage
boundary that Christoph and David asked for.</t>
        <t>A proxy server is a peer of the metadata server and the data servers that:</t>
        <ul spacing="normal">
          <li>
            <t>speaks the codec on behalf of clients that cannot;</t>
          </li>
          <li>
            <t>receives whole-stripe operations from a codec-ignorant client;</t>
          </li>
          <li>
            <t>encodes (or decodes) using whatever the layout's
 <xref target="fig-ffv2_coding_type4"/> demands;</t>
          </li>
          <li>
            <t>drives the CHUNK operations to the participating data servers;</t>
          </li>
          <li>
            <t>carries the partial-write / FINALIZE / COMMIT recovery machinery
 that the codec requires.</t>
          </li>
        </ul>
        <t>Three properties follow:</t>
        <ul spacing="normal">
          <li>
            <t>A legacy NFSv4.2 (or even NFSv3) client gets erasure-coded
 durability without speaking erasure coding.  The proxy server is where
 the codec lives; the client does not have to be upgraded when
 the codec is upgraded.</t>
          </li>
          <li>
            <t>Codec evolution is a server-side concern.  Adding a new entry
 to <xref target="fig-ffv2_coding_type4"/> requires updating the proxy servers and data servers,
 not every client in the deployment.  This matches the operational
 pattern of every other distributed-storage protocol on the wire.</t>
          </li>
          <li>
            <t>The recovery machinery (PENDING -&gt; FINALIZED -&gt; COMMITTED, the
 chunk-state machine, partial-write detection via
 <xref target="sec-chunk_guard4"/>) executes on the proxy server, not the client.  Clients
 see ordinary NFSv4.2 semantics; the proxy server is responsible for
 converting those semantics into the chunk state-machine the
 data servers implement.</t>
          </li>
        </ul>
        <t>A codec-aware NFSv4.2 client is still permitted (and is the fast
path: no proxy hop, no double bandwidth on the proxy's link).  The
proxy server is the answer for clients that either cannot speak the codec
or are too old to be upgraded.  In Christoph's framing, the proxy server is
the inside of the storage boundary; codec-aware clients are
implementations that have been admitted into that boundary by
design.</t>
        <t>The proxy server does carry a data-plane cost: client bytes traverse the
proxy on the way to the data servers, so the proxy's link sees roughly
twice the bandwidth of a direct client-to-data server path, and the proxy server pays
the encode/decode CPU.  This is the price of admission for clients
that do not speak the codec; it is the same store-and-forward cost
any storage gateway pays.  It does not affect codec-aware clients,
which talk to the data servers directly.</t>
      </section>
    </section>
    <section numbered="false" removeInRFC="true" anchor="sec-wg-concern-recall-storms">
      <name>Working Group Concern: Coherent Multi-data server Writes Without Recall Storms</name>
      <t>This appendix captures a working-group concern raised
during the review of an earlier revision of this draft:
the source of the concern, the question as the working
group asked it, the authors' understanding of what was
being asked, and how the current specification addresses
it.  This appendix is reviewer-aid material and is
removed from the final RFC.</t>
      <section numbered="false" anchor="source-1">
        <name>Source</name>
        <t>Christoph Hellwig, IETF 122, NFSv4 Working Group session, during
the flexible file v2 layout erasure-coding discussion.</t>
      </section>
      <section numbered="false" anchor="the-question-as-asked-1">
        <name>The Question as Asked</name>
        <t>Christoph observed that performing erasure coding across a set of
data servers, where clients need a coherent view of the encoded
data while writes are in flight, is "just really complicated,
especially without recalling layouts."  He continued: "maybe we
need a more efficient network operation that doesn't recall layout
but updates layouts in a different way, and that might reduce
the overhead.  Basically any scheme would require either a fair
amount of intelligence on the data servers or some form of updating
outstanding layouts to point to a new right-out-of-place location."
He explicitly noted he was "leaning to updating the data servers
to be smarter."</t>
        <t>The same conversation introduced the idea of a "generation counter
that gets sent over the wire to the data servers, which means the
data server now needs to look for a new location for the same
existing layout."</t>
      </section>
      <section numbered="false" anchor="what-we-believe-is-being-asked-1">
        <name>What We Believe Is Being Asked</name>
        <t>Two coupled requirements:</t>
        <ol spacing="normal" type="1"><li>
            <t>The metadata server must be able to mutate where data lives -- replace a
failing data server, redirect to a spare, rebalance, repair --
without serialising every layout-holding client through a
CB_LAYOUTRECALL round-trip.  A recall is global with respect
to the layout: every client holding it must drain in-flight I/O
and DELEGRETURN before the metadata server can mutate.  In an erasure-coded
workload with many concurrent clients, this turns a localised
data server hiccup into a global stall.</t>
          </li>
          <li>
            <t>The data servers must be smart enough to enforce per-client
access on a finer grain than "the file is reachable from the
network."  Anonymous-stateid I/O combined with synthetic-uid
fencing is a coarse instrument: fencing one client's access
to a file affects every client's access to that file.  The
only way to selectively revoke is to teach the data server who is
permitted, on which file, with which iomode -- which is the
"smarter data server" Christoph was asking for.</t>
          </li>
        </ol>
      </section>
      <section numbered="false" anchor="how-truststateid-revokestateid-and-bulkrevokestateid-address-this">
        <name>How TRUST_STATEID, REVOKE_STATEID, and BULK_REVOKE_STATEID Address This</name>
        <t>Sections <xref target="sec-TRUST_STATEID"/>, <xref target="sec-REVOKE_STATEID"/>, and
<xref target="sec-BULK_REVOKE_STATEID"/> of this document define exactly the
"smarter data server" the working group asked for.</t>
        <t>The mechanism:</t>
        <ul spacing="normal">
          <li>
            <t>At LAYOUTGET, the metadata server issues a real layout stateid and fans out
 TRUST_STATEID to each data server in the mirror set, registering
 <tt>(stateid.other, fh, clientid, iomode, expire)</tt> in a per-data server
 trust table.  CHUNK_WRITE and CHUNK_READ on the data server now validate
 against the trust table; an unknown, expired, or revoked
 stateid yields NFS4ERR_BAD_STATEID.</t>
          </li>
          <li>
            <t>When the metadata server needs to mutate the layout for a particular client
 -- because that client misbehaved, because a data server the layout
 points at is being drained, because the file is being repaired
 -- it issues REVOKE_STATEID to the affected data server.  Other clients'
 trust entries on the same file are untouched.</t>
          </li>
          <li>
            <t>When the metadata server needs to mutate at client-scope (lease expiry,
 client eviction), it issues BULK_REVOKE_STATEID, which removes
 every trust entry the named client has on the data server without
 affecting other clients.</t>
          </li>
        </ul>
        <t>The control-plane cost reshapes accordingly:</t>
        <ul spacing="normal">
          <li>
            <t>Layout mutation is no longer global.  The metadata server reroutes data to a
 spare data server, rebuilds shards from surviving copies, and revokes
 only the trust entries that pointed at the failing location.
 The other clients holding the layout are not contacted.</t>
          </li>
          <li>
            <t>The revoked client only learns of the mutation lazily, on its
 next CHUNK_WRITE or CHUNK_READ to the affected stripe.  That
 operation returns NFS4ERR_BAD_STATEID; the client responds with
 LAYOUTERROR; the metadata server replies with a refreshed layout pointing
 at the new location; the client re-trusts and resumes.  A
 client that never touches the affected stripe never pays the
 cost at all.</t>
          </li>
          <li>
            <t>With warm spares known to the metadata server, the entire repair can complete
 before any client notices.  The metadata server reconstructs onto a spare
 using server-to-server traffic, atomically swaps the layout slot
 in its in-memory state, and revokes only the trust entries on
 the now-evacuated data server.  Reading clients see no interruption (any
 k of the surviving shards reconstructs); writing clients pay
 one round-trip to refresh the layout when they next write the
 affected stripe.</t>
          </li>
        </ul>
        <t>The combination of TRUST_STATEID and a warm-spare data server pool is the
"more efficient network operation that updates layouts" Christoph
asked for.  It is not literally a layout update on the wire; it is
a primitive that makes layout updates a local event the metadata server can
resolve before the client has to pay a recall round-trip.</t>
        <t>The chunk state machine (PENDING -&gt; FINALIZED -&gt; COMMITTED) and
<xref target="sec-chunk_guard4"/> address the orthogonal concern of partial-write
recovery, ensuring that even when the metadata server reroutes mid-write the
data servers can detect non-atomic stripes via per-chunk generation
checks rather than via a global wall-clock or consensus protocol.</t>
      </section>
      <section numbered="false" anchor="combined-effect-on-the-cluster-tax">
        <name>Combined Effect on the "Cluster Tax"</name>
        <t>The Proxy Server addresses the codec-distribution cost; the trust
stateid mechanism addresses the layout-mutation cost.  Together,
they confine the residual cluster overhead to:</t>
        <ul spacing="normal">
          <li>
            <t>the store-and-forward bandwidth on the proxy server link, paid only by
 clients that route through a proxy server rather than going DS-direct;
 and</t>
          </li>
          <li>
            <t>one LAYOUTERROR/LAYOUTGET round-trip per client per affected
 stripe, paid only by clients that actually try to use a stripe
 whose backing has changed.</t>
          </li>
        </ul>
        <t>Neither cost scales with the number of layout-holding clients,
which is the property the working group asked for.</t>
      </section>
    </section>
    <section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The following from Hammerspace were instrumental in driving Flexible
File Version 2 Layout Type: David Flynn, Trond Myklebust, Didier
Feron, Jean-Pierre Monchanin, Pierre Evenou, and Brian Pawlowski.</t>
      <t>The Mojette Transform encoding type specification in
<xref target="sec-mojette-encoding"/> -- including the algebra, the bin
convention, the projection sizing, and the reconstruction
algorithms -- was contributed by Pierre Evenou, drawing on the
work of Nicolas Normand, Benoit Parrein, and the discrete
geometry research group at the University of Nantes.</t>
      <t>Christoph Hellwig was instrumental in making sure the Flexible File
Version 2 Layout Type was applicable to more than the Mojette
Transformation.</t>
      <t>David Black clarified at IETF 124 that the consistency goal of
flexible file v2 layout is RAID consistency across the shards of a stripe
rather than POSIX write ordering across application writes; that
framing is reflected in <xref target="sec-motivation"/> and in the Non-Goals
of <xref target="sec-system-model-consistency"/>.</t>
      <t>The authors thank Dave Noveck, Chuck Lever, Tigran
Mkrtchyan, Rick Macklem, and Christoph Hellwig for their
detailed review of earlier revisions of this draft.  Their
comments shaped the system model presentation, the chunk
lifecycle and guard semantics, the trusted-stateid design,
and many smaller choices recorded throughout the
document.</t>
      <t>Chris Inacio, Brian Pawlowski, and Gorry Fairhurst guided this
process.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAGACFWoAA9y963IcV3Iu+n89RW04TgiY6QZFEtJIpGfbEABK8JAADYCa
GTsccKG7AJTYXdWuqgbUmpCf5TzLebKT+WXmulRVg5S9Y58LY0KD7q7LuuTK
e345nU5dV3aL4lX2Pm/yxaJYZGdvLrPdFf13L3uzKH4ubxZF9qak/7zNN/W6
y34smrasq+yFy29umuLhFS5LLnl44eb1rMqX9Nx5k9920/t8UxXttLptHw6m
t3T9LV3eTh9eTL/82s3yrrirm82rrO3mbk6fXmV/Oz68OvnVzeqqLap23b7K
umZduHLV4K+2e/Hll99+SWNoivxV9n1RFTR891g3H++aer16lZ0VHX+ScV1u
2q5Y+qEfuI/Fhn6dv8pOq65oqqKbHvM4nWu7vJpf54u6okFsitatylfZv3b1
bJK1ddM1xW1Lf22W8gfNcpmvVmV1N8lm9XJZVF37b87l6+6+bl65bOoy+ldW
NPyr/ewHLAK+krW5uq+XeRt/Xzd3eVX+knc0zFf0Az2yaVf5rMCvxTIvF6+y
RX13v2n+8Y4/7dNrnavqZkn3PBT0zuzizdHB8xfP7c+vvvxa//zqq5f27Vdf
f/1C//zDVy+/tD+/+fp5+PNF+POl/vnN8z98Y38evDwIf35lf37zjT3h2xff
fPvKubK6jQf3fpFXH7/9wyvMR0nvMLtad3VT5ouMNueiKObTy3pRL+nDUT2n
xc3oEdmbfL3oplf1gna6mhW0qtnF4enxdFF+tA3GQ/3i07+prP0/7ct78Z0t
fu/LLm/uiu5Vdt91q1fPnj0WN/tFMWv3193H/WK+fvafP6346mf633xFG/Ps
6HL67dfTly9f7N938nah3stiRcO5KZrs+bff/oF+OD08O5y+PzlL5r3zvikf
6PrshIlw1ZRtkZ2t+bZ2x/XH1PKgHh/3y7zK94lMnuVtW95VILlnhX/AtJIH
PBusBa8G3fcKY4nGepsv2kK27Pk3z196snn+re3/twcv/P6/ADG9P7y4ODnt
zeYd7U+5otN2XLSzplwxDdsGfmj5vyc/57MuOy7p54KmfZHP6Yor2s6WaWRn
dMiyWd/tM4NqirLq/XC2n50xfVXz3g//tD99v599vy7oHdFsiW08x8e2aMqi
Zeq0d52enJzQNI7zLqdhL1dN0bYyheq2aAqmud3jo6M9HufZ+cW7w7PjdAEO
iQ/Vy6JrNtkx7WzBtMwMjPjVDItxuCA2V3b3SxB0d19k7+qfio6W4rMWYetc
D/ezP9H6tl3dXx5aghMaSL1Ol+DrLUvw9uzokiZy8OLgq0m2Wu1nz1+8mD5/
+XKSHX9/dIo7eYB/Orz6l3Tq/7wuWp5im9W32Yeq/I81ceS2zWistAhtvVhj
AcrBktw29TJ739Ay4HP71Pzf0TTz7pdoKs+//cM3W6ZyScehuitIXOzsODed
TrP8hl5LBOjcmKyjL+pHGjA9akU/Y3A3JEMK2kbeKdrXfM6ksVtXXZ3lzn9B
734omj3MNb6CpFnd5HdFNi8eylmxh03PM5Z8+xnx/sKl8tULVhOjV5sVsbmW
7r8tq2LOq9fd8+d6tuZzn+Wty6us+LkjEcl30lt5MnRV3tmEeOxrYiy0L+l4
WlzmmuI/1mVDv1eLDY1uUS7Ljt41L+6aAneVzFty2a1HIt5kNZxMHnPnt+QL
ksfzzZTmRfRAR37V1CQ860VLU8bJ4i9kr3lqxHtql8/n9EYefFM/lPMCr7yj
g7Khm76r6ZVHi5LmO235x2XZNDXvLV5Kg3E0vHZNU5gJr8ntlNHjG0x+jqWf
p6/fF6qo6PP1Gf+nq68vaPC0C84xj1rL8aclkFVnBYFY8kdaORICJJJroQxa
8YeDjJUNfjvUj4xFM39a0DJku1B7/rEsulvm3HsT93hfzu4x/2Z2T5xintFO
/Ou/7Rqj59v1p3277Rl/8awt8H//AFXgmh//Rzx9bz+7rNcNjYpWocDSlG1L
p1KGIPzGz2KWM3HTt+uq/+o7Wrn1DasVz/jN08c70dqexVrbHi3en3XC32PC
XszTovSenn3G0/d0N5blfL4onPs7Vsyaei5cwrnTalRB3W2JRi+VnJ6/4L36
299UDfn1173JKK2S7Fk3xKkWcso6PmXCkIiI5FQQ+bMIo0k83hPrx5kV+ilb
t6hZYZ3LGaYfmcjm5S1kRBc/tRWy8z/Z+WuhrPDZnfPg7us52CbJt7y64yXF
m2hGvQNLb5TZkb7166/GFhzPcZyTPE84CQ4CTjBPZ3qT8+doYXTqPJ18Rq/j
n9eQ20rl4TC/AtG/lOGw1vDrrxOHc7D/pXzJWiV9KYdj/3m8LRNQp/zwQq8m
bfPXX4kGDrMeW5UxtevVirRv4WZPc02Hub77cHnFNEiUaC+S58muZVXxmNWk
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
83HbSqnlcWs/tB7bZH6Fxy6o5uXCaDkf/wLzFLSe07KpC3PT78bPtX7d0OEq
trTillcP7T6djHzzyfVUAdabM7VXZz2xrOJwm0O4TYJsIepmqhNDAmyFL3V1
XxJYkWonnha+xYVbWiFvhkeZSt0ZbScK74by59m0Vec2ulukd7joDvEKDwIg
1rpvO7/LvPJLW2y0uIhL5KLKKAXUbwYC5U6p6E7p+qQMphs6iEurkya4hLua
1EdWeBjWrG7iiESUht21DkmLb+JEBr1pF9jFh2YNq+Bo1S2RdwnZqVGqug5C
HJeSbFqLDkEfk4ppQ7ZRpA71fivcz1hjm4uZV6IX0WwgadMx8YPkFIhNwg74
cCtYuWOnviX6B3qjdKapW2MVj51LFYtPygyCUcciWRmReKYuDr4/Ovj92Q9v
iBnggiiSTk7Pjw673VxkjOBM4Yh4TGxCjWKLI4x359pU6hoAc3jN7z5uoGTq
pDvRXJ2IaQh4nqCxsmnUdr1ri0v1uBGawJRtmoHFTlp7tWzaDlbe9gRcn5Tj
xUszKcmjiWmnbQCuoCFMPM0OCm7XFMiSNASKBqwW8xmD/JCV5xX3RioSeASG
XM5Ebbtcja+ZyTRpYlfecCiwLzR9XSxZJ2khmiKUgu+w7Xm98nop5dKzaUdz
xBkFPFo1lymmhOhl8c0uZsy4YtjBF6fJ2Yo3tlbY5kHWCD4X0hVQulsvmyAD
aTRkAQntsF+pY46bTO+j5EpYLTlCUBrRU9pvssqldiUJfoTsMspQuwQiw+o2
Z6ECWv9EqyTC6Pi3PdvhyDXChFRdl6xEuCBQsLuom/dc7Ei5PFz4hXJLBeTT
WMyV/1A11g0hxZIUcgQGUz2bWPbWtCYjpOJsIAabJlEXrRm2pE4UmL7LpU7X
45AKgUGIHCQHA9s7FD+xFKQ9YJFVhilgLnCUCi9FhVQXKLoc4CSpVI8YXyLM
zFgkKHWTLWs8b54Si0pmzzVBcBDNTTSgjHklhNl50lRIP8z2iCDudiwvJjfm
vuSN93YhIYvyGmNLPJqjxQoVg34+XlXIJSsSsRQxvFppYqvYdVlXl4uqfC+5
cVL/qzt9vQyD/aYMVx0LQTpEQVQKa0+qDEgMq0D21/TKL0wK0qRxNTKbJAZD
y4iiTjezWSNbRjwSAAOn8NYiSm8WbFFEyogYiN2VZ6LMcaRQnlBcT2zrdKcP
jVh3isorwR1jbFWrmlCz26JgoTDvtiLXWd3cihNFqHroOG9PNUWr6c0GLWMe
f6VXNfZcYtbz+wx7A4iEqXZAa7NJFuLdLIoOoFRVksZHFcWzst/zjRAC97SY
W6S0XO4XN4Bge6d/pZOgaqQHS4TAhuWI0SeK0vJraQNf15SGbErZZRU2X7m+
ZVsuH0MDN+IUA9I/8nW5IO/JYrnXGRD0GwHfbXQF+VEOyFVccyjj6sarhZ2Y
CwrcE67ubJwqJplBSJOc4b1poRXY9FRF0eLy8CYzGhXY2PwD0DWZj2vVhGh4
opkzLuqcdn7Dh5b2b1F1OHFcLwr4KtcjbLVxf9Dt0emJr4Js0AY5XER1FBYz
lo6FhxVJQLNXEwbcScVShVJkiR/O8m8yB1HySXC+zMvRe4nb1tcrzmGhb5Bj
Ip5mI+jDFwxVmKScDmkEDax0ZFQGFGB7ZnPxK7bnKBjiEWCtthQli12zLTaU
F8233v5oPeHf9M0uY9Yg18gFs0l8NtEi8Te3ZzWi6sRzrvVc1HDz+LR7KAxv
ZG8oy6BetyFDl15kjqXwSDosDICjCVQKxuOsN0oTunZLrQcndtbl1L8VuhI6
SgVmxMCzxk9uIlkklGwIrctDlr3B3UFfU01VpGKHX00aRZEISbtAASkZ23SY
pC0liS0I0Mp1KD9FHi8pStvo3UpIYpKguHpPMk+NOd/ySH1U+9R+Jo2jP+SG
miBrubkgpdALuAs/psuNbiHtRe4WkuupW0hvztxCcvmXuoWiPRH8kmxo5TvD
ICNy8ltUbgnWm2yGgPUU54jwHL8oAkUFFaj4QZoAqoJLQIFyFtrUHkqtrVZw
OaJvmy7Tak1yJJFRNbtaKh+cyEsGKdGcU6osZtcA8RSfSd4gw1fgtKHUHoT+
iEhlNoXfjOYvn/cnw/DnSevXT/Hf/4FfMXX/4LPrf+U2P1nT5uSpuHv2yDD7
I+/41PWa9nufRG9qNyi+9CT+xCdFqN+2l9qlnfalZ/I1f0GlX3RP+9Lp0dHh
xdnJ65M3J2//8Ub+knH4xWOmX4mbs/6S+9S+41NxxsfVtn0lvcs9sVve6i1d
H0rucl23dPSkY6v8TxkqA70L49JxKX9ICK3jh9qX8gF+XPM+fQpAfB07eM0f
Py/SguYXPJUNRnxKdYjp+LA6rRijs7mp54YJT0XapO8enlUNhRL3Ay3iJuFf
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
7/Q1do7zJzZuvJWfN9Z9q8M4oYcmqjBMogfDKEIwbMcBhpH7xnruh6nP3o5x
/MZ2LPwAuevJ1ICTy3RZTNnY6T7scrf3Pi/GPTcPfPzDXYKdU2IXgWcV2NKF
/xBfXe9Mdz+Pl88D/WHdbfc33OmA+qR12dPw53pnbJO86gexo0WH+tPdKJ/g
Q4k74f9JDzbOMJHMT8+DJ6z5/J386Z6Q6El2l8R5RTRif32R/8vqaoqM9EKp
v6rVtPzTow4CAL0i8s09+iMjLrGHcFNRgVhyyTPoklE1FP53LfAHtiwvqd1d
7wEX28ZOoLXiaq7FcidNjCh4NPJKlmQQ6KVwuGuqHddVDeFqm6q6u7u900pW
RUpAc0tEc4jWXFc3I9stts//67/+K/9totULnj4BB/oKCFK8z7VPDJaXKdjm
jfwRT7T6ADIn5PpdN9EX5FVw8vuNnBh/ynf2Nl96/vpQL322+VJ6sF76fC+T
a8v5epZH80NDvJv/NYtXq32nXe7hnzo7Ptx8I/W340b39eYb0fv2je5rue0P
fiVORMk7Vlz0RvX1dVOudv3n6fL6kr/bs5dNy/nN6ja+jL+LLpMoz669TMvQ
2uvccuGO8Rj7dYz95hcFd5Az2qInX9WTu3/9M1qUt13PaUXbl3WtOiNyfDvo
mNPp8pI/08eteEAQ/G1P8otkUrgv7cGVPl7yT9FLuy1I1K+dLX2oZYTi2Yv6
USxvmrivtOvenblT7OLy5Q8vOPgaj94V0R119bymgmJSBiKaaDMtrRv4Rwxi
x01VTVHK3fQm/rrjep2nzofwjzokTthAiKeiSKW4SF8RvH85PCNxLYVH055b
HnqSjLqTXr45+gum+tyD66J1Eq616wLeF4FWy8rUJYtUqczI3qs7AAAu49c3
4ML2r+qeBx3ylNCbXU5HUsLES2lPglAJAD4xMA2ALr7xJa263J+F6bGQpRxz
5e1ilXHB8OC9wTpdL4XV9mpdTVF9njJpwE9Ukf9ASs7PMzltGe3K1VNRLKqi
VDiU4OM0GooHtOZtXBN9hlIYtMdqK5ch4owzIc/YaeNN68wtVpQI0PcQRysN
4xGG8QzjSs5fPsWreoTx/YOBAvz0qnbf7coV5ps/otPx6dOnup2ju/Q3/Usk
MV1blVYW24sTeSwXG4lsL06kslxs5bK9elJ+qMblJV5311+Nj40IXbr8D/1X
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
Yny9ahZekSAHdJhTisAq8SplikApcPINmBjHUr3uv7aF/rAvP3sTmjrQTPBt
XHWJ0W1/J78k+MkwSPjbFWZd+SY400f55UKnJaxXuLVox6vNZc80MLVDUYTV
IBg3Ar70tGQqUaX2L/mmFoqGNjNUUOvqagVrRRkzRr02S1iezQJEF2kB5G00
90GYXjdGZQVs3yW3SyNOBNplrerdZGapNTkPyQihTioCZm/w5MZZR6CoPDm7
AagZCWkbLAKIgnMyJjC8pqp/KDcy533vVS3pFy+xx2ZQ6Upw42mqwWVTAPY3
KYAWO3pUlEFDXdcKryyZrC0zWhjXppBuGwO9IhSVQrCxHUS3qqpD3oJyDGn5
N9JwVmeMNh3D/wKdPiUg9CikEQRGTWha4PcE5d+MUZ9T7qQe0VuI2342QVzO
lMBZrSOvkfGMvlkE71gYeuTAYQLaglhd9NFcuXJZoWy3P1RcYjOvJqEnC6kH
KKSrrm4Lag5NbzQkszivlhc84xhMmXj72roEMK1etU+I33c5ww42uR3LeuMH
2GQIcU/MZWe6cmqFSmTHz8sP9Xwzdwfj8sL/Xaa6/g9vJS2qq2Zdl0zLe+p3
wruzi/Oz83PvD1IWQ8yQx1+Onn4xepoaIsSbi2JFzcBFbToWSgKYQIl2Rehk
GU8+e+y3nqNzS5oFdfyD4Jdw+gUFWnFXKCqqApCyUzt7H1v5IhfC4aTG1hCf
4pE90Kh1SU9+2Dq1BjHoWo6lZap0f0QWeaScs7sUKxTpQI+qGcA+buOyA2t1
UhsKFminhKYIefauBUpAKf1H4WfSduQ5myZo8FhyP9yo0GM12+kD7R9/Frqf
kOjBBSp/qCgr1l7XS6V+gs/jvK4Y313i00HSyXeQtPJ1DaEehAkbbR3uwqm8
xan47EgzQbrWhl1wbz+Ic0cP/NCheZFGvGVbO8C7+G9ps7JdrtclQdca2sqS
t3QS+unJVKGbGMYkjbYk6ynYGVq4a8YmaxbABa0ThtfkRngUJ8XexQ8VrvY4
9+PFzjoYLKw11FYa62+Xu9HxJxw9LTbCDnusGsxC29YSzg9uwwDKbIZtn0+7
1DgBVBmjQgD+qayWRhaykFtRrXF5G3xLiGh0pJHLmpGJLI6IDkKZGR8nTvwe
1XXmM6SZOK4t+dp+Z1DWp8avdJLRpfwujNMf8VfYywFbmcPwsaabBmDb4L4B
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

-->

</rfc>
