<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
     There has to be one entity for each item to be referenced.
     An alternate method (rfc include) is described in the references. -->

<!ENTITY RFC2119 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119">
<!ENTITY RFC4506 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4506">
<!ENTITY RFC5226 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5226">
<!ENTITY RFC5531 PUBLIC "" "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5531">
<!ENTITY I-D.deason-afs3-type-time PUBLIC "" "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.deason-afs3-type-time">
<!ENTITY I-D.keiser-afs3-capabilities PUBLIC "" "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.keiser-afs3-capabilities">
<!ENTITY I-D.keiser-afs3-xdr-union PUBLIC "" "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.keiser-afs3-xdr-union">
<!ENTITY I-D.keiser-afs3-xdr-primitive-types PUBLIC "" "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.keiser-afs3-xdr-primitive-types">
<!ENTITY I-D.wilkinson-afs3-standardisation PUBLIC "" "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.wilkinson-afs3-standardisation">

]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- used by XSLT processors -->

<!-- For a complete list and description of processing instructions (PIs),
     please see http://xml.resource.org/authoring/README.html. -->
<!-- Below are generally applicable Processing Instructions (PIs) that most I-Ds might want to use.
     (Here they are set differently than their defaults in xml2rfc v1.32) -->
<!-- give errors regarding ID-nits and DTD validation -->
<?rfc strict="yes" ?>

<!-- control the table of contents (ToC) -->
<!-- generate a ToC -->
<?rfc toc="yes" ?>

<!-- the number of levels of subsections in ToC. default: 3 -->
<?rfc tocdepth="4" ?>

<!-- control references -->
<?rfc symrefs="yes" ?>

<!-- use symbolic references tags, i.e, [RFC2119] instead of [1] -->
<?rfc sortrefs="yes" ?>

<!-- sort the reference entries alphabetically -->

<!-- control vertical white space
     (using these PIs as follows is recommended by the RFC Editor) -->
<!-- do not start each main section on a new page -->
<?rfc compact="yes" ?>
<!-- keep one blank line between list items -->
<?rfc subcompact="no" ?>

<!-- end of list of popular I-D processing instructions -->

<rfc
category="info"
docName="draft-tkeiser-afs3-volser-tlv-04"
ipr="noDerivativesTrust200902"
submissionType="independent">
  <!-- category values: std, bcp, info, exp, and historic
     ipr values: full3667, noModification3667, noDerivatives3667
     you can add the attributes updates="NNNN" and obsoletes="NNNN"
     they will automatically be output with "(if approved)" -->



  <!-- ***** FRONT MATTER ***** -->

  <front>
    <!-- The abbreviated title is used in the page header - it is only necessary if the
         full title is longer than 39 characters -->

    <title abbrev="AFSVol TLV RPCs">AFSVol Tag-Length-Value Remote Procedure Call Extensions</title>

    <!-- add role="editor" below for the editors if appropriate -->

    <!-- Another author who claims to be an editor -->



    <author fullname="Thomas Keiser" initials="T.E.K."
            surname="Keiser" >
      <organization abbrev="Sine Nomine">Sine Nomine Associates</organization>
      <address>
        <postal>
          <street>43596 Blacksmith Square</street>
          <city>Ashburn</city>
          <region>VA</region>
          <code>20147</code>
          <country>USA</country>
        </postal>
        <email>tkeiser@gmail.com</email>
      </address>
    </author>


    <author fullname="Steven Jenkins" initials="S.J."
            surname="Jenkins" >
      <address>
        <email>steven.jenkins@gmail.com</email>
      </address>
    </author>


    <author surname="Deason" fullname="Andrew Deason" initials="A.P.D." role="editor">
      <organization abbrev="Sine Nomine">Sine Nomine Associates</organization>
      <address>
        <postal>
          <street>43596 Blacksmith Square</street>
          <city>Ashburn</city>
          <region>Virginia</region>
          <code>20147-4606</code>
          <country>USA</country>
        </postal>

        <phone>+1 703 723 6673</phone>

        <email>adeason@sinenomine.net</email>
      </address>
    </author>


    <date year="2012" />

    <!-- If the month and year are both specified and are the current ones, xml2rfc will fill
         in the current day for you. If only the current year is specified, xml2rfc will fill
	 in the current day and month for you. If the year is not the current one, it is
	 necessary to specify at least a month (xml2rfc assumes day="1" if not specified for the
	 purpose of calculating the expiry date).  With drafts it is normally sufficient to
	 specify just the year. -->

    <!-- Meta-data Declarations -->

    <area>General</area>

    <workgroup>N/A</workgroup>

    <!-- WG name at the upperleft corner of the doc,
         IETF is fine for individual submissions.
	 If this element is not present, the default is "Network Working Group",
         which is used by the RFC Editor as a nod to the history of the IETF. -->

    <keyword>afs</keyword>
    <keyword>afs3</keyword>
    <keyword>afs-3</keyword>

    <!-- Keywords will be incorporated into HTML output
         files in a meta tag but they have no effect on text or nroff
         output. If you submit your draft to the RFC Editor, the
         keywords will be used for the search engine. -->

    <abstract>
<t>        AFS-3 is a distributed file system based upon prototypes
        developed at Carnegie Mellon University during the 1980s.
        AFS-3 heavily leverages Remote Procedure Calls (RPCs) as 
        the foundation for its distributed architecture.  
        This memo extends the volume management interface
        to support getting and setting of AFS volume attributes via an
        extensible Tag-Length-Value (TLV) encoding, which is based upon AFS-3 extensible
        discriminated unions.  TLV-based get and set RPCs are specified, along
        with a tag enumeration RPC.</t>
<t>        In addition, tags are allocated for 
        existing volume and transaction metadata, and 
        implementation-private tags are allocated for metadata 
        related to the OpenAFS Demand Attach File Server, and
        the RxOSD protocol suite.
</t>

    </abstract>


    <note title="Internet Draft Comments">
      <t>
        Comments regarding this draft are solicited.  Please include the AFS-3 protocol
        standardization mailing list (afs3-standardization@openafs.org) as a recipient
        of any comments.
      </t>
    </note>


<note title="AFS-3 Document State">
<t>
  This document is in state "draft", as per the document state definitions
  set forth in <xref target="I-D.wilkinson-afs3-standardisation"/>.
</t>
</note>

  </front>


  <middle>
    <section title="Introduction">
      <t>
        AFS-3 <xref target="CMU-ITC-88-062"/> <xref target="CMU-ITC-87-068"/>
        is a distributed file system that has its origins
        in the VICE project <xref target="CMU-ITC-84-020"/>
        <xref target="CMU-ITC-85-039"/> at the Carnegie Mellon University
        Information Technology Center <xref target="CMU-ITC-83-025"/>
        a joint venture between CMU and IBM.  VICE later became AFS when
        CMU moved development to a new commercial venture called
        Transarc Corporation, which later became IBM
        Pittsburgh Labs.  AFS-3 is a suite of un-standardized 
        network protocols based on a remote procedure call (RPC)
        suite known as Rx.  While de jure standards for AFS-3
        fail to exist, the various AFS-3 implementations have 
        agreed upon certain de facto
        standards, largely helped by the existence of
        an open source fork called OpenAFS that has served
        the role of reference implementation.  In addition to
        using OpenAFS as a reference, IBM wrote and donated developer
        documentation that contains somewhat outdated specifications
        for the Rx protocol and all AFS-3 remote procedure calls, as
        well as a detailed description of the AFS-3 system architecture.
      </t>

      <t>
        The AFS-3 architecture consists of many administrative
        domains called "cells" <xref target="CMU-ITC-88-070"/>
        which are glued together to form a globally distributed file system.  
        Each cell consists of: client nodes, which run cache manager daemons; file
        servers, which run file server daemons and volume server daemons;
        and database server nodes, which can run volume location database 
        servers, protection database servers, backup database servers, or
        several other obscure and/or deprecated database services.
      </t>

      <t>
        This memo focuses on the volume server <xref target="AFS3-VVL"/>
        component of AFS-3.
        The volume server provides an RPC interface for managing
        AFS volumes.  Volumes are the unit of storage administration in AFS-3.
        Each volume contains a subtree of the file system, along with
        special directory entries called mount points, which are used to
        link volumes together into a (potentially cyclic) directed graph.
        Mount points can cross cell boundaries, thus permitting construction of
        a cross-organizational, globally distributed, location-transparent
        file system.  The file system is location-transparent because mount 
        points contain volume names and cell names (which are resolved to locations
        by contacting the appropriate cell's volume location database), rather than
        encoding the data's physical location directly in the pointer.  This memo
        extends the AFS-3 volume server RPC interface with a suite of new RPCs that 
        provide extensible volume metadata get and set operations.
      </t>

      <section title="Motivations">
        <t>
          The current AFSVol volume metadata introspection routines use 
          hard-coded XDR <xref target="RFC4506"/> structure definitions.  This
          significantly limits protocol extensibility because new remote
          procedure calls and structure definitions must be defined during each
          protocol revision.  To some degree, this has been due to the lack of
          protocol standards documents: certain sites co-opted unused protocol
          fields for private uses, thus precluding the standards process from
          reclaiming these fields (without breaking existing deployments).
          Hence, each time new functionality is required, a new RPC--and,
          typically, new XDR data structures--need to be defined.  This is a
          rather expensive process--both in terms of standardization, and
          implementation.  Frequently, this leads to a desire to postpone
          protocol feature enhancements until many changes can be aggregated
          into a monolithic protocol upgrade.
        </t>

        <t>
          This memo introduces a new tag-length-value (TLV) encoding
          mechanism based upon the AFS-3 extensible discriminated union 
          primitive type <xref target="I-D.keiser-afs3-xdr-union"/>.
          This TLV encoding is utilized for getting and setting AFS-3 volume
          metadata.  The key advantage of this design is that new TLV tuples can
          be allocated without defining a new RPC.  Furthermore, because
          ext-union includes a length field in the encoding, it is always
          possible for a peer to decode the remainder of the XDR stream--even
          when a tag (and, thus, its XDR encoding) is unrecognized.  Hence,
          decode error handling can happen at the application layer, instead of
          deep within the Rx protocol stack.
        </t>

        <t>
          As the TLV changes require the addition of several new RPC interfaces
          (that are intended to eventually supplant extant interfaces), it is
          logical to add AFSVol capabilities <xref target="I-D.keiser-afs3-capabilities"/>
          for these new interfaces.
        </t>
      </section>

      <section title="Goals">
        <t>
          This memo aims to standardize a new TLV encoding mechanism for volume
          metadata.  In addition, this memo will standardize the TLV encoding of
          volume metadata which is currently available via several AFSVol XDR structures,
          as well as specify the encoding of several new pieces of AFS-3 volume metadata
          that are not currently available via the AFSVol interface.  For example, metadata
          specific to the OpenAFS Demand Attach File Server <xref target="DAFS"/>
          will be made available via
          the AFSVol service, whereas in the past it was only available locally on the
          file server machine via a proprietary interprocess communication mechanism.
        </t>
      </section>

      <section title="Abbreviations">
  <t>
<list style="hanging" hangIndent="10">

<t hangText="AFS      -">Historically, AFS stood for the Andrew File System; AFS no longer stands for anything</t>

<t hangText="afscbint  -">AFS-3 Cache Manager RPC Interface Definition</t>

<t hangText="afsint    -">AFS-3 File Server RPC Interface Definition</t>

<t hangText="AFSVol    -">AFS Volume Server Rx RPC Implementation</t>

<t hangText="CM        -">AFS-3 Cache Manager</t>

<t hangText="DAFS     -">OpenAFS Demand Attach File Server</t>

<t hangText="FS        -">AFS-3 File Server</t>

<t hangText="RPC      -">Remote Procedure Call</t>

<t hangText="RPC-L    -">Rx RPC Interface Definition Language (fork of ONC RPC <xref target="RFC5531"/> .x file format)</t>

<t hangText="Rx       -">The Remote Procedure Call mechanism utilized by AFS-3 <xref target="AFS3-RX"/></t>

<t hangText="RXAFS     -">AFS File Server Rx RPC Implementation</t>

<t hangText="RXAFSCB   -">AFS Cache Manager Rx RPC Implementation</t>

<t hangText="TLV      -">Tag-Length-Value encoding</t>


<t hangText="TSV      -">Tag nameSpace Version ordinal</t>
<t hangText="TTL       -">Time to Live for cached data</t>

<t hangText="volint    -">AFS-3 Volume Server RPC Interface Definition</t>

<t hangText="volser    -">AFS-3 Volume Server</t>

<t hangText="XDR      -">eXternal Data Representation <xref target="RFC4506"/></t>


</list>
  </t>
</section>

    </section>

    <section title="Conventions" anchor="sec-rfc2119">
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
      "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
      document are to be interpreted as described in <xref
      target="RFC2119">RFC 2119</xref>.</t>
    </section>


    <section anchor="sec-cap-new" title="New Capability Bit Allocations">
      <section title="VICED_CAPABILITY_DAFS">
        <t>
          When this capability bit is asserted, the file server is advertising
          that it supports Demand Attach File Server version 1 
          protocol semantics.  Specifically, DAFS v1 semantics imply
          that the following invariants MAY be violated by the fileserver:
        </t>

        <t>
          <list style="numbers">
            <t>
              any indication, which is visible to an afsint client, that a file server is restarting
              implies that all call back state will be invalidated; and
            </t>
            <t>
              RXAFS_GetVolumeStatus will return exact on-disk header state for the
              volume in question.
            </t>
          </list>
        </t>
      </section>

      <section title="AFSVOL_CAPABILITY_DAFS">
        <t>
          When this capability bit is asserted, the volserver is advertising
          that it supports Demand Attach File Server version 1 
          protocol semantics.  Specifically, DAFS v1 semantics imply
          that the following invariants MAY be violated by the volserver:
        </t>

        <t>
          <list style="numbers">
            <t>
              RPCs returning volintInfo (AFSVolListVolumes, AFSVolListOneVolume)
              and volintXInfo (AFSVolXListVolumes, AFSVolXListOneVolume)
              will return exact on-disk header state for the volume in question
            </t>
          </list>
        </t>

        <t>
          In addition, the combination of AFSVOL_CAPABILITY_DAFS and
          AFSVOL_CAPABILITY_TLV MAY imply that the tag AFSVOL_TLV_TAG_VOL_STATE_DAFS_RAW
          exists.  However, this implication SHOULD NOT be relied upon, as DAFS may
          evolve to the point where AFSVOL_TLV_TAG_VOL_STATE_DAFS_RAW has to be
          deprecated.  When both of these capabilities are asserted, the client SHOULD
          still gracefully handle the VOLSER_TAG_UNSUPPORTED error for 
          AFSVOL_TLV_TAG_VOL_STATE_DAFS_RAW.
        </t>
      </section>

      <section title="AFSVOL_CAPABILITY_TLV">
        <t>
          Assertion of this capability bit indicates the ability to service the RPC calls
          described in <xref target="sec-tlv" />.
        </t>
      </section>
    </section>

    <section title="TLV Interface" anchor="sec-tlv">
      <t>
        A new suite of RPCs will be standardized to get/set 
        tag-length-value tuples, and to enumerate supported tags. The 
        tag namespace will be controlled by the AFS Assigned Numbers 
        Registrar as an assigned numbers namespace.
      </t>

      <section title="Encoding">
        <t>
          The TLV data will be encoded using the AFS-3 extensible
          discriminated union <xref target="I-D.keiser-afs3-xdr-union"/>.
          The RPC-L specification for the base TLV types is as follows (NB: this
          is pseudocode; a less-concise, but machine-parseable version of this
          specification is included in <xref target="app-tlv-xdr"/>).
        </t>

        <figure align="center" anchor="tag_enum">
          <artwork><![CDATA[
/* registrar-controlled tag namespace */
enum AFSVol_TLV_tag {
    ...
};

const AFSVOL_TLV_TAG_MAX = 1024;         /* upper-bound on number of
                                          * TLV tuples per RPC */
const AFSVOL_TLV_OPAQUE_MAX = 262144;    /* upper-bound on size of
                                          * value payload */
const AFSVOL_TLV_TIME_MAX = 21845;       /* upper-bound on length of
                                            AFSTime vector payload */
const AFSVOL_TLV_UINT64_MAX = 32768;     /* upper-bound on length of
                                            uint64 vector payload */

enum AFSVol_TLV_type {
    AFSVOL_TLV_TYPE_NULL          = 0,
    AFSVOL_TLV_TYPE_TRUE          = 1,
    AFSVOL_TLV_TYPE_FALSE         = 2,
    AFSVOL_TLV_TYPE_UINT64        = 3,
    AFSVOL_TLV_TYPE_UINT64_VEC    = 4,
    AFSVOL_TLV_TYPE_INT64         = 5,
    AFSVOL_TLV_TYPE_INT64_VEC     = 6,
    AFSVOL_TLV_TYPE_UUID          = 7,
    AFSVOL_TLV_TYPE_STRING        = 8,
    AFSVOL_TLV_TYPE_TIME_ABS      = 9,
    AFSVOL_TLV_TYPE_TIME_ABS_VEC  = 10,
    AFSVOL_TLV_TYPE_TIME_REL      = 11,
    AFSVOL_TLV_TYPE_TIME_REL_VEC  = 12,
    AFSVOL_TLV_TYPE_VOL_ID        = 13,
    AFSVOL_TLV_TYPE_VOL_ID_VEC    = 14,
    AFSVOL_TLV_TYPE_PART_ID       = 15,
    AFSVOL_TLV_TYPE_PART_ID_VEC   = 16,
    AFSVOL_TLV_TYPE_DISK_BLOCKS   = 17,
    AFSVOL_TLV_TYPE_STAT_COUNTER  = 18,
    AFSVOL_TLV_TYPE_STAT_GAUGE    = 19,
    AFSVOL_TLV_TYPE_BIT64         = 20,
    AFSVOL_TLV_TYPE_VOL_DOW_USE   = 21,
    AFSVOL_TLV_TYPE_OPAQUE        = 22
};

ext-union AFSVol_TLV_value switch(AFSVol_TLV_type type) {
 case AFSVOL_TLV_TYPE_NULL:
 case AFSVOL_TLV_TYPE_TRUE:
 case AFSVOL_TLV_TYPE_FALSE:
    void;

 case AFSVOL_TLV_TYPE_UINT64:
 case AFSVOL_TLV_TYPE_VOL_ID:
 case AFSVOL_TLV_TYPE_PART_ID:
 case AFSVOL_TLV_TYPE_DISK_BLOCKS:
 case AFSVOL_TLV_TYPE_STAT_COUNTER:
 case AFSVOL_TLV_TYPE_BIT64:
    afs_uint64 u_u64;

 case AFSVOL_TLV_TYPE_INT64:
 case AFSVOL_TLV_TYPE_STAT_GAUGE:
    afs_int64 u_s64;

 case AFSVOL_TLV_TYPE_UINT64_VEC:
 case AFSVOL_TLV_TYPE_VOL_ID_VEC:
 case AFSVOL_TLV_TYPE_PART_ID_VEC:
    afs_uint64 u_u64_vec<AFSVOL_TLV_UINT64_MAX>;

 case AFSVOL_TLV_TYPE_INT64_VEC:
    afs_int64 u_s64_vec<AFSVOL_TLV_UINT64_MAX>;

 case AFSVOL_TLV_TYPE_TIME_ABS:
    AFSTime u_time_abs;

 case AFSVOL_TLV_TYPE_TIME_REL:
    AFSRelTimestamp u_time_rel;

 case AFSVOL_TLV_TYPE_TIME_ABS_VEC:
    AFSTime u_time_abs_vec<AFSVOL_TLV_TIME_MAX>;

 case AFSVOL_TLV_TYPE_TIME_REL_VEC:
    AFSRelTimestamp u_time_rel_vec<AFSVOL_TLV_UINT64_MAX>;

 case AFSVOL_TLV_TYPE_UUID:
    afsUUID u_uuid;

 case AFSVOL_TLV_TYPE_STRING:
    string u_string<AFSVOL_TLV_OPAQUE_MAX>;

 case AFSVOL_TLV_TYPE_VOL_DOW_USE:
    /* type defined later in this memo */
    AFSVol_stat_use_per_dow u_vol_dow_use;

 case AFSVOL_TLV_TYPE_OPAQUE:
    opaque u_opaque<AFSVOL_TLV_OPAQUE_MAX>;
};

const AFSVOL_TLV_FLAG_UNSUPPORTED = 0x1;
const AFSVOL_TLV_FLAG_READ_ERROR = 0x2;
const AFSVOL_TLV_FLAG_CRITICAL = 0x4;
const AFSVOL_TLV_FLAG_QUALIFIER_NO_MATCH = 0x8;
const AFSVOL_TLV_FLAG_MORE = 0x10;
const AFSVOL_TLV_FLAG_OBJ_NOT_SUPP = 0x20;

struct AFSVol_TLV {
    afs_uint32 tlv_tag;
    afs_uint32 tlv_flags;
    AFSVol_TLV_value tlv_value;
};
]]></artwork>
          <postamble>TLV XDR pseudocode</postamble>
        </figure>

        <section title="Data Value Types" anchor="sec-tlv-types">
          <t>
            The core of the TLV definition above is the AFS-3 extensible
            discriminated union primitive type.
            The following discriminators are initially defined in this memo:
          </t>

          <t>
            <list style="hanging" hangIndent="4">
              <t hangText="AFSVOL_TLV_TYPE_NULL = 0">
                <vspace blankLines="1"/>
                This shall map to type XDR void in the AFSVol_TLV_value union.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_TRUE = 1">
                <vspace blankLines="1"/>
                This shall map to type XDR void in the AFSVol_TLV_value union.
                It is used to communicate the boolean value true.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_FALSE = 2">
                <vspace blankLines="1"/>
                This shall map to type XDR void in the AFSVol_TLV_value union.
                It is used to communicate the boolean value false.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_UINT64 = 3">
                <vspace blankLines="1"/>
                This shall map to type afs_uint64 in the AFSVol_TLV_value union.
                The semantics of this field are defined by the tag.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_UINT64_VEC = 4">
                <vspace blankLines="1"/>
                This shall map to an XDR variable length vector of up to 32768 afs_uint64
                values.  The semantics of this field are defined by the tag.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_INT64 = 5">
                <vspace blankLines="1"/>
                This shall map to type afs_int64 in the AFSVol_TLV_value union.
                The semantics of this field are defined by the tag.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_INT64_VEC = 6">
                <vspace blankLines="1"/>
                This shall map to an XDR variable length vector of up to 32768 afs_int64
                values.  The semantics of this field are defined by the tag.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_UUID = 7">
                <vspace blankLines="1"/>
                This shall map to an afsUUID 
                <xref target="I-D.keiser-afs3-xdr-primitive-types"/> type.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_STRING = 8">
                <vspace blankLines="1"/>
                This shall map to an XDR string of maximum length 262144.
                The semantics of this field are defined by the tag.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_TIME_ABS = 9">
                <vspace blankLines="1"/>
                This shall map to an AFSTime in the AFSVol_TLV_value union.
                This absolute timestamp shall be encoded using the rules 
                specified in the AFS-3 time type specification
                <xref target="I-D.deason-afs3-type-time"/>.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_TIME_ABS_VEC = 10">
                <vspace blankLines="1"/>
                This shall map to an XDR variable length vector of up to 21845 AFSTime
                values in the AFSVol_TLV_value union.
                The absolute timestamp contained within each vector element shall be encoded 
                using the rules specified in 
                the AFS-3 time type specification
                <xref target="I-D.deason-afs3-type-time"/>.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_TIME_REL = 11">
                <vspace blankLines="1"/>
                This shall map to an AFSRelTimestamp in the AFSVol_TLV_value union.
                This relative timestamp (time interval) shall be encoded using the rules 
                specified in
                the AFS-3 time type specification
                <xref target="I-D.deason-afs3-type-time"/>.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_TIME_REL_VEC = 12">
                <vspace blankLines="1"/>
                This shall map to an XDR variable length vector of up to 32768 AFSRelTimestamp
                values in the AFSVol_TLV_value union.
                The relative timestamp (time interval) contained within each vector element 
                shall be encoded using the rules specified in
                the AFS-3 time type specification
                <xref target="I-D.deason-afs3-type-time"/>.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_VOL_ID = 13">
                <vspace blankLines="1"/>
                This shall map to an afs_uint64 in the AFSVol_TLV_value union.  This field shall
                contain an AFS-3 volume identifier.  When transmitting 32-bit volume identifiers,
                the upper 32 bits of this field MUST all be zeroes.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_VOL_ID_VEC = 14">
                <vspace blankLines="1"/>
                This shall map to an XDR variable length vector of up to 32768 afs_uint64 
                values in the AFSVol_TLV_value union.
                The elements within this vector shall contain AFS-3 volume identifiers.  When
                transmitting 32-bit volume identifiers, the upper 32 bits of the value MUST all
                be zeroes.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_PART_ID = 15">
                <vspace blankLines="1"/>
                This shall map to an afs_uint64 in the AFSVol_TLV_value union.  This field shall
                contain an AFS-3 vice partition identifier.  When transmitting 32-bit partition identifiers,
                the upper 32 bits of this field MUST all be zeroes.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_PART_ID_VEC = 16">
                <vspace blankLines="1"/>
                This shall map to an XDR variable length vector of up to 32768 afs_uint64 
                values in the AFSVol_TLV_value union.
                The elements within this vector shall contain AFS-3 vice partition identifiers.  When
                transmitting 32-bit partition identifiers, the upper 32 bits of the value MUST all
                be zeroes.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_DISK_BLOCKS = 17">
                <vspace blankLines="1"/>
                This shall map to an afs_uint64 in the AFSVol_TLV_value union.  This field shall
                contain an unsigned integer count in units of (1024 octet) disk blocks.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_STAT_COUNTER = 18">
                <vspace blankLines="1"/>
                This shall map to an afs_uint64 in the AFSVol_TLV_value union.  This field shall
                contain an unsigned integer counter statistic.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_STAT_GAUGE = 19">
                <vspace blankLines="1"/>
                This shall map to an afs_int64 in the AFSVol_TLV_value union.  This field shall
                contain a signed integer gauge (level) statistic.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_BIT64 = 20">
                <vspace blankLines="1"/>
                This shall map to an afs_uint64 in the AFSVol_TLV_value union.  This field shall
                contain a 64-bit bit field.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_VOL_DOW_USE = 21">
                <vspace blankLines="1"/>
                This shall map to an type AFSVol_stat_use_per_dow, as defined in
                <xref target="sec-use_per_dow"/>.
              </t>
              <t hangText="AFSVOL_TLV_TYPE_OPAQUE = 22">
                <vspace blankLines="1"/>
                This shall map to an XDR opaque byte array of maximum length 262144.
                The semantics and encoding of this field are defined by the tag
                (please see <xref target="sec-tlv-opaque_usage"/> for further
                 discussion).
              </t>
            </list>
          </t>
        </section>

        <section title="TLV Flags" anchor="sec-tlv-flags">
          <t>
            The AFSVol_TLV structure contains a 32-bit flags field for communication of
            various ancillary boolean values.  This memo defines and allocates the 
            following flag bits:
          </t>

          <t>
            <list style="hanging" hangIndent="4">
              <t hangText="AFSVOL_TLV_FLAG_UNSUPPORTED = 0x1">
                  <vspace blankLines="1"/>
                  When this flag is asserted, it tells the RPC caller that this tag is
                  not supported by this server.
              </t>
              <t hangText="AFSVOL_TLV_FLAG_READ_ERROR = 0x2">
                  <vspace blankLines="1"/>
                  When this flag is asserted, it tells the RPC caller that the server
                  was unable to read a value for this tag, despite the tag being supported
                  by the server.
              </t>
              <t hangText="AFSVOL_TLV_FLAG_CRITICAL = 0x4">
                  <vspace blankLines="1"/>
                  When this flag is asserted, it informs the peer that failure to decode
                  the payload associated with this tag is a fatal error that should result
                  in aborting this RPC call.
              </t>
              <t hangText="AFSVOL_TLV_FLAG_QUALIFIER_NO_MATCH = 0x8">
                  <vspace blankLines="1"/>
                  When this flag is asserted, it informs the caller that the qualifier
                  passed in did not match any record.
              </t>
              <t hangText="AFSVOL_TLV_FLAG_MORE = 0x10">
                  <vspace blankLines="1"/>
                  When this flag is asserted, it informs the caller that the server was unable
                  to send all available tags because the AFSVOL_TLV_TAG_MAX XDR vector length
                  limit was exceeded.
              </t>
              <t hangText="AFSVOL_TLV_FLAG_OBJ_NOT_SUPP = 0x20">
                  <vspace blankLines="1"/>
                  When this flag is asserted, it tells the RPC caller that the
                  object in question does not support this specific tag, despite
                  the tag generally being supported by the server.  An example
                  of this scenario could be a volume object which was created
                  using a format too old to support new metadata fields.
              </t>
            </list>
          </t>
        </section>

        <section title="Use of AFSVOL_TLV_TYPE_OPAQUE" anchor="sec-tlv-opaque_usage">
          <t>
            When possible, future protocol augmentations 
            requiring the definition of new data types should request 
            allocation of a new standards-track payload type code. 
            Allocation of a type code should coincide with 
            standardization of the payload encoding associated with 
            the type code allocation.  However, in limited 
            circumstances where:
          </t>

          <t>
            <list style="numbers">
              <t>
                it is known a priori that there will never be any 
                encoding ambiguity (i.e., the opaque type for this tag 
                shall map to exactly one XDR type), and 
              </t>
              <t>
                the cost of type code allocation and encoding 
                standardization are deemed too high
              </t>
            </list>
          </t>

          <t>
            use of the type code AFSVOL_TLV_TYPE_OPAQUE may be an acceptable
            alternative.
          </t>
        </section>

      </section>

      <section title="Qualifiers">
        <t>
          In some cases the value associated with a tag will be 
          large, structured data. A qualifier is a tag-specific 
          parameter which allows a caller to address a subset of 
          the value stored in a tag. For TLV get interfaces, 
          specifying a qualifer can reduce the amount of data 
          sent over the wire. For TLV set interfaces, specifying 
          a qualifier permits a client to modify a subset of a 
          structured value without endangering cache coherence. 
          Qualifiers are marshalled over the wire as type 
          AFSVol_TLV_value. Unless otherwise noted, it should be 
          assumed that a tag only supports the null qualifier 
          (ext-union discriminator set to AFSVOL_TLV_TYPE_NULL). 
          The null qualifier always references the entire value 
          for a given tag.
        </t>
      </section>
    </section>

    <section title="AFSVol TLV Interface">
      <section title="Error Codes">
        <t>
          A collection of new wire error codes are a required substrate.  The
          following new error codes are defined:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="VOLSER_TAG_UNSUPPORTED">
              <vspace blankLines="1"/>
              This server implementation does not support this tag.
            </t>
            <t hangText="VOLSER_TAG_READ_ONLY">
              <vspace blankLines="1"/>
              This tag is marked read-only, and thus AFSVolSetVolumeTLV cannot
              be invoked.
            </t>
            <t hangText="VOLSER_TAG_WRITE_FAILED">
              <vspace blankLines="1"/>
              AFSVolSetVolumeTLV failed to write to this tag for an unspecified
              reason.
            </t>
            <t hangText="VOLSER_TAG_DECODE_FAILED">
              <vspace blankLines="1"/>
              AFSVolSetVolumeTLV could not set the value passed for this tag
              because the AFSVol_TLV_value ext-union decoder raised an error
              flag.  This error may also be returned if, e.g., the XDR type
              includes opaque data, then failure to validate the octet stream
              embedded within the opaque would also result in this error code.
            </t>
            <t hangText="VOLSER_TAG_UNSUPPORTED_ENCODING">
              <vspace blankLines="1"/>
              The discriminant passed in AFSVol_TLV_value to AFSVolSetVolumeTLV
              is not supported by this implementation for this particular tag
              (e.g., an AFSVOL_TLV_TYPE_OPAQUE value was passed to a tag which
               only supports AFSVOL_TLV_TYPE_UINT64).
            </t>
            <t hangText="VOLSER_TLV_QUALIFIER_DECODE_FAILED">
              <vspace blankLines="1"/>
              A qualifier could not be decoded because an AFSVol_TLV_value
              ext-union decoder raised an error flag.  This error may also be
              returned if, e.g., the XDR type includes opaque data, then failure
              to validate the octet stream embedded within the opaque would also
              result in this error code.
            </t>
            <t hangText="VOLSER_TLV_QUALIFIER_UNSUPPORTED_ENCODING">
              <vspace blankLines="1"/>
              The discriminant passed in AFSVol_TLV_value in the qualifier
              is not supported by this implementation for this particular tag
              (e.g., an AFSVOL_TLV_TYPE_OPAQUE value was passed as the qualifier
               to a tag which only supports qualifiers of type
               AFSVOL_TLV_TYPE_UINT64).
            </t>
            <t hangText="VOLSER_TLV_QUALIFIER_INVALID">
              <vspace blankLines="1"/>
              The qualifier passed to the RPC was successfully decoded, and was
              of a supported type, however the value of the qualifier failed
              application-layer sanity checks.
            </t>
            <t hangText="VOLSER_TRANS_INVALID">
              <vspace blankLines="1"/>
              An RPC failed to execute because the transaction ID passed as an
              IN parameter was invalid.
            </t>
          </list>
        </t>
      </section>

      <section title="Tag Introspection">
        <t>
          In order for clients to determine which tags are supported by a given
          server, an RPC is provided for obtaining the list of tags.  In
          addition to returning the tags, this RPC also returns a tag namespace
          version (TSV) ordinal that can be used by clients to determine
          whether a consistent set of tags was fetched from the server.
          Additionally, this version ordinal can be compared against the value
          returned by all other TLV RPC calls to determine whether the tag cache
          remains coherent.  The Rx procedure specification for the tag
          enumeration RPC is as follows:
        </t>

        <figure align="left" anchor="tlv_get_tags">
          <artwork><![CDATA[
typedef afs_uint64 AFSVol_TLV_TSV;
typedef AFSVol_TLV_tag AFSVol_TLV_tag_vec<AFSVOL_TLV_TAG_MAX>;

proc GetVolumeTLVTags(
    IN AFSVol_TLV_tag offset,
    OUT AFSVol_TLV_tag_vec * tags,
    OUT AFSVol_TLV_TSV * tsv
) = XXX;
]]></artwork>
        </figure>

        <t>
          A compliant implementation MUST implement this RPC.
          The call parameters are defined as follows:

          <list style="hanging" hangIndent="4">
            <t hangText="offset">
              <vspace blankLines="1"/>
              The offset IN parameter specifies the numeric offset of 
              the first tag to return. A value of zero indicates that 
              the client wants to start the enumeration at the 
              beginning of the tag list.
            </t>
            <t hangText="tags">
              <vspace blankLines="1"/>
              The tags OUT parameter contains a sorted list of 
              supported tags, beginning with the first supported tag 
              greater than or equal to the offset IN parameter.
            </t>
            <t hangText="tsv">
              <vspace blankLines="1"/>
              The tsv OUT parameter contains the current server tag
              namespace version ordinal.  When this value changes from
              the previously-seen value on the client, it indicates that tag
              namespace cache coherence has been lost, and the client SHOULD
              restart fetching the tag namespace from offset zero.
            </t>
          </list>
        </t>

        <section title="Tag Namespace Cache Coherence">
          <t>
            Because the AFSVol interface is stateless, cache coherence cannot
            be maintained via the normal AFS mechanism.  Thus, AFSVol clients
            MUST treat enumerated tags as ephemeral with a TTL of two hours.  
          </t>

<!--
          <t>
            As described in <xref target="sec-cap_cc"/>, a client MAY use the
            Rx epoch returned by the AFSVol server as an indication that the
            cache should be invalidated prior to the two hour TTL, but MUST NOT
            use this as an optimization to extend cache lifetime beyond the two
            hour TTL, as the server may change its supported tag enumeration at
            runtime.
          </t>
-->

          <t>
            The Tag nameSpace Version (TSV) ordinal is used to communicate the
            current version of the tag namespace to the caller.  Version zero
            is a reserved value, so the server must initialize this verion 
            ordinal to a value great than 1.  Servers MUST ensure that version
            ordinals are unique within any 2 hour TTL period.
          </t>
        </section>
      </section>

      <section title="TLV Get">
        <t>
          The Rx procedure specification for the TLV get 
          interface will be as follows:
        </t>

        <figure align="center" anchor="tlv_get_single">
          <artwork><![CDATA[
struct AFSVol_TLV_query {
    AFSVol_TLV_tag tq_tag;
    AFSVol_TLV_value tq_qualifier;
};

typedef AFSVol_TLV_query AFSVol_TLV_query_vec<AFSVOL_TLV_TAG_MAX>;
typedef AFSVol_TLV AFSVol_TLV_vec<AFSVOL_TLV_TAG_MAX>;

proc GetOneVolumeTLV(
    IN afs_uint64 partId,
    IN afs_uint64 volId,
    IN AFSVol_TLV_query_vec * queries,
    OUT AFSVol_TLV_vec * tuples,
    OUT AFSVol_TLV_TSV * tsv
) = XXX;
]]></artwork>
        </figure>

        <t>
          A compliant implementation MUST implement this RPC.
          The call parameters are defined as follows:

          <list style="hanging" hangIndent="4">
            <t hangText="partId">
              <vspace blankLines="1"/>
              The partId IN parameter specifies the disk partition on 
              which the volume is located.
            </t>
            <t hangText="volId">
              <vspace blankLines="1"/>
              The volId IN parameter specifies the volume for which 
              TLV tuples are being requested.
            </t>
            <t hangText="queries">
              <vspace blankLines="1"/>
              The queries IN parameter specifies an optional list of 
              tags for which TLV tuples are desired. If this 
              parameter is zero-length, then the server will return 
              up to AFSVOL_TLV_TAG_MAX TLV tuples. If an unknown tag 
              identifier is passed in the tags parameter, then the 
              server will return a tuple with the 
              AFSVOL_TLV_FLAG_UNSUPPORTED bit asserted in 
              AFSVol_TLV.tlv_flags, and the tlv type set to 
              AFSVOL_TLV_TYPE_NULL.  
              If the volume object in question
              does not support a given metadata tag, then a tuple will
              be returned with AFSVOL_TLV_FLAG_OBJ_NOT_SUPP set in the
              AFSVol_TLV.tlv_flags field, and the tlv type set to
              AFSVOL_TLV_TYPE_NULL.  
              Similarly, if the server is 
              unable to retrieve the value for a supported tag, then 
              a tuple will be returned with 
              AFSVOL_TLV_FLAG_READ_ERROR set in the 
              AFSVol_TLV.tlv_flags field, and the tlv type set to 
              AFSVOL_TLV_TYPE_NULL.  The AFSVol_TLV_query.tq_qualifier 
              field contains optional tag-specific qualifiers which 
              would allow the implementation to return a subset of 
              the data for a specific tag.  When a non-NULL qualifier
              is passed, and the qualifier fails to match any record,
              then the flag bit AFSVOL_TLV_FLAG_QUALIFIER_NO_MATCH
              will be set in AFSVol_TLV.tlv_flags field, and the tlv
              type set to AFSVOL_TLV_TYPE_NULL.
            </t>
            <t hangText="tuples">
              <vspace blankLines="1"/>
              The tuples OUT parameter contains up to 
              AFSVOL_TLV_TAG_MAX TLV tuples for this volume.  
              If all tags cannot be sent due to AFSVOL_TLV_TAG_MAX 
              vector length limit, then the flag bit AFSVOL_TLV_FLAG_MORE 
              SHALL be asserted in the last element.
            </t>
            <t hangText="tsv">
              <vspace blankLines="1"/>
              The tsv OUT parameter contains the current server tag
              namespace version ordinal.  When this value changes from
              the previously-seen value on the client, it indicates that tag
              namespace cache coherence has been lost, and the client SHOULD
              use AFSVolGetVolumeTLVTags (see <xref target="tlv_get_tags"/>)
              to re-fetch the tag namespace.
            </t>
          </list>
        </t>
      </section>

      <section title="TLV Streaming Get">
        <t>
          This call is similar to the call described in the 
          previous section, with the exception that TLV tuples 
          will be returned for multiple volumes at once using an 
          Rx split call interface. The Rx procedure specification 
          is as follows:
        </t>

        <figure align="center" anchor="tlv_get_multi">
          <artwork><![CDATA[
const AFSVOL_BULK_GETVOLUME_MAX = 1024;

typedef afs_uint64 AFSVol_TLV_part_id_vec<AFSVOL_BULK_GETVOLUME_MAX>;
typedef afs_uint64 AFSVol_TLV_vol_id_vec<AFSVOL_BULK_GETVOLUME_MAX>;

struct AFSVol_TLV_vol_list {
    afs_uint64 partId;
    AFSVol_TLV_Vol_id_vec * volIds;
};

typedef struct AFSVol_TLV_vol_list 
AFSVol_TLV_get_filter<AFSVOL_BULK_GETVOLUME_MAX>;

proc GetVolumesTLV(
    IN AFSVol_TLV_get_filter * filter,
    IN AFSVol_TLV_query_vec * queries,
    OUT AFSVol_TLV_TSV * tsv
) split = XXX;
]]></artwork>
        </figure>

        <t>
          Implementation of this RPC is OPTIONAL.
          The call parameters are defined as follows:

          <list style="hanging" hangIndent="4">
            <t hangText="filter">
              <vspace blankLines="1"/>
              The filter IN parameter specifies an optional list of
              vice partitions and volume identifiers.  If the filter
              vector is zero-length, then TLV information is requested
              for all volumes on all vice partitions.  If this list is
              non-zero in length, then TLV information is requested
              only for volumes on specific vice partitions.  Furthermore,
              if the volIds vector in a specific filter vector index
              is non-zero in length, then TLV information is only
              returned for thoese volumes whose identifiers are enumerated
              in the volIds vector.
            </t>
            <t hangText="queries">
              <vspace blankLines="1"/>
              The queries IN parameter specifies an optional list of 
              tags for which TLV tuples are desired. If this 
              parameter is zero-length, then the server will return 
              up to AFSVOL_TLV_TAG_MAX TLV tuples. If an unknown tag 
              identifier is passed in the tags parameter, then the 
              server will return a tuple with the 
              AFSVOL_TLV_FLAG_UNSUPPORTED bit asserted in 
              AFSVol_TLV.tlv_flags, and the tlv type set to 
              AFSVOL_TLV_TYPE_NULL. 
              If the volume object in question
              does not support a given metadata tag, then a tuple will
              be returned with AFSVOL_TLV_FLAG_OBJ_NOT_SUPP set in the
              AFSVol_TLV.tlv_flags field, and the tlv type set to
              AFSVOL_TLV_TYPE_NULL.  
              Similarly, if the server is 
              unable to retrieve the value for a supported tag, then 
              a tuple will be returned with 
              AFSVOL_TLV_FLAG_READ_ERROR set in the 
              AFSVol_TLV.tlv_flags field, and the tlv type set to 
              AFSVOL_TLV_TYPE_NULL. The AFSVol_TLV_query.tq_qualifier 
              field contains optional tag-specific qualifiers which 
              would allow the implementation to return a subset of 
              the data for a specific tag.  When a non-NULL qualifier
              is passed, and the qualifier fails to match any record,
              then the flag bit AFSVOL_TLV_FLAG_QUALIFIER_NO_MATCH
              will be set in AFSVol_TLV.tlv_flags field, and the tlv
              type set to AFSVOL_TLV_TYPE_NULL.
            </t>
            <t hangText="tsv">
              <vspace blankLines="1"/>
              The tsv OUT parameter contains the current server tag
              namespace version ordinal.  When this value changes from
              the previously-seen value on the client, it indicates that tag
              namespace cache coherence has been lost, and the client SHOULD
              use AFSVolGetVolumeTLVTags (see <xref target="tlv_get_tags"/>)
              to re-fetch the tag namespace.
            </t>
          </list>
        </t>

        <section title="Split call stream encoding" anchor="sec-tlv-split">
          <t>
            The contents of the split call stream shall be an 
            xdrrec stream containing a finite sequence of 
            XDR-encoded AFSVol_TLV structures, each of which shall 
            be marked as a separate record (typically by calling 
            xdrrec_endofrecord). End of sequence will be annotated 
            by a dummy tuple containing the special tag type 
            AFSVOL_TLV_TAG_EOS.
          </t>
        </section>
      </section>

      <section title="TLV Set">
        <t>
          The Rx procedure specification for the TLV set 
          interface will be as follows:
        </t>

        <figure align="center" anchor="tlv_set">
          <artwork><![CDATA[
struct AFSVol_TLV_store {
    AFSVol_TLV ts_tuple;
    AFSVol_TLV_value ts_qualifier;
};

typedef AFSVol_TLV_store AFSVol_TLV_store_vec<AFSVOL_TLV_TAG_MAX>;
typedef afs_int32 AFSVol_TLV_result_vec<AFSVOL_TLV_TAG_MAX>;

proc SetVolumeTLV(
    IN afs_int32 trans,
    IN AFSVol_TLV_TSV assert_tsv,
    IN AFSVol_TLV_store_vec * tuples,
    OUT AFSVol_TLV_result_vec * results,
    OUT AFSVol_TLV_TSV * server_tsv
) = XXX;
]]></artwork>
        </figure>

        <t>
          Implementation of this RPC is OPTIONAL.
          The call parameters are defined as follows:

          <list style="hanging" hangIndent="4">
            <t hangText="trans">
              <vspace blankLines="1"/>
              The trans IN parameter specifies the transaction ID 
              returned by a previous invocation of AFSVolTransCreate.
            </t>
            <t hangText="assert_tsv">
              <vspace blankLines="1"/>
              The assert_tsv IN parameter contains the TSV ordinal expected by
              the client.  When this parameter is zero, it implies that the
              client wants the values to be set, regardless of the current
              server tag namespace version.  However, if the value of this
              parameter is non-zero, it MUST match the current server TSV.
              When there is a TSV mismatch, the call MUST fail with error code
              VOLSER_TAG_TSV_MISMATCH.
            </t>
            <t hangText="tuples">
              <vspace blankLines="1"/>
              The tuples IN parameter contains the list of TLV tuples 
              to be set by the server. 
            </t>
            <t hangText="results">
              <vspace blankLines="1"/>
              The results OUT parameter contains a list of error 
              codes, one per tuple. These error codes provide 
              specific information regarding the success/failure of 
              each TLV set operation. Valid error codes include: 
              <list style="symbols">
                <t>VOLSER_TAG_UNSUPPORTED</t>
                <t>VOLSER_TAG_READ_ONLY</t>
                <t>VOLSER_TAG_WRITE_FAILED</t>
                <t>VOLSER_TAG_DECODE_FAILED</t>
                <t>VOLSER_TAG_UNSUPPORTED_ENCODING</t>
                <t>VOLSER_TAG_TSV_MISMATCH</t>
                <t>VOLSER_TLV_QUALIFIER_UNSUPPORTED_ENCODING</t>
                <t>VOLSER_TLV_QUALIFIER_DECODE_FAILED</t>
                <t>VOLSER_TLV_QUALIFIER_INVALID</t>
                <t>VOLSERFAILEDOP</t>
                <t>VOLSERBAD_ACCESS</t>
                <t>VOLSER_TRANS_INVALID</t>
              </list>
            </t>
            <t hangText="server_tsv">
              <vspace blankLines="1"/>
              The tsv OUT parameter contains the current server tag
              namespace version ordinal.  When this value changes from
              the previously-seen value on the client, it indicates that tag
              namespace cache coherence has been lost, and the client SHOULD
              use AFSVolGetVolumeTLVTags (see <xref target="tlv_get_tags"/>)
              to re-fetch the tag namespace.
            </t>
          </list>
        </t>

        <section title="Call preprocessing">
          <t>
            The SetVolumeTLV begins by scanning all elements within 
            the tuples array. If any elements have the 
            AFSVOL_TLV_FLAG_CRITICAL bit asserted in 
            tuples[i].ts_tuple.ts_flags, then preprocessing of the 
            tuple must occur. For each tuple with the critical bit 
            set, several preprocessing validation steps will be taken.
          </t>

          <section title="Verify tag is supported">
            <t>
              The tag stored in tuples[i].ts_tuple.tlv_tag is checked 
              to ensure that the server supports it. In the event 
              that the tag is not supported, then the corresponding 
              array index in the results array will be set to 
              VOLSER_TAG_UNSUPPORTED, and the RPC call abort at the 
              conclusion of critical tuple preprocessing with error 
              code VOLSERFAILEDOP.
            </t>
          </section>

          <section title="Verify tag is writeable">
            <t>
              The tag stored in tuples[i].ts_tuple.tlv_flag is 
              checked to ensure that it is a writeable property. In 
              the event that the tag is read-only, then the 
              corresponding array index in the results array will be 
              set to VOLSER_TAG_READ_ONLY, and the RPC call will abort 
              at the conclusion of critical tuple preprocessing with 
              error code VOLSERFAILEDOP.
            </t>
          </section>

          <section title="Verify value encoding is supported">
            <t>
              The ext-union discriminator in 
              tuples[i].ts_tuple.tlv_value is checked to make sure 
              that it is a supported type. If the discriminator is 
              not a supported type, then the corresponding array 
              index in the results array will be set to 
              VOLSER_TAG_UNSUPPORTED_ENCODING, and the RPC call will 
              abort at the conclusion of critical tuple preprocessing 
              with error code VOLSERFAILEDOP.
            </t>
          </section>

          <section title="Verify value can be decoded">
            <t>
              The value stored in tuples[i].ts_tuple.tlv_value is 
              checked to make sure that it can be decoded. If the 
              wire-encoded data cannot be decoded, then the 
              corresponding array index in the results array will be 
              set to VOLSER_TAG_DECODE_FAILED, and the RPC call will 
              abort at the conclusion of critical tuple preprocessing 
              with error code VOLSERFAILEDOP.
            </t>
          </section>

          <section title="Verify qualifier is supported">
            <t>
              Qualifiers are specific to a given tag. If for any 
              reason the tag-specific validation logic determines 
              that the qualifier is invalid, it may set the 
              corresponding array index in the results array to one 
              of VOLSER_TLV_QUALIFIER_UNSUPPORTED_ENCODING, 
              VOLSER_TLV_QUALIFIER_DECODE_FAILED, or 
              VOLSER_TLV_QUALIFIER_INVALID. As with the other validation 
              steps, if a critical tuple fails qualifier validation, 
              then the RPC call will abort at the conclusion of 
              critical tuple preprocessing with error code VOLSERFAILEDOP.
            </t>
          </section>
        </section>

        <section title="Call processing">
          <t>
            Once the necessary validation steps have been 
            performed, the call will perform the set operations for 
            each tuple. Errors encountered during the processing of 
            each tuple will be recorded in the appropriate array 
            index of the results array. At the conclusion the RPC 
            will either return 0 if all set operations succeeded, 
            or VOLSERFAILEDOP if any failed.
          </t>
        </section>
      </section>
    </section>

    <section title="Mapping of existing metadata onto TLV namespace">
      <t>
        Existing metadata available from several interfaces 
        will also be exported as TLV tuples. This is being done 
        not only for completeness, but also to prevent data 
        races between AFSVolGetOneVolumeTLV, and the various 
        legacy introspection interfaces. 
      </t>

      <section title="volintXInfo" anchor="sec-tlv-volintXInfo">
        <t>
          All metadata exported via the volintXInfo XDR structure 
          will now be exported as TLV tuples. Unless otherwise 
          specified, the values associated with each tag shall be 
          identical to that returned for the associated field in 
          volintXInfo by the AFSVolXListOneVolume interface. The 
          following tuples will be allocated to export existing 
          members of volintXInfo:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_TLV_TAG_VOL_NAME">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.name. This 
              tuple MUST have a payload of type 
              AFSVOL_TLV_TYPE_STRING. The u_string payload field MUST 
              contain a null-terminated string.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STATUS">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.status. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_IN_USE">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.inUse. This 
              tuple will contain a boolean value, and therefore MUST 
              have a payload type of either: AFSVOL_TLV_TYPE_TRUE, or 
              AFSVOL_TLV_TYPE_FALSE.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_ID">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.volid. This 
              tuple MUST have a payload of type AFSVOL_TLV_TYPE_VOL_ID.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TYPE">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.type. This 
              tuple MUST have a payload of type AFSVOL_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_CLONE_ID">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.cloneID. This 
              tuple MUST have a payload of type AFSVOL_TLV_TYPE_VOL_ID.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_BACKUP_ID">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.backupID. This 
              tuple MUST have a payload of type AFSVOL_TLV_TYPE_VOL_ID.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_PARENT_ID">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.parentID. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_VOL_ID.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_COPY_DATE">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.copyDate. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_TIME_ABS. 
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_CREATE_DATE">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.creationDate. 
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_TIME_ABS. This timestamp shall be encoded 
              using the rules specified in
              the AFS-3 time type specification
              <xref target="I-D.deason-afs3-type-time"/>.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_ACCESS_DATE">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.accessDate. 
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_TIME_ABS. This timestamp shall be encoded 
              using the rules specified in
              the AFS-3 time type specification
              <xref target="I-D.deason-afs3-type-time"/>.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_UPDATE_DATE">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.updateDate. 
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_TIME_ABS. This timestamp shall be encoded 
              using the rules specified in
              the AFS-3 time type specification
              <xref target="I-D.deason-afs3-type-time"/>.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_BACKUP_DATE">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.backupDate. 
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_TIME_ABS. This timestamp shall be encoded 
              using the rules specified in
              the AFS-3 time type specification
              <xref target="I-D.deason-afs3-type-time"/>.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_SIZE">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.size. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_DISK_BLOCKS.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_FILE_COUNT">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.filecount. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_STAT_GAUGE.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_QUOTA_BLOCKS">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.maxquota. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_DISK_BLOCKS.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.dayUse. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_STAT_COUNTER.
              This field tracks volume accesses by AFS-3 clients over
              the course of this calendar day, since midnight
              local time of the file server.  
              <vspace blankLines="1"/>
              Operational monitoring
              applications which need to correlate the start time for
              the counter against a date SHOULD simultaneously query
              the value of tag AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY_DATE.
              For further discussion of the cache coherence implications,
              please see <xref target="sec-use_per_dow_cc"/>.
              <vspace blankLines="1"/>
              It should be noted that the definition of an "access" is 
              implementation-private, and thus comparison of access 
              rates across AFS-3 implementations is not possible.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_USE_PER_DOW">
              <vspace blankLines="1"/>
              This is the TLV exportation of the daily usage statistics
              for the past week.  
              This tuple may have two different
              payload types, depending upon whether or not a qualifier
              is delivered.  The payload and qualifier types will be 
              discussed in <xref target="sec-use_per_dow"/>.
              <vspace blankLines="1"/>
              It should be noted that the definition of an "access" is 
              implementation-private, and thus comparison of access 
              rates across AFS-3 implementations is not possible.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_READS">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.stat_reads. 
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_UINT64_VEC.
              This vector SHALL be of length 4.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_WRITES">
              <vspace blankLines="1"/>
              This is the TLV analogue of volintXInfo.stat_reads. 
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_UINT64_VEC.
              This vector SHALL be of length 4.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_FILE_SAME_AUTHOR">
              <vspace blankLines="1"/>
              This is the TLV analogue of 
              volintXInfo.stat_fileSameAuthor. This tuple MUST have 
              payload of type 
              AFSVOL_TLV_TYPE_UINT64_VEC.
              This vector SHALL be of length 6.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_FILE_DIFFERENT_AUTHOR">
              <vspace blankLines="1"/>
              This is the TLV analogue of 
              volintXInfo.stat_fileDiffAuthor. This tuple MUST have 
              payload of type AFSVOL_TLV_TYPE_UINT64_VEC. 
              This vector SHALL be of length 6.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_DIR_SAME_AUTHOR">
              <vspace blankLines="1"/>
              This is the TLV analogue of 
              volintXInfo.stat_dirSameAuthor. This tuple MUST have 
              payload of type AFSVOL_TLV_TYPE_UINT64_VEC.
              This vector SHALL be of length 6.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_DIR_DIFFERENT_AUTHOR">
              <vspace blankLines="1"/>
              This is the TLV analogue of 
              volintXInfo.stat_dirDiffAuthor. This tuple MUST have 
              payload of type AFSVOL_TLV_TYPE_UINT64_VEC.
              This vector SHALL be of length 6.
            </t>
          </list>
        </t>
      </section>

      <section title="transDebugInfo" anchor="sec-tlv-transDebugInfo">
        <t>
          All metadata exported via the transDebugInfo XDR 
          structure will now be exported as TLV tuples. Unless 
          otherwise specified, the values associated with each 
          tag shall be identical to that returned for the 
          associated field in transDebugInfo by the 
          AFSVolMonitor interface. The following tuples will be 
          allocated to export existing members of transDebugInfo:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_ID">
              <vspace blankLines="1"/>
              This is the TLV analogue of transDebugInfo.tid. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_UINT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_TIME">
              <vspace blankLines="1"/>
              This is the TLV analogue of transDebugInfo.time. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_TIME_REL. 
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_CREATE_TIME">
              <vspace blankLines="1"/>
              This is the TLV analogue of 
              transDebugInfo.creationTime. This tuple MUST have 
              payload of type AFSVOL_TLV_TYPE_TIME_ABS.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_RETURN_CODE">
              <vspace blankLines="1"/>
              This is the TLV analogue of transDebugInfo.returnCode. 
              This tuple MUST have payload of type AFSVOL_TLV_TYPE_INT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_ATTACH_MODE">
              <vspace blankLines="1"/>
              This is the TLV analogue of transDebugInfo.iflags. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_BIT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_STATUS">
              <vspace blankLines="1"/>
              This is the TLV analogue of transDebugInfo.vflags This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_BIT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_FLAGS">
              <vspace blankLines="1"/>
              This is the TLV analogue of transDebugInfo.tflags. This 
              tuple MUST have payload of type AFSVOL_TLV_TYPE_BIT64.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_LAST_PROC_NAME">
              <vspace blankLines="1"/>
              This is the TLV analogue of 
              transDebugInfo.lastProcName. This tuple MUST have 
              payload of type AFSVOL_TLV_TYPE_STRING. The u_string 
              payload field MUST contain a null-terminated string.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_CALL_VALID">
              <vspace blankLines="1"/>
              This is the TLV analogue of transDebugInfo.callValid.  This 
              tuple will contain a boolean value, and therefore MUST 
              have a payload type of either: AFSVOL_TLV_TYPE_TRUE, or 
              AFSVOL_TLV_TYPE_FALSE.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_READ_NEXT">
              <vspace blankLines="1"/>
              This is the TLV analogue of transDebugInfo.readNext. 
              This tuple MUST have payload of type AFSVOL_TLV_TYPE_STAT_COUNTER.
              This field contains the next expected Rx data packet sequence
              number expected by the receive side of this transaction's 
              bulk data transfer operation.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_XMIT_NEXT">
              <vspace blankLines="1"/>
              This is the TLV analogue of 
              transDebugInfo.transmitNext. This tuple MUST have 
              payload of type AFSVOL_TLV_TYPE_STAT_COUNTER.
              This field contains the next Rx data packet sequence
              number to be used by the transmit side of this transaction's 
              bulk data transfer operation.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_LAST_RECV_TIME">
              <vspace blankLines="1"/>
              This is the TLV analogue of 
              transDebugInfo.lastReceiveTime. This tuple MUST have 
              payload of type AFSVOL_TLV_TYPE_TIME_ABS.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_TRANS_LAST_SEND_TIME">
              <vspace blankLines="1"/>
              This is the TLV analogue of 
              transDebugInfo.lastSendTime. This tuple MUST have 
              payload of type AFSVOL_TLV_TYPE_TIME_ABS.
            </t>
          </list>
        </t>
      </section>

      <section title="Additional de facto-standardized fields" anchor="sec-tlv-de_facto">
        <t>
          Certain fields from the IBM AFS and OpenAFS file 
          server's VolumeDiskData header are generally useful. In 
          particular, several fields exported via the 
          AFSVolGetFlags and AFSVolSetFlags RPCs should be 
          exported via the TLV interface. The full list of 
          supported TLV tuples are:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_TLV_TAG_VOL_IN_SERVICE">
              <vspace blankLines="1"/>
              This tuple will contain a boolean value, and therefore 
              MUST have a payload type of either: 
              AFSVOL_TLV_TYPE_TRUE, or AFSVOL_TLV_TYPE_FALSE. When 
              this bit is not asserted, the volume is 
              administratively prohibited from coming online.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_BLESSED">
              <vspace blankLines="1"/>
              This tuple will contain a boolean value, and therefore 
              MUST have a payload type of either: 
              AFSVOL_TLV_TYPE_TRUE, or AFSVOL_TLV_TYPE_FALSE. When 
              this bit is not asserted, the volume is 
              administratively prohibited from coming online.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_RESTORED_FROM_ID">
              <vspace blankLines="1"/>
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_VOL_ID. When this field is non-zero, it 
              contains the volume ID contained in the dump from which 
              it was restored.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_DESTROYED">
              <vspace blankLines="1"/>
              This tuple will contain a boolean value, and therefore 
              MUST have a payload type of either: 
              AFSVOL_TLV_TYPE_TRUE, or AFSVOL_TLV_TYPE_FALSE. When 
              this bit is asserted, this volume is flagged for deletion.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_NEEDS_SALVAGE">
              <vspace blankLines="1"/>
              This tuple will contain a boolean value, and therefore 
              MUST have a payload type of either: 
              AFSVOL_TLV_TYPE_TRUE, or AFSVOL_TLV_TYPE_FALSE. When 
              this bit is asserted, this volume requires a salvage.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_OFFLINE_MESSAGE">
              <vspace blankLines="1"/>
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_STRING. The u_string payload field MUST 
              contain a null-terminated string. This field stores an 
              administrative message to indicate why the volume is offline.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_EXPIRATION_DATE">
              <vspace blankLines="1"/>
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_TIME_ABS. This timestamp shall be encoded 
              using the rules specified in
              the AFS-3 time type specification
              <xref target="I-D.deason-afs3-type-time"/>.
              To the best knowledge of the authors, 
              this field is not standardized by any implementation.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_QUOTA_RESERVATION">
              <vspace blankLines="1"/>
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_DISK_BLOCKS.  This field, otherwise known as 
              minquota, specifies the amount of storage (in units of 
              1024 octets) that are reserved on the underlying 
              storage for use by this volume.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY_DATE">
              <vspace blankLines="1"/>
              This tuple MUST have payload of type
              AFSVOL_TLV_TYPE_TIME_ABS.  This field, otherwise known as
              dayUseDate, specifies the timestamp when 
              AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY was reset to zero, and the
              previous value rolled over to index 0 of 
              AFSVOL_TLV_TAG_VOL_STAT_USE_PER_DOW.
            </t>
          </list>
        </t>
      </section>

      <section title="Day-of-week usage statistics" anchor="sec-use_per_dow">
        <t>
          The day-of-week usage statistics accessed via tag 
          AFSVOL_TLV_TAG_VOL_STAT_USE_PER_DOW 
          provide access to historic data for the
          7 days prior to the current access counter available via tag
          AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY.  Depending on the desired
          mode of statistics collection, two qualifier types are supported
          by this tag.
        </t>

        <section title="Qualifiers">
          <section title="NULL qualifier">
            <t>
              When the qualifier is of type AFSVOL_TLV_TYPE_NULL,
              then a custom payload of type AFSVOL_TLV_TYPE_VOL_DOW_USE will 
              be used to deliver day-of-week usage data for the past week.
              This type is defined as follows:
            </t>

            <figure align="center" anchor="tlv_week_use">
              <artwork><![CDATA[
struct AFSVol_stat_use_per_dow {
    afs_uint64 stat_dow[7];
    afs_uint32 stat_flags;
};
]]></artwork>
            </figure>

            <t>
              Seven bits in the stat_flags field are used to assert data validity
              for each day of week.  These bits are present to help monitoring
              applications distinguish between days for which no data was collected
              (e.g. due to the volume being less than eight days old) and days when
              there were exactly zero accesses.  These bits are defined as follows:
            </t>

            <figure align="center">
              <artwork><![CDATA[ 
Flag                        Description
-----                       -----------
AFSVOL_VOL_STAT_DOW0_VALID  stat_dow[0] is valid
AFSVOL_VOL_STAT_DOW1_VALID  stat_dow[1] is valid
AFSVOL_VOL_STAT_DOW2_VALID  stat_dow[2] is valid
AFSVOL_VOL_STAT_DOW3_VALID  stat_dow[3] is valid
AFSVOL_VOL_STAT_DOW4_VALID  stat_dow[4] is valid
AFSVOL_VOL_STAT_DOW5_VALID  stat_dow[5] is valid
AFSVOL_VOL_STAT_DOW6_VALID  stat_dow[6] is valid
AFSVOL_VOL_STAT_DOW_FUZZY   server incapable of guaranteeing validity
              ]]></artwork>
              <postamble>Day-of-week statistics flags</postamble>
            </figure>

            <t>
              Server implementations which are incapable of distinguishing between
              days when there was no usage, and for which there is no data SHOULD
              make a best-effort to populate the 7 per-day bits, and MUST assert
              the 0x80 stat_flags bit.
            </t>
          </section>

          <section title="UINT64 qualifier">
            <t>
              When the qualifier is of type AFSVOL_TLV_TYPE_UINT64,
              then a payload of type AFSVOL_TLV_TYPE_UINT64 will be
              used to deliver day-of-week usage data for the day of week
              specified in the uint64 qualifier.  Valid qualifiers are in
              the range 0 to 6, where 0 means the day prior to the current day,
              and 6 means 7 days prior to the current day.
            </t>
          </section>
        </section>

        <section title="Calendar day correlation" anchor="sec-use_per_dow_cc">
          <t>
            Clients who need to poll AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY or
            AFSVOL_TLV_TAG_VOL_STAT_USE_PER_DOW, and need to correlate this
            statistical data with specific calendar days SHOULD
            simultaneously query for the value stored at tag 
            AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY_DATE.   By querying these tags
            in the same RPC invocation, the caller will be able correlate the
            usage statistics with calendar days in a race-free manner.
            Querying AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY_DATE in a
            separate RPC invocation is not guarnteed to yield correct results,
            as there is no way to guarantee the value didn't change between the
            two RPC invocations.
          </t>
        </section>
      </section>
    </section>

    <section title="Extended volume state exportation" anchor="sec-tlv-dafs">
      <t>
        In addition to exporting the existing volser state, DAFS
        state metadata will also be exported via the TLV interface.
        Specifically, an extended volume state field, and a raw
        DAFS state debugging tag, will be exported.
      </t>

      <section title="Volume state explanations" anchor="sec-mapped_volume_states">
        <t>
          Given that volume state information is useful across 
          all server implementations, a collection of generic 
          state explanations shall be standardized.  These standardized
          enumeration values shall be published via a special volume 
          state explanation tag.  The following states are initially 
          defined in the namespace:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_VOL_STATE_EXPL_NONE">
              <vspace blankLines="1"/>
              No further explanation is deemed necessary.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_UNKNOWN">
              <vspace blankLines="1"/>
              This volume is in its current state for unknown
              reasons.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_OUT_OF_SERVICE">
              <vspace blankLines="1"/>
              This volume is administratively out of service. For 
              example, the IBM AFS and OpenAFS implementations both 
              permit an administrator to force a volume offline by 
              mutating the blessed or inService disk header bits.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_DELETED">
              <vspace blankLines="1"/>
              This volume no longer exists on-disk.  This record merely
              serves as a pointer to tell clients that the volume has
              been permanently deleted, or moved to a new location.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_READY">
              <vspace blankLines="1"/>
              This volume is ready to service requests.  If the
              primary volume state is offline, this means the
              volume is ready to be brought online as soon as
              a remote procedure call needs to access this volume.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_ATTACHING">
              <vspace blankLines="1"/>
              This volume is busy attaching.  Assuming the process completes
              successfully, the volume will be brought online.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_DETACHING">
              <vspace blankLines="1"/>
              This volume is busy detaching.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_BUSY">
              <vspace blankLines="1"/>
              This volume is busy performing some ancillary operation 
              which requires exclusive access.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_IO_BUSY">
              <vspace blankLines="1"/>
              This volume is busy performing an I/O operation which 
              requires exclusive access.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_SALVAGING">
              <vspace blankLines="1"/>
              This volume is currently being salvaged in the background.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_SALVAGE_NEEDED">
              <vspace blankLines="1"/>
              This volume is offline, and will require a salvage 
              before it can be brought online.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_ERROR">
              <vspace blankLines="1"/>
              This volume has been forced offline due to a 
              non-recoverable error. Manual intervention by an 
              administrator will be necessary to bring this volume 
              back to an operable state.
            </t>
            <t hangText="AFSVOL_VOL_STATE_EXPL_VOLUME_OPERATION">
              <vspace blankLines="1"/>
              This volume is currently offline because a volume 
              transaction requires exclusive access.
            </t>
          </list>
        </t>

        <figure align="center">
          <artwork><![CDATA[
enum AFSVol_vol_state_expl {
    AFSVOL_VOL_STATE_EXPL_NONE = 0,
    AFSVOL_VOL_STATE_EXPL_UNKNOWN = 1,
    AFSVOL_VOL_STATE_EXPL_OUT_OF_SERVICE = 2,
    AFSVOL_VOL_STATE_EXPL_DELETED = 3,
    AFSVOL_VOL_STATE_EXPL_READY = 4,
    AFSVOL_VOL_STATE_EXPL_ATTACHING = 5,
    AFSVOL_VOL_STATE_EXPL_DETACHING = 6,
    AFSVOL_VOL_STATE_EXPL_BUSY = 7,
    AFSVOL_VOL_STATE_EXPL_IO_BUSY = 8,
    AFSVOL_VOL_STATE_EXPL_SALVAGING = 9,
    AFSVOL_VOL_STATE_EXPL_SALVAGE_NEEDED = 10,
    AFSVOL_VOL_STATE_EXPL_ERROR = 11,
    AFSVOL_VOL_STATE_EXPL_VOLUME_OPERATION = 12
};
]]></artwork>
        <postamble>XDR definition of Volume State Enumeration</postamble>
        </figure>
      </section>

      <section title="Mapped process types" anchor="sec-mapped_process_types">
        <t>
          It is useful to be able to track volume ownership by 
          process type. In order to do this, a new program type 
          namespace must be defined. The following types are 
          initially defined in the program type namespace:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_PROGRAM_TYPE_NONE">
              <vspace blankLines="1"/>
              This value refers to the absence of a process.
            </t>
            <t hangText="AFSVOL_PROGRAM_TYPE_FILE_SERVER">
              <vspace blankLines="1"/>
              An afs file server process (Rx service ID 1).
            </t>
            <t hangText="AFSVOL_PROGRAM_TYPE_VOLUME_SERVER">
              <vspace blankLines="1"/>
              An afs volume server process (Rx service ID 4).
            </t>
            <t hangText="AFSVOL_PROGRAM_TYPE_SALVAGER">
              <vspace blankLines="1"/>
              An afs stand-alone salvager process.
            </t>
            <t hangText="AFSVOL_PROGRAM_TYPE_SALVAGE_SERVER">
              <vspace blankLines="1"/>
              An OpenAFS DAFS salvage server process.
            </t>
            <t hangText="AFSVOL_PROGRAM_TYPE_VOLUME_UTILITY">
              <vspace blankLines="1"/>
              Any ancillary stand-alone volume utility process.
            </t>
            <t hangText="AFSVOL_PROGRAM_TYPE_UNKNOWN">
              <vspace blankLines="1"/>
              This value refers to an unknown process type.
            </t>
          </list>
        </t>

        <figure align="center">
          <artwork><![CDATA[
enum AFSVol_program_type {
    AFSVOL_PROGRAM_TYPE_NONE = 0,
    AFSVOL_PROGRAM_TYPE_FILE_SERVER = 1,
    AFSVOL_PROGRAM_TYPE_VOLUME_SERVER = 2,
    AFSVOL_PROGRAM_TYPE_SALVAGER = 3,
    AFSVOL_PROGRAM_TYPE_SALVAGE_SERVER = 4,
    AFSVOL_PROGRAM_TYPE_VOLUME_UTILITY = 5,
    AFSVOL_PROGRAM_TYPE_UNKNOWN = 6
};
]]></artwork>
        <postamble>XDR definition of Program Type Enumeration</postamble>
        </figure>
      </section>

      <section title="TLV tuples">
        <t>
          Volume state will be exported via five new TLV tuples:
        </t>

        <t>
          <list style="hanging" hangIndent="4">
            <t hangText="AFSVOL_TLV_TAG_VOL_STATE_ONLINE">
              <vspace blankLines="1"/>
              This tuple MUST have payload of either type
              AFSVOL_TLV_TYPE_TRUE, or AFSVOL_TLV_TYPE_FALSE.
              This value SHALL tell the caller whether or not the volume
              is fully online.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STATE_AVAILABLE">
              <vspace blankLines="1"/>
              This tuple MUST have payload of either type
              AFSVOL_TLV_TYPE_TRUE, or AFSVOL_TLV_TYPE_FALSE.
              This tuple shall tell the caller whether or not the volume
              is available.  This SHOULD be asserted either when the
              volume is fully online, or when the volume can be brought
              online on-demand within a reasonable length of time following 
              receipt of an RPC call to Rx service id 1 requesting access 
              to the volume.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STATE_EXPL">
              <vspace blankLines="1"/>
              This tuple MUST have payload of type 
              AFSVOL_TLV_TYPE_UINT64. The u_u64 payload shall contain 
              a volume state explanation enumeration value, as defined in 
              <xref target="sec-mapped_volume_states"/>.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STATE_DAFS_RAW">
              <vspace blankLines="1"/>
              For servers exporting capability 
              AFSVOL_CAPABILITY_DAFS, this payload MUST be of type 
              AFSVOL_TLV_TYPE_OPAQUE. Encoding of raw state is 
              unspecified and implementation-private.
            </t>
            <t hangText="AFSVOL_TLV_TAG_VOL_STATE_OWNING_PROCESS">
              <vspace blankLines="1"/>
              This tag should only be advertised as available on server 
              implementations which support tracking volume ownership by 
              process type.  When available, this payload MUST be of type 
              AFSVOL_TLV_TYPE_UINT64. The u_u64 payload shall contain 
              a program type enumeration value, as defined in 
              <xref target="sec-mapped_process_types"/>.
            </t>
          </list>
        </t>
      </section>
    </section>

    <section title="AFS-3 Object Storage Extensions Policy Attributes" anchor="sec-tlv-osd">
      <t>
        RxOSD 
        <xref target="AFS-OSD08"/> <xref target="AFS-OSD09"/>
        requires two TLV tuples to encode new quota types:
      </t>

      <t>
        <list style="hanging" hangIndent="4">
          <t hangText="AFSVOL_TLV_TAG_VOL_QUOTA_BLOCKS_STORED_LOCALLY">
            <vspace blankLines="1"/>
            The value in this tuple defines the maximum allowable storage,
            in units of blocks, that may be stored on the local file server
            partition.  When storage is required beyond this limit, some data
            must be migrated to object storage devices (OSDs).  This tuple MUST
            have a payload of type AFSVOL_TLV_TYPE_DISK_BLOCKS.
          </t>

          <t hangText="AFSVOL_TLV_TAG_VOL_QUOTA_FILES">
            <vspace blankLines="1"/>
            The value in this tuple defines the maximum allowable file count
            for this volume.  This tuple MUST have a payload of type 
            AFSVOL_TLV_TYPE_UINT64.
          </t>
        </list>
      </t>
    </section>

    <section title="Backward Compatibility">
      <t>
        AFSVol services providing extended Tag-Length-Value RPCs MUST 
        provide backwards compatible interfaces to both legacy 
        clients and servers. Additionally, interoperability 
        between TLV versions must also be specified if they do 
        not comply with the following requirements:
      </t>

      <t>
        <list style="numbers">
          <t>
            AFSVol TLV servers replying to legacy AFSVol clients MUST 
            provide the identical response to an AFSVol server.
          </t>
          <t>
            AFSVol TLV clients communicating with AFSVol servers 
            MUST fall back to using non-TLV AFSVol RPCs. 
          </t>
          <t>
            AFSVol TLV clients to AFSVol TLV servers:

            <list style="letters">
              <t>
                Where capabilities match or the server can 
                provide capabilities including those which the 
                client requests, the server MUST reply with exactly 
                the capabilities requested.
              </t>
              <t>
                Where the client requests capabilities that the 
                server does not provide it MUST either return an
                'unknown tag' error code, or (OPTIONAL) fall back 
                to an non-TLV AFSVol response.
              </t>
            </list>
          </t>
        </list>
      </t>
    </section>

    <section anchor="Acknowledgements" title="Acknowledgements">
      <t>
        We would like to thank all of the participants at the 2009 Edinburgh AFS 
        hackathon for their input into the design of this TLV mechanism.  Alistair
        Ferguson has provided much useful feedback, especially with regard to backwards
        compatibility and discriminated union type identifier namespace allocations.
        Andrew Deason and Michael Meffie have provided considerable input with
        regard to the discriminated union XDR decoding problem, AFS registrar
        and namespace allocation concerns, what metadata should be exported in the
        initial revision, the notion of data qualifiers, as well as commentary about
        how they envision this extension being used to support future protocol
        extensions.  Derrick Brashear has provided helpful feedback with regard to
        restructuring the volume state reporting tags.  Thanks to Christof Hanke and Hartmut Reuter 
        for collaborating to make this memo compatible with their RxOSD protocol enhancments, 
        and, furthermore, for providing helpful feedback regarding the language in this draft.  
        Finally, special thanks to Jeffrey Hutzelman for providing
        considerable help with restructuring this memo to improve readability and limit
        its scope to something tractable.
      </t>
    </section>

    <!-- Possibly a 'Contributors' section ... -->

    <section title="IANA Considerations">
      <t>This memo includes no request to IANA.</t>
    </section>

    <section title="AFS Assign Numbers Registrar Considerations">
      <t>
        The AFS Assigned Numbers Registrar will need to consider 
        several assigned numbers requests.
      </t>

      <section title="Namespace allocations">
        <t>
          First and foremost, this memo requests that the AFS 
          Registrar assume control over several new registries:
        </t>

        <t>
          <list style="numbers">
            <t>AFSVol TLV payload type namespace</t>
            <t>AFSVol TLV tag namespace</t>
            <t>AFSVol TLV flag namespace</t>
            <t>AFSVol TLV Day-of-Week Stats flag namespace</t>
            <t>AFSVol Mapped Volume State namespace</t>
            <t>AFSVol Program Type namespace</t>
          </list>
        </t>

        <section title="AFSVol TLV Payloads">
          <t>
            This memo requests the allocation of a new registry with
            the formal name "AFSVol TLV Payloads".  This registry will
            be used to track allocations of enumeration values in the
            AFSVol_TLV_type XDR enum, and the mapping of these values 
            onto their respective XDR type definitions.  This is a 32-bit
            unsigned namespace.  Allocations can fall into one of a few
            categories:
          </t>

          <t>
            <figure align="center">
              <artwork><![CDATA[ 
Range            Description
-----            -----------
0 to 0xfeffffff  - AFS-STDS Early Assignment
0xff000000       - Private Assignment
 to 0xfffeffff
0xffff0000       - reserved
 to 0xffffffff
              ]]></artwork>
              <postamble>Subdivision into allocation policy regions</postamble>
            </figure>
          </t>

          <t>
            In the table above, "AFS-STDS Early Assignment" refers to the 
            allocation policy described in <xref target="I-D.wilkinson-afs3-standardisation"/>;
            "Private Assignment", and "Reserved" are as-described in 
            <xref target="RFC5226"/>.
          </t>

          <t>
            Allocation requests for the "AFS-STDS Early Assignment" region MUST
            contain the following information:
          </t>

          <t>
            <list style="symbols">
              <t>type name</t>
              <t>RFC section reference to definition of data encoding associated with this type enumeration value</t>
            </list>
          </t>

          <t>
            In addition, an "AFS-STDS Early Assignment" allocation request MAY include the following 
            optional elements:
          </t>

          <t>
            <list style="symbols">
              <t>type description</t>
              <t>desired value in AFSVol_TLV_type enumeration</t>
              <t>RFC section reference to discussion regarding backwards compatibility</t>
              <t>RFC section reference to relevant security considerations</t>
            </list>
          </t>
        </section>

        <section title="AFSVol TLV Tags">
          <t>
            This memo requests the allocation of a new registry with
            the formal name "AFSVol TLV Tags".  This registry will
            be used to track allocations of enumeration values in the
            AFSVol_TLV_tag XDR enum, and the mapping of these values 
            onto legal tags and qualifiers.  This is a 32-bit
            unsigned namespace.  Allocations can fall into one of a few
            categories:
          </t>

          <figure align="center">
            <artwork><![CDATA[ 
Range            Description
-----            -----------
0 to 0xfeffffff  - AFS-STDS Early Assignment
0xff000000       - Private Assignment
 to 0xfffeffff
0xffff0000       - reserved
 to 0xffffffff
            ]]></artwork>
            <postamble>Subdivision into allocation policy regions</postamble>
          </figure>

          <t>
            In the table above, "AFS-STDS Early Assignment" refers to the 
            allocation policy described in <xref target="I-D.wilkinson-afs3-standardisation"/>;
            "Private Assignment", and "Reserved" are as-described in 
            <xref target="RFC5226"/>.
          </t>

          <t>
            Allocation requests for the "AFS-STDS Early Assignment" region MUST
            contain the following information:
          </t>

          <t>
            <list style="symbols">
              <t>tag name</t>
              <t>RFC section reference to definition of tag semantics</t>
            </list>
          </t>

          <t>
            In addition, an "AFS-STDS Early Assignment" allocation request MAY include the following 
            optional elements:
          </t>

          <t>
            <list style="symbols">
              <t>tag description</t>
              <t>desired value in AFSVol_TLV_tag enumeration</t>
              <t>RFC section reference to definition of qualifier semantics for this tag</t>
              <t>RFC section reference to discussion regarding backwards compatibility</t>
              <t>RFC section reference to relevant security considerations</t>
            </list>
          </t>
        </section>

        <section title="AFSVol TLV Flags">
          <t>
            This memo requests the allocation of a new registry with
            the formal name "AFSVol TLV Flags".  This registry will
            be used to track allocations of flag bits in the
            AFSVol_TLV.tlv_flags field.  This is a 32-bit
            flag namespace.  All flag bit allocations shall fall under
            the "AFS-STDS Early Assignment" allocation policy, as 
            described in <xref target="I-D.wilkinson-afs3-standardisation"/>.
            Flag bit allocation requests MUST contain the following information:
          </t>

          <t>
            <list style="symbols">
              <t>flag name</t>
              <t>RFC section reference to definition of flag semantics</t>
            </list>
          </t>

          <t>
            In addition, an allocation request MAY include the following 
            optional elements:
          </t>

          <t>
            <list style="symbols">
              <t>flag description</t>
              <t>desired flag bit value</t>
              <t>RFC section reference to discussion regarding backwards compatibility</t>
              <t>RFC section reference to relevant security considerations</t>
            </list>
          </t>
        </section>

        <section title="AFSVol DoW Stats Flags">
          <t>
            This memo requests the allocation of a new registry with
            the formal name "AFSVol DoW Stats Flags".  This registry will
            be used to track allocations of flag bits in the
            AFSVol_stat_use_per_dow.stat_flags field.  This is a 32-bit
            flag namespace.  All flag bit allocations shall fall under
            the "AFS-STDS Early Assignment" allocation policy, as 
            described in <xref target="I-D.wilkinson-afs3-standardisation"/>.
            Flag bit allocation requests MUST contain the following information:
          </t>

          <t>
            <list style="symbols">
              <t>flag name</t>
              <t>RFC section reference to definition of flag semantics</t>
            </list>
          </t>

          <t>
            In addition, an allocation request MAY include the following 
            optional elements:
          </t>

          <t>
            <list style="symbols">
              <t>flag description</t>
              <t>desired flag bit value</t>
              <t>RFC section reference to discussion regarding backwards compatibility</t>
              <t>RFC section reference to relevant security considerations</t>
            </list>
          </t>
        </section>

        <section title="AFSVol Vol State Expls">
          <t>
            This memo requests the allocation of a new registry with
            the formal name "AFSVol Vol State Expls".  This registry will
            be used to track allocations of enumeration values in the
            AFSVol_vol_state_expl enum (see <xref target="sec-mapped_volume_states"/>). 
            This is a 32-bit unsigned namespace.  Allocations can fall into one of a few
            categories:
          </t>

          <t>
            <figure align="center">
              <artwork><![CDATA[ 
Range            Description
-----            -----------
0 to 0xfeffffff  - AFS-STDS Early Assignment
0xff000000       - Private Assignment
 to 0xffffffff
              ]]></artwork>
              <postamble>Subdivision into allocation policy regions</postamble>
            </figure>
          </t>

          <t>
            In the table above, "AFS-STDS Early Assignment" refers to the 
            allocation policy described in <xref target="I-D.wilkinson-afs3-standardisation"/>;
            "Private Assignment" is as-described in 
            <xref target="RFC5226"/>.
          </t>

          <t>
            Allocation requests for the "AFS-STDS Early Assignment" region MUST
            contain the following information:
          </t>

          <t>
            <list style="symbols">
              <t>state name</t>
              <t>RFC section reference to definition of this volume state enumeration value</t>
            </list>
          </t>

          <t>
            In addition, an "AFS-STDS Early Assignment" allocation request MAY include the following 
            optional elements:
          </t>

          <t>
            <list style="symbols">
              <t>state description</t>
              <t>desired value in AFSVol_vol_state_expl enumeration</t>
              <t>RFC section reference to discussion regarding backwards compatibility</t>
              <t>RFC section reference to relevant security considerations</t>
            </list>
          </t>
        </section>

        <section title="AFSVol Program Types">
          <t>
            This memo requests the allocation of a new registry with
            the formal name "AFSVol Program Types".  This registry will
            be used to track allocations of enumeration values in the
            AFSVol_program_type enum (see <xref target="sec-mapped_process_types"/>). 
            This is a 32-bit unsigned namespace.  Allocations can fall into one of a few
            categories:
          </t>

          <t>
            <figure align="center">
              <artwork><![CDATA[ 
Range            Description
-----            -----------
0 to 0xfeffffff  - AFS-STDS Early Assignment
0xff000000       - Private Assignment
 to 0xffffffff
              ]]></artwork>
              <postamble>Subdivision into allocation policy regions</postamble>
            </figure>
          </t>

          <t>
            In the table above, "AFS-STDS Early Assignment" refers to the 
            allocation policy described in <xref target="I-D.wilkinson-afs3-standardisation"/>;
            "Private Assignment" is as-described in 
            <xref target="RFC5226"/>.
          </t>

          <t>
            Allocation requests for the "AFS-STDS Early Assignment" region MUST
            contain the following information:
          </t>

          <t>
            <list style="symbols">
              <t>program name</t>
              <t>RFC section reference to definition of this program type enumeration value</t>
            </list>
          </t>

          <t>
            In addition, an "AFS-STDS Early Assignment" allocation request MAY include the following 
            optional elements:
          </t>

          <t>
            <list style="symbols">
              <t>program description</t>
              <t>desired value in AFSVol_program_type enumeration</t>
              <t>RFC section reference to discussion regarding backwards compatibility</t>
              <t>RFC section reference to relevant security considerations</t>
            </list>
          </t>
        </section>
      </section>

      <section title="Assigned numbers allocations">
        <t>
          In addition to requesting the allocation of new 
          registries, this memo also requests several new 
          allocations within existing assigned numbers 
          registries. 
        </t>

        <section title="VICED Capability bits">
          <t>
            One new capability bit is requested:

            <list style="symbols"><t>VICED_CAPABILITY_DAFS (see <xref target="sec-cap-new"/>)</t></list>

          </t>
        </section>

        <section title="AFSVol Capabilities">
          <t>
            The following allocations are requested in the "AFSVol Capabilites" registry
            <xref target="I-D.keiser-afs3-capabilities"/>:

            <list style="symbols">
              <t>AFSVOL_CAPABILITY_DAFS = 0x1 (see <xref target="sec-cap-new"/>)</t>
              <t>AFSVOL_CAPABILITY_TLV = 0x2 (see <xref target="sec-cap-new"/>)</t>
            </list>
          </t>
        </section>

        <section title="AFSVol TLV Payloads">
          <t>
            The following initial allocations are requested in the newly-created registry "AFSVol TLV Payloads":
          </t>

          <t>
            <list style="symbols">
              <t>AFSVOL_TLV_TYPE_NULL = 0 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_TRUE = 1 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_FALSE = 2 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_UINT64 = 3 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_UINT64_VEC = 4 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_INT64 = 5 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_INT64_VEC = 6 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_UUID = 7 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_STRING = 8 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_TIME_ABS = 9 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_TIME_ABS_VEC = 10 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_TIME_REL = 11 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_TIME_REL_VEC = 12 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_VOL_ID = 13 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_VOL_ID_VEC = 14 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_PART_ID = 15 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_PART_ID_VEC = 16 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_DISK_BLOCKS = 17 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_STAT_COUNTER = 18 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_STAT_GAUGE = 19 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_BIT64 = 20 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_VOL_DOW_USE = 21 (see <xref target="sec-tlv-types"/>)</t>
              <t>AFSVOL_TLV_TYPE_OPAQUE = 22 (see <xref target="sec-tlv-types"/>)</t>
            </list>
          </t>
        </section>

        <section title="AFSVol TLV Tags">
          <t>
            The following initial allocations are requested in the newly-created registry "AFSVol TLV Tags":
          </t>

          <t>
            <list style="symbols">
              <t>AFSVOL_TLV_TAG_EOS = 0 (see <xref target="sec-tlv-split"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_NAME = 1 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STATUS = 2 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_IN_USE = 3 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_ID = 4 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TYPE = 5 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_CLONE_ID = 6 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_BACKUP_ID = 7 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_PARENT_ID = 8 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_COPY_DATE = 9 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_CREATE_DATE = 10 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_ACCESS_DATE = 11 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_UPDATE_DATE = 12 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_BACKUP_DATE = 13 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_SIZE = 14 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_FILE_COUNT = 15 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_QUOTA_BLOCKS = 16 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY = 17 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_USE_PER_DOW = 18 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_READS = 19 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_WRITES = 20 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_FILE_SAME_AUTHOR = 21 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_FILE_DIFFERENT_AUTHOR = 22 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_DIR_SAME_AUTHOR = 23 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_DIR_DIFFERENT_AUTHOR = 24 (see <xref target="sec-tlv-volintXInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_ID = 25 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_TIME = 26 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_CREATE_TIME = 27 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_RETURN_CODE = 28 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_ATTACH_MODE = 29 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_STATUS = 30 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_FLAGS = 31 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_LAST_PROC_NAME = 32 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_CALL_VALID = 33 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_READ_NEXT = 34 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_XMIT_NEXT = 35 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_LAST_RECV_TIME = 36 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_TRANS_LAST_SEND_TIME = 37 (see <xref target="sec-tlv-transDebugInfo"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_IN_SERVICE = 38 (see <xref target="sec-tlv-de_facto"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_BLESSED = 39 (see <xref target="sec-tlv-de_facto"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_RESTORED_FROM_ID = 40 (see <xref target="sec-tlv-de_facto"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_DESTROYED = 41 (see <xref target="sec-tlv-de_facto"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_NEEDS_SALVAGE = 42 (see <xref target="sec-tlv-de_facto"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_OFFLINE_MESSAGE = 43 (see <xref target="sec-tlv-de_facto"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_EXPIRATION_DATE = 44 (see <xref target="sec-tlv-de_facto"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_QUOTA_RESERVATION = 45 (see <xref target="sec-tlv-de_facto"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY_DATE = 46 (see <xref target="sec-tlv-de_facto"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STATE_ONLINE = 47 (see <xref target="sec-tlv-dafs"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STATE_AVAILABLE = 48 (see <xref target="sec-tlv-dafs"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STATE_EXPL = 49 (see <xref target="sec-tlv-dafs"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STATE_DAFS_RAW = 50 (see <xref target="sec-tlv-dafs"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_STATE_OWNING_PROCESS = 51 (see <xref target="sec-tlv-dafs"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_QUOTA_BLOCKS_STORED_LOCALLY = 52 (see <xref target="sec-tlv-osd"/>)</t>
              <t>AFSVOL_TLV_TAG_VOL_QUOTA_FILES = 53 (see <xref target="sec-tlv-osd"/>)</t>
            </list>
          </t>
        </section>

        <section title="AFSVol TLV Flags">
          <t>
            The following initial allocations are requested within the newly-created registry "AFSVol TLV Flags":
          </t>

          <t>
            <list style="symbols">
              <t>AFSVOL_TLV_FLAG_UNSUPPORTED = 0x1 (see <xref target="sec-tlv-flags"/>)</t>
              <t>AFSVOL_TLV_FLAG_READ_ERROR = 0x2 (see <xref target="sec-tlv-flags"/>)</t>
              <t>AFSVOL_TLV_FLAG_CRITICAL = 0x4 (see <xref target="sec-tlv-flags"/>)</t>
              <t>AFSVOL_TLV_FLAG_QUALIFIER_NO_MATCH = 0x8 (see <xref target="sec-tlv-flags"/>)</t>
              <t>AFSVOL_TLV_FLAG_MORE = 0x10 (see <xref target="sec-tlv-flags"/>)</t>
              <t>AFSVOL_TLV_FLAG_OBJ_NOT_SUPP = 0x20 (see <xref target="sec-tlv-flags"/>)</t>
            </list>
          </t>
        </section>

        <section title="AFSVol DoW Stats Flags">
          <t>
            The following initial allocations are requested within the newly-created registry "AFSVol DoW Stats Flags":
          </t>

          <t>
            <list style="symbols">
              <t>AFSVOL_VOL_STAT_DOW0_VALID = 0x1 (see <xref target="sec-use_per_dow"/>)</t>
              <t>AFSVOL_VOL_STAT_DOW1_VALID = 0x2 (see <xref target="sec-use_per_dow"/>)</t>
              <t>AFSVOL_VOL_STAT_DOW2_VALID = 0x4 (see <xref target="sec-use_per_dow"/>)</t>
              <t>AFSVOL_VOL_STAT_DOW3_VALID = 0x8 (see <xref target="sec-use_per_dow"/>)</t>
              <t>AFSVOL_VOL_STAT_DOW4_VALID = 0x10 (see <xref target="sec-use_per_dow"/>)</t>
              <t>AFSVOL_VOL_STAT_DOW5_VALID = 0x20 (see <xref target="sec-use_per_dow"/>)</t>
              <t>AFSVOL_VOL_STAT_DOW6_VALID = 0x40 (see <xref target="sec-use_per_dow"/>)</t>
              <t>AFSVOL_VOL_STAT_DOW_FUZZY = 0x80 (see <xref target="sec-use_per_dow"/>)</t>
            </list>
          </t>
        </section>

        <section title="VOLS Error Table">
          <t>
            Within the VOLS error table (offset 1492325120), 
            several new codes need to be allocated: 
          </t>

          <t>
            <list style="symbols">
              <t>VOLSER_TAG_UNSUPPORTED</t>
              <t>VOLSER_TAG_READ_ONLY</t>
              <t>VOLSER_TAG_WRITE_FAILED</t>
              <t>VOLSER_TAG_DECODE_FAILED</t>
              <t>VOLSER_TAG_UNSUPPORTED_ENCODING</t>
              <t>VOLSER_TLV_QUALIFIER_UNSUPPORTED_ENCODING</t>
              <t>VOLSER_TLV_QUALIFIER_DECODE_FAILED</t>
              <t>VOLSER_TLV_QUALIFIER_INVALID</t>
              <t>VOLSER_TRANS_INVALID</t>
            </list>
          </t>
        </section>

        <section title="AFSVol Vol State Expls">
          <t>
            The following initial allocations are requested within the newly-created registry "AFSVol Vol State Expls":
          </t>

          <t>
            <list style="symbols">
              <t>AFSVOL_VOL_STATE_EXPL_NONE = 0 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_UNKNOWN = 1 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_OUT_OF_SERVICE = 2 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_DELETED = 3 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_READY = 4 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_ATTACHING = 5 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_DETACHING = 6 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_BUSY = 7 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_IO_BUSY = 8 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_SALVAGING = 9 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_SALVAGE_NEEDED = 10 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_ERROR = 11 (see <xref target="sec-mapped_volume_states"/>)</t>
              <t>AFSVOL_VOL_STATE_EXPL_VOLUME_OPERATION = 12 (see <xref target="sec-mapped_volume_states"/>)</t>
            </list>
          </t>
        </section>

        <section title="AFSVol Program Types">
          <t>
            Within the new AFS program type namespace, the 
            following allocations are requested:
          </t>

          <t>
            <list style="symbols">
              <t>AFSVOL_PROGRAM_TYPE_NONE = 0 (see <xref target="sec-mapped_process_types"/>)</t>
              <t>AFSVOL_PROGRAM_TYPE_FILE_SERVER = 1 (see <xref target="sec-mapped_process_types"/>)</t>
              <t>AFSVOL_PROGRAM_TYPE_VOLUME_SERVER = 2 (see <xref target="sec-mapped_process_types"/>)</t>
              <t>AFSVOL_PROGRAM_TYPE_SALVAGER = 3 (see <xref target="sec-mapped_process_types"/>)</t>
              <t>AFSVOL_PROGRAM_TYPE_SALVAGE_SERVER = 4 (see <xref target="sec-mapped_process_types"/>)</t>
              <t>AFSVOL_PROGRAM_TYPE_VOLUME_UTILITY = 5 (see <xref target="sec-mapped_process_types"/>)</t>
              <t>AFSVOL_PROGRAM_TYPE_UNKNOWN = 6 (see <xref target="sec-mapped_process_types"/>)</t>
            </list>
          </t>
        </section>
      </section>
    </section>

    <section anchor="Security" title="Security Considerations">
      <t>
        Security and authorization issues are tag-specific.  Most known
        implementations of the legacy AFSVol RPCs permitted rxnull
        connections to perform the four ListVolume RPCs, and AFSVolMonitor.
        Arguably, it is time to re-evaluate this decision, and subsequently
        restrict access to some tags, as they do permit potentially sensitive
        volume--or operational--metadata to leak onto public networks.
      </t>
    </section>
  </middle>

  <!-- BACK MATTER -->

  <back>

    <references title="Normative References">
      &RFC2119;
      &RFC5226;
      &I-D.deason-afs3-type-time;
      &I-D.keiser-afs3-capabilities;
      &I-D.keiser-afs3-xdr-union;
      &I-D.keiser-afs3-xdr-primitive-types;
      &I-D.wilkinson-afs3-standardisation;
    </references>

    <references title="Informative References">
      &RFC4506;
      &RFC5531;
            <reference anchor="CMU-ITC-84-020">
        <front>
          <title>VICE File System Services</title>

          <author initials="M.J." surname="West" fullname="MJ West">
            <organization abbrev="CMU-ITC">Carnegie Mellon University Information Technology Center</organization>
          </author>

          <date year="1984" month="August" day="7" />
        </front>
        <seriesInfo name="CMU ITC Tech. Rep." value="CMU-ITC-84-020" />
      </reference>

            <reference anchor="CMU-ITC-83-025">
        <front>
          <title>The Information Technology Center</title>

          <author initials="J.H." surname="Morris" fullname="James H. Morris">
            <organization abbrev="CMU">Carnegie Mellon University</organization>
          </author>
          <author initials="D." surname="Van Houweling" fullname="Douglas Van Houweling">
            <organization abbrev="CMU">Carnegie Mellon University</organization>
          </author>
          <author initials="K." surname="Slack" fullname="Keith Slack">
            <organization abbrev="IBM">International Business Machines Corporation</organization>
          </author>

          <date year="1983"/>
        </front>
        <seriesInfo name="CMU ITC Tech. Rep." value="CMU-ITC-83-025" />
      </reference>

            <reference anchor="CMU-ITC-88-070">
        <front>
          <title>Design and Specification of the Cellular Andrew Environment</title>

          <author initials="E.R." surname="Zayas" fullname="Edward R. Zayas">
            <organization abbrev="CMU-ITC">Carnegie Mellon University Information Technology Center</organization>
          </author>
          <author initials="C.F." surname="Everhart" fullname="Craig F. Everhart">
            <organization abbrev="CMU-ITC">Carnegie Mellon University Information Technology Center</organization>
          </author>

          <date year="1988" month="August" day="2" />
        </front>
        <seriesInfo name="CMU ITC Tech. Rep." value="CMU-ITC-88-070" />
      </reference>

            <reference anchor="CMU-ITC-85-039">
        <front>
          <title>The ITC Distributed File System: Principles and Design</title>

          <author initials="M." surname="Satyanarayanan" fullname="M. Satyanarayanan">
            <organization abbrev="CMU-ITC">Carnegie Mellon University Information Technology Center</organization>
          </author>
          <author initials="J.H." surname="Howard" fullname="John H. Howard">
            <organization abbrev="CMU-ITC">Carnegie Mellon University Information Technology Center</organization>
          </author>
          <author initials="D.A." surname="Nichols" fullname="David A. Nichols">
            <organization abbrev="CMU-ITC">Carnegie Mellon University Information Technology Center</organization>
          </author>
          <author initials="R.N." surname="Sidebotham" fullname="Robert N. Sidebotham">
            <organization abbrev="CMU-ITC">Carnegie Mellon University Information Technology Center</organization>
          </author>
          <author initials="A.Z." surname="Spector" fullname="Alfred Z. Spector">
            <organization abbrev="CMU-ITC">Carnegie Mellon University Information Technology Center</organization>
          </author>
          <author initials="M.J." surname="West" fullname="Michael J. West">
            <organization abbrev="CMU-ITC">Carnegie Mellon University Information Technology Center</organization>
          </author>

          <date year="1985" month="December"/>
        </front>
        <seriesInfo name="Proc. 10th ACM Symp. Operating Sys. Princ." value="Vol. 19, No. 5" />
      </reference>

            <reference anchor="CMU-ITC-88-062">
        <front>
          <title>An Overview of the Andrew File System"</title>

          <author initials="J.H." surname="Howard" fullname="John H. Howard">
            <organization abbrev="CMU-ITC">Carnegie Mellon University Information Technology Center</organization>
          </author>

          <date year="1988" month="February" />
        </front>
        <seriesInfo name="Proc. 1988 USENIX Winter Tech. Conf." value="pp. 23-26" />
      </reference>

            <reference anchor="CMU-ITC-87-068">
        <front>
          <title>Scale and Performance in a Distributed File System</title>

          <author initials="J.H." surname="Howard" fullname="John H. Howard">
            <organization abbrev="CMU">Carnegie Mellon University</organization>
          </author>
          <author initials="M.L." surname="Kazar" fullname="Michael L. Kazar">
            <organization abbrev="CMU">Carnegie Mellon University</organization>
          </author>
          <author initials="S.G." surname="Menees" fullname="Sherri G. Menees">
            <organization abbrev="CMU">Carnegie Mellon University</organization>
          </author>
          <author initials="D.A." surname="Nichols" fullname="David A. Nichols">
            <organization abbrev="CMU">Carnegie Mellon University</organization>
          </author>
          <author initials="M." surname="Satyanarayanan" fullname="M. Satyanarayanan">
            <organization abbrev="CMU">Carnegie Mellon University</organization>
          </author>
          <author initials="R.N." surname="Sidebotham" fullname="Robert N. Sidebotham">
            <organization abbrev="CMU">Carnegie Mellon University</organization>
          </author>
          <author initials="M.J." surname="West" fullname="Michael J. West">
            <organization abbrev="CMU">Carnegie Mellon University</organization>
          </author>

          <date year="1988" month="February" />
        </front>
        <seriesInfo name="ACM Trans. Comp. Sys." value="Vol. 6, No. 1, pp. 51-81" />
      </reference>

            <reference anchor="AFS3-RX">
        <front>
          <title>AFS-3 Programmer's Reference: Specification for the Rx Remote Procedure Call Facility</title>

          <author initials="E.R." surname="Zayas" fullname="Edward R. Zayas">
            <organization abbrev="Transarc">Transarc Corporation</organization>
          </author>

          <date year="1991" month="August" day="28" />
        </front>
        <seriesInfo name="Transarc Corp. Tech. Rep." value="FS-00-D164" />
      </reference>

            <reference anchor="AFS3-VVL">
        <front>
          <title>AFS-3 Programmer's Reference: Volume Server/Volume Location Server Interface</title>

          <author initials="E.R." surname="Zayas" fullname="Edward R. Zayas">
            <organization abbrev="Transarc">Transarc Corporation</organization>
          </author>

          <date year="1991" month="August" day="29" />
        </front>
        <seriesInfo name="Transarc Corp. Tech. Rep." value="FS-00-D165" />
      </reference>

            <reference anchor="DAFS" target="http://workshop.openafs.org/afsbpw06/talks/tkeiser-dafs.pdf">
        <front>
          <title>Demand Attach / Fast-restart File Server</title>

          <author initials="T.E." surname="Keiser" fullname="Thomas E. Keiser">
            <organization abbrev="Sine Nomine">Sine Nomine Associates</organization>
          </author>

          <date year="2006" month="June" day="16" />
        </front>
        <seriesInfo name="AFS and Kerberos Best Practices Workshop" value="2006" />
      </reference>

            <reference anchor="AFS-OSD08" target="http://workshop.openafs.org/afsbpw08/talks/thu_3/OpenAFS+ObjectStorage.pdf">
        <front>
          <title>AFS + Object Storage</title>

          <author initials="R." surname="Tobbicke" fullname="Rainer Tobbicke">
            <organization abbrev="CERN">European Organization for Nuclear Research</organization>
          </author>
          <author initials="A." surname="Maslennikov" fullname="Andrei Maslennikov">
            <organization abbrev="CASPUR">Consorzio interuniversitario per le Applicazioni di Supercalcolo Per Universita e Ricerca</organization>
          </author>
          <author initials="L." surname="Giammarino" fullname="Ludovico Giammarino">
            <organization abbrev="CASPUR">Consorzio interuniversitario per le Applicazioni di Supercalcolo Per Universita e Ricerca</organization>
          </author>
          <author initials="R." surname="Belloni" fullname="Roberto Belloni">
            <organization abbrev="CASPUR">Consorzio interuniversitario per le Applicazioni di Supercalcolo Per Universita e Ricerca</organization>
          </author>
          <author initials="H." surname="Reuter" fullname="Hartmut Reuter">
            <organization abbrev="RZG">Rechenzentrum Garching, Max Planck Institute for Plasmaphysics</organization>
          </author>

          <date year="2008" month="May" day="22" />
        </front>
        <seriesInfo name="AFS and Kerberos Best Practices Workshop" value="2008" />
      </reference>

            <reference anchor="AFS-OSD09" target="http://workshop.openafs.org/afsbpw09/talks/thu_2/Embedded_filesystems_opt.pdf">
        <front>
          <title>Embedded Filesystems (Direct Client Access to Vice Partitions)</title>

          <author initials="H." surname="Reuter" fullname="Hartmut Reuter">
            <organization abbrev="RZG">Rechenzentrum Garching, Max Planck Institute for Plasmaphysics</organization>
          </author>
          <author initials="F." surname="Frank" fullname="Felix Frank">
            <organization abbrev="DESY">Deutsches Elektronen Synchrotron</organization>
          </author>
          <author initials="A." surname="Maslennikov" fullname="Andrei Maslennikov">
            <organization abbrev="CASPUR">Consorzio interuniversitario per le Applicazioni di Supercalcolo Per Universita e Ricerca</organization>
          </author>

          <date year="2009" month="June" day="4" />
        </front>
        <seriesInfo name="AFS and Kerberos Best Practices Workshop" value="2009" />
      </reference>

    </references>


    <section anchor="app-tlv-xdr" title="Sample Rx RPC-L Definition for AFSVol TLV Mechanism">
      <figure align="left" anchor="afsvol-tlv-xdr">
        <artwork><![CDATA[
const AFSVOL_TLV_TAG_MAX = 1024;         /* upper-bound on number of
                                          * TLV tuples per RPC */
const AFSVOL_TLV_OPAQUE_MAX = 262144;    /* upper-bound on size of
                                          * value payload */
const AFSVOL_TLV_UINT64_MAX = 32768;     /* upper-bound on length of
                                            uint64 vector payload */
const AFSVOL_TLV_TIME_MAX = 21845;       /* upper-bound on length of
                                            AFSTime vector payload */
const AFSVOL_BULK_GETVOLUME_MAX = 1024;  /* upper-bound on 
                                          * (partition, volume) 
                                          * tuples per RPC */

const AFSVOL_TLV_FLAG_UNSUPPORTED = 0x1;
const AFSVOL_TLV_FLAG_READ_ERROR = 0x2;
const AFSVOL_TLV_FLAG_CRITICAL = 0x4;
const AFSVOL_TLV_FLAG_QUALIFIER_NO_MATCH = 0x8;
const AFSVOL_TLV_FLAG_MORE = 0x10;
const AFSVOL_TLV_FLAG_OBJ_NOT_SUPP = 0x20;

enum AFSVol_TLV_type {
    AFSVOL_TLV_TYPE_NULL          = 0,
    AFSVOL_TLV_TYPE_TRUE          = 1,
    AFSVOL_TLV_TYPE_FALSE         = 2,
    AFSVOL_TLV_TYPE_UINT64        = 3,
    AFSVOL_TLV_TYPE_UINT64_VEC    = 4,
    AFSVOL_TLV_TYPE_INT64         = 5,
    AFSVOL_TLV_TYPE_INT64_VEC     = 6,
    AFSVOL_TLV_TYPE_UUID          = 7,
    AFSVOL_TLV_TYPE_STRING        = 8,
    AFSVOL_TLV_TYPE_TIME_ABS      = 9,
    AFSVOL_TLV_TYPE_TIME_ABS_VEC  = 10,
    AFSVOL_TLV_TYPE_TIME_REL      = 11,
    AFSVOL_TLV_TYPE_TIME_REL_VEC  = 12,
    AFSVOL_TLV_TYPE_VOL_ID        = 13,
    AFSVOL_TLV_TYPE_VOL_ID_VEC    = 14,
    AFSVOL_TLV_TYPE_PART_ID       = 15,
    AFSVOL_TLV_TYPE_PART_ID_VEC   = 16,
    AFSVOL_TLV_TYPE_DISK_BLOCKS   = 17,
    AFSVOL_TLV_TYPE_STAT_COUNTER  = 18,
    AFSVOL_TLV_TYPE_STAT_GAUGE    = 19,
    AFSVOL_TLV_TYPE_BIT64         = 20,
    AFSVOL_TLV_TYPE_VOL_DOW_USE   = 21,
    AFSVOL_TLV_TYPE_OPAQUE        = 22
};

const AFSVOL_VOL_STAT_DOW0_VALID = 0x1;
const AFSVOL_VOL_STAT_DOW1_VALID = 0x2;
const AFSVOL_VOL_STAT_DOW2_VALID = 0x4;
const AFSVOL_VOL_STAT_DOW3_VALID = 0x8;
const AFSVOL_VOL_STAT_DOW4_VALID = 0x10;
const AFSVOL_VOL_STAT_DOW5_VALID = 0x20;
const AFSVOL_VOL_STAT_DOW6_VALID = 0x40;
const AFSVOL_VOL_STAT_DOW_FUZZY  = 0x80;

struct AFSVol_stat_use_per_dow {
    afs_uint64 stat_dow[7];
    afs_uint32 stat_flags;
};

enum AFSVol_vol_state_expl {
    AFSVOL_VOL_STATE_EXPL_NONE = 0,
    AFSVOL_VOL_STATE_EXPL_UNKNOWN = 1,
    AFSVOL_VOL_STATE_EXPL_OUT_OF_SERVICE = 2,
    AFSVOL_VOL_STATE_EXPL_DELETED = 3,
    AFSVOL_VOL_STATE_EXPL_READY = 4,
    AFSVOL_VOL_STATE_EXPL_ATTACHING = 5,
    AFSVOL_VOL_STATE_EXPL_DETACHING = 6,
    AFSVOL_VOL_STATE_EXPL_BUSY = 7,
    AFSVOL_VOL_STATE_EXPL_IO_BUSY = 8,
    AFSVOL_VOL_STATE_EXPL_SALVAGING = 9,
    AFSVOL_VOL_STATE_EXPL_SALVAGE_NEEDED = 10,
    AFSVOL_VOL_STATE_EXPL_ERROR = 11,
    AFSVOL_VOL_STATE_EXPL_VOLUME_OPERATION = 12
};

enum AFSVol_program_type {
    AFSVOL_PROGRAM_TYPE_NONE = 0,
    AFSVOL_PROGRAM_TYPE_FILE_SERVER = 1,
    AFSVOL_PROGRAM_TYPE_VOLUME_SERVER = 2,
    AFSVOL_PROGRAM_TYPE_SALVAGER = 3,
    AFSVOL_PROGRAM_TYPE_SALVAGE_SERVER = 4,
    AFSVOL_PROGRAM_TYPE_VOLUME_UTILITY = 5,
    AFSVOL_PROGRAM_TYPE_UNKNOWN = 6
};

ext-union AFSVol_TLV_value switch(AFSVol_TLV_type type) {
 case AFSVOL_TLV_TYPE_NULL:
    void;

 case AFSVOL_TLV_TYPE_TRUE:
    void;

 case AFSVOL_TLV_TYPE_FALSE:
    void;

 case AFSVOL_TLV_TYPE_UINT64:
    afs_uint64 u_u64;

 case AFSVOL_TLV_TYPE_VOL_ID:
    afs_uint64 u_vol_id;

 case AFSVOL_TLV_TYPE_PART_ID:
    afs_uint64 u_part_id;

 case AFSVOL_TLV_TYPE_DISK_BLOCKS:
    afs_uint64 u_disk_blocks;

 case AFSVOL_TLV_TYPE_STAT_COUNTER:
    afs_uint64 u_stat_counter;

 case AFSVOL_TLV_TYPE_BIT64:
    afs_uint64 u_bit64;

 case AFSVOL_TLV_TYPE_INT64:
    afs_int64 u_s64;

 case AFSVOL_TLV_TYPE_STAT_GAUGE:
    afs_int64 u_stat_gauge;

 case AFSVOL_TLV_TYPE_UINT64_VEC:
    afs_uint64 u_u64_vec<AFSVOL_TLV_UINT64_MAX>;

 case AFSVOL_TLV_TYPE_VOL_ID_VEC:
    afs_uint64 u_vol_id_vec<AFSVOL_TLV_UINT64_MAX>;

 case AFSVOL_TLV_TYPE_PART_ID_VEC:
    afs_uint64 u_part_id_vec<AFSVOL_TLV_UINT64_MAX>;

 case AFSVOL_TLV_TYPE_INT64_VEC:
    afs_int64 u_s64_vec<AFSVOL_TLV_UINT64_MAX>;

 case AFSVOL_TLV_TYPE_TIME_ABS:
    AFSTime u_time_abs;

 case AFSVOL_TLV_TYPE_TIME_REL:
    AFSRelTimestamp u_time_rel;

 case AFSVOL_TLV_TYPE_TIME_ABS_VEC:
    AFSTime u_time_abs_vec<AFSVOL_TLV_TIME_MAX>;

 case AFSVOL_TLV_TYPE_TIME_REL_VEC:
    AFSRelTimestamp u_time_rel_vec<AFSVOL_TLV_UINT64_MAX>;

 case AFSVOL_TLV_TYPE_UUID:
    afsUUID u_uuid;

 case AFSVOL_TLV_TYPE_STRING:
    string u_string<AFSVOL_TLV_OPAQUE_MAX>;

 case AFSVOL_TLV_TYPE_VOL_DOW_USE:
    /* type defined later in this memo */
    AFSVol_stat_use_per_dow u_vol_dow_use;

 case AFSVOL_TLV_TYPE_OPAQUE:
    opaque u_opaque<AFSVOL_TLV_OPAQUE_MAX>;
};

/* registrar-controlled tag namespace */
enum AFSVol_TLV_tag {
    AFSVOL_TLV_TAG_EOS = 0,
    AFSVOL_TLV_TAG_VOL_NAME = 1,
    AFSVOL_TLV_TAG_VOL_STATUS = 2,
    AFSVOL_TLV_TAG_VOL_IN_USE = 3,
    AFSVOL_TLV_TAG_VOL_ID = 4,
    AFSVOL_TLV_TAG_VOL_TYPE = 5,
    AFSVOL_TLV_TAG_VOL_CLONE_ID = 6,
    AFSVOL_TLV_TAG_VOL_BACKUP_ID = 7,
    AFSVOL_TLV_TAG_VOL_PARENT_ID = 8,
    AFSVOL_TLV_TAG_VOL_COPY_DATE = 9,
    AFSVOL_TLV_TAG_VOL_CREATE_DATE = 10,
    AFSVOL_TLV_TAG_VOL_ACCESS_DATE = 11,
    AFSVOL_TLV_TAG_VOL_UPDATE_DATE = 12,
    AFSVOL_TLV_TAG_VOL_BACKUP_DATE = 13,
    AFSVOL_TLV_TAG_VOL_SIZE = 14,
    AFSVOL_TLV_TAG_VOL_FILE_COUNT = 15,
    AFSVOL_TLV_TAG_VOL_QUOTA_BLOCKS = 16,
    AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY = 17,
    AFSVOL_TLV_TAG_VOL_STAT_USE_PER_DOW = 18,
    AFSVOL_TLV_TAG_VOL_STAT_READS = 19,
    AFSVOL_TLV_TAG_VOL_STAT_WRITES = 20,
    AFSVOL_TLV_TAG_VOL_STAT_FILE_SAME_AUTHOR = 21,
    AFSVOL_TLV_TAG_VOL_STAT_FILE_DIFFERENT_AUTHOR = 22,
    AFSVOL_TLV_TAG_VOL_STAT_DIR_SAME_AUTHOR = 23,
    AFSVOL_TLV_TAG_VOL_STAT_DIR_DIFFERENT_AUTHOR = 24,
    AFSVOL_TLV_TAG_VOL_TRANS_ID = 25,
    AFSVOL_TLV_TAG_VOL_TRANS_TIME = 26,
    AFSVOL_TLV_TAG_VOL_TRANS_CREATE_TIME = 27,
    AFSVOL_TLV_TAG_VOL_TRANS_RETURN_CODE = 28,
    AFSVOL_TLV_TAG_VOL_TRANS_ATTACH_MODE = 29,
    AFSVOL_TLV_TAG_VOL_TRANS_STATUS = 30,
    AFSVOL_TLV_TAG_VOL_TRANS_FLAGS = 31,
    AFSVOL_TLV_TAG_VOL_TRANS_LAST_PROC_NAME = 32,
    AFSVOL_TLV_TAG_VOL_TRANS_CALL_VALID = 33,
    AFSVOL_TLV_TAG_VOL_TRANS_READ_NEXT = 34,
    AFSVOL_TLV_TAG_VOL_TRANS_XMIT_NEXT = 35,
    AFSVOL_TLV_TAG_VOL_TRANS_LAST_RECV_TIME = 36,
    AFSVOL_TLV_TAG_VOL_TRANS_LAST_SEND_TIME = 37,
    AFSVOL_TLV_TAG_VOL_IN_SERVICE = 38,
    AFSVOL_TLV_TAG_VOL_BLESSED = 39,
    AFSVOL_TLV_TAG_VOL_RESTORED_FROM_ID = 40,
    AFSVOL_TLV_TAG_VOL_DESTROYED = 41,
    AFSVOL_TLV_TAG_VOL_NEEDS_SALVAGE = 42,
    AFSVOL_TLV_TAG_VOL_OFFLINE_MESSAGE = 43,
    AFSVOL_TLV_TAG_VOL_EXPIRATION_DATE = 44,
    AFSVOL_TLV_TAG_VOL_QUOTA_RESERVATION = 45,
    AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY_DATE = 46,
    AFSVOL_TLV_TAG_VOL_STATE_ONLINE = 47,
    AFSVOL_TLV_TAG_VOL_STATE_AVAILABLE = 48,
    AFSVOL_TLV_TAG_VOL_STATE_EXPL = 49,
    AFSVOL_TLV_TAG_VOL_STATE_DAFS_RAW = 50,
    AFSVOL_TLV_TAG_VOL_STATE_OWNING_PROCESS = 51,
    AFSVOL_TLV_TAG_VOL_QUOTA_BLOCKS_STORED_LOCALLY = 52,
    AFSVOL_TLV_TAG_VOL_QUOTA_FILES = 53
};


struct AFSVol_TLV {
    afs_uint32 tlv_tag;
    afs_uint32 tlv_flags;
    AFSVol_TLV_value tlv_value;
};

struct AFSVol_TLV_query {
    AFSVol_TLV_tag tq_tag;
    AFSVol_TLV_value tq_qualifier;
};

struct AFSVol_TLV_store {
    AFSVol_TLV ts_tuple;
    AFSVol_TLV_value ts_qualifier;
};

typedef afs_uint64 AFSVol_TLV_TSV;
typedef AFSVol_TLV_tag AFSVol_TLV_tag_vec<AFSVOL_TLV_TAG_MAX>;
typedef AFSVol_TLV_query AFSVol_TLV_query_vec<AFSVOL_TLV_TAG_MAX>;
typedef AFSVol_TLV AFSVol_TLV_vec<AFSVOL_TLV_TAG_MAX>;
typedef afs_uint64 AFSVol_TLV_part_id_vec<AFSVOL_BULK_GETVOLUME_MAX>;
typedef afs_uint64 AFSVol_TLV_vol_id_vec<AFSVOL_BULK_GETVOLUME_MAX>;
typedef AFSVol_TLV_store AFSVol_TLV_store_vec<AFSVOL_TLV_TAG_MAX>;
typedef afs_int32 AFSVol_TLV_result_vec<AFSVOL_TLV_TAG_MAX>;

struct AFSVol_TLV_vol_list {
    afs_uint64 partId;
    AFSVol_TLV_Vol_id_vec * volIds;
};

typedef struct AFSVol_TLV_vol_list 
AFSVol_TLV_get_filter<AFSVOL_BULK_GETVOLUME_MAX>;


proc GetVolumeTLVTags(
    IN AFSVol_TLV_tag offset,
    OUT AFSVol_TLV_tag_vec * tags,
    OUT AFSVol_TLV_TSV * tsv
) = XXX;

proc GetOneVolumeTLV(
    IN afs_uint64 partId,
    IN afs_uint64 volId,
    IN AFSVol_TLV_query_vec * queries,
    OUT AFSVol_TLV_vec * tuples,
    OUT AFSVol_TLV_TSV * tsv
) = XXX;

proc GetVolumesTLV(
    IN AFSVol_TLV_get_filter * filter,
    IN AFSVol_TLV_query_vec * queries,
    OUT AFSVol_TLV_TSV * tsv
) split = XXX;

proc SetVolumeTLV(
    IN afs_int32 trans,
    IN AFSVol_TLV_TSV assert_tsv
    IN AFSVol_TLV_store_vec * tuples,
    OUT AFSVol_TLV_result_vec * results,
    OUT AFSVol_TLV_TSV * server_tsv
) = XXX;
]]></artwork>
      </figure>
    </section>

    <!-- Change Log
v00 2009-11-11  TEK  Initial Version
v01 2010-04-06  TEK  - reorganize document to flow better
                     - add RxOSD tags
                     - break out volume state tags into a few booleans, and
                       an enumeration to contain explanatory annotations
                     - rewrite introductory section and abstract to better
                       introduce the context of this memo (AFS-3) to new readers
v02 2010-06-15  TEK  - ERRATA: AFSCAPABILITIESMAX is actually defined to be 196,
                       not 192 as I would have assumed
                     - add section re: cache coherence to the tag enumeration RPC
                     - add section re: day-of-week usage following discussion
                       with mmeffie
                     - s/AFSVOL_TLV_TAG_VOL_DAY_USE/AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY/
                       following discussion with mmeffie
                     - add AFSVOL_TLV_TAG_VOL_STAT_USE_TODAY_DATE following
                       discussion with mmeffie
                     - add section re: definition of each tlv payload type
                     - add section re: definition of each tlv flag
                     - add note soliciting comments to afs3-stds list
                     - s/GCO Registrar/AFS Assigned Numbers Registrar/
                     - s/afsint/AFSVol/ so that we keep our options open with
                       respect to wider standardization of TLV semantics
                     - add AFSVOL_TLV_TYPE_UINT64_VEC payload type
                     - convert various tags from AFSVOL_TLV_TYPE_OPAQUE to
                       AFSVOL_TLV_TYPE_UINT64_VEC
                     - add AFSVOL_TLV_FLAG_QUALIFIER_NO_MATCH flag
                     - write AFSVol TLV Payloads registry definition
                     - write AFSVol TLV Tags registry definition
                     - add registry for AFSVol_TLV.tlv_flags
                     - add registry for AFSVol_stat_use_per_dow.stat_flags
                     - write AFSVol Vol State Expls registry definition
                     - write AFSVol Program Types registry definition
                     - add numeric value assignments for newly created registries
                     - add RFC section references to new allocations
                     - add reference to Simon's AFS-STDS charter
                     - add an appendix with sample XDR for AFSVol Capabilities
                     - add an appendix with sample XDR for AFSVol TLV
                     - various cosmetic improvements (e.g. adding vspace tags)
v03 2010-08-04  TEK  - split unsigned 64-bit type down into several more
                       descriptive types that allow the TLV data stream to be
                       more self-describing.
                     - add a signed 64-bit integer type to allow for relative
                       timestamps
                     - now that we have more descriptive types, use them in
                       a number of places
                     - change AFSVOL_TLV_TAG_VOL_TRANS_CALL_VALID into a
                       boolean type payload
                     - make sure rxgen can parse the XDR in the appendix
                     - make sure generated C code compiles and links
                     - add in-text cites for AFS3-VVL, AFS3-FSCM, DAFS, and OSD.
                     - provide motivations for GetCapabilities RPC
                     - provide protocol semantic definitions for each newly
                       allocated capability bits
                     - allocate AFSVOL_TLV_FLAG_MORE bit to notify caller when
                       we can't send all tags due to AFSVOL_TLV_TAG_MAX length 
                       limit
v04 2012-09-11  TEK  - add underscores to new volser error code symbolic names
                       to improve code point readability
                     - change undelivered capabilities vector entries from
                       implictly zero to undefined (thus improving generality
                       and extensibility of the capabilities interface)
                     - remove Rx epoch-based capabilities cache invalidation
                       language, as this is a layering violation
                     - remove Rx epoch-based tag namespace cache invalidation
                       language, as this is a layering violation
                     - introduce a monotonic tag namespace version (TSV) ordinal
                       as a replacement tag namespace cache coherence mechanism
                     - add TSV OUT parameters to each TLV RPC
                     - add a TSV IN parameter to the AFSVolSetVolumeTLV RPC for
                       purposes of asserting desired TSV for a set operation
                     - define which RPCs are OPTIONAL for-/REQUIRED of- a
                       compliant implementation
                     - change anchor names to not include colons since new
                       versions of the parser appear to consider that a reserved
                       character...
                     - change document titles to no longer include ampersands
                       since new versions of the parser appear to consider that
                       a special character even inside of quoted strings
                     - change TLV language to reference 
                       I-D.keiser-afs3-xdr-union
                     - change time language to reference
                       draft-deason-afs3-type-time-03
                     - add AFSVOL_TLV_FLAG_OBJ_NOT_SUPP to distinguish between
                       read errors resulting from I/O problems, and read errors
                       caused by the metadata for a given object (e.g., volume)
                       not supporting a specific tag
                     - clarification of the text describing when use of 
                       AFSVOL_TLV_TYPE_OPAQUE may be acceptable
                     - add a VOLSER_TRANS_INVALID error code so that we stop
                       using ENOENT on the wire for this error case
                     - update SetVolumeTLV list of acceptable error codes
                     - add a section defining each new VOLS error table code
                     - implement Andrew's suggestion to merge the partid and volid
                       vectors in GetVolumesTLV to improve encoding efficiency of filters
                     - fix private assignment ranges, as per Andrew
                     - refer to RxOSD as "the RxOSD protocol suite"
                     - as per Andrew, make it clear that allowance of rxnull connections
                       to AFSVol introspection interfaces is not prescribed in any
                       protocol specification; it is merely convention
                     - as per Steven, split AFSVolGetCapabilities out into a new i-d,
                       and add it as normative reference: draft-keiser-afs3-capabilities
                     - VOLSER_TAG_DECODE_FAILED: s/could set/could not set/
		     - convert a bunch of things over to our m4 macro library
		     - utilize our bibxml library to simplify references
		     - add Andrew as an editor so he can resurrect the document after
		       my departure
     -->

  </back>

</rfc>
