Skip to main content

Network File System (NFS) Version 4 Protocol
draft-ietf-nfsv4-rfc3530bis-27

The information below is for an old version of the document.
Document Type
This is an older version of an Internet-Draft that was ultimately published as RFC 7530.
Authors Thomas Haynes , David Noveck
Last updated 2013-08-16
RFC stream Internet Engineering Task Force (IETF)
Formats
Reviews
Additional resources Mailing list discussion
Stream WG state WG Document
Document shepherd (None)
IESG IESG state Became RFC 7530 (Proposed Standard)
Consensus boilerplate Unknown
Telechat date (None)
Responsible AD Martin Stiemerling
IESG note ** No value found for 'doc.notedoc.note' **
Send notices to nfsv4-chairs@tools.ietf.org, draft-ietf-nfsv4-rfc3530bis@tools.ietf.org
IANA IANA review state Version Changed - Review Needed
draft-ietf-nfsv4-rfc3530bis-27

        This prevents the potential reuse of a particular operation
        "slot" in a future minor version.

   6.   Minor versions must not delete attributes.

   7.   Minor versions must not delete flag bits or enumeration values.

   8.   Minor versions may declare an operation MUST NOT be implemented.

        Specifying that an operation MUST NOT be implemented is
        equivalent to obsoleting an operation.  For the client, it means
        that the operation MUST NOT be sent to the server.  For the
        server, an NFS error can be returned as opposed to "dropping"
        the request as an XDR decode error.  This approach allows for
        the obsolescence of an operation while maintaining its structure
        so that a future minor version can reintroduce the operation.

        1.  Minor versions may declare that an attribute MUST NOT be
            implemented.

        2.  Minor versions may declare that a flag bit or enumeration
            value MUST NOT be implemented.

   9.   Minor versions may downgrade features from REQUIRED to
        RECOMMENDED, or RECOMMENDED to OPTIONAL.

   10.  Minor versions may upgrade features from OPTIONAL to RECOMMENDED
        or RECOMMENDED to REQUIRED.

   11.  A client and server that support minor version X SHOULD support
        minor versions 0 through X-1 as well.

   12.  Except for infrastructural changes, no new features may be
        introduced as REQUIRED in a minor version.

        This rule allows for the introduction of new functionality and
        forces the use of implementation experience before designating a
        feature as REQUIRED.  On the other hand, some classes of
        features are infrastructural and have broad effects.  Allowing
        infrastructural features to be RECOMMENDED or OPTIONAL
        complicates implementation of the minor version.

   13.  A client MUST NOT attempt to use a stateid, filehandle, or
        similar returned object from the COMPOUND procedure with minor
        version X for another COMPOUND procedure with minor version Y,
        where X != Y.

Haynes & Noveck         Expires February 17, 2014             [Page 166]
Internet-Draft                    NFSv4                      August 2013

12.  Internationalization

12.1.  Introduction

   This section describes NFSv4.0 internationalization as implemented by
   existing clients and servers.  As a result, the keywords "MUST",
   "SHOULD", and "MAY", even though they retain their normal meanings,
   reflect patterns of existing implementation:

   o  Behavior implemented by all existing clients or servers is
      described using "MUST", since new implementations need to follow
      existing ones to be assured of interoperability.

   o  Behavior implemented by no existing clients or servers is
      described using "MUST NOT", if such behavior poses
      interoperability problems.

   o  Behavior implemented by most existing clients or servers, where
      that behavior is more desirable than any alternative is described
      using "SHOULD", since new implementations need to follow that
      existing practice unless there are strong reasons to do otherwise.
      This also holds for "SHOULD NOT".

   o  Behavior implemented by some not all existing clients or servers,
      is described using "MAY", indicating that new implementations have
      a choice as to whether they will behave in that way.

   o  Behavior implemented by all existing clients or servers, so far as
      is known, but where there remains some uncertainty as to details
      is described using "should".  Such cases primary concern details
      of error returns.  New implementations should follow existing
      practice even though such situations generally do not affect
      interoperability.

12.2.  String Encoding

   Strings that potentially contain non-ASCII Characters are represented
   in NFSv4 using the UTF-8 encoding of Unicode.  See [RFC2279] for
   precise encoding and decoding rules.

   Some details of the protocol treatment depend on the type of string:

   o  For strings that are component names, any non-ASCII characters
      MUST be represented using the UTF-8 encoding of Unicode.

   o  For strings whose form is defined by other internet standards,
      non-ASCII characters MUST be represented using the UTF-8 encoding
      of Unicode.  In addition other sorts of restrictions defined by

Haynes & Noveck         Expires February 17, 2014             [Page 167]
Internet-Draft                    NFSv4                      August 2013

      those standards need to be addressed.  See section 11.4 for
      details.

   o  For other sorts of strings, any non-ASCII characters SHOULD be
      represented using the UTF-8 encoding of Unicode.

12.3.  Normalization

   The client and server operating environments may differ in their
   policies and operational methods with respect to character
   normalization (See [Unicode1] for a discussion of normalization
   forms).  This difference may also exist between applications on the
   same client.  This adds to the difficulty of providing a single
   normalization policy for the protocol that allows for maximal
   interoperability.  This issue is similar to the character case issues
   where the server may or may not support case insensitive file name
   matching and may or may not preserve the character case when storing
   file names.  The protocol does not mandate a particular behavior but
   allows for a range of useful behaviors.

   The NFS version 4 protocol does not mandate the use of a particular
   normalization form at this time.  A subsequent minor version of the
   NFSv4 protocol might specify a particular normalization form.
   Therefore, the server and client can expect that they may receive
   unnormalized characters within protocol requests and responses.  If
   the operating environment requires normalization, then the
   implementation must normalize the various UTF-8 encoded strings
   within the protocol before presenting the information to an
   application (at the client) or local file system (at the server).

   Server implementations MAY normalize file names to conform to a
   particular normalization form before using the resulting string when
   looking up or creating a file.  Servers MAY also perform
   normalization-insensitive string comparisons without modifying name
   to match a particular normalization form.  Servers MUST NOT reject a
   file name because it doesn't a conform to a particular normalization
   form.

12.4.  Types with Processing Defined by Other Internet Areas

   There are two types of strings which NFSv4 deals with whose
   processing is defined by other Internet standards, and where issues
   related to different handling choices by server operating systems or
   server file systems do not apply.

   These are as follows:

Haynes & Noveck         Expires February 17, 2014             [Page 168]
Internet-Draft                    NFSv4                      August 2013

   o  Server names as they appear in the fs_locations attribute.  Note
      that for most purposes, such server names will only be sent by the
      server to the client.  The exception is use of the fs_locations
      attribute in a VERIFY or NVERIFY operation.

   o  Principal suffixes which are used to denote sets of users and
      groups, and are in the form of domain names.

   The general rules for handling all of these domain-related strings
   are similar and independent of role the of the sender or receiver as
   client or server although the consequences of failure to obey these
   rules may be different for client or server.  The server can report
   errors when it is sent invalid strings, whereas the client will
   simply ignore invalid string or use a default value in their place.

   The string sent SHOULD be in the form of a U-label although it MAY be
   in the form of an A-label or a UTF-8 string that would not map to
   itself when canonicalized by applying ToUnicode(ToASCII(...)).  The
   receiver needs to be able to accept domain and server names in any of
   the formats allowed.  The server MUST reject, using the error
   NFS4ERR_INVAL, a string which is not valid UTF-8 or which begins with
   "xn--" and violates the rules for a valid A-label.

   When a domain string is part of id@domain or group@domain, the server
   SHOULD map domain strings which are A-labels or are UTF-8 domain
   names which are not U-labels, to the corresponding U-label, using
   ToUnicode(domain) or ToUnicode(ToASCII(domain)).  As a result, the
   domain name returned within a userid on a GETATTR may not match that
   sent when the userid is set using SETATTR, although when this
   happens, the domain will be in the form of a U-label.  When the
   server does not map domain strings which are not U-labels into a
   U-label, which it MAY do, it MUST NOT modify the domain and the
   domain returned on a GETATTR of the userid MUST be the same as that
   used when setting the userid by the SETATTR.

   The server MAY implement VERIFY and NVERIFY without translating
   internal state to a string form, so that, for example, a user
   principal which represents a specific numeric user id, will match a
   different principal string which represents the same numeric user id.

12.5.  UTF-8 Related Errors

   Where the client sends an invalid UTF-8 string, the server SHOULD
   return an NFS4ERR_INVAL error.  This includes cases in which
   inappropriate prefixes are detected and where the count includes
   trailing bytes that do not constitute a full UCS character.

   Where the client supplied string is not rejected with NFS4ERR_INVAL

Haynes & Noveck         Expires February 17, 2014             [Page 169]
Internet-Draft                    NFSv4                      August 2013

   but contains characters that are not supported by the server as a
   value for that string (e.g. names containing characters that have
   more than two octets on a file system that supports Unicode
   characters only), the server should return an NFS4ERR_BADCHAR error.

   Where a UTF-8 string is used as a file name, and the file system,
   while supporting all of the characters within the name, does not
   allow that particular name to be used, the error should return the
   error NFS4ERR_BADNAME.  This includes situations in which the server
   file system imposes a normalization constraint on name strings, but
   will also include such situations as file system prohibitions of "."
   and ".." as file names for certain operations, and other such
   constraints.

13.  Error Values

   NFS error numbers are assigned to failed operations within a Compound
   (COMPOUND or CB_COMPOUND) request.  A Compound request contains a
   number of NFS operations that have their results encoded in sequence
   in a Compound reply.  The results of successful operations will
   consist of an NFS4_OK status followed by the encoded results of the
   operation.  If an NFS operation fails, an error status will be
   entered in the reply and the Compound request will be terminated.

13.1.  Error Definitions

                        Protocol Error Definitions

       +-----------------------------+--------+-------------------+
       | Error                       | Number | Description       |
       +-----------------------------+--------+-------------------+
       | NFS4_OK                     | 0      | Section 13.1.3.1  |
       | NFS4ERR_ACCESS              | 13     | Section 13.1.6.1  |
       | NFS4ERR_ATTRNOTSUPP         | 10032  | Section 13.1.11.1 |
       | NFS4ERR_ADMIN_REVOKED       | 10047  | Section 13.1.5.1  |
       | NFS4ERR_BADCHAR             | 10040  | Section 13.1.7.1  |
       | NFS4ERR_BADHANDLE           | 10001  | Section 13.1.2.1  |
       | NFS4ERR_BADNAME             | 10041  | Section 13.1.7.2  |
       | NFS4ERR_BADOWNER            | 10039  | Section 13.1.11.2 |
       | NFS4ERR_BADTYPE             | 10007  | Section 13.1.4.1  |
       | NFS4ERR_BADXDR              | 10036  | Section 13.1.1.1  |
       | NFS4ERR_BAD_COOKIE          | 10003  | Section 13.1.1.2  |
       | NFS4ERR_BAD_RANGE           | 10042  | Section 13.1.8.1  |
       | NFS4ERR_BAD_SEQID           | 10026  | Section 13.1.8.2  |
       | NFS4ERR_BAD_STATEID         | 10025  | Section 13.1.5.2  |
       | NFS4ERR_CLID_INUSE          | 10017  | Section 13.1.10.1 |
       | NFS4ERR_DEADLOCK            | 10045  | Section 13.1.8.3  |

Haynes & Noveck         Expires February 17, 2014             [Page 170]
Internet-Draft                    NFSv4                      August 2013

       | NFS4ERR_DELAY               | 10008  | Section 13.1.1.3  |
       | NFS4ERR_DENIED              | 10010  | Section 13.1.8.4  |
       | NFS4ERR_DQUOT               | 69     | Section 13.1.4.2  |
       | NFS4ERR_EXIST               | 17     | Section 13.1.4.3  |
       | NFS4ERR_EXPIRED             | 10011  | Section 13.1.5.3  |
       | NFS4ERR_FBIG                | 27     | Section 13.1.4.4  |
       | NFS4ERR_FHEXPIRED           | 10014  | Section 13.1.2.2  |
       | NFS4ERR_FILE_OPEN           | 10046  | Section 13.1.4.5  |
       | NFS4ERR_GRACE               | 10013  | Section 13.1.9.1  |
       | NFS4ERR_INVAL               | 22     | Section 13.1.1.4  |
       | NFS4ERR_IO                  | 5      | Section 13.1.4.6  |
       | NFS4ERR_ISDIR               | 21     | Section 13.1.2.3  |
       | NFS4ERR_LEASE_MOVED         | 10031  | Section 13.1.5.4  |
       | NFS4ERR_LOCKED              | 10012  | Section 13.1.8.5  |
       | NFS4ERR_LOCKS_HELD          | 10037  | Section 13.1.8.6  |
       | NFS4ERR_LOCK_NOTSUPP        | 10043  | Section 13.1.8.7  |
       | NFS4ERR_LOCK_RANGE          | 10028  | Section 13.1.8.8  |
       | NFS4ERR_MINOR_VERS_MISMATCH | 10021  | Section 13.1.3.2  |
       | NFS4ERR_MLINK               | 31     | Section 13.1.4.7  |
       | NFS4ERR_MOVED               | 10019  | Section 13.1.2.4  |
       | NFS4ERR_NAMETOOLONG         | 63     | Section 13.1.7.3  |
       | NFS4ERR_NOENT               | 2      | Section 13.1.4.8  |
       | NFS4ERR_NOFILEHANDLE        | 10020  | Section 13.1.2.5  |
       | NFS4ERR_NOSPC               | 28     | Section 13.1.4.9  |
       | NFS4ERR_NOTDIR              | 20     | Section 13.1.2.6  |
       | NFS4ERR_NOTEMPTY            | 66     | Section 13.1.4.10 |
       | NFS4ERR_NOTSUPP             | 10004  | Section 13.1.1.5  |
       | NFS4ERR_NOT_SAME            | 10027  | Section 13.1.11.3 |
       | NFS4ERR_NO_GRACE            | 10033  | Section 13.1.9.2  |
       | NFS4ERR_NXIO                | 6      | Section 13.1.4.11 |
       | NFS4ERR_OLD_STATEID         | 10024  | Section 13.1.5.5  |
       | NFS4ERR_OPENMODE            | 10038  | Section 13.1.8.9  |
       | NFS4ERR_OP_ILLEGAL          | 10044  | Section 13.1.3.3  |
       | NFS4ERR_PERM                | 1      | Section 13.1.6.2  |
       | NFS4ERR_RECLAIM_BAD         | 10034  | Section 13.1.9.3  |
       | NFS4ERR_RECLAIM_CONFLICT    | 10035  | Section 13.1.9.4  |
       | NFS4ERR_RESOURCE            | 10018  | Section 13.1.3.4  |
       | NFS4ERR_RESTOREFH           | 10030  | Section 13.1.4.12 |
       | NFS4ERR_ROFS                | 30     | Section 13.1.4.13 |
       | NFS4ERR_SAME                | 10009  | Section 13.1.11.4 |
       | NFS4ERR_SERVERFAULT         | 10006  | Section 13.1.1.6  |
       | NFS4ERR_STALE               | 70     | Section 13.1.2.7  |
       | NFS4ERR_STALE_CLIENTID      | 10022  | Section 13.1.10.2 |
       | NFS4ERR_STALE_STATEID       | 10023  | Section 13.1.5.6  |
       | NFS4ERR_SYMLINK             | 10029  | Section 13.1.2.8  |
       | NFS4ERR_TOOSMALL            | 10005  | Section 13.1.1.7  |
       | NFS4ERR_WRONGSEC            | 10016  | Section 13.1.6.3  |

Haynes & Noveck         Expires February 17, 2014             [Page 171]
Internet-Draft                    NFSv4                      August 2013

       | NFS4ERR_XDEV                | 18     | Section 13.1.4.14 |
       +-----------------------------+--------+-------------------+

                                  Table 5

13.1.1.  General Errors

   This section deals with errors that are applicable to a broad set of
   different purposes.

13.1.1.1.  NFS4ERR_BADXDR (Error Code 10036)

   The arguments for this operation do not match those specified in the
   XDR definition.  This includes situations in which the request ends
   before all the arguments have been seen.  Note that this error
   applies when fixed enumerations (these include booleans) have a value
   within the input stream which is not valid for the enum.  A replier
   may pre-parse all operations for a Compound procedure before doing
   any operation execution and return RPC-level XDR errors in that case.

13.1.1.2.  NFS4ERR_BAD_COOKIE (Error Code 10003)

   Used for operations that provide a set of information indexed by some
   quantity provided by the client or cookie sent by the server for an
   earlier invocation.  Where the value cannot be used for its intended
   purpose, this error results.

13.1.1.3.  NFS4ERR_DELAY (Error Code 10008)

   For any of a number of reasons, the replier could not process this
   operation in what was deemed a reasonable time.  The client should
   wait and then try the request with a new RPC transaction ID.

   Some example of situations that might lead to this situation:

   o  A server that supports hierarchical storage receives a request to
      process a file that had been migrated.

   o  An operation requires a delegation recall to proceed and waiting
      for this delegation recall makes processing this request in a
      timely fashion impossible.

13.1.1.4.  NFS4ERR_INVAL (Error Code 22)

   The arguments for this operation are not valid for some reason, even
   though they do match those specified in the XDR definition for the
   request.

Haynes & Noveck         Expires February 17, 2014             [Page 172]
Internet-Draft                    NFSv4                      August 2013

13.1.1.5.  NFS4ERR_NOTSUPP (Error Code 10004)

   Operation not supported, either because the operation is an OPTIONAL
   one and is not supported by this server or because the operation MUST
   NOT be implemented in the current minor version.

13.1.1.6.  NFS4ERR_SERVERFAULT (Error Code 10006)

   An error occurred on the server which does not map to any of the
   specific legal NFSv4 protocol error values.  The client should
   translate this into an appropriate error.  UNIX clients may choose to
   translate this to EIO.

13.1.1.7.  NFS4ERR_TOOSMALL (Error Code 10005)

   Used where an operation returns a variable amount of data, with a
   limit specified by the client.  Where the data returned cannot be
   fitted within the limit specified by the client, this error results.

13.1.2.  Filehandle Errors

   These errors deal with the situation in which the current or saved
   filehandle, or the filehandle passed to PUTFH intended to become the
   current filehandle, is invalid in some way.  This includes situations
   in which the filehandle is a valid filehandle in general but is not
   of the appropriate object type for the current operation.

   Where the error description indicates a problem with the current or
   saved filehandle, it is to be understood that filehandles are only
   checked for the condition if they are implicit arguments of the
   operation in question.

13.1.2.1.  NFS4ERR_BADHANDLE (Error Code 10001)

   Illegal NFS filehandle for the current server.  The current
   filehandle failed internal consistency checks.  Once accepted as
   valid (by PUTFH), no subsequent status change can cause the
   filehandle to generate this error.

13.1.2.2.  NFS4ERR_FHEXPIRED (Error Code 10014)

   A current or saved filehandle which is an argument to the current
   operation is volatile and has expired at the server.

13.1.2.3.  NFS4ERR_ISDIR (Error Code 21)

   The current or saved filehandle designates a directory when the
   current operation does not allow a directory to be accepted as the

Haynes & Noveck         Expires February 17, 2014             [Page 173]
Internet-Draft                    NFSv4                      August 2013

   target of this operation.

13.1.2.4.  NFS4ERR_MOVED (Error Code 10019)

   The file system which contains the current filehandle object is not
   present at the server.  It may have been relocated, migrated to
   another server or may have never been present.  The client may obtain
   the new file system location by obtaining the "fs_locations" or
   attribute for the current filehandle.  For further discussion, refer
   to Section 8.

13.1.2.5.  NFS4ERR_NOFILEHANDLE (Error Code 10020)

   The logical current or saved filehandle value is required by the
   current operation and is not set.  This may be a result of a
   malformed COMPOUND operation (i.e., no PUTFH or PUTROOTFH before an
   operation that requires the current filehandle be set).

13.1.2.6.  NFS4ERR_NOTDIR (Error Code 20)

   The current (or saved) filehandle designates an object which is not a
   directory for an operation in which a directory is required.

13.1.2.7.  NFS4ERR_STALE (Error Code 70)

   The current or saved filehandle value designating an argument to the
   current operation is invalid.  The file system object referred to by
   that filehandle no longer exists or access to it has been revoked.

13.1.2.8.  NFS4ERR_SYMLINK (Error Code 10029)

   The current filehandle designates a symbolic link when the current
   operation does not allow a symbolic link as the target.

13.1.3.  Compound Structure Errors

   This section deals with errors that relate to overall structure of a
   Compound request (by which we mean to include both COMPOUND and
   CB_COMPOUND), rather than to particular operations.

   There are a number of basic constraints on the operations that may
   appear in a Compound request.

13.1.3.1.  NFS_OK (Error code 0)

   Indicates the operation completed successfully, in that all of the
   constituent operations completed without error.

Haynes & Noveck         Expires February 17, 2014             [Page 174]
Internet-Draft                    NFSv4                      August 2013

13.1.3.2.  NFS4ERR_MINOR_VERS_MISMATCH (Error code 10021)

   The minor version specified is not one that the current listener
   supports.  This value is returned in the overall status for the
   Compound but is not associated with a specific operation since the
   results must specify a result count of zero.

13.1.3.3.  NFS4ERR_OP_ILLEGAL (Error Code 10044)

   The operation code is not a valid one for the current Compound
   procedure.  The opcode in the result stream matched with this error
   is the ILLEGAL value, although the value that appears in the request
   stream may be different.  Where an illegal value appears and the
   replier pre-parses all operations for a Compound procedure before
   doing any operation execution, an RPC-level XDR error may be returned
   in this case.

13.1.3.4.  NFS4ERR_RESOURCE (Error Code 10018)

   For the processing of the Compound procedure, the server may exhaust
   available resources and cannot continue processing operations within
   the Compound procedure.  This error will be returned from the server
   in those instances of resource exhaustion related to the processing
   of the Compound procedure.

13.1.4.  File System Errors

   These errors describe situations which occurred in the underlying
   file system implementation rather than in the protocol or any NFSv4.x
   feature.

13.1.4.1.  NFS4ERR_BADTYPE (Error Code 10007)

   An attempt was made to create an object with an inappropriate type
   specified to CREATE.  This may be because the type is undefined,
   because it is a type not supported by the server, or because it is a
   type for which create is not intended such as a regular file or named
   attribute, for which OPEN is used to do the file creation.

13.1.4.2.  NFS4ERR_DQUOT (Error Code 69)

   Resource (quota) hard limit exceeded.  The user's resource limit on
   the server has been exceeded.

13.1.4.3.  NFS4ERR_EXIST (Error Code 17)

   A file system object of the specified target name (when creating,
   renaming or linking) already exists.

Haynes & Noveck         Expires February 17, 2014             [Page 175]
Internet-Draft                    NFSv4                      August 2013

13.1.4.4.  NFS4ERR_FBIG (Error Code 27)

   Filesystem object too large.  The operation would have caused a file
   system object to grow beyond the server's limit.

13.1.4.5.  NFS4ERR_FILE_OPEN (Error Code 10046)

   The operation is not allowed because a file system object involved in
   the operation is currently open.  Servers may, but are not required
   to disallow linking-to, removing, or renaming open file system
   objects.

13.1.4.6.  NFS4ERR_IO (Error Code 6)

   Indicates that an I/O error occurred for which the file system was
   unable to provide recovery.

13.1.4.7.  NFS4ERR_MLINK (Error Code 31)

   The request would have caused the server's limit for the number of
   hard links a file system object may have to be exceeded.

13.1.4.8.  NFS4ERR_NOENT (Error Code 2)

   Indicates no such file or directory.  The file system object
   referenced by the name specified does not exist.

13.1.4.9.  NFS4ERR_NOSPC (Error Code 28)

   Indicates no space left on device.  The operation would have caused
   the server's file system to exceed its limit.

13.1.4.10.  NFS4ERR_NOTEMPTY (Error Code 66)

   An attempt was made to remove a directory that was not empty.

13.1.4.11.  NFS4ERR_NXIO (Error Code 5)

   I/O error.  No such device or address.

13.1.4.12.  NFS4ERR_RESTOREFH (Error Code 10030)

   The RESTOREFH operation does not have a saved filehandle (identified
   by SAVEFH) to operate upon.

Haynes & Noveck         Expires February 17, 2014             [Page 176]
Internet-Draft                    NFSv4                      August 2013

13.1.4.13.  NFS4ERR_ROFS (Error Code 30)

   Indicates a read-only file system.  A modifying operation was
   attempted on a read-only file system.

13.1.4.14.  NFS4ERR_XDEV (Error Code 18)

   Indicates an attempt to do an operation, such as linking, that
   inappropriately crosses a boundary.  This may be due to such
   boundaries as:

   o  That between file systems (where the fsids are different).

   o  That between different named attribute directories or between a
      named attribute directory and an ordinary directory.

   o  That between regions of a file system that the file system
      implementation treats as separate (for example for space
      accounting purposes), and where cross-connection between the
      regions are not allowed.

13.1.5.  State Management Errors

   These errors indicate problems with the stateid (or one of the
   stateids) passed to a given operation.  This includes situations in
   which the stateid is invalid as well as situations in which the
   stateid is valid but designates revoked locking state.  Depending on
   the operation, the stateid when valid may designate opens, byte-range
   locks, or file delegations.

13.1.5.1.  NFS4ERR_ADMIN_REVOKED (Error Code 10047)

   A stateid designates locking state of any type that has been revoked
   due to administrative interaction, possibly while the lease is valid,
   or because a delegation was revoked because of failure to return it,
   while the lease was valid.

13.1.5.2.  NFS4ERR_BAD_STATEID (Error Code 10025)

   A stateid generated by the current server instance was used which
   either:

   o  Does not designate any locking state (either current or
      superseded) for a current (state-owner, file) pair.

   o  Designates locking state that was freed after lease expiration but
      without any lease cancelation, as may happen in the handling of
      "courtesy locks".

Haynes & Noveck         Expires February 17, 2014             [Page 177]
Internet-Draft                    NFSv4                      August 2013

13.1.5.3.  NFS4ERR_EXPIRED (Error Code 10011)

   A stateid or clientid designates locking state of any type that has
   been revoked or released due to cancellation of the client's lease,
   either immediately upon lease expiration, or following a later
   request for a conflicting lock.

13.1.5.4.  NFS4ERR_LEASE_MOVED (Error Code 10031)

   A lease being renewed is associated with a file system that has been
   migrated to a new server.

13.1.5.5.  NFS4ERR_OLD_STATEID (Error Code 10024)

   A stateid is provided with a seqid value that is not the most
   current.

13.1.5.6.  NFS4ERR_STALE_STATEID (Error Code 10023)

   A stateid generated by an earlier server instance was used.

13.1.6.  Security Errors

   These are the various permission-related errors in NFSv4.

13.1.6.1.  NFS4ERR_ACCESS (Error Code 13)

   Indicates permission denied.  The caller does not have the correct
   permission to perform the requested operation.  Contrast this with
   NFS4ERR_PERM (Section 13.1.6.2), which restricts itself to owner or
   privileged user permission failures.

13.1.6.2.  NFS4ERR_PERM (Error Code 1)

   Indicates requester is not the owner.  The operation was not allowed
   because the caller is neither a privileged user (root) nor the owner
   of the target of the operation.

13.1.6.3.  NFS4ERR_WRONGSEC (Error Code 10016)

   Indicates that the security mechanism being used by the client for
   the operation does not match the server's security policy.  The
   client should change the security mechanism being used and re-send
   the operation.  SECINFO can be used to determine the appropriate
   mechanism.

Haynes & Noveck         Expires February 17, 2014             [Page 178]
Internet-Draft                    NFSv4                      August 2013

13.1.7.  Name Errors

   Names in NFSv4 are UTF-8 strings.  When the strings are not of length
   zero, the error NFS4ERR_INVAL results.  When they are not valid UTF-8
   the error NFS4ERR_INVAL also results, but servers may accommodate
   file systems with different character formats and not return this
   error.  Besides this, there are a number of other errors to indicate
   specific problems with names.

13.1.7.1.  NFS4ERR_BADCHAR (Error Code 10040)

   A UTF-8 string contains a character which is not supported by the
   server in the context in which it being used.

13.1.7.2.  NFS4ERR_BADNAME (Error Code 10041)

   A name string in a request consisted of valid UTF-8 characters
   supported by the server but the name is not supported by the server
   as a valid name for current operation.  An example might be creating
   a file or directory named ".." on a server whose file system uses
   that name for links to parent directories.

   This error should not be returned due a normalization issue in a
   string.  When a file system keeps names in a particular normalization
   form, it is the server's responsibility to do the appropriate
   normalization, rather than rejecting the name.

13.1.7.3.  NFS4ERR_NAMETOOLONG (Error Code 63)

   Returned when the filename in an operation exceeds the server's
   implementation limit.

13.1.8.  Locking Errors

   This section deal with errors related to locking, both as to share
   reservations and byte-range locking.  It does not deal with errors
   specific to the process of reclaiming locks.  Those are dealt with in
   the next section.

13.1.8.1.  NFS4ERR_BAD_RANGE (Error Code 10042)

   The range for a LOCK, LOCKT, or LOCKU operation is not appropriate to
   the allowable range of offsets for the server.  E.g., this error
   results when a server which only supports 32-bit ranges receives a
   range that cannot be handled by that server.  (See Section 15.12.4).

Haynes & Noveck         Expires February 17, 2014             [Page 179]
Internet-Draft                    NFSv4                      August 2013

13.1.8.2.  NFS4ERR_BAD_SEQID (Error Code 10026)

   The sequence number (seqid) in a locking request is neither the next
   expected number or the last number processed.

13.1.8.3.  NFS4ERR_DEADLOCK (Error Code 10045)

   The server has been able to determine a file locking deadlock
   condition for a blocking lock request.

13.1.8.4.  NFS4ERR_DENIED (Error Code 10010)

   An attempt to lock a file is denied.  Since this may be a temporary
   condition, the client is encouraged to re-send the lock request until
   the lock is accepted.  See Section 9.4 for a discussion of the re-
   send.

13.1.8.5.  NFS4ERR_LOCKED (Error Code 10012)

   A read or write operation was attempted on a file where there was a
   conflict between the I/O and an existing lock:

   o  There is a share reservation inconsistent with the I/O being done.

   o  The range to be read or written intersects an existing mandatory
      byte range lock.

13.1.8.6.  NFS4ERR_LOCKS_HELD (Error Code 10037)

   An operation was prevented by the unexpected presence of locks.

13.1.8.7.  NFS4ERR_LOCK_NOTSUPP (Error Code 10043)

   A locking request was attempted which would require the upgrade or
   downgrade of a lock range already held by the owner when the server
   does not support atomic upgrade or downgrade of locks.

13.1.8.8.  NFS4ERR_LOCK_RANGE (Error Code 10028)

   A lock request is operating on a range that overlaps in part a
   currently held lock for the current lock owner and does not precisely
   match a single such lock where the server does not support this type
   of request, and thus does not implement POSIX locking semantics
   [fcntl].  See Section 15.12.5, Section 15.13.5, and Section 15.14.5
   for a discussion of how this applies to LOCK, LOCKT, and LOCKU
   respectively.

Haynes & Noveck         Expires February 17, 2014             [Page 180]
Internet-Draft                    NFSv4                      August 2013

13.1.8.9.  NFS4ERR_OPENMODE (Error Code 10038)

   The client attempted a READ, WRITE, LOCK or other operation not
   sanctioned by the stateid passed (e.g., writing to a file opened only
   for read).

13.1.9.  Reclaim Errors

   These errors relate to the process of reclaiming locks after a server
   restart.

13.1.9.1.  NFS4ERR_GRACE (Error Code 10013)

   The server is in its recovery or grace period which should at least
   match the lease period of the server.  A locking request other than a
   reclaim could not be granted during that period.

13.1.9.2.  NFS4ERR_NO_GRACE (Error Code 10033)

   The server cannot guarantee that it has not granted state to another
   client which may conflict with this client's state.  No further
   reclaims from this client will succeed.

13.1.9.3.  NFS4ERR_RECLAIM_BAD (Error Code 10034)

   The server cannot guarantee that it has not granted state to another
   client which may conflict with the requested state.  However, this
   applies only to the state requested in this call; further reclaims
   may succeed.

   Unlike NFS4ERR_RECLAIM_CONFLICT, this can occur between correctly
   functioning clients and servers: the "edge condition" scenarios
   described in Section 9.6.3.1 leave only the server knowing whether
   the client's locks are still valid, and NFS4ERR_RECLAIM_BAD is the
   server's way of informing the client that they are not.

13.1.9.4.  NFS4ERR_RECLAIM_CONFLICT (Error Code 10035)

   The reclaim attempted by the client conflicts with a lock already
   held by another client.  Unlike NFS4ERR_RECLAIM_BAD, this can only
   occur if one of the clients misbehaved.

13.1.10.  Client Management Errors

   This sections deals with errors associated with requests used to
   create and manage client IDs.

Haynes & Noveck         Expires February 17, 2014             [Page 181]
Internet-Draft                    NFSv4                      August 2013

13.1.10.1.  NFS4ERR_CLID_INUSE (Error Code 10017)

   The SETCLIENTID operation has found that a client id is already in
   use by another client.

13.1.10.2.  NFS4ERR_STALE_CLIENTID (Error Code 10022)

   A client ID not recognized by the server was used in a locking or
   SETCLIENTID_CONFIRM request.

13.1.11.  Attribute Handling Errors

   This section deals with errors specific to attribute handling within
   NFSv4.

13.1.11.1.  NFS4ERR_ATTRNOTSUPP (Error Code 10032)

   An attribute specified is not supported by the server.  This error
   MUST NOT be returned by the GETATTR operation.

13.1.11.2.  NFS4ERR_BADOWNER (Error Code 10039)

   Returned when an owner or owner_group attribute value or the who
   field of an ace within an ACL attribute value cannot be translated to
   a local representation.

13.1.11.3.  NFS4ERR_NOT_SAME (Error Code 10027)

   This error is returned by the VERIFY operation to signify that the
   attributes compared were not the same as those provided in the
   client's request.

13.1.11.4.  NFS4ERR_SAME (Error Code 10009)

   This error is returned by the NVERIFY operation to signify that the
   attributes compared were the same as those provided in the client's
   request.

13.2.  Operations and their valid errors

   This section contains a table which gives the valid error returns for
   each protocol operation.  The error code NFS4_OK (indicating no
   error) is not listed but should be understood to be returnable by all
   operations except ILLEGAL.

              Valid error returns for each protocol operation

Haynes & Noveck         Expires February 17, 2014             [Page 182]
Internet-Draft                    NFSv4                      August 2013

   +---------------------+---------------------------------------------+
   | Operation           | Errors                                      |
   +---------------------+---------------------------------------------+
   | ACCESS              | NFS4ERR_ACCESS, NFS4ERR_BADHANDLE,          |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,           |
   |                     | NFS4ERR_IO, NFS4ERR_MOVED,                  |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_RESOURCE,     |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE          |
   | CLOSE               | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADHANDLE,   |
   |                     | NFS4ERR_BAD_SEQID, NFS4ERR_BAD_STATEID,     |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_EXPIRED, NFS4ERR_FHEXPIRED,         |
   |                     | NFS4ERR_INVAL, NFS4ERR_ISDIR,               |
   |                     | NFS4ERR_LEASE_MOVED, NFS4ERR_LOCKS_HELD,    |
   |                     | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,        |
   |                     | NFS4ERR_OLD_STATEID, NFS4ERR_RESOURCE,      |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,         |
   |                     | NFS4ERR_STALE_STATEID                       |
   | COMMIT              | NFS4ERR_ACCESS, NFS4ERR_BADHANDLE,          |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,           |
   |                     | NFS4ERR_IO, NFS4ERR_ISDIR, NFS4ERR_MOVED,   |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_RESOURCE,     |
   |                     | NFS4ERR_ROFS, NFS4ERR_SERVERFAULT,          |
   |                     | NFS4ERR_STALE, NFS4ERR_SYMLINK              |
   | CREATE              | NFS4ERR_ACCESS, NFS4ERR_ATTRNOTSUPP,        |
   |                     | NFS4ERR_BADCHAR, NFS4ERR_BADHANDLE,         |
   |                     | NFS4ERR_BADNAME, NFS4ERR_BADOWNER,          |
   |                     | NFS4ERR_BADTYPE, NFS4ERR_BADXDR,            |
   |                     | NFS4ERR_DELAY, NFS4ERR_DQUOT,               |
   |                     | NFS4ERR_EXIST, NFS4ERR_FHEXPIRED,           |
   |                     | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,   |
   |                     | NFS4ERR_NAMETOOLONG, NFS4ERR_NOFILEHANDLE,  |
   |                     | NFS4ERR_NOSPC, NFS4ERR_NOTDIR,              |
   |                     | NFS4ERR_PERM, NFS4ERR_RESOURCE,             |
   |                     | NFS4ERR_ROFS, NFS4ERR_SERVERFAULT,          |
   |                     | NFS4ERR_STALE                               |
   | DELEGPURGE          | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_NOTSUPP, NFS4ERR_LEASE_MOVED,       |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_SERVERFAULT,      |
   |                     | NFS4ERR_STALE_CLIENTID                      |

Haynes & Noveck         Expires February 17, 2014             [Page 183]
Internet-Draft                    NFSv4                      August 2013

   | DELEGRETURN         | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BAD_STATEID, |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_EXPIRED, NFS4ERR_INVAL,             |
   |                     | NFS4ERR_LEASE_MOVED, NFS4ERR_MOVED,         |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTSUPP,      |
   |                     | NFS4ERR_OLD_STATEID, NFS4ERR_RESOURCE,      |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,         |
   |                     | NFS4ERR_STALE_STATEID                       |
   | GETATTR             | NFS4ERR_ACCESS, NFS4ERR_BADHANDLE,          |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,           |
   |                     | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,   |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_RESOURCE,     |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE          |
   | GETFH               | NFS4ERR_BADHANDLE, NFS4ERR_FHEXPIRED,       |
   |                     | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,        |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_SERVERFAULT,      |
   |                     | NFS4ERR_STALE                               |
   | ILLEGAL             | NFS4ERR_BADXDR, NFS4ERR_OP_ILLEGAL          |
   | LINK                | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,            |
   |                     | NFS4ERR_BADHANDLE, NFS4ERR_BADNAME,         |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_DQUOT, NFS4ERR_EXIST,               |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_FILE_OPEN,       |
   |                     | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_ISDIR,   |
   |                     | NFS4ERR_MLINK, NFS4ERR_MOVED,               |
   |                     | NFS4ERR_NAMETOOLONG, NFS4ERR_NOENT,         |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,        |
   |                     | NFS4ERR_NOTDIR, NFS4ERR_NOTSUPP,            |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_ROFS,             |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,         |
   |                     | NFS4ERR_WRONGSEC, NFS4ERR_XDEV              |
   | LOCK                | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,      |
   |                     | NFS4ERR_BADHANDLE, NFS4ERR_BAD_RANGE,       |
   |                     | NFS4ERR_BAD_SEQID, NFS4ERR_BAD_STATEID,     |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DEADLOCK,           |
   |                     | NFS4ERR_DELAY, NFS4ERR_DENIED,              |
   |                     | NFS4ERR_EXPIRED, NFS4ERR_FHEXPIRED,         |
   |                     | NFS4ERR_GRACE, NFS4ERR_INVAL,               |
   |                     | NFS4ERR_ISDIR, NFS4ERR_LEASE_MOVED,         |
   |                     | NFS4ERR_LOCK_NOTSUPP, NFS4ERR_LOCK_RANGE,   |
   |                     | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,        |
   |                     | NFS4ERR_NO_GRACE, NFS4ERR_OLD_STATEID,      |
   |                     | NFS4ERR_OPENMODE, NFS4ERR_RECLAIM_BAD,      |
   |                     | NFS4ERR_RECLAIM_CONFLICT, NFS4ERR_RESOURCE, |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,         |
   |                     | NFS4ERR_STALE_CLIENTID,                     |
   |                     | NFS4ERR_STALE_STATEID                       |

Haynes & Noveck         Expires February 17, 2014             [Page 184]
Internet-Draft                    NFSv4                      August 2013

   | LOCKT               | NFS4ERR_ACCESS, NFS4ERR_BADHANDLE,          |
   |                     | NFS4ERR_BAD_RANGE, NFS4ERR_BADXDR,          |
   |                     | NFS4ERR_DELAY, NFS4ERR_DENIED,              |
   |                     | NFS4ERR_EXPIRED, NFS4ERR_FHEXPIRED,         |
   |                     | NFS4ERR_GRACE, NFS4ERR_INVAL,               |
   |                     | NFS4ERR_ISDIR, NFS4ERR_LEASE_MOVED,         |
   |                     | NFS4ERR_LOCK_RANGE, NFS4ERR_MOVED,          |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_RESOURCE,     |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,         |
   |                     | NFS4ERR_STALE_CLIENTID                      |
   | LOCKU               | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,      |
   |                     | NFS4ERR_BADHANDLE, NFS4ERR_BAD_RANGE,       |
   |                     | NFS4ERR_BAD_SEQID, NFS4ERR_BAD_STATEID,     |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_EXPIRED, NFS4ERR_FHEXPIRED,         |
   |                     | NFS4ERR_GRACE, NFS4ERR_INVAL,               |
   |                     | NFS4ERR_ISDIR, NFS4ERR_LEASE_MOVED,         |
   |                     | NFS4ERR_LOCK_RANGE, NFS4ERR_MOVED,          |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_OLD_STATEID,  |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_SERVERFAULT,      |
   |                     | NFS4ERR_STALE, NFS4ERR_STALE_STATEID        |
   | LOOKUP              | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,            |
   |                     | NFS4ERR_BADHANDLE, NFS4ERR_BADNAME,         |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,           |
   |                     | NFS4ERR_IO, NFS4ERR_MOVED,                  |
   |                     | NFS4ERR_NAMETOOLONG, NFS4ERR_NOENT,         |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,       |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_SERVERFAULT,      |
   |                     | NFS4ERR_STALE, NFS4ERR_SYMLINK,             |
   |                     | NFS4ERR_WRONGSEC                            |
   | LOOKUPP             | NFS4ERR_ACCESS, NFS4ERR_BADHANDLE,          |
   |                     | NFS4ERR_DELAY, NFS4ERR_FHEXPIRED,           |
   |                     | NFS4ERR_IO, NFS4ERR_MOVED, NFS4ERR_NOENT,   |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,       |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_SERVERFAULT,      |
   |                     | NFS4ERR_STALE, NFS4ERR_SYMLINK,             |
   |                     | NFS4ERR_WRONGSEC                            |
   | NVERIFY             | NFS4ERR_ACCESS, NFS4ERR_ATTRNOTSUPP,        |
   |                     | NFS4ERR_BADCHAR, NFS4ERR_BADHANDLE,         |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,           |
   |                     | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,   |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_SAME,         |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE          |

Haynes & Noveck         Expires February 17, 2014             [Page 185]
Internet-Draft                    NFSv4                      August 2013

   | OPEN                | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,      |
   |                     | NFS4ERR_ATTRNOTSUPP, NFS4ERR_BADCHAR,       |
   |                     | NFS4ERR_BADHANDLE, NFS4ERR_BADNAME,         |
   |                     | NFS4ERR_BADOWNER, NFS4ERR_BADXDR,           |
   |                     | NFS4ERR_BAD_SEQID, NFS4ERR_BAD_STATEID,     |
   |                     | NFS4ERR_DELAY, NFS4ERR_DQUOT,               |
   |                     | NFS4ERR_EXIST, NFS4ERR_EXPIRED,             |
   |                     | NFS4ERR_FBIG, NFS4ERR_FHEXPIRED,            |
   |                     | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,   |
   |                     | NFS4ERR_ISDIR, NFS4ERR_MOVED,               |
   |                     | NFS4ERR_NAMETOOLONG, NFS4ERR_NOENT,         |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,        |
   |                     | NFS4ERR_NOTDIR, NFS4ERR_NOTSUP,             |
   |                     | NFS4ERR_NO_GRACE, NFS4ERR_OLD_STATEID,      |
   |                     | NFS4ERR_PERM, NFS4ERR_RECLAIM_BAD,          |
   |                     | NFS4ERR_RECLAIM_CONFLICT, NFS4ERR_RESOURCE, |
   |                     | NFS4ERR_ROFS, NFS4ERR_SERVERFAULT,          |
   |                     | NFS4ERR_SHARE_DENIED, NFS4ERR_STALE,        |
   |                     | NFS4ERR_STALE_CLIENTID, NFS4ERR_SYMLINK,    |
   |                     | NFS4ERR_WRONGSEC                            |
   | OPENATTR            | NFS4ERR_ACCESS, NFS4ERR_BADHANDLE,          |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_DQUOT, NFS4ERR_FHEXPIRED,           |
   |                     | NFS4ERR_IO, NFS4ERR_MOVED, NFS4ERR_NOENT,   |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,        |
   |                     | NFS4ERR_NOTSUPP, NFS4ERR_RESOURCE,          |
   |                     | NFS4ERR_ROFS, NFS4ERR_SERVERFAULT,          |
   |                     | NFS4ERR_STALE                               |
   | OPEN_CONFIRM        | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADHANDLE,   |
   |                     | NFS4ERR_BAD_SEQID, NFS4ERR_BAD_STATEID,     |
   |                     | NFS4ERR_BADXDR, NFS4ERR_EXPIRED,            |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,           |
   |                     | NFS4ERR_ISDIR, NFS4ERR_LEASE_MOVED,         |
   |                     | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,        |
   |                     | NFS4ERR_OLD_STATEID, NFS4ERR_RESOURCE,      |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,         |
   |                     | NFS4ERR_STALE_STATEID                       |
   | OPEN_DOWNGRADE      | NFS4ERR_ADMIN_REVOKED, NFS4ERR_BADHANDLE,   |
   |                     | NFS4ERR_BADXDR, NFS4ERR_BAD_SEQID,          |
   |                     | NFS4ERR_BAD_STATEID, NFS4ERR_DELAY,         |
   |                     | NFS4ERR_EXPIRED, NFS4ERR_FHEXPIRED,         |
   |                     | NFS4ERR_INVAL, NFS4ERR_LEASE_MOVED,         |
   |                     | NFS4ERR_LOCKS_HELD, NFS4ERR_MOVED,          |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_OLD_STATEID,  |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_ROFS,             |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,         |
   |                     | NFS4ERR_STALE_STATEID                       |

Haynes & Noveck         Expires February 17, 2014             [Page 186]
Internet-Draft                    NFSv4                      August 2013

   | PUTFH               | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,          |
   |                     | NFS4ERR_DELAY, NFS4ERR_FHEXPIRED,           |
   |                     | NFS4ERR_MOVED, NFS4ERR_SERVERFAULT,         |
   |                     | NFS4ERR_STALE, NFS4ERR_WRONGSEC             |
   | PUTPUBFH            | NFS4ERR_DELAY, NFS4ERR_SERVERFAULT,         |
   |                     | NFS4ERR_WRONGSEC                            |
   | PUTROOTFH           | NFS4ERR_DELAY, NFS4ERR_SERVERFAULT,         |
   |                     | NFS4ERR_WRONGSEC                            |
   | READ                | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,      |
   |                     | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,          |
   |                     | NFS4ERR_BAD_STATEID, NFS4ERR_DELAY,         |
   |                     | NFS4ERR_EXPIRED, NFS4ERR_FHEXPIRED,         |
   |                     | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,   |
   |                     | NFS4ERR_ISDIR, NFS4ERR_LEASE_MOVED,         |
   |                     | NFS4ERR_LOCKED, NFS4ERR_MOVED,              |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_OLD_STATEID,  |
   |                     | NFS4ERR_OPENMODE, NFS4ERR_RESOURCE,         |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,         |
   |                     | NFS4ERR_STALE_STATEID, NFS4ERR_SYMLINK      |
   | READDIR             | NFS4ERR_ACCESS, NFS4ERR_BADHANDLE,          |
   |                     | NFS4ERR_BADXDR, NFS4ERR_BAD_COOKIE,         |
   |                     | NFS4ERR_DELAY, NFS4ERR_FHEXPIRED,           |
   |                     | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,   |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOTDIR,       |
   |                     | NFS4ERR_NOT_SAME, NFS4ERR_RESOURCE,         |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,         |
   |                     | NFS4ERR_TOOSMALL                            |
   | READLINK            | NFS4ERR_ACCESS, NFS4ERR_BADHANDLE,          |
   |                     | NFS4ERR_DELAY, NFS4ERR_FHEXPIRED,           |
   |                     | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_ISDIR,   |
   |                     | NFS4ERR_MOVED, NFS4ERR_NOTSUP,              |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_NOFILEHANDLE,     |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE          |
   | RELEASE_LOCKOWNER   | NFS4ERR_BADXDR, NFS4ERR_EXPIRED,            |
   |                     | NFS4ERR_LEASE_MOVED, NFS4ERR_LOCKS_HELD,    |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_SERVERFAULT,      |
   |                     | NFS4ERR_STALE_CLIENTID                      |
   | REMOVE              | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,            |
   |                     | NFS4ERR_BADHANDLE, NFS4ERR_BADNAME,         |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_FILE_OPEN,       |
   |                     | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,   |
   |                     | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,         |
   |                     | NFS4ERR_NOENT, NFS4ERR_NOFILEHANDLE,        |
   |                     | NFS4ERR_NOTDIR, NFS4ERR_NOTEMPTY,           |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_ROFS,             |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE          |

Haynes & Noveck         Expires February 17, 2014             [Page 187]
Internet-Draft                    NFSv4                      August 2013

   | RENAME              | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,            |
   |                     | NFS4ERR_BADHANDLE, NFS4ERR_BADNAME,         |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_DQUOT, NFS4ERR_EXIST,               |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_FILE_OPEN,       |
   |                     | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,   |
   |                     | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,         |
   |                     | NFS4ERR_NOENT, NFS4ERR_NOFILEHANDLE,        |
   |                     | NFS4ERR_NOSPC, NFS4ERR_NOTDIR,              |
   |                     | NFS4ERR_NOTEMPTY, NFS4ERR_RESOURCE,         |
   |                     | NFS4ERR_ROFS, NFS4ERR_SERVERFAULT,          |
   |                     | NFS4ERR_STALE, NFS4ERR_WRONGSEC,            |
   |                     | NFS4ERR_XDEV                                |
   | RENEW               | NFS4ERR_ACCESS, NFS4ERR_BADXDR,             |
   |                     | NFS4ERR_CB_PATH_DOWN, NFS4ERR_EXPIRED,      |
   |                     | NFS4ERR_LEASE_MOVED, NFS4ERR_RESOURCE,      |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE_CLIENTID |
   | RESTOREFH           | NFS4ERR_BADHANDLE, NFS4ERR_FHEXPIRED,       |
   |                     | NFS4ERR_MOVED, NFS4ERR_RESOURCE,            |
   |                     | NFS4ERR_RESTOREFH, NFS4ERR_SERVERFAULT,     |
   |                     | NFS4ERR_STALE, NFS4ERR_WRONGSEC             |
   | SAVEFH              | NFS4ERR_BADHANDLE, NFS4ERR_FHEXPIRED,       |
   |                     | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,        |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_SERVERFAULT,      |
   |                     | NFS4ERR_STALE                               |
   | SECINFO             | NFS4ERR_ACCESS, NFS4ERR_BADCHAR,            |
   |                     | NFS4ERR_BADHANDLE, NFS4ERR_BADNAME,         |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_INVAL,           |
   |                     | NFS4ERR_MOVED, NFS4ERR_NAMETOOLONG,         |
   |                     | NFS4ERR_NOENT, NFS4ERR_NOFILEHANDLE,        |
   |                     | NFS4ERR_NOTDIR, NFS4ERR_RESOURCE,           |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE          |
   | SETATTR             | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,      |
   |                     | NFS4ERR_ATTRNOTSUPP, NFS4ERR_BADCHAR,       |
   |                     | NFS4ERR_BADHANDLE, NFS4ERR_BADOWNER,        |
   |                     | NFS4ERR_BADXDR, NFS4ERR_BAD_STATEID,        |
   |                     | NFS4ERR_DELAY, NFS4ERR_DQUOT,               |
   |                     | NFS4ERR_EXPIRED, NFS4ERR_FBIG,              |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,           |
   |                     | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_ISDIR,   |
   |                     | NFS4ERR_LEASE_MOVED, NFS4ERR_LOCKED,        |
   |                     | NFS4ERR_MOVED, NFS4ERR_NOFILEHANDLE,        |
   |                     | NFS4ERR_NOSPC, NFS4ERR_OLD_STATEID,         |
   |                     | NFS4ERR_OPENMODE, NFS4ERR_PERM,             |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_ROFS,             |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE,         |
   |                     | NFS4ERR_STALE_STATEID                       |

Haynes & Noveck         Expires February 17, 2014             [Page 188]
Internet-Draft                    NFSv4                      August 2013

   | SETCLIENTID         | NFS4ERR_BADXDR, NFS4ERR_CLID_INUSE,         |
   |                     | NFS4ERR_DELAY, NFS4ERR_INVAL,               |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_SERVERFAULT       |
   | SETCLIENTID_CONFIRM | NFS4ERR_BADXDR, NFS4ERR_CLID_INUSE,         |
   |                     | NFS4ERR_DELAY, NFS4ERR_RESOURCE,            |
   |                     | NFS4ERR_SERVERFAULT, NFS4ERR_STALE_CLIENTID |
   | VERIFY              | NFS4ERR_ACCESS, NFS4ERR_ATTRNOTSUPP,        |
   |                     | NFS4ERR_BADCHAR, NFS4ERR_BADHANDLE,         |
   |                     | NFS4ERR_BADXDR, NFS4ERR_DELAY,              |
   |                     | NFS4ERR_FHEXPIRED, NFS4ERR_GRACE,           |
   |                     | NFS4ERR_INVAL, NFS4ERR_IO, NFS4ERR_MOVED,   |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOT_SAME,     |
   |                     | NFS4ERR_RESOURCE, NFS4ERR_SERVERFAULT,      |
   |                     | NFS4ERR_STALE                               |
   | WRITE               | NFS4ERR_ACCESS, NFS4ERR_ADMIN_REVOKED,      |
   |                     | NFS4ERR_BADXDR, NFS4ERR_BADHANDLE,          |
   |                     | NFS4ERR_BAD_STATEID, NFS4ERR_DELAY,         |
   |                     | NFS4ERR_DQUOT, NFS4ERR_EXPIRED,             |
   |                     | NFS4ERR_FBIG, NFS4ERR_FHEXPIRED,            |
   |                     | NFS4ERR_GRACE, NFS4ERR_INVAL, NFS4ERR_IO,   |
   |                     | NFS4ERR_ISDIR, NFS4ERR_LEASE_MOVED,         |
   |                     | NFS4ERR_LOCKED, NFS4ERR_MOVED,              |
   |                     | NFS4ERR_NOFILEHANDLE, NFS4ERR_NOSPC,        |
   |                     | NFS4ERR_NXIO, NFS4ERR_OLD_STATEID,          |
   |                     | NFS4ERR_OPENMODE, NFS4ERR_RESOURCE,         |
   |                     | NFS4ERR_ROFS, NFS4ERR_SERVERFAULT,          |
   |                     | NFS4ERR_STALE, NFS4ERR_STALE_STATEID,       |
   |                     | NFS4ERR_SYMLINK                             |
   +---------------------+---------------------------------------------+

                                  Table 6

13.3.  Callback operations and their valid errors

   This section contains a table which gives the valid error returns for
   each callback operation.  The error code NFS4_OK (indicating no
   error) is not listed but should be understood to be returnable by all
   callback operations with the exception of CB_ILLEGAL.

Haynes & Noveck         Expires February 17, 2014             [Page 189]
Internet-Draft                    NFSv4                      August 2013

         Valid error returns for each protocol callback operation

   +-------------+-----------------------------------------------------+
   | Callback    | Errors                                              |
   | Operation   |                                                     |
   +-------------+-----------------------------------------------------+
   | CB_GETATTR  | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR, NFS4ERR_DELAY,   |
   |             | NFS4ERR_INVAL, NFS4ERR_SERVERFAULT                  |
   | CB_ILLEGAL  | NFS4ERR_BADXDR, NFS4ERR_OP_ILLEGAL                  |
   | CB_RECALL   | NFS4ERR_BADHANDLE, NFS4ERR_BADXDR,                  |
   |             | NFS4ERR_BAD_STATEID, NFS4ERR_DELAY,                 |
   |             | NFS4ERR_SERVERFAULT                                 |
   +-------------+-----------------------------------------------------+

                                  Table 7

13.4.  Errors and the operations that use them

   +--------------------------+----------------------------------------+
   | Error                    | Operations                             |
   +--------------------------+----------------------------------------+
   | NFS4ERR_ACCESS           | ACCESS, COMMIT, CREATE, GETATTR, LINK, |
   |                          | LOCK, LOCKT, LOCKU, LOOKUP, LOOKUPP,   |
   |                          | NVERIFY, OPEN, OPENATTR, READ,         |
   |                          | READDIR, READLINK, REMOVE, RENAME,     |
   |                          | RENEW, SECINFO, SETATTR, VERIFY, WRITE |
   | NFS4ERR_ADMIN_REVOKED    | CLOSE, DELEGRETURN, LOCK, LOCKU, OPEN, |
   |                          | OPEN_CONFIRM, OPEN_DOWNGRADE, READ,    |
   |                          | SETATTR, WRITE                         |
   | NFS4ERR_ATTRNOTSUPP      | CREATE, NVERIFY, OPEN, SETATTR, VERIFY |
   | NFS4ERR_BADCHAR          | CREATE, LINK, LOOKUP, NVERIFY, OPEN,   |
   |                          | REMOVE, RENAME, SECINFO, SETATTR,      |
   |                          | VERIFY                                 |
   | NFS4ERR_BADHANDLE        | ACCESS, CB_GETATTR, CB_RECALL, CLOSE,  |
   |                          | COMMIT, CREATE, GETATTR, GETFH, LINK,  |
   |                          | LOCK, LOCKT, LOCKU, LOOKUP, LOOKUPP,   |
   |                          | NVERIFY, OPEN, OPENATTR, OPEN_CONFIRM, |
   |                          | OPEN_DOWNGRADE, PUTFH, READ, READDIR,  |
   |                          | READLINK, REMOVE, RENAME, RESTOREFH,   |
   |                          | SAVEFH, SECINFO, SETATTR, VERIFY,      |
   |                          | WRITE                                  |
   | NFS4ERR_BADNAME          | CREATE, LINK, LOOKUP, OPEN, REMOVE,    |
   |                          | RENAME, SECINFO                        |
   | NFS4ERR_BADOWNER         | CREATE, OPEN, SETATTR                  |
   | NFS4ERR_BADTYPE          | CREATE                                 |

Haynes & Noveck         Expires February 17, 2014             [Page 190]
Internet-Draft                    NFSv4                      August 2013

   | NFS4ERR_BADXDR           | ACCESS, CB_GETATTR, CB_ILLEGAL,        |
   |                          | CB_RECALL, CLOSE, COMMIT, CREATE,      |
   |                          | DELEGPURGE, DELEGRETURN, GETATTR,      |
   |                          | ILLEGAL, LINK, LOCK, LOCKT, LOCKU,     |
   |                          | LOOKUP, NVERIFY, OPEN, OPENATTR,       |
   |                          | OPEN_CONFIRM, OPEN_DOWNGRADE, PUTFH,   |
   |                          | READ, READDIR, RELEASE_LOCKOWNER,      |
   |                          | REMOVE, RENAME, RENEW, SECINFO,        |
   |                          | SETATTR, SETCLIENTID,                  |
   |                          | SETCLIENTID_CONFIRM, VERIFY, WRITE     |
   | NFS4ERR_BAD_COOKIE       | READDIR                                |
   | NFS4ERR_BAD_RANGE        | LOCK, LOCKT, LOCKU                     |
   | NFS4ERR_BAD_SEQID        | CLOSE, LOCK, LOCKU, OPEN,              |
   |                          | OPEN_CONFIRM, OPEN_DOWNGRADE           |
   | NFS4ERR_BAD_STATEID      | CB_RECALL, CLOSE, DELEGRETURN, LOCK,   |
   |                          | LOCKU, OPEN, OPEN_CONFIRM,             |
   |                          | OPEN_DOWNGRADE, READ, SETATTR, WRITE   |
   | NFS4ERR_CB_PATH_DOWN     | RENEW                                  |
   | NFS4ERR_CLID_INUSE       | SETCLIENTID, SETCLIENTID_CONFIRM       |
   | NFS4ERR_DEADLOCK         | LOCK                                   |
   | NFS4ERR_DELAY            | ACCESS, CB_GETATTR, CB_RECALL, CLOSE,  |
   |                          | COMMIT, CREATE, DELEGPURGE,            |
   |                          | DELEGRETURN, GETATTR, LINK, LOCK,      |
   |                          | LOCKT, LOCKU, LOOKUP, LOOKUPP,         |
   |                          | NVERIFY, OPEN, OPENATTR,               |
   |                          | OPEN_DOWNGRADE, PUTFH, PUTPUBFH,       |
   |                          | PUTROOTFH, READ, READDIR, READLINK,    |
   |                          | REMOVE, RENAME, SECINFO, SETATTR,      |
   |                          | SETCLIENTID, SETCLIENTID_CONFIRM,      |
   |                          | VERIFY, WRITE                          |
   | NFS4ERR_DENIED           | LOCK, LOCKT                            |
   | NFS4ERR_DQUOT            | CREATE, LINK, OPEN, OPENATTR, RENAME,  |
   |                          | SETATTR, WRITE                         |
   | NFS4ERR_EXIST            | CREATE, LINK, OPEN, RENAME             |
   | NFS4ERR_EXPIRED          | CLOSE, DELEGRETURN, LOCK, LOCKT,       |
   |                          | LOCKU, OPEN, OPEN_CONFIRM,             |
   |                          | OPEN_DOWNGRADE, READ,                  |
   |                          | RELEASE_LOCKOWNER, RENEW, SETATTR,     |
   |                          | WRITE                                  |
   | NFS4ERR_FBIG             | OPEN, SETATTR, WRITE                   |
   | NFS4ERR_FHEXPIRED        | ACCESS, CLOSE, COMMIT, CREATE,         |
   |                          | GETATTR, GETFH, LINK, LOCK, LOCKT,     |
   |                          | LOCKU, LOOKUP, LOOKUPP, NVERIFY, OPEN, |
   |                          | OPENATTR, OPEN_CONFIRM,                |
   |                          | OPEN_DOWNGRADE, PUTFH, READ, READDIR,  |
   |                          | READLINK, REMOVE, RENAME, RESTOREFH,   |
   |                          | SAVEFH, SECINFO, SETATTR, VERIFY,      |
   |                          | WRITE                                  |

Haynes & Noveck         Expires February 17, 2014             [Page 191]
Internet-Draft                    NFSv4                      August 2013

   | NFS4ERR_FILE_OPEN        | LINK, REMOVE, RENAME                   |
   | NFS4ERR_GRACE            | GETATTR, LOCK, LOCKT, LOCKU, NVERIFY,  |
   |                          | OPEN, READ, REMOVE, RENAME, SETATTR,   |
   |                          | VERIFY, WRITE                          |
   | NFS4ERR_INVAL            | ACCESS, CB_GETATTR, CLOSE, COMMIT,     |
   |                          | CREATE, DELEGRETURN, GETATTR, LINK,    |
   |                          | LOCK, LOCKT, LOCKU, LOOKUP, NVERIFY,   |
   |                          | OPEN, OPEN_CONFIRM, OPEN_DOWNGRADE,    |
   |                          | READ, READDIR, READLINK, REMOVE,       |
   |                          | RENAME, SECINFO, SETATTR, SETCLIENTID, |
   |                          | VERIFY, WRITE                          |
   | NFS4ERR_IO               | ACCESS, COMMIT, CREATE, GETATTR, LINK, |
   |                          | LOOKUP, LOOKUPP, NVERIFY, OPEN,        |
   |                          | OPENATTR, READ, READDIR, READLINK,     |
   |                          | REMOVE, RENAME, SETATTR, VERIFY, WRITE |
   | NFS4ERR_ISDIR            | CLOSE, COMMIT, LINK, LOCK, LOCKT,      |
   |                          | LOCKU, OPEN, OPEN_CONFIRM, READ,       |
   |                          | READLINK, SETATTR, WRITE               |
   | NFS4ERR_LEASE_MOVED      | CLOSE, DELEGPURGE, DELEGRETURN, LOCK,  |
   |                          | LOCKT, LOCKU, OPEN_CONFIRM,            |
   |                          | OPEN_DOWNGRADE, READ,                  |
   |                          | RELEASE_LOCKOWNER, RENEW, SETATTR,     |
   |                          | WRITE                                  |
   | NFS4ERR_LOCKED           | READ, SETATTR, WRITE                   |
   | NFS4ERR_LOCKS_HELD       | CLOSE, OPEN_DOWNGRADE,                 |
   |                          | RELEASE_LOCKOWNER                      |
   | NFS4ERR_LOCK_NOTSUPP     | LOCK                                   |
   | NFS4ERR_LOCK_RANGE       | LOCK, LOCKT, LOCKU                     |
   | NFS4ERR_MLINK            | LINK                                   |
   | NFS4ERR_MOVED            | ACCESS, CLOSE, COMMIT, CREATE,         |
   |                          | DELEGRETURN, GETATTR, GETFH, LINK,     |
   |                          | LOCK, LOCKT, LOCKU, LOOKUP, LOOKUPP,   |
   |                          | NVERIFY, OPEN, OPENATTR, OPEN_CONFIRM, |
   |                          | OPEN_DOWNGRADE, PUTFH, READ, READDIR,  |
   |                          | READLINK, REMOVE, RENAME, RESTOREFH,   |
   |                          | SAVEFH, SECINFO, SETATTR, VERIFY,      |
   |                          | WRITE                                  |
   | NFS4ERR_NAMETOOLONG      | CREATE, LINK, LOOKUP, OPEN, REMOVE,    |
   |                          | RENAME, SECINFO                        |
   | NFS4ERR_NOENT            | LINK, LOOKUP, LOOKUPP, OPEN, OPENATTR, |
   |                          | REMOVE, RENAME, SECINFO                |
   | NFS4ERR_NOFILEHANDLE     | ACCESS, CLOSE, COMMIT, CREATE,         |
   |                          | DELEGRETURN, GETATTR, GETFH, LINK,     |
   |                          | LOCK, LOCKT, LOCKU, LOOKUP, LOOKUPP,   |
   |                          | NVERIFY, OPEN, OPENATTR, OPEN_CONFIRM, |
   |                          | OPEN_DOWNGRADE, READ, READDIR,         |
   |                          | READLINK, REMOVE, RENAME, SAVEFH,      |
   |                          | SECINFO, SETATTR, VERIFY, WRITE        |

Haynes & Noveck         Expires February 17, 2014             [Page 192]
Internet-Draft                    NFSv4                      August 2013

   | NFS4ERR_NOSPC            | CREATE, LINK, OPEN, OPENATTR, RENAME,  |
   |                          | SETATTR, WRITE                         |
   | NFS4ERR_NOTDIR           | CREATE, LINK, LOOKUP, LOOKUPP, OPEN,   |
   |                          | READDIR, REMOVE, RENAME, SECINFO       |
   | NFS4ERR_NOTEMPTY         | REMOVE, RENAME                         |
   | NFS4ERR_NOTSUP           | OPEN, READLINK                         |
   | NFS4ERR_NOTSUPP          | DELEGPURGE, DELEGRETURN, LINK,         |
   |                          | OPENATTR                               |
   | NFS4ERR_NOT_SAME         | READDIR, VERIFY                        |
   | NFS4ERR_NO_GRACE         | LOCK, OPEN                             |
   | NFS4ERR_NXIO             | WRITE                                  |
   | NFS4ERR_OLD_STATEID      | CLOSE, DELEGRETURN, LOCK, LOCKU, OPEN, |
   |                          | OPEN_CONFIRM, OPEN_DOWNGRADE, READ,    |
   |                          | SETATTR, WRITE                         |
   | NFS4ERR_OPENMODE         | LOCK, READ, SETATTR, WRITE             |
   | NFS4ERR_OP_ILLEGAL       | CB_ILLEGAL, ILLEGAL                    |
   | NFS4ERR_PERM             | CREATE, OPEN, SETATTR                  |
   | NFS4ERR_RECLAIM_BAD      | LOCK, OPEN                             |
   | NFS4ERR_RECLAIM_CONFLICT | LOCK, OPEN                             |
   | NFS4ERR_RESOURCE         | ACCESS, CLOSE, COMMIT, CREATE,         |
   |                          | DELEGPURGE, DELEGRETURN, GETATTR,      |
   |                          | GETFH, LINK, LOCK, LOCKT, LOCKU,       |
   |                          | LOOKUP, LOOKUPP, OPEN, OPENATTR,       |
   |                          | OPEN_CONFIRM, OPEN_DOWNGRADE, READ,    |
   |                          | READDIR, READLINK, RELEASE_LOCKOWNER,  |
   |                          | REMOVE, RENAME, RENEW, RESTOREFH,      |
   |                          | SAVEFH, SECINFO, SETATTR, SETCLIENTID, |
   |                          | SETCLIENTID_CONFIRM, VERIFY, WRITE     |
   | NFS4ERR_RESTOREFH        | RESTOREFH                              |
   | NFS4ERR_ROFS             | COMMIT, CREATE, LINK, OPEN, OPENATTR,  |
   |                          | OPEN_DOWNGRADE, REMOVE, RENAME,        |
   |                          | SETATTR, WRITE                         |
   | NFS4ERR_SAME             | NVERIFY                                |
   | NFS4ERR_SERVERFAULT      | ACCESS, CB_GETATTR, CB_RECALL, CLOSE,  |
   |                          | COMMIT, CREATE, DELEGPURGE,            |
   |                          | DELEGRETURN, GETATTR, GETFH, LINK,     |
   |                          | LOCK, LOCKT, LOCKU, LOOKUP, LOOKUPP,   |
   |                          | NVERIFY, OPEN, OPENATTR, OPEN_CONFIRM, |
   |                          | OPEN_DOWNGRADE, PUTFH, PUTPUBFH,       |
   |                          | PUTROOTFH, READ, READDIR, READLINK,    |
   |                          | RELEASE_LOCKOWNER, REMOVE, RENAME,     |
   |                          | RENEW, RESTOREFH, SAVEFH, SECINFO,     |
   |                          | SETATTR, SETCLIENTID,                  |
   |                          | SETCLIENTID_CONFIRM, VERIFY, WRITE     |
   | NFS4ERR_SHARE_DENIED     | OPEN                                   |

Haynes & Noveck         Expires February 17, 2014             [Page 193]
Internet-Draft                    NFSv4                      August 2013

   | NFS4ERR_STALE            | ACCESS, CLOSE, COMMIT, CREATE,         |
   |                          | DELEGRETURN, GETATTR, GETFH, LINK,     |
   |                          | LOCK, LOCKT, LOCKU, LOOKUP, LOOKUPP,   |
   |                          | NVERIFY, OPEN, OPENATTR, OPEN_CONFIRM, |
   |                          | OPEN_DOWNGRADE, PUTFH, READ, READDIR,  |
   |                          | READLINK, REMOVE, RENAME, RESTOREFH,   |
   |                          | SAVEFH, SECINFO, SETATTR, VERIFY,      |
   |                          | WRITE                                  |
   | NFS4ERR_STALE_CLIENTID   | DELEGPURGE, LOCK, LOCKT, OPEN,         |
   |                          | RELEASE_LOCKOWNER, RENEW,              |
   |                          | SETCLIENTID_CONFIRM                    |
   | NFS4ERR_STALE_STATEID    | CLOSE, DELEGRETURN, LOCK, LOCKU,       |
   |                          | OPEN_CONFIRM, OPEN_DOWNGRADE, READ,    |
   |                          | SETATTR, WRITE                         |
   | NFS4ERR_SYMLINK          | COMMIT, LOOKUP, LOOKUPP, OPEN, READ,   |
   |                          | WRITE                                  |
   | NFS4ERR_TOOSMALL         | READDIR                                |
   | NFS4ERR_WRONGSEC         | LINK, LOOKUP, LOOKUPP, OPEN, PUTFH,    |
   |                          | PUTPUBFH, PUTROOTFH, RENAME, RESTOREFH |
   | NFS4ERR_XDEV             | LINK, RENAME                           |
   +--------------------------+----------------------------------------+

                                  Table 8

14.  NFSv4 Requests

   For the NFSv4 RPC program, there are two traditional RPC procedures:
   NULL and COMPOUND.  All other functionality is defined as a set of
   operations and these operations are defined in normal XDR/RPC syntax
   and semantics.  However, these operations are encapsulated within the
   COMPOUND procedure.  This requires that the client combine one or
   more of the NFSv4 operations into a single request.

   The NFS4_CALLBACK program is used to provide server to client
   signaling and is constructed in a similar fashion as the NFSv4
   program.  The procedures CB_NULL and CB_COMPOUND are defined in the
   same way as NULL and COMPOUND are within the NFS program.  The
   CB_COMPOUND request also encapsulates the remaining operations of the
   NFS4_CALLBACK program.  There is no predefined RPC program number for
   the NFS4_CALLBACK program.  It is up to the client to specify a
   program number in the "transient" program range.  The program and
   port number of the NFS4_CALLBACK program are provided by the client
   as part of the SETCLIENTID/SETCLIENTID_CONFIRM sequence.  The program
   and port can be changed by another SETCLIENTID/SETCLIENTID_CONFIRM
   sequence, and it is possible to use the sequence to change them
   within a client incarnation without removing relevant leased client
   state.

Haynes & Noveck         Expires February 17, 2014             [Page 194]
Internet-Draft                    NFSv4                      August 2013

14.1.  Compound Procedure

   The COMPOUND procedure provides the opportunity for better
   performance within high latency networks.  The client can avoid
   cumulative latency of multiple RPCs by combining multiple dependent
   operations into a single COMPOUND procedure.  A compound operation
   may provide for protocol simplification by allowing the client to
   combine basic procedures into a single request that is customized for
   the client's environment.

   The CB_COMPOUND procedure precisely parallels the features of
   COMPOUND as described above.

   The basic structure of the COMPOUND procedure is:

   +-----+--------------+--------+-----------+-----------+-----------+--
   | tag | minorversion | numops | op + args | op + args | op + args |
   +-----+--------------+--------+-----------+-----------+-----------+--

   and the reply's structure is:

     +------------+-----+--------+-----------------------+--
     |last status | tag | numres | status + op + results |
     +------------+-----+--------+-----------------------+--

   The numops and numres fields, used in the depiction above, represent
   the count for the counted array encoding use to signify the number of
   arguments or results encoded in the request and response.  As per the
   XDR encoding, these counts must match exactly the number of operation
   arguments or results encoded.

14.2.  Evaluation of a Compound Request

   The server will process the COMPOUND procedure by evaluating each of
   the operations within the COMPOUND procedure in order.  Each
   component operation consists of a 32 bit operation code, followed by
   the argument of length determined by the type of operation.  The
   results of each operation are encoded in sequence into a reply
   buffer.  The results of each operation are preceded by the opcode and
   a status code (normally zero).  If an operation results in a non-zero
   status code, the status will be encoded and evaluation of the
   compound sequence will halt and the reply will be returned.  Note
   that evaluation stops even in the event of "non error" conditions
   such as NFS4ERR_SAME.

   There are no atomicity requirements for the operations contained
   within the COMPOUND procedure.  The operations being evaluated as
   part of a COMPOUND request may be evaluated simultaneously with other

Haynes & Noveck         Expires February 17, 2014             [Page 195]
Internet-Draft                    NFSv4                      August 2013

   COMPOUND requests that the server receives.

   A COMPOUND is not a transaction and it is the client's responsibility
   for recovering from any partially completed COMPOUND procedure.
   These may occur at any point due to errors such as NFS4ERR_RESOURCE
   and NFS4ERR_DELAY.  Note that these errors can occur in an otherwise
   valid operation string.  Further, a server reboot which occurs in the
   middle of processing a COMPOUND procedure may leave the client with
   the difficult task of determining how far COMPOUND processing has
   proceeded.  Therefore, the client should avoid overly complex
   COMPOUND procedures in the event of the failure of an operation
   within the procedure.

   Each operation assumes a "current" and "saved" filehandle that is
   available as part of the execution context of the compound request.
   Operations may set, change, or return the current filehandle.  The
   "saved" filehandle is used for temporary storage of a filehandle
   value and as operands for the RENAME and LINK operations.

14.3.  Synchronous Modifying Operations

   NFSv4 operations that modify the file system are synchronous.  When
   an operation is successfully completed at the server, the client can
   depend that any data associated with the request is now on stable
   storage (the one exception is in the case of the file data in a WRITE
   operation with the UNSTABLE4 option specified).

   This implies that any previous operations within the same compound
   request are also reflected in stable storage.  This behavior enables
   the client's ability to recover from a partially executed compound
   request which may resulted from the failure of the server.  For
   example, if a compound request contains operations A and B and the
   server is unable to send a response to the client, depending on the
   progress the server made in servicing the request the result of both
   operations may be reflected in stable storage or just operation A may
   be reflected.  The server must not have just the results of operation
   B in stable storage.

14.4.  Operation Values

   The operations encoded in the COMPOUND procedure are identified by
   operation values.  To avoid overlap with the RPC procedure numbers,
   operations 0 (zero) and 1 are not defined.  Operation 2 is not
   defined but reserved for future use with minor versioning.

Haynes & Noveck         Expires February 17, 2014             [Page 196]
Internet-Draft                    NFSv4                      August 2013

15.  NFSv4 Procedures

15.1.  Procedure 0: NULL - No Operation

15.1.1.  SYNOPSIS

     <null>

15.1.2.  ARGUMENT

     void;

15.1.3.  RESULT

     void;

15.1.4.  DESCRIPTION

   Standard NULL procedure.  Void argument, void response.  This
   procedure has no functionality associated with it.  Because of this
   it is sometimes used to measure the overhead of processing a service
   request.  Therefore, the server should ensure that no unnecessary
   work is done in servicing this procedure.

15.2.  Procedure 1: COMPOUND - Compound Operations

15.2.1.  SYNOPSIS

     compoundargs -> compoundres

15.2.2.  ARGUMENT

     union nfs_argop4 switch (nfs_opnum4 argop) {
             case <OPCODE>: <argument>;
             ...
     };

   struct COMPOUND4args {
           utf8str_cs      tag;
           uint32_t        minorversion;
           nfs_argop4      argarray<>;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 197]
Internet-Draft                    NFSv4                      August 2013

15.2.3.  RESULT

     union nfs_resop4 switch (nfs_opnum4 resop) {
             case <OPCODE>: <argument>;
             ...
     };

   struct COMPOUND4res {
           nfsstat4        status;
           utf8str_cs      tag;
           nfs_resop4      resarray<>;
   };

15.2.4.  DESCRIPTION

   The COMPOUND procedure is used to combine one or more of the NFS
   operations into a single RPC request.  The main NFS RPC program has
   two main procedures: NULL and COMPOUND.  All other operations use the
   COMPOUND procedure as a wrapper.

   The COMPOUND procedure is used to combine individual operations into
   a single RPC request.  The server interprets each of the operations
   in turn.  If an operation is executed by the server and the status of
   that operation is NFS4_OK, then the next operation in the COMPOUND
   procedure is executed.  The server continues this process until there
   are no more operations to be executed or one of the operations has a
   status value other than NFS4_OK.

   In the processing of the COMPOUND procedure, the server may find that
   it does not have the available resources to execute any or all of the
   operations within the COMPOUND sequence.  In this case, the error
   NFS4ERR_RESOURCE will be returned for the particular operation within
   the COMPOUND procedure where the resource exhaustion occurred.  This
   assumes that all previous operations within the COMPOUND sequence
   have been evaluated successfully.  The results for all of the
   evaluated operations must be returned to the client.

   The server will generally choose between two methods of decoding the
   client's request.  The first would be the traditional one-pass XDR
   decode, in which decoding of the entire COMPOUND precedes execution
   of any operation within it.  If there is an XDR decoding error in
   this case, an RPC XDR decode error would be returned.  The second
   method would be to make an initial pass to decode the basic COMPOUND
   request and then to XDR decode each of the individual operations, as
   the server is ready to execute it.  In this case, the server may
   encounter an XDR decode error during such an operation decode, after
   previous operations within the COMPOUND have been executed.  In this

Haynes & Noveck         Expires February 17, 2014             [Page 198]
Internet-Draft                    NFSv4                      August 2013

   case, the server would return the error NFS4ERR_BADXDR to signify the
   decode error.

   The COMPOUND arguments contain a "minorversion" field.  The initial
   and default value for this field is 0 (zero).  This field will be
   used by future minor versions such that the client can communicate to
   the server what minor version is being requested.  If the server
   receives a COMPOUND procedure with a minorversion field value that it
   does not support, the server MUST return an error of
   NFS4ERR_MINOR_VERS_MISMATCH and a zero length resultdata array.

   Contained within the COMPOUND results is a "status" field.  If the
   results array length is non-zero, this status must be equivalent to
   the status of the last operation that was executed within the
   COMPOUND procedure.  Therefore, if an operation incurred an error
   then the "status" value will be the same error value as is being
   returned for the operation that failed.

   Note that operations, 0 (zero) and 1 (one) are not defined for the
   COMPOUND procedure.  Operation 2 is not defined but reserved for
   future definition and use with minor versioning.  If the server
   receives a operation array that contains operation 2 and the
   minorversion field has a value of 0 (zero), an error of
   NFS4ERR_OP_ILLEGAL, as described in the next paragraph, is returned
   to the client.  If an operation array contains an operation 2 and the
   minorversion field is non-zero and the server does not support the
   minor version, the server returns an error of
   NFS4ERR_MINOR_VERS_MISMATCH.  Therefore, the
   NFS4ERR_MINOR_VERS_MISMATCH error takes precedence over all other
   errors.

   It is possible that the server receives a request that contains an
   operation that is less than the first legal operation (OP_ACCESS) or
   greater than the last legal operation (OP_RELEASE_LOCKOWNER).  In
   this case, the server's response will encode the opcode OP_ILLEGAL
   rather than the illegal opcode of the request.  The status field in
   the ILLEGAL return results will set to NFS4ERR_OP_ILLEGAL.  The
   COMPOUND procedure's return results will also be NFS4ERR_OP_ILLEGAL.

   The definition of the "tag" in the request is left to the
   implementor.  It may be used to summarize the content of the compound
   request for the benefit of packet sniffers and engineers debugging
   implementations.  However, the value of "tag" in the response SHOULD
   be the same value as provided in the request.  This applies to the
   tag field of the CB_COMPOUND procedure as well.

Haynes & Noveck         Expires February 17, 2014             [Page 199]
Internet-Draft                    NFSv4                      August 2013

15.2.4.1.  Current Filehandle

   The current and saved filehandle are used throughout the protocol.
   Most operations implicitly use the current filehandle as a argument
   and many set the current filehandle as part of the results.  The
   combination of client specified sequences of operations and current
   and saved filehandle arguments and results allows for greater
   protocol flexibility.  The best or easiest example of current
   filehandle usage is a sequence like the following:

     PUTFH fh1              {fh1}
     LOOKUP "compA"         {fh2}
     GETATTR                {fh2}
     LOOKUP "compB"         {fh3}
     GETATTR                {fh3}
     LOOKUP "compC"         {fh4}
     GETATTR                {fh4}
     GETFH

                                 Figure 1

   In this example, the PUTFH (Section 15.22) operation explicitly sets
   the current filehandle value while the result of each LOOKUP
   operation sets the current filehandle value to the resultant file
   system object.  Also, the client is able to insert GETATTR operations
   using the current filehandle as an argument.

   The PUTROOTFH (Section 15.24) and PUTPUBFH (Section 15.24) operations
   also set the current filehandle.  The above example would replace
   "PUTFH fh1" with PUTROOTFH or PUTPUBFH with no filehandle argument in
   order to achieve the same effect (on the assumption that "compA" is
   directly below the root of the namespace).

   Along with the current filehandle, there is a saved filehandle.
   While the current filehandle is set as the result of operations like
   LOOKUP, the saved filehandle must be set directly with the use of the
   SAVEFH operation.  The SAVEFH operations copies the current
   filehandle value to the saved value.  The saved filehandle value is
   used in combination with the current filehandle value for the LINK
   and RENAME operations.  The RESTOREFH operation will copy the saved
   filehandle value to the current filehandle value; as a result, the
   saved filehandle value may be used a sort of "scratch" area for the
   client's series of operations.

Haynes & Noveck         Expires February 17, 2014             [Page 200]
Internet-Draft                    NFSv4                      August 2013

15.2.5.  IMPLEMENTATION

   Since an error of any type may occur after only a portion of the
   operations have been evaluated, the client must be prepared to
   recover from any failure.  If the source of an NFS4ERR_RESOURCE error
   was a complex or lengthy set of operations, it is likely that if the
   number of operations were reduced the server would be able to
   evaluate them successfully.  Therefore, the client is responsible for
   dealing with this type of complexity in recovery.

   The client SHOULD NOT construct a COMPOUND which mixes operations for
   different client IDs.

15.3.  Operation 3: ACCESS - Check Access Rights

15.3.1.  SYNOPSIS

     (cfh), accessreq -> supported, accessrights

15.3.2.  ARGUMENT

   const ACCESS4_READ      = 0x00000001;
   const ACCESS4_LOOKUP    = 0x00000002;
   const ACCESS4_MODIFY    = 0x00000004;
   const ACCESS4_EXTEND    = 0x00000008;
   const ACCESS4_DELETE    = 0x00000010;
   const ACCESS4_EXECUTE   = 0x00000020;

   struct ACCESS4args {
           /* CURRENT_FH: object */
           uint32_t        access;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 201]
Internet-Draft                    NFSv4                      August 2013

15.3.3.  RESULT

   struct ACCESS4resok {
           uint32_t        supported;
           uint32_t        access;
   };

   union ACCESS4res switch (nfsstat4 status) {
    case NFS4_OK:
            ACCESS4resok   resok4;
    default:
            void;
   };

15.3.4.  DESCRIPTION

   ACCESS determines the access rights that a user, as identified by the
   credentials in the RPC request, has with respect to the file system
   object specified by the current filehandle.  The client encodes the
   set of access rights that are to be checked in the bit mask "access".
   The server checks the permissions encoded in the bit mask.  If a
   status of NFS4_OK is returned, two bit masks are included in the
   response.  The first, "supported", represents the access rights for
   which the server can verify reliably.  The second, "access",
   represents the access rights available to the user for the filehandle
   provided.  On success, the current filehandle retains its value.

   Note that the supported field will contain only as many values as
   were originally sent in the arguments.  For example, if the client
   sends an ACCESS operation with only the ACCESS4_READ value set and
   the server supports this value, the server will return only
   ACCESS4_READ even if it could have reliably checked other values.

   The results of this operation are necessarily advisory in nature.  A
   return status of NFS4_OK and the appropriate bit set in the bit mask
   does not imply that such access will be allowed to the file system
   object in the future.  This is because access rights can be revoked
   by the server at any time.

   The following access permissions may be requested:

   ACCESS4_READ:  Read data from file or read a directory.

   ACCESS4_LOOKUP:  Look up a name in a directory (no meaning for non-
      directory objects).

Haynes & Noveck         Expires February 17, 2014             [Page 202]
Internet-Draft                    NFSv4                      August 2013

   ACCESS4_MODIFY:  Rewrite existing file data or modify existing
      directory entries.

   ACCESS4_EXTEND:  Write new data or add directory entries.

   ACCESS4_DELETE:  Delete an existing directory entry.

   ACCESS4_EXECUTE:  Execute file (no meaning for a directory).

   On success, the current filehandle retains its value.

15.3.5.  IMPLEMENTATION

   In general, it is not sufficient for the client to attempt to deduce
   access permissions by inspecting the uid, gid, and mode fields in the
   file attributes or by attempting to interpret the contents of the ACL
   attribute.  This is because the server may perform uid or gid mapping
   or enforce additional access control restrictions.  It is also
   possible that the server may not be in the same ID space as the
   client.  In these cases (and perhaps others), the client cannot
   reliably perform an access check with only current file attributes.

   In the NFSv2 protocol, the only reliable way to determine whether an
   operation was allowed was to try it and see if it succeeded or
   failed.  Using the ACCESS operation in the NFSv4 protocol, the client
   can ask the server to indicate whether or not one or more classes of
   operations are permitted.  The ACCESS operation is provided to allow
   clients to check before doing a series of operations which might
   result in an access failure.  The OPEN operation provides a point
   where the server can verify access to the file object and method to
   return that information to the client.  The ACCESS operation is still
   useful for directory operations or for use in the case the UNIX API
   "access" is used on the client.

   The information returned by the server in response to an ACCESS call
   is not permanent.  It was correct at the exact time that the server
   performed the checks, but not necessarily afterward.  The server can
   revoke access permission at any time.

   The client should use the effective credentials of the user to build
   the authentication information in the ACCESS request used to
   determine access rights.  It is the effective user and group
   credentials that are used in subsequent read and write operations.

   Many implementations do not directly support the ACCESS4_DELETE
   permission.  Operating systems like UNIX will ignore the
   ACCESS4_DELETE bit if set on an access request on a non-directory
   object.  In these systems, delete permission on a file is determined

Haynes & Noveck         Expires February 17, 2014             [Page 203]
Internet-Draft                    NFSv4                      August 2013

   by the access permissions on the directory in which the file resides,
   instead of being determined by the permissions of the file itself.
   Therefore, the mask returned enumerating which access rights can be
   determined will have the ACCESS4_DELETE value set to 0.  This
   indicates to the client that the server was unable to check that
   particular access right.  The ACCESS4_DELETE bit in the access mask
   returned will then be ignored by the client.

15.4.  Operation 4: CLOSE - Close File

15.4.1.  SYNOPSIS

     (cfh), seqid, open_stateid -> open_stateid

15.4.2.  ARGUMENT

   struct CLOSE4args {
           /* CURRENT_FH: object */
           seqid4          seqid;
           stateid4        open_stateid;
   };

15.4.3.  RESULT

   union CLOSE4res switch (nfsstat4 status) {
    case NFS4_OK:
            stateid4       open_stateid;
    default:
            void;
   };

15.4.4.  DESCRIPTION

   The CLOSE operation releases share reservations for the regular or
   named attribute file as specified by the current filehandle.  The
   share reservations and other state information released at the server
   as a result of this CLOSE is only associated with the supplied
   stateid.  The sequence id provides for the correct ordering.  State
   associated with other OPENs is not affected.

   If byte-range locks are held, the client SHOULD release all locks
   before issuing a CLOSE.  The server MAY free all outstanding locks on
   CLOSE but some servers may not support the CLOSE of a file that still
   has byte-range locks held.  The server MUST return failure if any
   locks would exist after the CLOSE.

Haynes & Noveck         Expires February 17, 2014             [Page 204]
Internet-Draft                    NFSv4                      August 2013

   On success, the current filehandle retains its value.

15.4.5.  IMPLEMENTATION

   Even though CLOSE returns a stateid, this stateid is not useful to
   the client and should be treated as deprecated.  CLOSE "shuts down"
   the state associated with all OPENs for the file by a single open-
   owner.  As noted above, CLOSE will either release all file locking
   state or return an error.  Therefore, the stateid returned by CLOSE
   is not useful for operations that follow.

15.5.  Operation 5: COMMIT - Commit Cached Data

15.5.1.  SYNOPSIS

     (cfh), offset, count -> verifier

15.5.2.  ARGUMENT

   struct COMMIT4args {
           /* CURRENT_FH: file */
           offset4         offset;
           count4          count;
   };

15.5.3.  RESULT

   struct COMMIT4resok {
           verifier4       writeverf;
   };

   union COMMIT4res switch (nfsstat4 status) {
    case NFS4_OK:
            COMMIT4resok   resok4;
    default:
            void;
   };

15.5.4.  DESCRIPTION

   The COMMIT operation forces or flushes data to stable storage for the
   file specified by the current filehandle.  The flushed data is that
   which was previously written with a WRITE operation which had the
   stable field set to UNSTABLE4.

   The offset specifies the position within the file where the flush is

Haynes & Noveck         Expires February 17, 2014             [Page 205]
Internet-Draft                    NFSv4                      August 2013

   to begin.  An offset value of 0 (zero) means to flush data starting
   at the beginning of the file.  The count specifies the number of
   bytes of data to flush.  If count is 0 (zero), a flush from offset to
   the end of the file is done.

   The server returns a write verifier upon successful completion of the
   COMMIT.  The write verifier is used by the client to determine if the
   server has restarted or rebooted between the initial WRITE(s) and the
   COMMIT.  The client does this by comparing the write verifier
   returned from the initial writes and the verifier returned by the
   COMMIT operation.  The server must vary the value of the write
   verifier at each server event or instantiation that may lead to a
   loss of uncommitted data.  Most commonly this occurs when the server
   is rebooted; however, other events at the server may result in
   uncommitted data loss as well.

   On success, the current filehandle retains its value.

15.5.5.  IMPLEMENTATION

   The COMMIT operation is similar in operation and semantics to the
   POSIX fsync() [fsync] system call that synchronizes a file's state
   with the disk (file data and metadata is flushed to disk or stable
   storage).  COMMIT performs the same operation for a client, flushing
   any unsynchronized data and metadata on the server to the server's
   disk or stable storage for the specified file.  Like fsync(), it may
   be that there is some modified data or no modified data to
   synchronize.  The data may have been synchronized by the server's
   normal periodic buffer synchronization activity.  COMMIT should
   return NFS4_OK, unless there has been an unexpected error.

   COMMIT differs from fsync() in that it is possible for the client to
   flush a range of the file (most likely triggered by a buffer-
   reclamation scheme on the client before file has been completely
   written).

   The server implementation of COMMIT is reasonably simple.  If the
   server receives a full file COMMIT request, that is starting at
   offset 0 and count 0, it should do the equivalent of fsync()'ing the
   file.  Otherwise, it should arrange to have the cached data in the
   range specified by offset and count to be flushed to stable storage.
   In both cases, any metadata associated with the file must be flushed
   to stable storage before returning.  It is not an error for there to
   be nothing to flush on the server.  This means that the data and
   metadata that needed to be flushed have already been flushed or lost
   during the last server failure.

   The client implementation of COMMIT is a little more complex.  There

Haynes & Noveck         Expires February 17, 2014             [Page 206]
Internet-Draft                    NFSv4                      August 2013

   are two reasons for wanting to commit a client buffer to stable
   storage.  The first is that the client wants to reuse a buffer.  In
   this case, the offset and count of the buffer are sent to the server
   in the COMMIT request.  The server then flushes any cached data based
   on the offset and count, and flushes any metadata associated with the
   file.  It then returns the status of the flush and the write
   verifier.  The other reason for the client to generate a COMMIT is
   for a full file flush, such as may be done at close.  In this case,
   the client would gather all of the buffers for this file that contain
   uncommitted data, do the COMMIT operation with an offset of 0 and
   count of 0, and then free all of those buffers.  Any other dirty
   buffers would be sent to the server in the normal fashion.

   After a buffer is written by the client with the stable parameter set
   to UNSTABLE4, the buffer must be considered as modified by the client
   until the buffer has either been flushed via a COMMIT operation or
   written via a WRITE operation with stable parameter set to FILE_SYNC4
   or DATA_SYNC4.  This is done to prevent the buffer from being freed
   and reused before the data can be flushed to stable storage on the
   server.

   When a response is returned from either a WRITE or a COMMIT operation
   and it contains a write verifier that is different than previously
   returned by the server, the client will need to retransmit all of the
   buffers containing uncommitted cached data to the server.  How this
   is to be done is up to the implementor.  If there is only one buffer
   of interest, then it should probably be sent back over in a WRITE
   request with the appropriate stable parameter.  If there is more than
   one buffer, it might be worthwhile retransmitting all of the buffers
   in WRITE requests with the stable parameter set to UNSTABLE4 and then
   retransmitting the COMMIT operation to flush all of the data on the
   server to stable storage.  The timing of these retransmissions is
   left to the implementor.

   The above description applies to page-cache-based systems as well as
   buffer-cache-based systems.  In those systems, the virtual memory
   system will need to be modified instead of the buffer cache.

15.6.  Operation 6: CREATE - Create a Non-Regular File Object

15.6.1.  SYNOPSIS

     (cfh), name, type, attrs -> (cfh), cinfo, attrset

Haynes & Noveck         Expires February 17, 2014             [Page 207]
Internet-Draft                    NFSv4                      August 2013

15.6.2.  ARGUMENT

   union createtype4 switch (nfs_ftype4 type) {
    case NF4LNK:
            linktext4 linkdata;
    case NF4BLK:
    case NF4CHR:
            specdata4 devdata;
    case NF4SOCK:
    case NF4FIFO:
    case NF4DIR:
            void;
    default:
            void;  /* server should return NFS4ERR_BADTYPE */
   };

   struct CREATE4args {
           /* CURRENT_FH: directory for creation */
           createtype4     objtype;
           component4      objname;
           fattr4          createattrs;
   };

15.6.3.  RESULT

   struct CREATE4resok {
           change_info4    cinfo;
           bitmap4         attrset;        /* attributes set */
   };

   union CREATE4res switch (nfsstat4 status) {
    case NFS4_OK:
            CREATE4resok resok4;
    default:
            void;
   };

15.6.4.  DESCRIPTION

   The CREATE operation creates a non-regular file object in a directory
   with a given name.  The OPEN operation MUST be used to create a
   regular file.

   The objname specifies the name for the new object.  The objtype
   determines the type of object to be created: directory, symlink, etc.

Haynes & Noveck         Expires February 17, 2014             [Page 208]
Internet-Draft                    NFSv4                      August 2013

   If an object of the same name already exists in the directory, the
   server will return the error NFS4ERR_EXIST.

   For the directory where the new file object was created, the server
   returns change_info4 information in cinfo.  With the atomic field of
   the change_info4 struct, the server will indicate if the before and
   after change attributes were obtained atomically with respect to the
   file object creation.

   If the objname is of zero length, NFS4ERR_INVAL will be returned.
   The objname is also subject to the normal UTF-8, character support,
   and name checks.  See Section 12.5 for further discussion.

   If the objname has a length of 0 (zero), or if objname does not obey
   the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

   The current filehandle is replaced by that of the new object.

   The createattrs specifies the initial set of attributes for the
   object.  The set of attributes may include any writable attribute
   valid for the object type.  When the operation is successful, the
   server will return to the client an attribute mask signifying which
   attributes were successfully set for the object.

   If createattrs includes neither the owner attribute nor an ACL with
   an ACE for the owner, and if the server's file system both supports
   and requires an owner attribute (or an owner ACE) then the server
   MUST derive the owner (or the owner ACE).  This would typically be
   from the principal indicated in the RPC credentials of the call, but
   the server's operating environment or file system semantics may
   dictate other methods of derivation.  Similarly, if createattrs
   includes neither the group attribute nor a group ACE, and if the
   server's file system both supports and requires the notion of a group
   attribute (or group ACE), the server MUST derive the group attribute
   (or the corresponding owner ACE) for the file.  This could be from
   the RPC call's credentials, such as the group principal if the
   credentials include it (such as with AUTH_SYS), from the group
   identifier associated with the principal in the credentials (e.g.,
   POSIX systems have a user database [getpwnam] that has the group
   identifier for every user identifier), inherited from directory the
   object is created in, or whatever else the server's operating
   environment or file system semantics dictate.  This applies to the
   OPEN operation too.

   Conversely, it is possible the client will specify in createattrs an
   owner attribute or group attribute or ACL that the principal
   indicated the RPC call's credentials does not have permissions to
   create files for.  The error to be returned in this instance is

Haynes & Noveck         Expires February 17, 2014             [Page 209]
Internet-Draft                    NFSv4                      August 2013

   NFS4ERR_PERM.  This applies to the OPEN operation too.

15.6.5.  IMPLEMENTATION

   If the client desires to set attribute values after the create, a
   SETATTR operation can be added to the COMPOUND request so that the
   appropriate attributes will be set.

15.7.  Operation 7: DELEGPURGE - Purge Delegations Awaiting Recovery

15.7.1.  SYNOPSIS

     clientid ->

15.7.2.  ARGUMENT

   struct DELEGPURGE4args {
           clientid4       clientid;
   };

15.7.3.  RESULT

   struct DELEGPURGE4res {
           nfsstat4        status;
   };

15.7.4.  DESCRIPTION

   Purges all of the delegations awaiting recovery for a given client.
   This is useful for clients which do not commit delegation information
   to stable storage to indicate that conflicting requests need not be
   delayed by the server awaiting recovery of delegation information.

   This operation in provided to support clients that record delegation
   information on stable storage on the client.  In this case,
   DELEGPURGE should be issued immediately after doing delegation
   recovery (using CLAIM_DELEGATE_PREV) on all delegations known to the
   client.  Doing so will notify the server that no additional
   delegations for the client will be recovered allowing it to free
   resources, and avoid delaying other clients who make requests that
   conflict with the unrecovered delegations.  All client SHOULD use
   DELEGPURGE as part of recovery once it is known that no further
   CLAIM_DELEGATE_PREV recovery will be done.  This includes clients
   that do not record delegation information on stable storage, who
   would then do a DELEGPURGE immediately after SETCLIENTID_CONFIRM.

Haynes & Noveck         Expires February 17, 2014             [Page 210]
Internet-Draft                    NFSv4                      August 2013

   The set of delegations known to the server and the client may be
   different.  The reasons for this include:

   o  A client may fail after making a request which resulted in
      delegation but before it received the results and committed them
      to the client's stable storage.

   o  A client may fail after deleting its indication that a delegation
      exists but before the delegation return is fully processed by the
      server.

   o  In the case in which the server and the client restart, the server
      may have limited persistent recording of delegation to a subset of
      those in existence.

   o  A client may have only persistently recorded information about a
      subset of delegations.

   The server MAY support DELEGPURGE, but its support or non-support
   should match that of CLAIM_DELEGATE_PREV:

   o  A server may support both DELEGPURGE and CLAIM_DELEGATE_PREV.

   o  A server may support neither DELEGPURGE nor CLAIM_DELEGATE_PREV.

   This fact allows a client starting up to determine if the server is
   prepared to support persistent storage of delegation information and
   thus whether it may use write-back caching to local persistent
   storage, relying on CLAIM_DELEGATE_PREV recovery to allow such
   changed data to be flushed safely to the server in the event of
   client restart.

15.8.  Operation 8: DELEGRETURN - Return Delegation

15.8.1.  SYNOPSIS

     (cfh), stateid ->

15.8.2.  ARGUMENT

   struct DELEGRETURN4args {
           /* CURRENT_FH: delegated file */
           stateid4        deleg_stateid;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 211]
Internet-Draft                    NFSv4                      August 2013

15.8.3.  RESULT

   struct DELEGRETURN4res {
           nfsstat4        status;
   };

15.8.4.  DESCRIPTION

   Returns the delegation represented by the current filehandle and
   stateid.

   Delegations may be returned when recalled or voluntarily (i.e.,
   before the server has recalled them).  In either case the client must
   properly propagate state changed under the context of the delegation
   to the server before returning the delegation.

15.9.  Operation 9: GETATTR - Get Attributes

15.9.1.  SYNOPSIS

     (cfh), attrbits -> attrbits, attrvals

15.9.2.  ARGUMENT

   struct GETATTR4args {
           /* CURRENT_FH: directory or file */
           bitmap4         attr_request;
   };

15.9.3.  RESULT

   struct GETATTR4resok {
           fattr4          obj_attributes;
   };

   union GETATTR4res switch (nfsstat4 status) {
    case NFS4_OK:
            GETATTR4resok  resok4;
    default:
            void;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 212]
Internet-Draft                    NFSv4                      August 2013

15.9.4.  DESCRIPTION

   The GETATTR operation will obtain attributes for the file system
   object specified by the current filehandle.  The client sets a bit in
   the bitmap argument for each attribute value that it would like the
   server to return.  The server returns an attribute bitmap that
   indicates the attribute values for which it was able to return
   values, followed by the attribute values ordered lowest attribute
   number first.

   The server MUST return a value for each attribute that the client
   requests if the attribute is supported by the server.  If the server
   does not support an attribute or cannot approximate a useful value
   then it MUST NOT return the attribute value and MUST NOT set the
   attribute bit in the result bitmap.  The server MUST return an error
   if it supports an attribute on the target but cannot obtain its
   value.  In that case no attribute values will be returned.

   File systems which are absent should be treated as having support for
   a very small set of attributes as described in GETATTR Within an
   Absent File System (Section 8.3.1), even if previously, when the file
   system was present, more attributes were supported.

   All servers MUST support the REQUIRED attributes as specified in the
   section File Attributes (Section 5), for all file systems, with the
   exception of absent file systems.

   On success, the current filehandle retains its value.

15.9.5.  IMPLEMENTATION

   Suppose there is a OPEN_DELEGATE_WRITE delegation held by another
   client for file in question and size and/or change are among the set
   of attributes being interrogated.  The server has two choices.
   First, the server can obtain the actual current value of these
   attributes from the client holding the delegation by using the
   CB_GETATTR callback.  Second, the server, particularly when the
   delegated client is unresponsive, can recall the delegation in
   question.  The GETATTR MUST NOT proceed until one of the following
   occurs:

   o  The requested attribute values are returned in the response to
      CB_GETATTR.

   o  The OPEN_DELEGATE_WRITE delegation is returned.

   o  The OPEN_DELEGATE_WRITE delegation is revoked.

Haynes & Noveck         Expires February 17, 2014             [Page 213]
Internet-Draft                    NFSv4                      August 2013

   Unless one of the above happens very quickly, one or more
   NFS4ERR_DELAY errors will be returned while a delegation is
   outstanding.

15.10.  Operation 10: GETFH - Get Current Filehandle

15.10.1.  SYNOPSIS

     (cfh) -> filehandle

15.10.2.  ARGUMENT

     /* CURRENT_FH: */
     void;

15.10.3.  RESULT

   struct GETFH4resok {
           nfs_fh4         object;
   };

   union GETFH4res switch (nfsstat4 status) {
    case NFS4_OK:
           GETFH4resok     resok4;
    default:
           void;
   };

15.10.4.  DESCRIPTION

   This operation returns the current filehandle value.

   On success, the current filehandle retains its value.

15.10.5.  IMPLEMENTATION

   Operations that change the current filehandle like LOOKUP or CREATE
   do not automatically return the new filehandle as a result.  For
   instance, if a client needs to lookup a directory entry and obtain
   its filehandle then the following request is needed.

     PUTFH  (directory filehandle)
     LOOKUP (entry name)
     GETFH

Haynes & Noveck         Expires February 17, 2014             [Page 214]
Internet-Draft                    NFSv4                      August 2013

15.11.  Operation 11: LINK - Create Link to a File

15.11.1.  SYNOPSIS

     (sfh), (cfh), newname -> (cfh), cinfo

15.11.2.  ARGUMENT

   struct LINK4args {
           /* SAVED_FH: source object */
           /* CURRENT_FH: target directory */
           component4      newname;
   };

15.11.3.  RESULT

   struct LINK4resok {
           change_info4    cinfo;
   };

   union LINK4res switch (nfsstat4 status) {
    case NFS4_OK:
            LINK4resok resok4;
    default:
            void;
   };

15.11.4.  DESCRIPTION

   The LINK operation creates an additional newname for the file
   represented by the saved filehandle, as set by the SAVEFH operation,
   in the directory represented by the current filehandle.  The existing
   file and the target directory must reside within the same file system
   on the server.  On success, the current filehandle will continue to
   be the target directory.  If an object exists in the target directory
   with the same name as newname, the server must return NFS4ERR_EXIST.

   For the target directory, the server returns change_info4 information
   in cinfo.  With the atomic field of the change_info4 struct, the
   server will indicate if the before and after change attributes were
   obtained atomically with respect to the link creation.

   If the newname has a length of 0 (zero), or if newname does not obey
   the UTF-8 definition, the error NFS4ERR_INVAL will be returned.

Haynes & Noveck         Expires February 17, 2014             [Page 215]
Internet-Draft                    NFSv4                      August 2013

15.11.5.  IMPLEMENTATION

   Changes to any property of the "hard" linked files are reflected in
   all of the linked files.  When a link is made to a file, the
   attributes for the file should have a value for numlinks that is one
   greater than the value before the LINK operation.

   The statement "file and the target directory must reside within the
   same file system on the server" means that the fsid fields in the
   attributes for the objects are the same.  If they reside on different
   file systems, the error, NFS4ERR_XDEV, is returned.  On some servers,
   the filenames, "." and "..", are illegal as newname.

   In the case that newname is already linked to the file represented by
   the saved filehandle, the server will return NFS4ERR_EXIST.

   Note that symbolic links are created with the CREATE operation.

15.12.  Operation 12: LOCK - Create Lock

15.12.1.  SYNOPSIS

     (cfh) locktype, reclaim, offset, length, locker -> stateid

15.12.2.  ARGUMENT

   enum nfs_lock_type4 {
           READ_LT         = 1,
           WRITE_LT        = 2,
           READW_LT        = 3,    /* blocking read */
           WRITEW_LT       = 4     /* blocking write */
   };

Haynes & Noveck         Expires February 17, 2014             [Page 216]
Internet-Draft                    NFSv4                      August 2013

   /*
    * For LOCK, transition from open_owner to new lock_owner
    */
   struct open_to_lock_owner4 {
           seqid4          open_seqid;
           stateid4        open_stateid;
           seqid4          lock_seqid;
           lock_owner4     lock_owner;
   };

   /*
    * For LOCK, existing lock_owner continues to request file locks
    */
   struct exist_lock_owner4 {
           stateid4        lock_stateid;
           seqid4          lock_seqid;
   };

   union locker4 switch (bool new_lock_owner) {
    case TRUE:
           open_to_lock_owner4     open_owner;
    case FALSE:
           exist_lock_owner4       lock_owner;
   };

   /*
    * LOCK/LOCKT/LOCKU: Record lock management
    */
   struct LOCK4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           bool            reclaim;
           offset4         offset;
           length4         length;
           locker4         locker;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 217]
Internet-Draft                    NFSv4                      August 2013

15.12.3.  RESULT

   struct LOCK4denied {
           offset4         offset;
           length4         length;
           nfs_lock_type4  locktype;
           lock_owner4     owner;
   };

   struct LOCK4resok {
           stateid4        lock_stateid;
   };

   union LOCK4res switch (nfsstat4 status) {
    case NFS4_OK:
            LOCK4resok     resok4;
    case NFS4ERR_DENIED:
            LOCK4denied    denied;
    default:
            void;
   };

15.12.4.  DESCRIPTION

   The LOCK operation requests a byte-range lock for the byte range
   specified by the offset and length parameters.  The lock type is also
   specified to be one of the nfs_lock_type4s.  If this is a reclaim
   request, the reclaim parameter will be TRUE;

   Bytes in a file may be locked even if those bytes are not currently
   allocated to the file.  To lock the file from a specific offset
   through the end-of-file (no matter how long the file actually is) use
   a length field with all bits set to 1 (one).  If the length is zero,
   or if a length which is not all bits set to one is specified, and
   length when added to the offset exceeds the maximum 64-bit unsigned
   integer value, the error NFS4ERR_INVAL will result.

   Some servers may only support locking for byte offsets that fit
   within 32 bits.  If the client specifies a range that includes a byte
   beyond the last byte offset of the 32-bit range, but does not include
   the last byte offset of the 32-bit and all of the byte offsets beyond
   it, up to the end of the valid 64-bit range, such a 32-bit server
   MUST return the error NFS4ERR_BAD_RANGE.

   In the case that the lock is denied, the owner, offset, and length of
   a conflicting lock are returned.

Haynes & Noveck         Expires February 17, 2014             [Page 218]
Internet-Draft                    NFSv4                      August 2013

   On success, the current filehandle retains its value.

15.12.5.  IMPLEMENTATION

   If the server is unable to determine the exact offset and length of
   the conflicting lock, the same offset and length that were provided
   in the arguments should be returned in the denied results.  Section 9
   contains a full description of this and the other file locking
   operations.

   LOCK operations are subject to permission checks and to checks
   against the access type of the associated file.  However, the
   specific right and modes required for various type of locks, reflect
   the semantics of the server-exported file system, and are not
   specified by the protocol.  For example, Windows 2000 allows a write
   lock of a file open for READ, while a POSIX-compliant system does
   not.

   When the client makes a lock request that corresponds to a range that
   the lock-owner has locked already (with the same or different lock
   type), or to a sub-region of such a range, or to a region which
   includes multiple locks already granted to that lock-owner, in whole
   or in part, and the server does not support such locking operations
   (i.e., does not support POSIX locking semantics), the server will
   return the error NFS4ERR_LOCK_RANGE.  In that case, the client may
   return an error, or it may emulate the required operations, using
   only LOCK for ranges that do not include any bytes already locked by
   that lock-owner and LOCKU of locks held by that lock-owner
   (specifying an exactly-matching range and type).  Similarly, when the
   client makes a lock request that amounts to upgrading (changing from
   a read lock to a write lock) or downgrading (changing from write lock
   to a read lock) an existing record lock, and the server does not
   support such a lock, the server will return NFS4ERR_LOCK_NOTSUPP.
   Such operations may not perfectly reflect the required semantics in
   the face of conflicting lock requests from other clients.

   When a client holds an OPEN_DELEGATE_WRITE delegation, the client
   holding that delegation is assured that there are no opens by other
   clients.  Thus, there can be no conflicting LOCK operations from such
   clients.  Therefore, the client may be handling locking requests
   locally, without doing LOCK operations on the server.  If it does
   that, it must be prepared to update the lock status on the server, by
   sending appropriate LOCK and LOCKU operations before returning the
   delegation.

   When one or more clients hold OPEN_DELEGATE_READ delegations, any
   LOCK operation where the server is implementing mandatory locking
   semantics MUST result in the recall of all such delegations.  The

Haynes & Noveck         Expires February 17, 2014             [Page 219]
Internet-Draft                    NFSv4                      August 2013

   LOCK operation may not be granted until all such delegations are
   returned or revoked.  Except where this happens very quickly, one or
   more NFS4ERR_DELAY errors will be returned to requests made while the
   delegation remains outstanding.

   The locker argument specifies the lock-owner that is associated with
   the LOCK request.  The locker4 structure is a switched union that
   indicates whether the client has already created byte-range locking
   state associated with the current open file and lock-owner.  There
   are multiple cases to be considered, corresponding to possible
   combinations of whether locking state has been created for the
   current open file and lock-owner, and whether the boolean
   new_lock_owner is set.  In all of the cases, there is a lock_seqid
   specified, whether the lock-owner is specified explicitly or
   implicitly.  This seqid value is used for checking lock-owner
   sequencing/replay issues.  When the given lock-owner is not known to
   the server, this establishes an initial sequence value for the new
   lock-owner.

   o  In the case in which the state has been created and the boolean is
      false, the only part of the argument other than lock_seqid is just
      a stateid representing the set of locks associated with that open
      file and lock-owner.

   o  In the case in which the state has been created and the boolean is
      true, the server rejects the request with the error
      NFS4ERR_BAD_SEQID.  The only exception is where there is a
      retransmission of a previous request in which the boolean was
      true.  In this case, the lock_seqid will match the original
      request and the response will reflect the final case, below.

   o  In the case where no byte-range locking state has been established
      and the boolean is true, the argument contains an
      open_to_lock_owner structure which specifies the stateid of the
      open file and the lock-owner to be used for the lock.  Note that
      although the open-owner is not given explicitly, the open_seqid
      associated with it is used to check for open-owner sequencing
      issues.  This case provides a method to use the established state
      of the open_stateid to transition to the use of a lock stateid.

15.13.  Operation 13: LOCKT - Test For Lock

15.13.1.  SYNOPSIS

     (cfh) locktype, offset, length, owner -> {void, NFS4ERR_DENIED ->
     owner}

Haynes & Noveck         Expires February 17, 2014             [Page 220]
Internet-Draft                    NFSv4                      August 2013

15.13.2.  ARGUMENT

   struct LOCKT4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           offset4         offset;
           length4         length;
           lock_owner4     owner;
   };

15.13.3.  RESULT

   union LOCKT4res switch (nfsstat4 status) {
    case NFS4ERR_DENIED:
            LOCK4denied    denied;
    case NFS4_OK:
            void;
    default:
            void;
   };

15.13.4.  DESCRIPTION

   The LOCKT operation tests the lock as specified in the arguments.  If
   a conflicting lock exists, the owner, offset, length, and type of the
   conflicting lock are returned; if no lock is held, nothing other than
   NFS4_OK is returned.  Lock types READ_LT and READW_LT are processed
   in the same way in that a conflicting lock test is done without
   regard to blocking or non-blocking.  The same is true for WRITE_LT
   and WRITEW_LT.

   The ranges are specified as for LOCK.  The NFS4ERR_INVAL and
   NFS4ERR_BAD_RANGE errors are returned under the same circumstances as
   for LOCK.

   On success, the current filehandle retains its value.

15.13.5.  IMPLEMENTATION

   If the server is unable to determine the exact offset and length of
   the conflicting lock, the same offset and length that were provided
   in the arguments should be returned in the denied results.  Section 9
   contains further discussion of the file locking mechanisms.

   LOCKT uses a lock_owner4 rather a stateid4, as is used in LOCK to
   identify the owner.  This is because the client does not have to open

Haynes & Noveck         Expires February 17, 2014             [Page 221]
Internet-Draft                    NFSv4                      August 2013

   the file to test for the existence of a lock, so a stateid may not be
   available.

   The test for conflicting locks SHOULD exclude locks for the current
   lock-owner.  Note that since such locks are not examined the possible
   existence of overlapping ranges may not affect the results of LOCKT.
   If the server does examine locks that match the lock-owner for the
   purpose of range checking, NFS4ERR_LOCK_RANGE may be returned.  In
   the event that it returns NFS4_OK, clients may do a LOCK and receive
   NFS4ERR_LOCK_RANGE on the LOCK request because of the flexibility
   provided to the server.

   When a client holds an OPEN_DELEGATE_WRITE delegation, it may choose
   (see Section 15.12.5)) to handle LOCK requests locally.  In such a
   case, LOCKT requests will similarly be handled locally.

15.14.  Operation 14: LOCKU - Unlock File

15.14.1.  SYNOPSIS

     (cfh) type, seqid, stateid, offset, length -> stateid

15.14.2.  ARGUMENT

   struct LOCKU4args {
           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           seqid4          seqid;
           stateid4        lock_stateid;
           offset4         offset;
           length4         length;
   };

15.14.3.  RESULT

   union LOCKU4res switch (nfsstat4 status) {
    case   NFS4_OK:
            stateid4       lock_stateid;
    default:
            void;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 222]
Internet-Draft                    NFSv4                      August 2013

15.14.4.  DESCRIPTION

   The LOCKU operation unlocks the byte-range lock specified by the
   parameters.  The client may set the locktype field to any value that
   is legal for the nfs_lock_type4 enumerated type, and the server MUST
   accept any legal value for locktype.  Any legal value for locktype
   has no effect on the success or failure of the LOCKU operation.

   The ranges are specified as for LOCK.  The NFS4ERR_INVAL and
   NFS4ERR_BAD_RANGE errors are returned under the same circumstances as
   for LOCK.

   On success, the current filehandle retains its value.

15.14.5.  IMPLEMENTATION

   If the area to be unlocked does not correspond exactly to a lock
   actually held by the lock-owner the server may return the error
   NFS4ERR_LOCK_RANGE.  This includes the case in which the area is not
   locked, where the area is a sub-range of the area locked, where it
   overlaps the area locked without matching exactly or the area
   specified includes multiple locks held by the lock-owner.  In all of
   these cases, allowed by POSIX locking [fcntl] semantics, a client
   receiving this error, should if it desires support for such
   operations, simulate the operation using LOCKU on ranges
   corresponding to locks it actually holds, possibly followed by LOCK
   requests for the sub-ranges not being unlocked.

   When a client holds an OPEN_DELEGATE_WRITE delegation, it may choose
   (see Section 15.12.5)) to handle LOCK requests locally.  In such a
   case, LOCKU requests will similarly be handled locally.

15.15.  Operation 15: LOOKUP - Lookup Filename

15.15.1.  SYNOPSIS

     (cfh), component -> (cfh)

15.15.2.  ARGUMENT

   struct LOOKUP4args {
           /* CURRENT_FH: directory */
           component4      objname;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 223]
Internet-Draft                    NFSv4                      August 2013

15.15.3.  RESULT

   struct LOOKUP4res {
           /* CURRENT_FH: object */
           nfsstat4        status;
   };

15.15.4.  DESCRIPTION

   This operation LOOKUPs or finds a file system object using the
   directory specified by the current filehandle.  LOOKUP evaluates the
   component and if the object exists the current filehandle is replaced
   with the component's filehandle.

   If the component cannot be evaluated either because it does not exist
   or because the client does not have permission to evaluate the
   component, then an error will be returned and the current filehandle
   will be unchanged.

   If the component is of zero length, NFS4ERR_INVAL will be returned.
   The component is also subject to the normal UTF-8, character support,
   and name checks.  See Section 12.5 for further discussion.

15.15.5.  IMPLEMENTATION

   If the client wants to achieve the effect of a multi-component
   lookup, it may construct a COMPOUND request such as (and obtain each
   filehandle):

     PUTFH  (directory filehandle)
     LOOKUP "pub"
     GETFH
     LOOKUP "foo"
     GETFH
     LOOKUP "bar"
     GETFH

   NFSv4 servers depart from the semantics of previous NFS versions in
   allowing LOOKUP requests to cross mount points on the server.  The
   client can detect a mount point crossing by comparing the fsid
   attribute of the directory with the fsid attribute of the directory
   looked up.  If the fsids are different then the new directory is a
   server mount point.  UNIX clients that detect a mount point crossing
   will need to mount the server's file system.  This needs to be done
   to maintain the file object identity checking mechanisms common to
   UNIX clients.

Haynes & Noveck         Expires February 17, 2014             [Page 224]
Internet-Draft                    NFSv4                      August 2013

   Servers that limit NFS access to "shares" or "exported" file systems
   should provide a pseudo-file system into which the exported file
   systems can be integrated, so that clients can browse the server's
   name space.  The clients' view of a pseudo file system will be
   limited to paths that lead to exported file systems.

   Note: previous versions of the protocol assigned special semantics to
   the names "." and "..".  NFSv4 assigns no special semantics to these
   names.  The LOOKUPP operator must be used to lookup a parent
   directory.

   Note that this operation does not follow symbolic links.  The client
   is responsible for all parsing of filenames including filenames that
   are modified by symbolic links encountered during the lookup process.

   If the current filehandle supplied is not a directory but a symbolic
   link, the error NFS4ERR_SYMLINK is returned as the error.  For all
   other non-directory file types, the error NFS4ERR_NOTDIR is returned.

15.16.  Operation 16: LOOKUPP - Lookup Parent Directory

15.16.1.  SYNOPSIS

     (cfh) -> (cfh)

15.16.2.  ARGUMENT

     /* CURRENT_FH: object */
     void;

15.16.3.  RESULT

   struct LOOKUPP4res {
           /* CURRENT_FH: directory */
           nfsstat4        status;
   };

15.16.4.  DESCRIPTION

   The current filehandle is assumed to refer to a regular directory or
   a named attribute directory.  LOOKUPP assigns the filehandle for its
   parent directory to be the current filehandle.  If there is no parent
   directory an NFS4ERR_NOENT error must be returned.  Therefore,
   NFS4ERR_NOENT will be returned by the server when the current
   filehandle is at the root or top of the server's file tree.

Haynes & Noveck         Expires February 17, 2014             [Page 225]
Internet-Draft                    NFSv4                      August 2013

15.16.5.  IMPLEMENTATION

   As for LOOKUP, LOOKUPP will also cross mount points.

   If the current filehandle is not a directory or named attribute
   directory, the error NFS4ERR_NOTDIR is returned.

15.17.  Operation 17: NVERIFY - Verify Difference in Attributes

15.17.1.  SYNOPSIS

     (cfh), fattr -> -

15.17.2.  ARGUMENT

   struct NVERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };

15.17.3.  RESULT

   struct NVERIFY4res {
           nfsstat4        status;
   };

15.17.4.  DESCRIPTION

   This operation is used to prefix a sequence of operations to be
   performed if one or more attributes have changed on some file system
   object.  If all the attributes match then the error NFS4ERR_SAME must
   be returned.

   On success, the current filehandle retains its value.

15.17.5.  IMPLEMENTATION

   This operation is useful as a cache validation operator.  If the
   object to which the attributes belong has changed then the following
   operations may obtain new data associated with that object.  For
   instance, to check if a file has been changed and obtain new data if
   it has:

     PUTFH  (public)
     LOOKUP "foobar"
     NVERIFY attrbits attrs

Haynes & Noveck         Expires February 17, 2014             [Page 226]
Internet-Draft                    NFSv4                      August 2013

     READ 0 32767

   In the case that a recommended attribute is specified in the NVERIFY
   operation and the server does not support that attribute for the file
   system object, the error NFS4ERR_ATTRNOTSUPP is returned to the
   client.

   When the attribute rdattr_error or any write-only attribute (e.g.,
   time_modify_set) is specified, the error NFS4ERR_INVAL is returned to
   the client.

15.18.  Operation 18: OPEN - Open a Regular File

15.18.1.  SYNOPSIS

     (cfh), seqid, share_access, share_deny, owner, openhow, claim ->
     (cfh), stateid, cinfo, rflags, attrset, delegation

15.18.2.  ARGUMENT

   /*
    * Various definitions for OPEN
    */
   enum createmode4 {
           UNCHECKED4      = 0,
           GUARDED4        = 1,
           EXCLUSIVE4      = 2
   };

   union createhow4 switch (createmode4 mode) {
    case UNCHECKED4:
    case GUARDED4:
            fattr4         createattrs;
    case EXCLUSIVE4:
            verifier4      createverf;
   };

   enum opentype4 {
           OPEN4_NOCREATE  = 0,
           OPEN4_CREATE    = 1
   };

   union openflag4 switch (opentype4 opentype) {
    case OPEN4_CREATE:
            createhow4     how;
    default:
            void;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 227]
Internet-Draft                    NFSv4                      August 2013

   /* Next definitions used for OPEN delegation */
   enum limit_by4 {
           NFS_LIMIT_SIZE          = 1,
           NFS_LIMIT_BLOCKS        = 2
           /* others as needed */
   };

   struct nfs_modified_limit4 {
           uint32_t        num_blocks;
           uint32_t        bytes_per_block;
   };

   union nfs_space_limit4 switch (limit_by4 limitby) {
    /* limit specified as file size */
    case NFS_LIMIT_SIZE:
            uint64_t               filesize;
    /* limit specified by number of blocks */
    case NFS_LIMIT_BLOCKS:
            nfs_modified_limit4    mod_blocks;
   } ;

   enum open_delegation_type4 {
           OPEN_DELEGATE_NONE      = 0,
           OPEN_DELEGATE_READ      = 1,
           OPEN_DELEGATE_WRITE     = 2
   };

   enum open_claim_type4 {
           CLAIM_NULL              = 0,
           CLAIM_PREVIOUS          = 1,
           CLAIM_DELEGATE_CUR      = 2,
           CLAIM_DELEGATE_PREV     = 3
   };

   struct open_claim_delegate_cur4 {
           stateid4        delegate_stateid;
           component4      file;
   };

   union open_claim4 switch (open_claim_type4 claim) {
    /*
     * No special rights to file.
     * Ordinary OPEN of the specified file.
     */
    case CLAIM_NULL:
           /* CURRENT_FH: directory */
           component4      file;
    /*

Haynes & Noveck         Expires February 17, 2014             [Page 228]
Internet-Draft                    NFSv4                      August 2013

     * Right to the file established by an
     * open previous to server reboot. File
     * identified by filehandle obtained at
     * that time rather than by name.
     */
    case CLAIM_PREVIOUS:
           /* CURRENT_FH: file being reclaimed */
           open_delegation_type4   delegate_type;

    /*
     * Right to file based on a delegation
     * granted by the server. File is
     * specified by name.
     */
    case CLAIM_DELEGATE_CUR:
           /* CURRENT_FH: directory */
           open_claim_delegate_cur4        delegate_cur_info;

    /*
     * Right to file based on a delegation
     * granted to a previous boot instance
     * of the client.  File is specified by name.
     */
    case CLAIM_DELEGATE_PREV:
            /* CURRENT_FH: directory */
           component4      file_delegate_prev;
   };

   /*
    * OPEN: Open a file, potentially receiving an open delegation
    */
   struct OPEN4args {
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
           open_owner4     owner;
           openflag4       openhow;
           open_claim4     claim;
   };

15.18.3.  RESULT

   struct open_read_delegation4 {
    stateid4 stateid;    /* Stateid for delegation*/
    bool     recall;     /* Pre-recalled flag for
                            delegations obtained
                            by reclaim (CLAIM_PREVIOUS) */

Haynes & Noveck         Expires February 17, 2014             [Page 229]
Internet-Draft                    NFSv4                      August 2013

    nfsace4 permissions; /* Defines users who don't
                            need an ACCESS call to
                            open for read */
   };

   struct open_write_delegation4 {
    stateid4 stateid;      /* Stateid for delegation */
    bool     recall;       /* Pre-recalled flag for
                              delegations obtained
                              by reclaim
                              (CLAIM_PREVIOUS) */

    nfs_space_limit4
              space_limit; /* Defines condition that
                              the client must check to
                              determine whether the
                              file needs to be flushed
                              to the server on close.  */

    nfsace4   permissions; /* Defines users who don't
                              need an ACCESS call as
                              part of a delegated
                              open. */
   };

   union open_delegation4
   switch (open_delegation_type4 delegation_type) {
           case OPEN_DELEGATE_NONE:
                   void;
           case OPEN_DELEGATE_READ:
                   open_read_delegation4 read;
           case OPEN_DELEGATE_WRITE:
                   open_write_delegation4 write;
   };

   /*
    * Result flags
    */

   /* Client must confirm open */
   const OPEN4_RESULT_CONFIRM      = 0x00000002;
   /* Type of file locking behavior at the server */
   const OPEN4_RESULT_LOCKTYPE_POSIX = 0x00000004;

   struct OPEN4resok {
    stateid4       stateid;      /* Stateid for open */
    change_info4   cinfo;        /* Directory Change Info */
    uint32_t       rflags;       /* Result flags */

Haynes & Noveck         Expires February 17, 2014             [Page 230]
Internet-Draft                    NFSv4                      August 2013

    bitmap4        attrset;      /* attribute set for create*/
    open_delegation4 delegation; /* Info on any open
                                    delegation */
   };

   union OPEN4res switch (nfsstat4 status) {
    case NFS4_OK:
           /* CURRENT_FH: opened file */
           OPEN4resok      resok4;
    default:
           void;
   };

15.18.4.  Warning to Client Implementors

   OPEN resembles LOOKUP in that it generates a filehandle for the
   client to use.  Unlike LOOKUP though, OPEN creates server state on
   the filehandle.  In normal circumstances, the client can only release
   this state with a CLOSE operation.  CLOSE uses the current filehandle
   to determine which file to close.  Therefore, the client MUST follow
   every OPEN operation with a GETFH operation in the same COMPOUND
   procedure.  This will supply the client with the filehandle such that
   CLOSE can be used appropriately.

   Simply waiting for the lease on the file to expire is insufficient
   because the server may maintain the state indefinitely as long as
   another client does not attempt to make a conflicting access to the
   same file.

15.18.5.  DESCRIPTION

   The OPEN operation creates and/or opens a regular file in a directory
   with the provided name.  If the file does not exist at the server and
   creation is desired, specification of the method of creation is
   provided by the openhow parameter.  The client has the choice of
   three creation methods: UNCHECKED4, GUARDED4, or EXCLUSIVE4.

   If the current filehandle is a named attribute directory, OPEN will
   then create or open a named attribute file.  Note that exclusive
   create of a named attribute is not supported.  If the createmode is
   EXCLUSIVE4 and the current filehandle is a named attribute directory,
   the server will return EINVAL.

   UNCHECKED4 means that the file should be created if a file of that
   name does not exist and encountering an existing regular file of that
   name is not an error.  For this type of create, createattrs specifies
   the initial set of attributes for the file.  The set of attributes

Haynes & Noveck         Expires February 17, 2014             [Page 231]
Internet-Draft                    NFSv4                      August 2013

   may include any writable attribute valid for regular files.  When an
   UNCHECKED4 create encounters an existing file, the attributes
   specified by createattrs are not used, except that when an size of
   zero is specified, the existing file is truncated.  If GUARDED4 is
   specified, the server checks for the presence of a duplicate object
   by name before performing the create.  If a duplicate exists, an
   error of NFS4ERR_EXIST is returned as the status.  If the object does
   not exist, the request is performed as described for UNCHECKED4.  For
   each of these cases (UNCHECKED4 and GUARDED4) where the operation is
   successful, the server will return to the client an attribute mask
   signifying which attributes were successfully set for the object.

   EXCLUSIVE4 specifies that the server is to follow exclusive creation
   semantics, using the verifier to ensure exclusive creation of the
   target.  The server should check for the presence of a duplicate
   object by name.  If the object does not exist, the server creates the
   object and stores the verifier with the object.  If the object does
   exist and the stored verifier matches the client provided verifier,
   the server uses the existing object as the newly created object.  If
   the stored verifier does not match, then an error of NFS4ERR_EXIST is
   returned.  No attributes may be provided in this case, since the
   server may use an attribute of the target object to store the
   verifier.  If the server uses an attribute to store the exclusive
   create verifier, it will signify which attribute by setting the
   appropriate bit in the attribute mask that is returned in the
   results.

   For the target directory, the server returns change_info4 information
   in cinfo.  With the atomic field of the change_info4 struct, the
   server will indicate if the before and after change attributes were
   obtained atomically with respect to the link creation.

   Upon successful creation, the current filehandle is replaced by that
   of the new object.

   The OPEN operation provides for Windows share reservation capability
   with the use of the share_access and share_deny fields of the OPEN
   arguments.  The client specifies at OPEN the required share_access
   and share_deny modes.  For clients that do not directly support
   SHAREs (i.e., UNIX), the expected deny value is DENY_NONE.  In the
   case that there is a existing SHARE reservation that conflicts with
   the OPEN request, the server returns the error NFS4ERR_SHARE_DENIED.
   For a complete SHARE request, the client must provide values for the
   owner and seqid fields for the OPEN argument.  For additional
   discussion of SHARE semantics see Section 9.9.

   In the case that the client is recovering state from a server
   failure, the claim field of the OPEN argument is used to signify that

Haynes & Noveck         Expires February 17, 2014             [Page 232]
Internet-Draft                    NFSv4                      August 2013

   the request is meant to reclaim state previously held.

   The "claim" field of the OPEN argument is used to specify the file to
   be opened and the state information which the client claims to
   possess.  There are four basic claim types which cover the various
   situations for an OPEN.  They are as follows:

   CLAIM_NULL:  For the client, this is a new OPEN request and there is
      no previous state associate with the file for the client.

   CLAIM_PREVIOUS:  The client is claiming basic OPEN state for a file
      that was held previous to a server reboot.  Generally used when a
      server is returning persistent filehandles; the client may not
      have the file name to reclaim the OPEN.

   CLAIM_DELEGATE_CUR:  The client is claiming a delegation for OPEN as
      granted by the server.  Generally this is done as part of
      recalling a delegation.

   CLAIM_DELEGATE_PREV:  The client is claiming a delegation granted to
      a previous client instance.  This claim type is for use after a
      SETCLIENTID_CONFIRM and before the corresponding DELEGPURGE in two
      situations: after a client reboot and after a lease expiration
      that resulted in loss of all lock state.  The server MAY support
      CLAIM_DELEGATE_PREV.  If it does support CLAIM_DELEGATE_PREV,
      SETCLIENTID_CONFIRM MUST NOT remove the client's delegation state,
      and the server MUST support the DELEGPURGE operation.

   The following errors apply to use of the CLAIM_DELEGATE_PREV claim
   type:

   o  NFS4ERR_NOTSUPP is returned if the server does not support this
      claim type.

   o  NFS4ERR_INVAL is returned if the reclaim is done at an
      inappropriate time, e.g., after DELEGPURGE has been done.

   o  NFS4ERR_BAD_RECLAIM is returned if the other error conditions do
      not apply and the server has no record of the delegation whose
      reclaim is being attempted.

   For OPEN requests whose claim type is other than CLAIM_PREVIOUS
   (i.e., requests other than those devoted to reclaiming opens after a
   server reboot) that reach the server during its grace or lease
   expiration period, the server returns an error of NFS4ERR_GRACE.

   For any OPEN request, the server may return an open delegation, which
   allows further opens and closes to be handled locally on the client

Haynes & Noveck         Expires February 17, 2014             [Page 233]
Internet-Draft                    NFSv4                      August 2013

   as described in Section 10.4.  Note that delegation is up to the
   server to decide.  The client should never assume that delegation
   will or will not be granted in a particular instance.  It should
   always be prepared for either case.  A partial exception is the
   reclaim (CLAIM_PREVIOUS) case, in which a delegation type is claimed.
   In this case, delegation will always be granted, although the server
   may specify an immediate recall in the delegation structure.

   The rflags returned by a successful OPEN allow the server to return
   information governing how the open file is to be handled.

   OPEN4_RESULT_CONFIRM indicates that the client MUST execute an
   OPEN_CONFIRM operation before using the open file.
   OPEN4_RESULT_LOCKTYPE_POSIX indicates the server's file locking
   behavior supports the complete set of Posix locking techniques
   [fcntl].  From this the client can choose to manage file locking
   state in a way to handle a mis-match of file locking management.

   If the component is of zero length, NFS4ERR_INVAL will be returned.
   The component is also subject to the normal UTF-8, character support,
   and name checks.  See Section 12.5 for further discussion.

   When an OPEN is done and the specified open-owner already has the
   resulting filehandle open, the result is to "OR" together the new
   share and deny status together with the existing status.  In this
   case, only a single CLOSE need be done, even though multiple OPENs
   were completed.  When such an OPEN is done, checking of share
   reservations for the new OPEN proceeds normally, with no exception
   for the existing OPEN held by the same owner.  In this case, the
   stateid returned as an "other" field that matches that of the
   previous open while the "seqid" field is incremented to reflect the
   change status due to the new open.

   If the underlying file system at the server is only accessible in a
   read-only mode and the OPEN request has specified ACCESS_WRITE or
   ACCESS_BOTH, the server will return NFS4ERR_ROFS to indicate a read-
   only file system.

   As with the CREATE operation, the server MUST derive the owner, owner
   ACE, group, or group ACE if any of the four attributes are required
   and supported by the server's file system.  For an OPEN with the
   EXCLUSIVE4 createmode, the server has no choice, since such OPEN
   calls do not include the createattrs field.  Conversely, if
   createattrs is specified, and includes owner or group (or
   corresponding ACEs) that the principal in the RPC call's credentials
   does not have authorization to create files for, then the server may
   return NFS4ERR_PERM.

Haynes & Noveck         Expires February 17, 2014             [Page 234]
Internet-Draft                    NFSv4                      August 2013

   In the case of a OPEN which specifies a size of zero (e.g.,
   truncation) and the file has named attributes, the named attributes
   are left as is.  They are not removed.

15.18.6.  IMPLEMENTATION

   The OPEN operation contains support for EXCLUSIVE4 create.  The
   mechanism is similar to the support in NFSv3 [RFC1813].  As in NFSv3,
   this mechanism provides reliable exclusive creation.  Exclusive
   create is invoked when the how parameter is EXCLUSIVE4.  In this
   case, the client provides a verifier that can reasonably be expected
   to be unique.  A combination of a client identifier, perhaps the
   client network address, and a unique number generated by the client,
   perhaps the RPC transaction identifier, may be appropriate.

   If the object does not exist, the server creates the object and
   stores the verifier in stable storage.  For file systems that do not
   provide a mechanism for the storage of arbitrary file attributes, the
   server may use one or more elements of the object meta-data to store
   the verifier.  The verifier must be stored in stable storage to
   prevent erroneous failure on retransmission of the request.  It is
   assumed that an exclusive create is being performed because exclusive
   semantics are critical to the application.  Because of the expected
   usage, exclusive CREATE does not rely solely on the normally volatile
   duplicate request cache for storage of the verifier.  The duplicate
   request cache in volatile storage does not survive a crash and may
   actually flush on a long network partition, opening failure windows.
   In the UNIX local file system environment, the expected storage
   location for the verifier on creation is the meta-data (time stamps)
   of the object.  For this reason, an exclusive object create may not
   include initial attributes because the server would have nowhere to
   store the verifier.

   If the server cannot support these exclusive create semantics,
   possibly because of the requirement to commit the verifier to stable
   storage, it should fail the OPEN request with the error,
   NFS4ERR_NOTSUPP.

   During an exclusive CREATE request, if the object already exists, the
   server reconstructs the object's verifier and compares it with the
   verifier in the request.  If they match, the server treats the
   request as a success.  The request is presumed to be a duplicate of
   an earlier, successful request for which the reply was lost and that
   the server duplicate request cache mechanism did not detect.  If the
   verifiers do not match, the request is rejected with the status,
   NFS4ERR_EXIST.

   Once the client has performed a successful exclusive create, it must

Haynes & Noveck         Expires February 17, 2014             [Page 235]
Internet-Draft                    NFSv4                      August 2013

   issue a SETATTR to set the correct object attributes.  Until it does
   so, it should not rely upon any of the object attributes, since the
   server implementation may need to overload object meta-data to store
   the verifier.  The subsequent SETATTR must not occur in the same
   COMPOUND request as the OPEN.  This separation will guarantee that
   the exclusive create mechanism will continue to function properly in
   the face of retransmission of the request.

   Use of the GUARDED4 attribute does not provide exactly-once
   semantics.  In particular, if a reply is lost and the server does not
   detect the retransmission of the request, the operation can fail with
   NFS4ERR_EXIST, even though the create was performed successfully.
   The client would use this behavior in the case that the application
   has not requested an exclusive create but has asked to have the file
   truncated when the file is opened.  In the case of the client timing
   out and retransmitting the create request, the client can use
   GUARDED4 to prevent against a sequence like: create, write, create
   (retransmitted) from occurring.

   For SHARE reservations, the client must specify a value for
   share_access that is one of READ, WRITE, or BOTH.  For share_deny,
   the client must specify one of NONE, READ, WRITE, or BOTH.  If the
   client fails to do this, the server must return NFS4ERR_INVAL.

   Based on the share_access value (READ, WRITE, or BOTH) the client
   should check that the requester has the proper access rights to
   perform the specified operation.  This would generally be the results
   of applying the ACL access rules to the file for the current
   requester.  However, just as with the ACCESS operation, the client
   should not attempt to second-guess the server's decisions, as access
   rights may change and may be subject to server administrative
   controls outside the ACL framework.  If the requester is not
   authorized to READ or WRITE (depending on the share_access value),
   the server must return NFS4ERR_ACCESS.  Note that since the NFS
   version 4 protocol does not impose any requirement that READs and
   WRITEs issued for an open file have the same credentials as the OPEN
   itself, the server still must do appropriate access checking on the
   READs and WRITEs themselves.

   If the component provided to OPEN resolves to something other than a
   regular file, an error will be returned to the client.  If it is a
   directory, NFS4ERR_ISDIR is returned; otherwise, NFS4ERR_SYMLINK is
   returned.  Note that NFS4ERR_SYMLINK is returned for both symlinks
   and for special files of other types; NFS4ERR_INVAL would be
   inappropriate, since the arguments provided by the client were
   correct, and the client cannot necessarily know at the time it sent
   the OPEN that the component would resolve to a non-regular file.

Haynes & Noveck         Expires February 17, 2014             [Page 236]
Internet-Draft                    NFSv4                      August 2013

   If the current filehandle is not a directory, the error
   NFS4ERR_NOTDIR will be returned.

   If a COMPOUND contains an OPEN which establishes a
   OPEN_DELEGATE_WRITE delegation, then a subsequent GETATTR inside that
   COMPOUND SHOULD NOT result in a CB_GETATTR to the client.  The server
   SHOULD understand the GETATTR to be for the same client ID and avoid
   querying the client, which will not be able to respond.  This
   sequence of OPEN, GETATTR SHOULD be understood as an atomic retrieval
   of the initial size and change attribute.  Further, the client SHOULD
   NOT construct a COMPOUND which mixes operations for different client
   IDs.

15.19.  Operation 19: OPENATTR - Open Named Attribute Directory

15.19.1.  SYNOPSIS

     (cfh) createdir -> (cfh)

15.19.2.  ARGUMENT

   struct OPENATTR4args {
           /* CURRENT_FH: object */
           bool    createdir;
   };

15.19.3.  RESULT

   struct OPENATTR4res {
           /* CURRENT_FH: named attr directory */
           nfsstat4        status;
   };

15.19.4.  DESCRIPTION

   The OPENATTR operation is used to obtain the filehandle of the named
   attribute directory associated with the current filehandle.  The
   result of the OPENATTR will be a filehandle to an object of type
   NF4ATTRDIR.  From this filehandle, READDIR and LOOKUP operations can
   be used to obtain filehandles for the various named attributes
   associated with the original file system object.  Filehandles
   returned within the named attribute directory will have a type of
   NF4NAMEDATTR.

   The createdir argument allows the client to signify if a named
   attribute directory should be created as a result of the OPENATTR

Haynes & Noveck         Expires February 17, 2014             [Page 237]
Internet-Draft                    NFSv4                      August 2013

   operation.  Some clients may use the OPENATTR operation with a value
   of FALSE for createdir to determine if any named attributes exist for
   the object.  If none exist, then NFS4ERR_NOENT will be returned.  If
   createdir has a value of TRUE and no named attribute directory
   exists, one is created.  The creation of a named attribute directory
   assumes that the server has implemented named attribute support in
   this fashion and is not required to do so by this definition.

15.19.5.  IMPLEMENTATION

   If the server does not support named attributes for the current
   filehandle, an error of NFS4ERR_NOTSUPP will be returned to the
   client.

15.20.  Operation 20: OPEN_CONFIRM - Confirm Open

15.20.1.  SYNOPSIS

     (cfh), seqid, stateid -> stateid

15.20.2.  ARGUMENT

   struct OPEN_CONFIRM4args {
           /* CURRENT_FH: opened file */
           stateid4        open_stateid;
           seqid4          seqid;
   };

15.20.3.  RESULT

   struct OPEN_CONFIRM4resok {
           stateid4        open_stateid;
   };

   union OPEN_CONFIRM4res switch (nfsstat4 status) {
    case NFS4_OK:
            OPEN_CONFIRM4resok     resok4;
    default:
            void;
   };

15.20.4.  DESCRIPTION

   This operation is used to confirm the sequence id usage for the first
   time that a open-owner is used by a client.  The stateid returned
   from the OPEN operation is used as the argument for this operation

Haynes & Noveck         Expires February 17, 2014             [Page 238]
Internet-Draft                    NFSv4                      August 2013

   along with the next sequence id for the open-owner.  The sequence id
   passed to the OPEN_CONFIRM must be 1 (one) greater than the seqid
   passed to the OPEN operation.  If the server receives an unexpected
   sequence id with respect to the original open, then the server
   assumes that the client will not confirm the original OPEN and all
   state associated with the original OPEN is released by the server.

   On success, the current filehandle retains its value.

15.20.5.  IMPLEMENTATION

   A given client might generate many open_owner4 data structures for a
   given client ID.  The client will periodically either dispose of its
   open_owner4s or stop using them for indefinite periods of time.  The
   latter situation is why the NFSv4 protocol does not have an explicit
   operation to exit an open_owner4: such an operation is of no use in
   that situation.  Instead, to avoid unbounded memory use, the server
   needs to implement a strategy for disposing of open_owner4s that have
   no current open state for any files and have not been used recently.
   The time period used to determine when to dispose of open_owner4s is
   an implementation choice.  The time period should certainly be no
   less than the lease time plus any grace period the server wishes to
   implement beyond a lease time.  The OPEN_CONFIRM operation allows the
   server to safely dispose of unused open_owner4 data structures.

   In the case that a client issues an OPEN operation and the server no
   longer has a record of the open_owner4, the server needs to ensure
   that this is a new OPEN and not a replay or retransmission.

   Servers MUST NOT require confirmation on OPENs that grant delegations
   or are doing reclaim operations.  See Section 9.1.10 for details.
   The server can easily avoid this by noting whether it has disposed of
   one open_owner4 for the given client ID.  If the server does not
   support delegation, it might simply maintain a single bit that notes
   whether any open_owner4 (for any client) has been disposed of.

   The server must hold unconfirmed OPEN state until one of three events
   occur.  First, the client sends an OPEN_CONFIRM request with the
   appropriate sequence id and stateid within the lease period.  In this
   case, the OPEN state on the server goes to confirmed, and the
   open_owner4 on the server is fully established.

   Second, the client sends another OPEN request with a sequence id that
   is incorrect for the open_owner4 (out of sequence).  In this case,
   the server assumes the second OPEN request is valid and the first one
   is a replay.  The server cancels the OPEN state of the first OPEN
   request, establishes an unconfirmed OPEN state for the second OPEN
   request, and responds to the second OPEN request with an indication

Haynes & Noveck         Expires February 17, 2014             [Page 239]
Internet-Draft                    NFSv4                      August 2013

   that an OPEN_CONFIRM is needed.  The process then repeats itself.
   While there is a potential for a denial of service attack on the
   client, it is mitigated if the client and server require the use of a
   security flavor based on Kerberos V5 or some other flavor that uses
   cryptography.

   What if the server is in the unconfirmed OPEN state for a given
   open_owner4, and it receives an operation on the open_owner4 that has
   a stateid but the operation is not OPEN, or it is OPEN_CONFIRM but
   with the wrong stateid?  Then, even if the seqid is correct, the
   server returns NFS4ERR_BAD_STATEID, because the server assumes the
   operation is a replay: if the server has no established OPEN state,
   then there is no way, for example, a LOCK operation could be valid.

   Third, neither of the two aforementioned events occur for the
   open_owner4 within the lease period.  In this case, the OPEN state is
   canceled and disposal of the open_owner4 can occur.

15.21.  Operation 21: OPEN_DOWNGRADE - Reduce Open File Access

15.21.1.  SYNOPSIS

     (cfh), stateid, seqid, access, deny -> stateid

15.21.2.  ARGUMENT

   struct OPEN_DOWNGRADE4args {
           /* CURRENT_FH: opened file */
           stateid4        open_stateid;
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
   };

15.21.3.  RESULT

   struct OPEN_DOWNGRADE4resok {
           stateid4        open_stateid;
   };

   union OPEN_DOWNGRADE4res switch(nfsstat4 status) {
    case NFS4_OK:
           OPEN_DOWNGRADE4resok    resok4;
    default:
            void;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 240]
Internet-Draft                    NFSv4                      August 2013

15.21.4.  DESCRIPTION

   This operation is used to adjust the share_access and share_deny bits
   for a given open.  This is necessary when a given open-owner opens
   the same file multiple times with different share_access and
   share_deny flags.  In this situation, a close of one of the opens may
   change the appropriate share_access and share_deny flags to remove
   bits associated with opens no longer in effect.

   The share_access and share_deny bits specified in this operation
   replace the current ones for the specified open file.  The
   share_access and share_deny bits specified must be exactly equal to
   the union of the share_access and share_deny bits specified for some
   subset of the OPENs in effect for current open-owner on the current
   file.  If that constraint is not respected, the error NFS4ERR_INVAL
   should be returned.  Since share_access and share_deny bits are
   subsets of those already granted, it is not possible for this request
   to be denied because of conflicting share reservations.

   As the OPEN_DOWNGRADE may change a file to be not-open-for-write and
   a write byte-range lock might be held, the server may have to reject
   the OPEN_DOWNGRADE with a NFS4ERR_LOCKS_HELD.

   On success, the current filehandle retains its value.

15.22.  Operation 22: PUTFH - Set Current Filehandle

15.22.1.  SYNOPSIS

     filehandle -> (cfh)

15.22.2.  ARGUMENT

   struct PUTFH4args {
           nfs_fh4         object;
   };

15.22.3.  RESULT

   struct PUTFH4res {
           /* CURRENT_FH: */
           nfsstat4        status;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 241]
Internet-Draft                    NFSv4                      August 2013

15.22.4.  DESCRIPTION

   Replaces the current filehandle with the filehandle provided as an
   argument.

   If the security mechanism used by the requester does not meet the
   requirements of the filehandle provided to this operation, the server
   MUST return NFS4ERR_WRONGSEC.

   See Section 15.2.4.1 for more details on the current filehandle.

15.22.5.  IMPLEMENTATION

   Commonly used as the first operator in an NFS request to set the
   context for following operations.

15.23.  Operation 23: PUTPUBFH - Set Public Filehandle

15.23.1.  SYNOPSIS

     - -> (cfh)

15.23.2.  ARGUMENT

     void;

15.23.3.  RESULT

   struct PUTPUBFH4res {
           /* CURRENT_FH: public fh */
           nfsstat4        status;
   };

15.23.4.  DESCRIPTION

   Replaces the current filehandle with the filehandle that represents
   the public filehandle of the server's name space.  This filehandle
   may be different from the "root" filehandle which may be associated
   with some other directory on the server.

   The public filehandle represents the concepts embodied in [RFC2054],
   [RFC2055], [RFC2224].  The intent for NFSv4 is that the public
   filehandle (represented by the PUTPUBFH operation) be used as a
   method of providing WebNFS server compatibility with NFSv2 and NFSv3.

   The public filehandle and the root filehandle (represented by the
   PUTROOTFH operation) should be equivalent.  If the public and root

Haynes & Noveck         Expires February 17, 2014             [Page 242]
Internet-Draft                    NFSv4                      August 2013

   filehandles are not equivalent, then the public filehandle MUST be a
   descendant of the root filehandle.

15.23.5.  IMPLEMENTATION

   Used as the first operator in an NFS request to set the context for
   following operations.

   With the NFSv2 and 3 public filehandle, the client is able to specify
   whether the path name provided in the LOOKUP should be evaluated as
   either an absolute path relative to the server's root or relative to
   the public filehandle.  [RFC2224] contains further discussion of the
   functionality.  With NFSv4, that type of specification is not
   directly available in the LOOKUP operation.  The reason for this is
   because the component separators needed to specify absolute vs.
   relative are not allowed in NFSv4.  Therefore, the client is
   responsible for constructing its request such that the use of either
   PUTROOTFH or PUTPUBFH are used to signify absolute or relative
   evaluation of an NFS URL respectively.

   Note that there are warnings mentioned in [RFC2224] with respect to
   the use of absolute evaluation and the restrictions the server may
   place on that evaluation with respect to how much of its namespace
   has been made available.  These same warnings apply to NFSv4.  It is
   likely, therefore that because of server implementation details, an
   NFSv3 absolute public filehandle lookup may behave differently than
   an NFSv4 absolute resolution.

   There is a form of security negotiation as described in [RFC2755]
   that uses the public filehandle a method of employing Simple and
   Protected GSSAPI Negotiation Mechanism (SNEGO) [RFC4178].  This
   method is not available with NFSv4 as filehandles are not overloaded
   with special meaning and therefore do not provide the same framework
   as NFSv2 and NFSv3.  Clients should therefore use the security
   negotiation mechanisms described in this RFC.

15.24.  Operation 24: PUTROOTFH - Set Root Filehandle

15.24.1.  SYNOPSIS

     - -> (cfh)

15.24.2.  ARGUMENT

     void;

Haynes & Noveck         Expires February 17, 2014             [Page 243]
Internet-Draft                    NFSv4                      August 2013

15.24.3.  RESULT

   struct PUTROOTFH4res {
           /* CURRENT_FH: root fh */
           nfsstat4        status;
   };

15.24.4.  DESCRIPTION

   Replaces the current filehandle with the filehandle that represents
   the root of the server's name space.  From this filehandle a LOOKUP
   operation can locate any other filehandle on the server.  This
   filehandle may be different from the "public" filehandle which may be
   associated with some other directory on the server.

   See Section 15.2.4.1 for more details on the current filehandle.

15.24.5.  IMPLEMENTATION

   Commonly used as the first operator in an NFS request to set the
   context for following operations.

15.25.  Operation 25: READ - Read from File

15.25.1.  SYNOPSIS

     (cfh), stateid, offset, count -> eof, data

15.25.2.  ARGUMENT

   struct READ4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           count4          count;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 244]
Internet-Draft                    NFSv4                      August 2013

15.25.3.  RESULT

   struct READ4resok {
           bool            eof;
           opaque          data<>;
   };

   union READ4res switch (nfsstat4 status) {
    case NFS4_OK:
            READ4resok     resok4;
    default:
            void;
   };

15.25.4.  DESCRIPTION

   The READ operation reads data from the regular file identified by the
   current filehandle.

   The client provides an offset of where the READ is to start and a
   count of how many bytes are to be read.  An offset of 0 (zero) means
   to read data starting at the beginning of the file.  If offset is
   greater than or equal to the size of the file, the status, NFS4_OK,
   is returned with a data length set to 0 (zero) and eof is set to
   TRUE.  The READ is subject to access permissions checking.

   If the client specifies a count value of 0 (zero), the READ succeeds
   and returns 0 (zero) bytes of data again subject to access
   permissions checking.  The server may choose to return fewer bytes
   than specified by the client.  The client needs to check for this
   condition and handle the condition appropriately.

   The stateid value for a READ request represents a value returned from
   a previous byte-range lock or share reservation request or the
   stateid associated with a delegation.  The stateid is used by the
   server to verify that the associated share reservation and any byte-
   range locks are still valid and to update lease timeouts for the
   client.

   If the read ended at the end-of-file (formally, in a correctly formed
   READ request, if offset + count is equal to the size of the file), or
   the read request extends beyond the size of the file (if offset +
   count is greater than the size of the file), eof is returned as TRUE;
   otherwise it is FALSE.  A successful READ of an empty file will
   always return eof as TRUE.

   If the current filehandle is not a regular file, an error will be

Haynes & Noveck         Expires February 17, 2014             [Page 245]
Internet-Draft                    NFSv4                      August 2013

   returned to the client.  In the case the current filehandle
   represents a directory, NFS4ERR_ISDIR is returned; otherwise,
   NFS4ERR_INVAL is returned.

   For a READ with a stateid value of all bits 0, the server MAY allow
   the READ to be serviced subject to mandatory file locks or the
   current share deny modes for the file.  For a READ with a stateid
   value of all bits 1, the server MAY allow READ operations to bypass
   locking checks at the server.

   On success, the current filehandle retains its value.

15.25.5.  IMPLEMENTATION

   If the server returns a "short read" (i.e., fewer data than requested
   and eof is set to FALSE), the client should send another READ to get
   the remaining data.  A server may return less data than requested
   under several circumstances.  The file may have been truncated by
   another client or perhaps on the server itself, changing the file
   size from what the requesting client believes to be the case.  This
   would reduce the actual amount of data available to the client.  It
   is possible that the server reduces the transfer size and so returns
   a short read result.  Server resource exhaustion may also result in a
   short read.

   If mandatory byte-range locking is in effect for the file, and if the
   byte-range corresponding to the data to be read from the file is
   WRITE_LT locked by an owner not associated with the stateid, the
   server will return the NFS4ERR_LOCKED error.  The client should try
   to get the appropriate READ_LT via the LOCK operation before
   reattempting the READ.  When the READ completes, the client should
   release the byte-range lock via LOCKU.

   If another client has an OPEN_DELEGATE_WRITE delegation for the file
   being read, the delegation must be recalled, and the operation cannot
   proceed until that delegation is returned or revoked.  Except where
   this happens very quickly, one or more NFS4ERR_DELAY errors will be
   returned to requests made while the delegation remains outstanding.
   Normally, delegations will not be recalled as a result of a READ
   operation since the recall will occur as a result of an earlier OPEN.
   However, since it is possible for a READ to be done with a special
   stateid, the server needs to check for this case even though the
   client should have done an OPEN previously.

15.26.  Operation 26: READDIR - Read Directory

Haynes & Noveck         Expires February 17, 2014             [Page 246]
Internet-Draft                    NFSv4                      August 2013

15.26.1.  SYNOPSIS

     (cfh), cookie, cookieverf, dircount, maxcount, attr_request ->
     cookieverf { cookie, name, attrs }

15.26.2.  ARGUMENT

   struct READDIR4args {
           /* CURRENT_FH: directory */
           nfs_cookie4     cookie;
           verifier4       cookieverf;
           count4          dircount;
           count4          maxcount;
           bitmap4         attr_request;
   };

15.26.3.  RESULT

   struct entry4 {
           nfs_cookie4     cookie;
           component4      name;
           fattr4          attrs;
           entry4          *nextentry;
   };

   struct dirlist4 {
           entry4          *entries;
           bool            eof;
   };

   struct READDIR4resok {
           verifier4       cookieverf;
           dirlist4        reply;
   };

   union READDIR4res switch (nfsstat4 status) {
    case NFS4_OK:
            READDIR4resok  resok4;
    default:
            void;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 247]
Internet-Draft                    NFSv4                      August 2013

15.26.4.  DESCRIPTION

   The READDIR operation retrieves a variable number of entries from a
   file system directory and returns client requested attributes for
   each entry along with information to allow the client to request
   additional directory entries in a subsequent READDIR.

   The arguments contain a cookie value that represents where the
   READDIR should start within the directory.  A value of 0 (zero) for
   the cookie is used to start reading at the beginning of the
   directory.  For subsequent READDIR requests, the client specifies a
   cookie value that is provided by the server on a previous READDIR
   request.

   The cookieverf value should be set to 0 (zero) when the cookie value
   is 0 (zero) (first directory read).  On subsequent requests, it
   should be a cookieverf as returned by the server.  The cookieverf
   must match that returned by the READDIR in which the cookie was
   acquired.  If the server determines that the cookieverf is no longer
   valid for the directory, the error NFS4ERR_NOT_SAME must be returned.

   The dircount portion of the argument is a hint of the maximum number
   of bytes of directory information that should be returned.  This
   value represents the length of the names of the directory entries and
   the cookie value for these entries.  This length represents the XDR
   encoding of the data (names and cookies) and not the length in the
   native format of the server.

   The maxcount value of the argument is the maximum number of bytes for
   the result.  This maximum size represents all of the data being
   returned within the READDIR4resok structure and includes the XDR
   overhead.  The server may return less data.  If the server is unable
   to return a single directory entry within the maxcount limit, the
   error NFS4ERR_TOOSMALL will be returned to the client.

   Finally, attr_request represents the list of attributes to be
   returned for each directory entry supplied by the server.

   On successful return, the server's response will provide a list of
   directory entries.  Each of these entries contains the name of the
   directory entry, a cookie value for that entry, and the associated
   attributes as requested.  The "eof" flag has a value of TRUE if there
   are no more entries in the directory.

   The cookie value is only meaningful to the server and is used as a
   "bookmark" for the directory entry.  As mentioned, this cookie is
   used by the client for subsequent READDIR operations so that it may
   continue reading a directory.  The cookie is similar in concept to a

Haynes & Noveck         Expires February 17, 2014             [Page 248]
Internet-Draft                    NFSv4                      August 2013

   READ offset but should not be interpreted as such by the client.
   Ideally, the cookie value should not change if the directory is
   modified since the client may be caching these values.

   In some cases, the server may encounter an error while obtaining the
   attributes for a directory entry.  Instead of returning an error for
   the entire READDIR operation, the server can instead return the
   attribute 'fattr4_rdattr_error'.  With this, the server is able to
   communicate the failure to the client and not fail the entire
   operation in the instance of what might be a transient failure.
   Obviously, the client must request the fattr4_rdattr_error attribute
   for this method to work properly.  If the client does not request the
   attribute, the server has no choice but to return failure for the
   entire READDIR operation.

   For some file system environments, the directory entries "." and ".."
   have special meaning and in other environments, they may not.  If the
   server supports these special entries within a directory, they should
   not be returned to the client as part of the READDIR response.  To
   enable some client environments, the cookie values of 0, 1, and 2 are
   to be considered reserved.  Note that the UNIX client will use these
   values when combining the server's response and local representations
   to enable a fully formed UNIX directory presentation to the
   application.

   For READDIR arguments, cookie values of 1 and 2 SHOULD NOT be used
   and for READDIR results cookie values of 0, 1, and 2 MUST NOT be
   returned.

   On success, the current filehandle retains its value.

15.26.5.  IMPLEMENTATION

   The server's file system directory representations can differ
   greatly.  A client's programming interfaces may also be bound to the
   local operating environment in a way that does not translate well
   into the NFS protocol.  Therefore the use of the dircount and
   maxcount fields are provided to allow the client the ability to
   provide guidelines to the server.  If the client is aggressive about
   attribute collection during a READDIR, the server has an idea of how
   to limit the encoded response.  The dircount field provides a hint on
   the number of entries based solely on the names of the directory
   entries.  Since it is a hint, it may be possible that a dircount
   value is zero.  In this case, the server is free to ignore the
   dircount value and return directory information based on the
   specified maxcount value.

   The cookieverf may be used by the server to help manage cookie values

Haynes & Noveck         Expires February 17, 2014             [Page 249]
Internet-Draft                    NFSv4                      August 2013

   that may become stale.  It should be a rare occurrence that a server
   is unable to continue properly reading a directory with the provided
   cookie/cookieverf pair.  The server should make every effort to avoid
   this condition since the application at the client may not be able to
   properly handle this type of failure.

   The use of the cookieverf will also protect the client from using
   READDIR cookie values that may be stale.  For example, if the file
   system has been migrated, the server may or may not be able to use
   the same cookie values to service READDIR as the previous server
   used.  With the client providing the cookieverf, the server is able
   to provide the appropriate response to the client.  This prevents the
   case where the server may accept a cookie value but the underlying
   directory has changed and the response is invalid from the client's
   context of its previous READDIR.

   Since some servers will not be returning "." and ".." entries as has
   been done with previous versions of the NFS protocol, the client that
   requires these entries be present in READDIR responses must fabricate
   them.

15.27.  Operation 27: READLINK - Read Symbolic Link

15.27.1.  SYNOPSIS

     (cfh) -> linktext

15.27.2.  ARGUMENT

     /* CURRENT_FH: symlink */
     void;

15.27.3.  RESULT

   struct READLINK4resok {
           linktext4       link;
   };

   union READLINK4res switch (nfsstat4 status) {
    case NFS4_OK:
            READLINK4resok resok4;
    default:
            void;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 250]
Internet-Draft                    NFSv4                      August 2013

15.27.4.  DESCRIPTION

   READLINK reads the data associated with a symbolic link.  The data is
   a UTF-8 string that is opaque to the server.  That is, whether
   created by an NFS client or created locally on the server, the data
   in a symbolic link is not interpreted when created, but is simply
   stored.

   On success, the current filehandle retains its value.

15.27.5.  IMPLEMENTATION

   A symbolic link is nominally a pointer to another file.  The data is
   not necessarily interpreted by the server, just stored in the file.
   It is possible for a client implementation to store a path name that
   is not meaningful to the server operating system in a symbolic link.
   A READLINK operation returns the data to the client for
   interpretation.  If different implementations want to share access to
   symbolic links, then they must agree on the interpretation of the
   data in the symbolic link.

   The READLINK operation is only allowed on objects of type NF4LNK.
   The server should return the error, NFS4ERR_INVAL, if the object is
   not of type, NF4LNK.

15.28.  Operation 28: REMOVE - Remove Filesystem Object

15.28.1.  SYNOPSIS

     (cfh), filename -> change_info

15.28.2.  ARGUMENT

   struct REMOVE4args {
           /* CURRENT_FH: directory */
           component4      target;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 251]
Internet-Draft                    NFSv4                      August 2013

15.28.3.  RESULT

   struct REMOVE4resok {
           change_info4    cinfo;
   };

   union REMOVE4res switch (nfsstat4 status) {
    case NFS4_OK:
            REMOVE4resok   resok4;
    default:
            void;
   };

15.28.4.  DESCRIPTION

   The REMOVE operation removes (deletes) a directory entry M named by
   filename from the directory corresponding to the current filehandle.
   If the entry in the directory was the last reference to the
   corresponding file system object, the object may be destroyed.

   For the directory where the filename was removed, the server returns
   change_info4 information in cinfo.  With the atomic field of the
   change_info4 struct, the server will indicate if the before and after
   change attributes were obtained atomically with respect to the
   removal.

   If the target is of zero length, NFS4ERR_INVAL will be returned.  The
   target is also subject to the normal UTF-8, character support, and
   name checks.  See Section 12.5 for further discussion.

   On success, the current filehandle retains its value.

15.28.5.  IMPLEMENTATION

   NFSv3 required a different operator RMDIR for directory removal and
   REMOVE for non-directory removal.  This allowed clients to skip
   checking the file type when being passed a non-directory delete
   system call (e.g., unlink() [unlink] in POSIX) to remove a directory,
   as well as the converse (e.g., a rmdir() on a non-directory) because
   they knew the server would check the file type.  NFSv4 REMOVE can be
   used to delete any directory entry independent of its file type.  The
   implementor of an NFSv4 client's entry points from the unlink() and
   rmdir() system calls should first check the file type against the
   types the system call is allowed to remove before issuing a REMOVE.
   Alternatively, the implementor can produce a COMPOUND call that
   includes a LOOKUP/VERIFY sequence to verify the file type before a
   REMOVE operation in the same COMPOUND call.

Haynes & Noveck         Expires February 17, 2014             [Page 252]
Internet-Draft                    NFSv4                      August 2013

   The concept of last reference is server specific.  However, if the
   numlinks field in the previous attributes of the object had the value
   1, the client should not rely on referring to the object via a
   filehandle.  Likewise, the client should not rely on the resources
   (disk space, directory entry, and so on) formerly associated with the
   object becoming immediately available.  Thus, if a client needs to be
   able to continue to access a file after using REMOVE to remove it,
   the client should take steps to make sure that the file will still be
   accessible.  The usual mechanism used is to RENAME the file from its
   old name to a new hidden name.

   If the server finds that the file is still open when the REMOVE
   arrives:

   o  The server SHOULD NOT delete the file's directory entry if the
      file was opened with OPEN4_SHARE_DENY_WRITE or
      OPEN4_SHARE_DENY_BOTH.

   o  If the file was not opened with OPEN4_SHARE_DENY_WRITE or
      OPEN4_SHARE_DENY_BOTH, the server SHOULD delete the file's
      directory entry.  However, until last CLOSE of the file, the
      server MAY continue to allow access to the file via its
      filehandle.

15.29.  Operation 29: RENAME - Rename Directory Entry

15.29.1.  SYNOPSIS

     (sfh), oldname, (cfh), newname -> source_cinfo, target_cinfo

15.29.2.  ARGUMENT

   struct RENAME4args {
           /* SAVED_FH: source directory */
           component4      oldname;
           /* CURRENT_FH: target directory */
           component4      newname;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 253]
Internet-Draft                    NFSv4                      August 2013

15.29.3.  RESULT

   struct RENAME4resok {
           change_info4    source_cinfo;
           change_info4    target_cinfo;
   };

   union RENAME4res switch (nfsstat4 status) {
    case NFS4_OK:
           RENAME4resok    resok4;
    default:
           void;
   };

15.29.4.  DESCRIPTION

   The RENAME operation renames the object identified by oldname in the
   source directory corresponding to the saved filehandle, as set by the
   SAVEFH operation, to newname in the target directory corresponding to
   the current filehandle.  The operation is required to be atomic to
   the client.  Source and target directories must reside on the same
   file system on the server.  On success, the current filehandle will
   continue to be the target directory.

   If the target directory already contains an entry with the name,
   newname, the source object must be compatible with the target: either
   both are non-directories or both are directories and the target must
   be empty.  If compatible, the existing target is removed before the
   rename occurs (See Section 15.28 for client and server actions
   whenever a target is removed).  If they are not compatible or if the
   target is a directory but not empty, the server will return the
   error, NFS4ERR_EXIST.

   If oldname and newname both refer to the same file (they might be
   hard links of each other), then RENAME should perform no action and
   return success.

   For both directories involved in the RENAME, the server returns
   change_info4 information.  With the atomic field of the change_info4
   struct, the server will indicate if the before and after change
   attributes were obtained atomically with respect to the rename.

   If the oldname refers to a named attribute and the saved and current
   filehandles refer to different file system objects, the server will
   return NFS4ERR_XDEV just as if the saved and current filehandles
   represented directories on different file systems.

Haynes & Noveck         Expires February 17, 2014             [Page 254]
Internet-Draft                    NFSv4                      August 2013

   If the oldname or newname is of zero length, NFS4ERR_INVAL will be
   returned.  The oldname and newname are also subject to the normal
   UTF-8, character support, and name checks.  See Section 12.5 for
   further discussion.

15.29.5.  IMPLEMENTATION

   The RENAME operation must be atomic to the client.  The statement
   "source and target directories must reside on the same file system on
   the server" means that the fsid fields in the attributes for the
   directories are the same.  If they reside on different file systems,
   the error, NFS4ERR_XDEV, is returned.

   Based on the value of the fh_expire_type attribute for the object,
   the filehandle may or may not expire on a RENAME.  However, server
   implementors are strongly encouraged to attempt to keep filehandles
   from expiring in this fashion.

   On some servers, the file names "." and ".." are illegal as either
   oldname or newname, and will result in the error NFS4ERR_BADNAME.  In
   addition, on many servers the case of oldname or newname being an
   alias for the source directory will be checked for.  Such servers
   will return the error NFS4ERR_INVAL in these cases.

   If either of the source or target filehandles are not directories,
   the server will return NFS4ERR_NOTDIR.

15.30.  Operation 30: RENEW - Renew a Lease

15.30.1.  SYNOPSIS

     clientid -> ()

15.30.2.  ARGUMENT

   struct RENEW4args {
           clientid4       clientid;
   };

15.30.3.  RESULT

   struct RENEW4res {
           nfsstat4        status;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 255]
Internet-Draft                    NFSv4                      August 2013

15.30.4.  DESCRIPTION

   The RENEW operation is used by the client to renew leases which it
   currently holds at a server.  In processing the RENEW request, the
   server renews all leases associated with the client.  The associated
   leases are determined by the clientid provided via the SETCLIENTID
   operation.

15.30.5.  IMPLEMENTATION

   When the client holds delegations, it needs to use RENEW to detect
   when the server has determined that the callback path is down.  When
   the server has made such a determination, only the RENEW operation
   will renew the lease on delegations.  If the server determines the
   callback path is down, it returns NFS4ERR_CB_PATH_DOWN.  Even though
   it returns NFS4ERR_CB_PATH_DOWN, the server MUST renew the lease on
   the byte-range locks and share reservations that the client has
   established on the server.  If for some reason the lock and share
   reservation lease cannot be renewed, then the server MUST return an
   error other than NFS4ERR_CB_PATH_DOWN, even if the callback path is
   also down.  In the event that the server has conditions such that it
   could return either NFS4ERR_CB_PATH_DOWN or NFS4ERR_LEASE_MOVED,
   NFS4ERR_LEASE_MOVED MUST be handled first.

   The client that issues RENEW MUST choose the principal, RPC security
   flavor, and if applicable, GSS-API mechanism and service via one of
   the following algorithms:

   o  The client uses the same principal, RPC security flavor -- and if
      the flavor was RPCSEC_GSS -- the same mechanism and service that
      was used when the client id was established via
      SETCLIENTID_CONFIRM.

   o  The client uses any principal, RPC security flavor mechanism and
      service combination that currently has an OPEN file on the server.
      I.e., the same principal had a successful OPEN operation, the file
      is still open by that principal, and the flavor, mechanism, and
      service of RENEW match that of the previous OPEN.

   The server MUST reject a RENEW that does not use one the
   aforementioned algorithms, with the error NFS4ERR_ACCESS.

15.31.  Operation 31: RESTOREFH - Restore Saved Filehandle

15.31.1.  SYNOPSIS

     (sfh) -> (cfh)

Haynes & Noveck         Expires February 17, 2014             [Page 256]
Internet-Draft                    NFSv4                      August 2013

15.31.2.  ARGUMENT

     /* SAVED_FH: */
     void;

15.31.3.  RESULT

   struct RESTOREFH4res {
           /* CURRENT_FH: value of saved fh */
           nfsstat4        status;
   };

15.31.4.  DESCRIPTION

   Set the current filehandle to the value in the saved filehandle.  If
   there is no saved filehandle then return the error NFS4ERR_RESTOREFH.

15.31.5.  IMPLEMENTATION

   Operations like OPEN and LOOKUP use the current filehandle to
   represent a directory and replace it with a new filehandle.  Assuming
   the previous filehandle was saved with a SAVEFH operator, the
   previous filehandle can be restored as the current filehandle.  This
   is commonly used to obtain post-operation attributes for the
   directory, e.g.,

     PUTFH (directory filehandle)
     SAVEFH
     GETATTR attrbits     (pre-op dir attrs)
     CREATE optbits "foo" attrs
     GETATTR attrbits     (file attributes)
     RESTOREFH
     GETATTR attrbits     (post-op dir attrs)

15.32.  Operation 32: SAVEFH - Save Current Filehandle

15.32.1.  SYNOPSIS

     (cfh) -> (sfh)

15.32.2.  ARGUMENT

     /* CURRENT_FH: */
     void;

Haynes & Noveck         Expires February 17, 2014             [Page 257]
Internet-Draft                    NFSv4                      August 2013

15.32.3.  RESULT

   struct SAVEFH4res {
           /* SAVED_FH: value of current fh */
           nfsstat4        status;
   };

15.32.4.  DESCRIPTION

   Save the current filehandle.  If a previous filehandle was saved then
   it is no longer accessible.  The saved filehandle can be restored as
   the current filehandle with the RESTOREFH operator.

   On success, the current filehandle retains its value.

15.32.5.  IMPLEMENTATION

15.33.  Operation 33: SECINFO - Obtain Available Security

15.33.1.  SYNOPSIS

     (cfh), name -> { secinfo }

15.33.2.  ARGUMENT

   struct SECINFO4args {
           /* CURRENT_FH: directory */
           component4      name;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 258]
Internet-Draft                    NFSv4                      August 2013

15.33.3.  RESULT

   /*
    * From RFC 2203
    */
   enum rpc_gss_svc_t {
           RPC_GSS_SVC_NONE        = 1,
           RPC_GSS_SVC_INTEGRITY   = 2,
           RPC_GSS_SVC_PRIVACY     = 3
   };

   struct rpcsec_gss_info {
           sec_oid4        oid;
           qop4            qop;
           rpc_gss_svc_t   service;
   };

   /* RPCSEC_GSS has a value of '6' - See RFC 2203 */
   union secinfo4 switch (uint32_t flavor) {
    case RPCSEC_GSS:
            rpcsec_gss_info        flavor_info;
    default:
            void;
   };

   typedef secinfo4 SECINFO4resok<>;

   union SECINFO4res switch (nfsstat4 status) {
    case NFS4_OK:
            SECINFO4resok resok4;
    default:
            void;
   };

15.33.4.  DESCRIPTION

   The SECINFO operation is used by the client to obtain a list of valid
   RPC authentication flavors for a specific directory filehandle, file
   name pair.  SECINFO should apply the same access methodology used for
   LOOKUP when evaluating the name.  Therefore, if the requester does
   not have the appropriate access to LOOKUP the name then SECINFO must
   behave the same way and return NFS4ERR_ACCESS.

   The result will contain an array which represents the security
   mechanisms available, with an order corresponding to server's
   preferences, the most preferred being first in the array.  The client
   is free to pick whatever security mechanism it both desires and

Haynes & Noveck         Expires February 17, 2014             [Page 259]
Internet-Draft                    NFSv4                      August 2013

   supports, or to pick in the server's preference order the first one
   it supports.  The array entries are represented by the secinfo4
   structure.  The field 'flavor' will contain a value of AUTH_NONE,
   AUTH_SYS (as defined in [RFC5531]), or RPCSEC_GSS (as defined in
   [RFC2203]).

   For the flavors AUTH_NONE and AUTH_SYS, no additional security
   information is returned.  For a return value of RPCSEC_GSS, a
   security triple is returned that contains the mechanism object id (as
   defined in [RFC2743]), the quality of protection (as defined in
   [RFC2743]) and the service type (as defined in [RFC2203]).  It is
   possible for SECINFO to return multiple entries with flavor equal to
   RPCSEC_GSS with different security triple values.

   On success, the current filehandle retains its value.

   If the name has a length of 0 (zero), or if name does not obey the
   UTF-8 definition, the error NFS4ERR_INVAL will be returned.

15.33.5.  IMPLEMENTATION

   The SECINFO operation is expected to be used by the NFS client when
   the error value of NFS4ERR_WRONGSEC is returned from another NFS
   operation.  This signifies to the client that the server's security
   policy is different from what the client is currently using.  At this
   point, the client is expected to obtain a list of possible security
   flavors and choose what best suits its policies.

   As mentioned, the server's security policies will determine when a
   client request receives NFS4ERR_WRONGSEC.  The operations which may
   receive this error are: LINK, LOOKUP, LOOKUPP, OPEN, PUTFH, PUTPUBFH,
   PUTROOTFH, RENAME, RESTOREFH, and indirectly READDIR.  LINK and
   RENAME will only receive this error if the security used for the
   operation is inappropriate for saved filehandle.  With the exception
   of READDIR, these operations represent the point at which the client
   can instantiate a filehandle into the "current filehandle" at the
   server.  The filehandle is either provided by the client (PUTFH,
   PUTPUBFH, PUTROOTFH) or generated as a result of a name to filehandle
   translation (LOOKUP and OPEN).  RESTOREFH is different because the
   filehandle is a result of a previous SAVEFH.  Even though the
   filehandle, for RESTOREFH, might have previously passed the server's
   inspection for a security match, the server will check it again on
   RESTOREFH to ensure that the security policy has not changed.

   If the client wants to resolve an error return of NFS4ERR_WRONGSEC,
   the following will occur:

Haynes & Noveck         Expires February 17, 2014             [Page 260]
Internet-Draft                    NFSv4                      August 2013

   o  For LOOKUP and OPEN, the client will use SECINFO with the same
      current filehandle and name as provided in the original LOOKUP or
      OPEN to enumerate the available security triples.

   o  For LINK, PUTFH, RENAME, and RESTOREFH, the client will use
      SECINFO and provide the parent directory filehandle and object
      name which corresponds to the filehandle originally provided by
      the PUTFH RESTOREFH, or for LINK and RENAME, the SAVEFH.

   o  For LOOKUPP, PUTROOTFH and PUTPUBFH, the client will be unable to
      use the SECINFO operation since SECINFO requires a current
      filehandle and none exist for these two operations.  Therefore,
      the client must iterate through the security triples available at
      the client and reattempt the PUTROOTFH or PUTPUBFH operation.  In
      the unfortunate event none of the MANDATORY security triples are
      supported by the client and server, the client SHOULD try using
      others that support integrity.  Failing that, the client can try
      using AUTH_NONE, but because such forms lack integrity checks,
      this puts the client at risk.  Nonetheless, the server SHOULD
      allow the client to use whatever security form the client requests
      and the server supports, since the risks of doing so are on the
      client.

   The READDIR operation will not directly return the NFS4ERR_WRONGSEC
   error.  However, if the READDIR request included a request for
   attributes, it is possible that the READDIR request's security triple
   does not match that of a directory entry.  If this is the case and
   the client has requested the rdattr_error attribute, the server will
   return the NFS4ERR_WRONGSEC error in rdattr_error for the entry.

   Note that a server MAY use the AUTH_NONE flavor to signify that the
   client is allowed to attempt to use authentication flavors that are
   not explicitly listed in the SECINFO results.  Instead of using a
   listed flavor, the client might then, for instance opt to use an
   otherwise unlisted RPCSEC_GSS mechanism instead of AUTH_NONE.  It may
   wish to do so in order to meet an application requirement for data
   integrity or privacy.  In choosing to use an unlisted flavor, the
   client SHOULD always be prepared to handle a failure by falling back
   to using AUTH_NONE or another listed flavor.  It MUST NOT assume that
   identity mapping is supported, and should be prepared for the fact
   that its identity is squashed.

   See Section 17 for a discussion on the recommendations for security
   flavor used by SECINFO.

Haynes & Noveck         Expires February 17, 2014             [Page 261]
Internet-Draft                    NFSv4                      August 2013

15.34.  Operation 34: SETATTR - Set Attributes

15.34.1.  SYNOPSIS

     (cfh), stateid, attrmask, attr_vals -> attrsset

15.34.2.  ARGUMENT

   struct SETATTR4args {
           /* CURRENT_FH: target object */
           stateid4        stateid;
           fattr4          obj_attributes;
   };

15.34.3.  RESULT

   struct SETATTR4res {
           nfsstat4        status;
           bitmap4         attrsset;
   };

15.34.4.  DESCRIPTION

   The SETATTR operation changes one or more of the attributes of a file
   system object.  The new attributes are specified with a bitmap and
   the attributes that follow the bitmap in bit order.

   The stateid argument for SETATTR is used to provide byte-range
   locking context that is necessary for SETATTR requests that set the
   size attribute.  Since setting the size attribute modifies the file's
   data, it has the same locking requirements as a corresponding WRITE.
   Any SETATTR that sets the size attribute is incompatible with a share
   reservation that specifies OPEN4_SHARE_DENY_WRITE.  The area between
   the old end-of-file and the new end-of-file is considered to be
   modified just as would have been the case had the area in question
   been specified as the target of WRITE, for the purpose of checking
   conflicts with byte-range locks, for those cases in which a server is
   implementing mandatory byte-range locking behavior.  A valid stateid
   SHOULD always be specified.  When the file size attribute is not set,
   the special stateid consisting of all bits zero MAY be passed.

   On either success or failure of the operation, the server will return
   the attrsset bitmask to represent what (if any) attributes were
   successfully set.  The attrsset in the response is a subset of the
   bitmap4 that is part of the obj_attributes in the argument.

Haynes & Noveck         Expires February 17, 2014             [Page 262]
Internet-Draft                    NFSv4                      August 2013

   On success, the current filehandle retains its value.

15.34.5.  IMPLEMENTATION

   If the request specifies the owner attribute to be set, the server
   SHOULD allow the operation to succeed if the current owner of the
   object matches the value specified in the request.  Some servers may
   be implemented in a way as to prohibit the setting of the owner
   attribute unless the requester has privilege to do so.  If the server
   is lenient in this one case of matching owner values, the client
   implementation may be simplified in cases of creation of an object
   (e.g., an exclusive create via OPEN) followed by a SETATTR.

   The file size attribute is used to request changes to the size of a
   file.  A value of zero causes the file to be truncated, a value less
   than the current size of the file causes data from new size to the
   end of the file to be discarded, and a size greater than the current
   size of the file causes logically zeroed data bytes to be added to
   the end of the file.  Servers are free to implement this using holes
   or actual zero data bytes.  Clients should not make any assumptions
   regarding a server's implementation of this feature, beyond that the
   bytes returned will be zeroed.  Servers MUST support extending the
   file size via SETATTR.

   SETATTR is not guaranteed atomic.  A failed SETATTR may partially
   change a file's attributes, hence the reason why the reply always
   includes the status and the list of attributes that were set.

   If the object whose attributes are being changed has a file
   delegation that is held by a client other than the one doing the
   SETATTR, the delegation(s) must be recalled, and the operation cannot
   proceed to actually change an attribute until each such delegation is
   returned or revoked.  In all cases in which delegations are recalled,
   the server is likely to return one or more NFS4ERR_DELAY errors while
   the delegation(s) remains outstanding, although it might not do that
   if the delegations are returned quickly.

   Changing the size of a file with SETATTR indirectly changes the
   time_modify and change attributes.  A client must account for this as
   size changes can result in data deletion.

   The attributes time_access_set and time_modify_set are write-only
   attributes constructed as a switched union so the client can direct
   the server in setting the time values.  If the switched union
   specifies SET_TO_CLIENT_TIME4, the client has provided an nfstime4 to
   be used for the operation.  If the switch union does not specify
   SET_TO_CLIENT_TIME4, the server is to use its current time for the
   SETATTR operation.

Haynes & Noveck         Expires February 17, 2014             [Page 263]
Internet-Draft                    NFSv4                      August 2013

   If server and client times differ, programs that compare client time
   to file times can break.  A time maintenance protocol should be used
   to limit client/server time skew.

   Use of a COMPOUND containing a VERIFY operation specifying only the
   change attribute, immediately followed by a SETATTR, provides a means
   whereby a client may specify a request that emulates the
   functionality of the SETATTR guard mechanism of NFSv3.  Since the
   function of the guard mechanism is to avoid changes to the file
   attributes based on stale information, delays between checking of the
   guard condition and the setting of the attributes have the potential
   to compromise this function, as would the corresponding delay in the
   NFSv4 emulation.  Therefore, NFSv4 servers should take care to avoid
   such delays, to the degree possible, when executing such a request.

   If the server does not support an attribute as requested by the
   client, the server should return NFS4ERR_ATTRNOTSUPP.

   A mask of the attributes actually set is returned by SETATTR in all
   cases.  That mask MUST NOT include attribute bits not requested to be
   set by the client.  If the attribute masks in the request and reply
   are equal, the status field in the reply MUST be NFS4_OK.

15.35.  Operation 35: SETCLIENTID - Negotiate Client ID

15.35.1.  SYNOPSIS

     client, callback, callback_ident -> clientid, setclientid_confirm

15.35.2.  ARGUMENT

   struct SETCLIENTID4args {
           nfs_client_id4  client;
           cb_client4      callback;
           uint32_t        callback_ident;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 264]
Internet-Draft                    NFSv4                      August 2013

15.35.3.  RESULT

   struct SETCLIENTID4resok {
           clientid4       clientid;
           verifier4       setclientid_confirm;
   };

   union SETCLIENTID4res switch (nfsstat4 status) {
    case NFS4_OK:
            SETCLIENTID4resok      resok4;
    case NFS4ERR_CLID_INUSE:
            clientaddr4    client_using;
    default:
            void;
   };

15.35.4.  DESCRIPTION

   The client uses the SETCLIENTID operation to notify the server of its
   intention to use a particular client identifier, callback, and
   callback_ident for subsequent requests that entail creating lock,
   share reservation, and delegation state on the server.  Upon
   successful completion the server will return a shorthand client ID
   which, if confirmed via a separate step, will be used in subsequent
   file locking and file open requests.  Confirmation of the client ID
   must be done via the SETCLIENTID_CONFIRM operation to return the
   client ID and setclientid_confirm values, as verifiers, to the
   server.  The reason why two verifiers are necessary is that it is
   possible to use SETCLIENTID and SETCLIENTID_CONFIRM to modify the
   callback and callback_ident information but not the shorthand client
   ID.  In that event, the setclientid_confirm value is effectively the
   only verifier.

   The callback information provided in this operation will be used if
   the client is provided an open delegation at a future point.
   Therefore, the client must correctly reflect the program and port
   numbers for the callback program at the time SETCLIENTID is used.

   The callback_ident value is used by the server on the callback.  The
   client can leverage the callback_ident to eliminate the need for more
   than one callback RPC program number, while still being able to
   determine which server is initiating the callback.

15.35.5.  IMPLEMENTATION

   To understand how to implement SETCLIENTID, make the following
   notations.  Let:

Haynes & Noveck         Expires February 17, 2014             [Page 265]
Internet-Draft                    NFSv4                      August 2013

   x  be the value of the client.id subfield of the SETCLIENTID4args
      structure.

   v  be the value of the client.verifier subfield of the
      SETCLIENTID4args structure.

   c  be the value of the client ID field returned in the
      SETCLIENTID4resok structure.

   k  represent the value combination of the fields callback and
      callback_ident fields of the SETCLIENTID4args structure.

   s  be the setclientid_confirm value returned in the SETCLIENTID4resok
      structure.

   { v, x, c, k, s }  be a quintuple for a client record.  A client
      record is confirmed if there has been a SETCLIENTID_CONFIRM
      operation to confirm it.  Otherwise it is unconfirmed.  An
      unconfirmed record is established by a SETCLIENTID call.

   Since SETCLIENTID is a non-idempotent operation, let us assume that
   the server is implementing the duplicate request cache (DRC).

   When the server gets a SETCLIENTID { v, x, k } request, it processes
   it in the following manner.

   o  It first looks up the request in the DRC.  If there is a hit, it
      returns the result cached in the DRC.  The server does NOT remove
      client state (locks, shares, delegations) nor does it modify any
      recorded callback and callback_ident information for client { x }.

      For any DRC miss, the server takes the client id string x, and
      searches for client records for x that the server may have
      recorded from previous SETCLIENTID calls.  For any confirmed
      record with the same id string x, if the recorded principal does
      not match that of SETCLIENTID call, then the server returns a
      NFS4ERR_CLID_INUSE error.

      For brevity of discussion, the remaining description of the
      processing assumes that there was a DRC miss, and that where the
      server has previously recorded a confirmed record for client x,
      the aforementioned principal check has successfully passed.

   o  The server checks if it has recorded a confirmed record for { v,
      x, c, l, s }, where l may or may not equal k.  If so, and since
      the id verifier v of the request matches that which is confirmed
      and recorded, the server treats this as a probable callback
      information update and records an unconfirmed { v, x, c, k, t }

Haynes & Noveck         Expires February 17, 2014             [Page 266]
Internet-Draft                    NFSv4                      August 2013

      and leaves the confirmed { v, x, c, l, s } in place, such that t
      != s.  It does not matter if k equals l or not.  Any pre-existing
      unconfirmed { v, x, c, *, * } is removed.

      The server returns { c, t }.  It is indeed returning the old
      clientid4 value c, because the client apparently only wants to
      update callback value k to value l.  It's possible this request is
      one from the Byzantine router that has stale callback information,
      but this is not a problem.  The callback information update is
      only confirmed if followed up by a SETCLIENTID_CONFIRM { c, t }.

      The server awaits confirmation of k via SETCLIENTID_CONFIRM { c, t
      }.

      The server does NOT remove client (lock/share/delegation) state
      for x.

   o  The server has previously recorded a confirmed { u, x, c, l, s }
      record such that v != u, l may or may not equal k, and has not
      recorded any unconfirmed { *, x, *, *, * } record for x.  The
      server records an unconfirmed { v, x, d, k, t } (d != c, t != s).

      The server returns { d, t }.

      The server awaits confirmation of { d, k } via SETCLIENTID_CONFIRM
      { d, t }.

      The server does NOT remove client (lock/share/delegation) state
      for x.

   o  The server has previously recorded a confirmed { u, x, c, l, s }
      record such that v != u, l may or may not equal k, and recorded an
      unconfirmed { w, x, d, m, t } record such that c != d, t != s, m
      may or may not equal k, m may or may not equal l, and k may or may
      not equal l.  Whether w == v or w != v makes no difference.  The
      server simply removes the unconfirmed { w, x, d, m, t } record and
      replaces it with an unconfirmed { v, x, e, k, r } record, such
      that e != d, e != c, r != t, r != s.

      The server returns { e, r }.

      The server awaits confirmation of { e, k } via SETCLIENTID_CONFIRM
      { e, r }.

      The server does NOT remove client (lock/share/delegation) state
      for x.

Haynes & Noveck         Expires February 17, 2014             [Page 267]
Internet-Draft                    NFSv4                      August 2013

   o  The server has no confirmed { *, x, *, *, * } for x.  It may or
      may not have recorded an unconfirmed { u, x, c, l, s }, where l
      may or may not equal k, and u may or may not equal v.  Any
      unconfirmed record { u, x, c, l, * }, regardless whether u == v or
      l == k, is replaced with an unconfirmed record { v, x, d, k, t }
      where d != c, t != s.

      The server returns { d, t }.

      The server awaits confirmation of { d, k } via SETCLIENTID_CONFIRM
      { d, t }.  The server does NOT remove client (lock/share/
      delegation) state for x.

   The server generates the clientid and setclientid_confirm values and
   must take care to ensure that these values are extremely unlikely to
   ever be regenerated.

15.36.  Operation 36: SETCLIENTID_CONFIRM - Confirm Client ID

15.36.1.  SYNOPSIS

     clientid, setclientid_confirm -> -

15.36.2.  ARGUMENT

   struct SETCLIENTID_CONFIRM4args {
           clientid4       clientid;
           verifier4       setclientid_confirm;
   };

15.36.3.  RESULT

   struct SETCLIENTID_CONFIRM4res {
           nfsstat4        status;
   };

15.36.4.  DESCRIPTION

   This operation is used by the client to confirm the results from a
   previous call to SETCLIENTID.  The client provides the server
   supplied (from a SETCLIENTID response) client ID.  The server
   responds with a simple status of success or failure.

Haynes & Noveck         Expires February 17, 2014             [Page 268]
Internet-Draft                    NFSv4                      August 2013

15.36.5.  IMPLEMENTATION

   The client must use the SETCLIENTID_CONFIRM operation to confirm the
   following two distinct cases:

   o  The client's use of a new shorthand client identifier (as returned
      from the server in the response to SETCLIENTID), a new callback
      value (as specified in the arguments to SETCLIENTID) and a new
      callback_ident (as specified in the arguments to SETCLIENTID)
      value.  The client's use of SETCLIENTID_CONFIRM in this case also
      confirms the removal of any of the client's previous relevant
      leased state.  Relevant leased client state includes byte-range
      locks, share reservations, and where the server does not support
      the CLAIM_DELEGATE_PREV claim type, delegations.  If the server
      supports CLAIM_DELEGATE_PREV, then SETCLIENTID_CONFIRM MUST NOT
      remove delegations for this client; relevant leased client state
      would then just include byte-range locks and share reservations.

   o  The client's re-use of an old, previously confirmed, shorthand
      client identifier, a new callback value, and a new callback_ident
      value.  The client's use of SETCLIENTID_CONFIRM in this case MUST
      NOT result in the removal of any previous leased state (locks,
      share reservations, and delegations)

   We use the same notation and definitions for v, x, c, k, s, and
   unconfirmed and confirmed client records as introduced in the
   description of the SETCLIENTID operation.  The arguments to
   SETCLIENTID_CONFIRM are indicated by the notation { c, s }, where c
   is a value of type clientid4, and s is a value of type verifier4
   corresponding to the setclientid_confirm field.

   As with SETCLIENTID, SETCLIENTID_CONFIRM is a non-idempotent
   operation, and we assume that the server is implementing the
   duplicate request cache (DRC).

   When the server gets a SETCLIENTID_CONFIRM { c, s } request, it
   processes it in the following manner.

   o  It first looks up the request in the DRC.  If there is a hit, it
      returns the result cached in the DRC.  The server does not remove
      any relevant leased client state nor does it modify any recorded
      callback and callback_ident information for client { x } as
      represented by the shorthand value c.

   For a DRC miss, the server checks for client records that match the
   shorthand value c.  The processing cases are as follows:

Haynes & Noveck         Expires February 17, 2014             [Page 269]
Internet-Draft                    NFSv4                      August 2013

   o  The server has recorded an unconfirmed { v, x, c, k, s } record
      and a confirmed { v, x, c, l, t } record, such that s != t.  If
      the principals of the records do not match that of the
      SETCLIENTID_CONFIRM, the server returns NFS4ERR_CLID_INUSE, and no
      relevant leased client state is removed and no recorded callback
      and callback_ident information for client { x } is changed.
      Otherwise, the confirmed { v, x, c, l, t } record is removed and
      the unconfirmed { v, x, c, k, s } is marked as confirmed, thereby
      modifying recorded and confirmed callback and callback_ident
      information for client { x }.

      The server does not remove any relevant leased client state.

      The server returns NFS4_OK.

   o  The server has not recorded an unconfirmed { v, x, c, *, * } and
      has recorded a confirmed { v, x, c, *, s }.  If the principals of
      the record and of SETCLIENTID_CONFIRM do not match, the server
      returns NFS4ERR_CLID_INUSE without removing any relevant leased
      client state and without changing recorded callback and
      callback_ident values for client { x }.

      If the principals match, then what has likely happened is that the
      client never got the response from the SETCLIENTID_CONFIRM, and
      the DRC entry has been purged.  Whatever the scenario, since the
      principals match, as well as { c, s } matching a confirmed record,
      the server leaves client x's relevant leased client state intact,
      leaves its callback and callback_ident values unmodified, and
      returns NFS4_OK.

   o  The server has not recorded a confirmed { *, *, c, *, * }, and has
      recorded an unconfirmed { *, x, c, k, s }.  Even if this is a
      retry from client, nonetheless the client's first
      SETCLIENTID_CONFIRM attempt was not received by the server.  Retry
      or not, the server doesn't know, but it processes it as if were a
      first try.  If the principal of the unconfirmed { *, x, c, k, s }
      record mismatches that of the SETCLIENTID_CONFIRM request the
      server returns NFS4ERR_CLID_INUSE without removing any relevant
      leased client state.

      Otherwise, the server records a confirmed { *, x, c, k, s }.  If
      there is also a confirmed { *, x, d, *, t }, the server MUST
      remove the client x's relevant leased client state, and overwrite
      the callback state with k.  The confirmed record { *, x, d, *, t }
      is removed.

      Server returns NFS4_OK.

Haynes & Noveck         Expires February 17, 2014             [Page 270]
Internet-Draft                    NFSv4                      August 2013

   o  The server has no record of a confirmed or unconfirmed { *, *, c,
      *, s }.  The server returns NFS4ERR_STALE_CLIENTID.  The server
      does not remove any relevant leased client state, nor does it
      modify any recorded callback and callback_ident information for
      any client.

   The server needs to cache unconfirmed { v, x, c, k, s } client
   records and await for some time their confirmation.  As should be
   clear from the record processing discussions for SETCLIENTID and
   SETCLIENTID_CONFIRM, there are cases where the server does not
   deterministically remove unconfirmed client records.  To avoid
   running out of resources, the server is not required to hold
   unconfirmed records indefinitely.  One strategy the server might use
   is to set a limit on how many unconfirmed client records it will
   maintain, and then when the limit would be exceeded, remove the
   oldest record.  Another strategy might be to remove an unconfirmed
   record when some amount of time has elapsed.  The choice of the
   amount of time is fairly arbitrary but it is surely no higher than
   the server's lease time period.  Consider that leases need to be
   renewed before the lease time expires via an operation from the
   client.  If the client cannot issue a SETCLIENTID_CONFIRM after a
   SETCLIENTID before a period of time equal to that of a lease expires,
   then the client is unlikely to be able maintain state on the server
   during steady state operation.

   If the client does send a SETCLIENTID_CONFIRM for an unconfirmed
   record that the server has already deleted, the client will get
   NFS4ERR_STALE_CLIENTID back.  If so, the client should then start
   over, and send SETCLIENTID to reestablish an unconfirmed client
   record and get back an unconfirmed client ID and setclientid_confirm
   verifier.  The client should then send the SETCLIENTID_CONFIRM to
   confirm the client ID.

   SETCLIENTID_CONFIRM does not establish or renew a lease.  However, if
   SETCLIENTID_CONFIRM removes relevant leased client state, and that
   state does not include existing delegations, the server MUST allow
   the client a period of time no less than the value of lease_time
   attribute, to reclaim, (via the CLAIM_DELEGATE_PREV claim type of the
   OPEN operation) its delegations before removing unreclaimed
   delegations.

15.37.  Operation 37: VERIFY - Verify Same Attributes

15.37.1.  SYNOPSIS

     (cfh), fattr -> -

Haynes & Noveck         Expires February 17, 2014             [Page 271]
Internet-Draft                    NFSv4                      August 2013

15.37.2.  ARGUMENT

   struct VERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };

15.37.3.  RESULT

   struct VERIFY4res {
           nfsstat4        status;
   };

15.37.4.  DESCRIPTION

   The VERIFY operation is used to verify that attributes have a value
   assumed by the client before proceeding with following operations in
   the compound request.  If any of the attributes do not match then the
   error NFS4ERR_NOT_SAME must be returned.  The current filehandle
   retains its value after successful completion of the operation.

15.37.5.  IMPLEMENTATION

   One possible use of the VERIFY operation is the following compound
   sequence.  With this the client is attempting to verify that the file
   being removed will match what the client expects to be removed.  This
   sequence can help prevent the unintended deletion of a file.

     PUTFH (directory filehandle)
     LOOKUP (file name)
     VERIFY (filehandle == fh)
     PUTFH (directory filehandle)
     REMOVE (file name)

   This sequence does not prevent a second client from removing and
   creating a new file in the middle of this sequence but it does help
   avoid the unintended result.

   In the case that a recommended attribute is specified in the VERIFY
   operation and the server does not support that attribute for the file
   system object, the error NFS4ERR_ATTRNOTSUPP is returned to the
   client.

   When the attribute rdattr_error or any write-only attribute (e.g.,
   time_modify_set) is specified, the error NFS4ERR_INVAL is returned to
   the client.

Haynes & Noveck         Expires February 17, 2014             [Page 272]
Internet-Draft                    NFSv4                      August 2013

15.38.  Operation 38: WRITE - Write to File

15.38.1.  SYNOPSIS

     (cfh), stateid, offset, stable, data -> count, committed, writeverf

15.38.2.  ARGUMENT

   enum stable_how4 {
           UNSTABLE4       = 0,
           DATA_SYNC4      = 1,
           FILE_SYNC4      = 2
   };

   struct WRITE4args {
           /* CURRENT_FH: file */
           stateid4        stateid;
           offset4         offset;
           stable_how4     stable;
           opaque          data<>;
   };

15.38.3.  RESULT

   struct WRITE4resok {
           count4          count;
           stable_how4     committed;
           verifier4       writeverf;
   };

   union WRITE4res switch (nfsstat4 status) {
    case NFS4_OK:
            WRITE4resok    resok4;
    default:
            void;
   };

15.38.4.  DESCRIPTION

   The WRITE operation is used to write data to a regular file.  The
   target file is specified by the current filehandle.  The offset
   specifies the offset where the data should be written.  An offset of
   0 (zero) specifies that the write should start at the beginning of
   the file.  The count, as encoded as part of the opaque data
   parameter, represents the number of bytes of data that are to be
   written.  If the count is 0 (zero), the WRITE will succeed and return

Haynes & Noveck         Expires February 17, 2014             [Page 273]
Internet-Draft                    NFSv4                      August 2013

   a count of 0 (zero) subject to permissions checking.  The server may
   choose to write fewer bytes than requested by the client.

   Part of the write request is a specification of how the write is to
   be performed.  The client specifies with the stable parameter the
   method of how the data is to be processed by the server.  If stable
   is FILE_SYNC4, the server must commit the data written plus all file
   system metadata to stable storage before returning results.  This
   corresponds to the NFS version 2 protocol semantics.  Any other
   behavior constitutes a protocol violation.  If stable is DATA_SYNC4,
   then the server must commit all of the data to stable storage and
   enough of the metadata to retrieve the data before returning.  The
   server implementor is free to implement DATA_SYNC4 in the same
   fashion as FILE_SYNC4, but with a possible performance drop.  If
   stable is UNSTABLE4, the server is free to commit any part of the
   data and the metadata to stable storage, including all or none,
   before returning a reply to the client.  There is no guarantee
   whether or when any uncommitted data will subsequently be committed
   to stable storage.  The only guarantees made by the server are that
   it will not destroy any data without changing the value of verf and
   that it will not commit the data and metadata at a level less than
   that requested by the client.

   The stateid value for a WRITE request represents a value returned
   from a previous byte-range lock or share reservation request or the
   stateid associated with a delegation.  The stateid is used by the
   server to verify that the associated share reservation and any byte-
   range locks are still valid and to update lease timeouts for the
   client.

   Upon successful completion, the following results are returned.  The
   count result is the number of bytes of data written to the file.  The
   server may write fewer bytes than requested.  If so, the actual
   number of bytes written starting at location, offset, is returned.

   The server also returns an indication of the level of commitment of
   the data and metadata via committed.  If the server committed all
   data and metadata to stable storage, committed should be set to
   FILE_SYNC4.  If the level of commitment was at least as strong as
   DATA_SYNC4, then committed should be set to DATA_SYNC4.  Otherwise,
   committed must be returned as UNSTABLE4.  If stable was FILE4_SYNC,
   then committed must also be FILE_SYNC4: anything else constitutes a
   protocol violation.  If stable was DATA_SYNC4, then committed may be
   FILE_SYNC4 or DATA_SYNC4: anything else constitutes a protocol
   violation.  If stable was UNSTABLE4, then committed may be either
   FILE_SYNC4, DATA_SYNC4, or UNSTABLE4.

   The final portion of the result is the write verifier.  The write

Haynes & Noveck         Expires February 17, 2014             [Page 274]
Internet-Draft                    NFSv4                      August 2013

   verifier is a cookie that the client can use to determine whether the
   server has changed instance (boot) state between a call to WRITE and
   a subsequent call to either WRITE or COMMIT.  This cookie must be
   consistent during a single instance of the NFSv4 protocol service and
   must be unique between instances of the NFSv4 protocol server, where
   uncommitted data may be lost.

   If a client writes data to the server with the stable argument set to
   UNSTABLE4 and the reply yields a committed response of DATA_SYNC4 or
   UNSTABLE4, the client will follow up some time in the future with a
   COMMIT operation to synchronize outstanding asynchronous data and
   metadata with the server's stable storage, barring client error.  It
   is possible that due to client crash or other error that a subsequent
   COMMIT will not be received by the server.

   For a WRITE with a stateid value of all bits 0, the server MAY allow
   the WRITE to be serviced subject to mandatory file locks or the
   current share deny modes for the file.  For a WRITE with a stateid
   value of all bits 1, the server MUST NOT allow the WRITE operation to
   bypass locking checks at the server and are treated exactly the same
   as if a stateid of all bits 0 were used.

   On success, the current filehandle retains its value.

15.38.5.  IMPLEMENTATION

   It is possible for the server to write fewer bytes of data than
   requested by the client.  In this case, the server should not return
   an error unless no data was written at all.  If the server writes
   less than the number of bytes specified, the client should issue
   another WRITE to write the remaining data.

   It is assumed that the act of writing data to a file will cause the
   time_modified of the file to be updated.  However, the time_modified
   of the file should not be changed unless the contents of the file are
   changed.  Thus, a WRITE request with count set to 0 should not cause
   the time_modified of the file to be updated.

   The definition of stable storage has been historically a point of
   contention.  The following expected properties of stable storage may
   help in resolving design issues in the implementation.  Stable
   storage is persistent storage that survives:

   1.  Repeated power failures.

   2.  Hardware failures (of any board, power supply, etc.).

Haynes & Noveck         Expires February 17, 2014             [Page 275]
Internet-Draft                    NFSv4                      August 2013

   3.  Repeated software crashes, including reboot cycle.

   This definition does not address failure of the stable storage module
   itself.

   The verifier is defined to allow a client to detect different
   instances of an NFSv4 protocol server over which cached, uncommitted
   data may be lost.  In the most likely case, the verifier allows the
   client to detect server reboots.  This information is required so
   that the client can safely determine whether the server could have
   lost cached data.  If the server fails unexpectedly and the client
   has uncommitted data from previous WRITE requests (done with the
   stable argument set to UNSTABLE4 and in which the result committed
   was returned as UNSTABLE4 as well) it may not have flushed cached
   data to stable storage.  The burden of recovery is on the client and
   the client will need to retransmit the data to the server.

   A suggested verifier would be to use the time that the server was
   booted or the time the server was last started (if restarting the
   server without a reboot results in lost buffers).

   The committed field in the results allows the client to do more
   effective caching.  If the server is committing all WRITE requests to
   stable storage, then it should return with committed set to
   FILE_SYNC4, regardless of the value of the stable field in the
   arguments.  A server that uses an NVRAM accelerator may choose to
   implement this policy.  The client can use this to increase the
   effectiveness of the cache by discarding cached data that has already
   been committed on the server.

   Some implementations may return NFS4ERR_NOSPC instead of
   NFS4ERR_DQUOT when a user's quota is exceeded.  In the case that the
   current filehandle is a directory, the server will return
   NFS4ERR_ISDIR.  If the current filehandle is not a regular file or a
   directory, the server will return NFS4ERR_INVAL.

   If mandatory file locking is on for the file, and corresponding
   record of the data to be written file is read or write locked by an
   owner that is not associated with the stateid, the server will return
   NFS4ERR_LOCKED.  If so, the client must check if the owner
   corresponding to the stateid used with the WRITE operation has a
   conflicting read lock that overlaps with the region that was to be
   written.  If the stateid's owner has no conflicting read lock, then
   the client should try to get the appropriate write byte-range lock
   via the LOCK operation before re-attempting the WRITE.  When the
   WRITE completes, the client should release the byte-range lock via
   LOCKU.

Haynes & Noveck         Expires February 17, 2014             [Page 276]
Internet-Draft                    NFSv4                      August 2013

   If the stateid's owner had a conflicting read lock, then the client
   has no choice but to return an error to the application that
   attempted the WRITE.  The reason is that since the stateid's owner
   had a read lock, the server either attempted to temporarily
   effectively upgrade this read lock to a write lock, or the server has
   no upgrade capability.  If the server attempted to upgrade the read
   lock and failed, it is pointless for the client to re-attempt the
   upgrade via the LOCK operation, because there might be another client
   also trying to upgrade.  If two clients are blocked trying upgrade
   the same lock, the clients deadlock.  If the server has no upgrade
   capability, then it is pointless to try a LOCK operation to upgrade.

15.39.  Operation 39: RELEASE_LOCKOWNER - Release Lockowner State

15.39.1.  SYNOPSIS

     lock-owner -> ()

15.39.2.  ARGUMENT

   struct RELEASE_LOCKOWNER4args {
           lock_owner4     lock_owner;
   };

15.39.3.  RESULT

   struct RELEASE_LOCKOWNER4res {
           nfsstat4        status;
   };

15.39.4.  DESCRIPTION

   This operation is used to notify the server that the lock_owner is no
   longer in use by the client and that future client requests will not
   reference this lock_owner.  This allows the server to release cached
   state related to the specified lock_owner.  If file locks, associated
   with the lock_owner, are held at the server, the error
   NFS4ERR_LOCKS_HELD will be returned and no further action will be
   taken.

15.39.5.  IMPLEMENTATION

   The client may choose to use this operation to ease the amount of
   server state that is held.  Information that can be released when a
   RELEASE_LOCKOWNER is done includes the specified lock-owner string,
   the seqid associated with the lock-owner, any saved reply for the

Haynes & Noveck         Expires February 17, 2014             [Page 277]
Internet-Draft                    NFSv4                      August 2013

   lock-owner, and any lock stateids associated with that lock-owner.

   Depending on the behavior of applications at the client, it may be
   important for the client to use this operation since the server has
   certain obligations with respect to holding a reference to lock-
   owner-associated state as long as an associated file is open.
   Therefore, if the client knows for certain that the lock_owner will
   no longer be used, either to reference existing lock stateids
   associated with the lock-owner to create new ones, it should use
   RELEASE_LOCKOWNER.

15.40.  Operation 10044: ILLEGAL - Illegal operation

15.40.1.  SYNOPSIS

     <null> -> ()

15.40.2.  ARGUMENT

     void;

15.40.3.  RESULT

   struct ILLEGAL4res {
           nfsstat4        status;
   };

15.40.4.  DESCRIPTION

   This operation is a place holder for encoding a result to handle the
   case of the client sending an operation code within COMPOUND that is
   not supported.  See Section 15.2.4 for more details.

   The status field of ILLEGAL4res MUST be set to NFS4ERR_OP_ILLEGAL.

15.40.5.  IMPLEMENTATION

   A client will probably not send an operation with code OP_ILLEGAL but
   if it does, the response will be ILLEGAL4res just as it would be with
   any other invalid operation code.  Note that if the server gets an
   illegal operation code that is not OP_ILLEGAL, and if the server
   checks for legal operation codes during the XDR decode phase, then
   the ILLEGAL4res would not be returned.

Haynes & Noveck         Expires February 17, 2014             [Page 278]
Internet-Draft                    NFSv4                      August 2013

16.  NFSv4 Callback Procedures

   The procedures used for callbacks are defined in the following
   sections.  In the interest of clarity, the terms "client" and
   "server" refer to NFS clients and servers, despite the fact that for
   an individual callback RPC, the sense of these terms would be
   precisely the opposite.

16.1.  Procedure 0: CB_NULL - No Operation

16.1.1.  SYNOPSIS

     <null>

16.1.2.  ARGUMENT

     void;

16.1.3.  RESULT

     void;

16.1.4.  DESCRIPTION

   Standard NULL procedure.  Void argument, void response.  Even though
   there is no direct functionality associated with this procedure, the
   server will use CB_NULL to confirm the existence of a path for RPCs
   from server to client.

16.2.  Procedure 1: CB_COMPOUND - Compound Operations

16.2.1.  SYNOPSIS

     compoundargs -> compoundres

16.2.2.  ARGUMENT

   enum nfs_cb_opnum4 {
           OP_CB_GETATTR           = 3,
           OP_CB_RECALL            = 4,
           OP_CB_ILLEGAL           = 10044
   };

Haynes & Noveck         Expires February 17, 2014             [Page 279]
Internet-Draft                    NFSv4                      August 2013

   union nfs_cb_argop4 switch (unsigned argop) {
    case OP_CB_GETATTR:
         CB_GETATTR4args           opcbgetattr;
    case OP_CB_RECALL:
         CB_RECALL4args            opcbrecall;
    case OP_CB_ILLEGAL:            void;
   };

   struct CB_COMPOUND4args {
           utf8str_cs      tag;
           uint32_t        minorversion;
           uint32_t        callback_ident;
           nfs_cb_argop4   argarray<>;
   };

16.2.3.  RESULT

   union nfs_cb_resop4 switch (unsigned resop) {
    case OP_CB_GETATTR:    CB_GETATTR4res  opcbgetattr;
    case OP_CB_RECALL:     CB_RECALL4res   opcbrecall;
    case OP_CB_ILLEGAL:    CB_ILLEGAL4res  opcbillegal;
   };

   struct CB_COMPOUND4res {
           nfsstat4        status;
           utf8str_cs      tag;
           nfs_cb_resop4   resarray<>;
   };

16.2.4.  DESCRIPTION

   The CB_COMPOUND procedure is used to combine one or more of the
   callback procedures into a single RPC request.  The main callback RPC
   program has two main procedures: CB_NULL and CB_COMPOUND.  All other
   operations use the CB_COMPOUND procedure as a wrapper.

   In the processing of the CB_COMPOUND procedure, the client may find
   that it does not have the available resources to execute any or all
   of the operations within the CB_COMPOUND sequence.  In this case, the
   error NFS4ERR_RESOURCE will be returned for the particular operation
   within the CB_COMPOUND procedure where the resource exhaustion
   occurred.  This assumes that all previous operations within the
   CB_COMPOUND sequence have been evaluated successfully.

   Contained within the CB_COMPOUND results is a 'status' field.  This
   status must be equivalent to the status of the last operation that

Haynes & Noveck         Expires February 17, 2014             [Page 280]
Internet-Draft                    NFSv4                      August 2013

   was executed within the CB_COMPOUND procedure.  Therefore, if an
   operation incurred an error then the 'status' value will be the same
   error value as is being returned for the operation that failed.

   For the definition of the "tag" field, see Section 15.2.

   The value of callback_ident is supplied by the client during
   SETCLIENTID.  The server must use the client supplied callback_ident
   during the CB_COMPOUND to allow the client to properly identify the
   server.

   Illegal operation codes are handled in the same way as they are
   handled for the COMPOUND procedure.

16.2.5.  IMPLEMENTATION

   The CB_COMPOUND procedure is used to combine individual operations
   into a single RPC request.  The client interprets each of the
   operations in turn.  If an operation is executed by the client and
   the status of that operation is NFS4_OK, then the next operation in
   the CB_COMPOUND procedure is executed.  The client continues this
   process until there are no more operations to be executed or one of
   the operations has a status value other than NFS4_OK.

16.2.6.  Operation 3: CB_GETATTR - Get Attributes

16.2.6.1.  SYNOPSIS

     fh, attr_request -> attrmask, attr_vals

16.2.6.2.  ARGUMENT

   struct CB_GETATTR4args {
           nfs_fh4 fh;
           bitmap4 attr_request;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 281]
Internet-Draft                    NFSv4                      August 2013

16.2.6.3.  RESULT

   struct CB_GETATTR4resok {
           fattr4  obj_attributes;
   };

   union CB_GETATTR4res switch (nfsstat4 status) {
    case NFS4_OK:
            CB_GETATTR4resok       resok4;
    default:
            void;
   };

16.2.6.4.  DESCRIPTION

   The CB_GETATTR operation is used by the server to obtain the current
   modified state of a file that has been OPEN_DELEGATE_WRITE delegated.
   The attributes size and change are the only ones guaranteed to be
   serviced by the client.  See Section 10.4.3 for a full description of
   how the client and server are to interact with the use of CB_GETATTR.

   If the filehandle specified is not one for which the client holds a
   OPEN_DELEGATE_WRITE delegation, an NFS4ERR_BADHANDLE error is
   returned.

16.2.6.5.  IMPLEMENTATION

   The client returns attrmask bits and the associated attribute values
   only for the change attribute, and attributes that it may change
   (time_modify, and size).

16.2.7.  Operation 4: CB_RECALL - Recall an Open Delegation

16.2.7.1.  SYNOPSIS

     stateid, truncate, fh -> ()

16.2.7.2.  ARGUMENT

   struct CB_RECALL4args {
           stateid4        stateid;
           bool            truncate;
           nfs_fh4         fh;
   };

Haynes & Noveck         Expires February 17, 2014             [Page 282]
Internet-Draft                    NFSv4                      August 2013

16.2.7.3.  RESULT

   struct CB_RECALL4res {
           nfsstat4        status;
   };

16.2.7.4.  DESCRIPTION

   The CB_RECALL operation is used to begin the process of recalling an
   open delegation and returning it to the server.

   The truncate flag is used to optimize recall for a file which is
   about to be truncated to zero.  When it is set, the client is freed
   of obligation to propagate modified data for the file to the server,
   since this data is irrelevant.

   If the handle specified is not one for which the client holds an open
   delegation, an NFS4ERR_BADHANDLE error is returned.

   If the stateid specified is not one corresponding to an open
   delegation for the file specified by the filehandle, an
   NFS4ERR_BAD_STATEID is returned.

16.2.7.5.  IMPLEMENTATION

   The client should reply to the callback immediately.  Replying does
   not complete the recall except when an error was returned.  The
   recall is not complete until the delegation is returned using a
   DELEGRETURN.

16.2.8.  Operation 10044: CB_ILLEGAL - Illegal Callback Operation

16.2.8.1.  SYNOPSIS

     <null> -> ()

16.2.8.2.  ARGUMENT

     void;

Haynes & Noveck         Expires February 17, 2014             [Page 283]
Internet-Draft                    NFSv4                      August 2013

16.2.8.3.  RESULT

   /*
    * CB_ILLEGAL: Response for illegal operation numbers
    */
   struct CB_ILLEGAL4res {
           nfsstat4        status;
   };

16.2.8.4.  DESCRIPTION

   This operation is a place-holder for encoding a result to handle the
   case of the client sending an operation code within COMPOUND that is
   not supported.  See Section 15.2.4 for more details.

   The status field of CB_ILLEGAL4res MUST be set to NFS4ERR_OP_ILLEGAL.

16.2.8.5.  IMPLEMENTATION

   A server will probably not send an operation with code OP_CB_ILLEGAL
   but if it does, the response will be CB_ILLEGAL4res just as it would
   be with any other invalid operation code.  Note that if the client
   gets an illegal operation code that is not OP_ILLEGAL, and if the
   client checks for legal operation codes during the XDR decode phase,
   then the CB_ILLEGAL4res would not be returned.

17.  Security Considerations

   NFS has historically used a model where, from an authentication
   perspective, the client was the entire machine, or at least the
   source IP address of the machine.  The NFS server relied on the NFS
   client to make the proper authentication of the end-user.  The NFS
   server in turn shared its files only to specific clients, as
   identified by the client's source IP address.  Given this model, the
   AUTH_SYS RPC security flavor simply identified the end-user using the
   client to the NFS server.  When processing NFS responses, the client
   ensured that the responses came from the same IP address and port
   number that the request was sent to.  While such a model is easy to
   implement and simple to deploy and use, it is certainly not a safe
   model.  Thus, NFSv4 mandates that implementations support a security
   model that uses end to end authentication, where an end-user on a
   client mutually authenticates (via cryptographic schemes that do not
   expose passwords or keys in the clear on the network) to a principal
   on an NFS server.  Consideration should also be given to the
   integrity and privacy of NFS requests and responses.  The issues of
   end to end mutual authentication, integrity, and privacy are

Haynes & Noveck         Expires February 17, 2014             [Page 284]
Internet-Draft                    NFSv4                      August 2013

   discussed as part of Section 3.

   When an NFSv4 mandated security model is used and a security
   principal or an NFSv4 name in user@dns_domain form needs to be
   translated to or from a local representation as described in
   Section 5.9, the translation SHOULD be done in a secure manner that
   preserves the integrity of the translation.  For communication with a
   name service such as LDAP ([RFC4511]), this means employing a
   security service that uses authentication and data integrity.
   Kerberos and Transport Layer Security (TLS) ([RFC5246]) are examples
   of such a security service.

   Note that being REQUIRED to implement does not mean REQUIRED to use;
   AUTH_SYS can be used by NFSv4 clients and servers.  However, AUTH_SYS
   is merely an OPTIONAL security flavor in NFSv4, and so
   interoperability via AUTH_SYS is not assured.

   For reasons of reduced administration overhead, better performance
   and/or reduction of CPU utilization, users of NFSv4 implementations
   may choose to not use security mechanisms that enable integrity
   protection on each remote procedure call and response.  The use of
   mechanisms without integrity leaves the customer vulnerable to an
   attacker in between the NFS client and server that modifies the RPC
   request and/or the response.  While implementations are free to
   provide the option to use weaker security mechanisms, there are two
   operations in particular that warrant the implementation overriding
   user choices.

   The first such operation is SECINFO.  It is recommended that the
   client issue the SECINFO call such that it is protected with a
   security flavor that has integrity protection, such as RPCSEC_GSS
   with a security triple that uses either rpc_gss_svc_integrity or
   rpc_gss_svc_privacy (rpc_gss_svc_privacy includes integrity
   protection) service.  Without integrity protection encapsulating
   SECINFO and therefore its results, an attacker in the middle could
   modify results such that the client might select a weaker algorithm
   in the set allowed by server, making the client and/or server
   vulnerable to further attacks.

   The second operation that SHOULD use integrity protection is any
   GETATTR for the fs_locations attribute.  The attack has two steps.
   First the attacker modifies the unprotected results of some operation
   to return NFS4ERR_MOVED.  Second, when the client follows up with a
   GETATTR for the fs_locations attribute, the attacker modifies the
   results to cause the client migrate its traffic to a server
   controlled by the attacker.

   Because the operations SETCLIENTID/SETCLIENTID_CONFIRM are

Haynes & Noveck         Expires February 17, 2014             [Page 285]
Internet-Draft                    NFSv4                      August 2013

   responsible for the release of client state, it is imperative that
   the principal used for these operations is checked against and match
   the previous use of these operations.  See Section 9.1.1 for further
   discussion.

18.  IANA Considerations

   This section uses terms that are defined in [RFC5226].

18.1.  Named Attribute Definitions

   IANA had created a registry called the "NFSv4 Named Attribute
   Definitions Registry" for [RFC3530] and [RFC5661].  This section
   introduces no new changes, but it does recap the intent.

   The NFSv4 protocol supports the association of a file with zero or
   more named attributes.  The name space identifiers for these
   attributes are defined as string names.  The protocol does not define
   the specific assignment of the name space for these file attributes.
   The IANA registry promotes interoperability where common interests
   exist.  While application developers are allowed to define and use
   attributes as needed, they are encouraged to register the attributes
   with IANA.

   Such registered named attributes are presumed to apply to all minor
   versions of NFSv4, including those defined subsequently to the
   registration.  Where the named attribute is intended to be limited
   with regard to the minor versions for which they are not be used, the
   assignment in registry will clearly state the applicable limits.

   All assignments to the registry are made on a First Come First Served
   basis, per section 4.1 of [RFC5226].  The policy for each assignment
   is Specification Required, per section 4.1 of [RFC5226].

   Under the NFSv4 specification, the name of a named attribute can in
   theory be up to 2^32 - 1 bytes in length, but in practice NFSv4
   clients and servers will be unable to handle a string that long.
   IANA should reject any assignment request with a named attribute that
   exceeds 128 UTF-8 characters.  To give IESG the flexibility to set up
   bases of assignment of Experimental Use and Standards Action, the
   prefixes of "EXPE" and "STDS" are Reserved.  The zero length named
   attribute name is Reserved.

   The prefix "PRIV" is allocated for Private Use. A site that wants to
   make use of unregistered named attributes without risk of conflicting
   with an assignment in IANA's registry should use the prefix "PRIV" in
   all of its named attributes.

Haynes & Noveck         Expires February 17, 2014             [Page 286]
Internet-Draft                    NFSv4                      August 2013

   Because some NFSv4 clients and servers have case insensitive
   semantics, the fifteen additional lower case and mixed case
   permutations of each of "EXPE", "PRIV", and "STDS", are Reserved
   (e.g. "expe", "expE", "exPe", etc. are Reserved).  Similarly, IANA
   must not allow two assignments that would conflict if both named
   attributes were converted to a common case.

   The registry of named attributes is a list of assignments, each
   containing three fields for each assignment.

   1.  A US-ASCII string name that is the actual name of the attribute.
       This name must be unique.  This string name can be 1 to 128 UTF-8
       characters long.

   2.  A reference to the specification of the named attribute.  The
       reference can consume up to 256 bytes (or more if IANA permits).

   3.  The point of contact of the registrant.  The point of contact can
       consume up to 256 bytes (or more if IANA permits).

18.1.1.  Initial Registry

   There is no initial registry.

18.1.2.  Updating Registrations

   The registrant is always permitted to update the point of contact
   field.  To make any other change will require Expert Review or IESG
   Approval.

19.  References

19.1.  Normative References

   [I-D.ietf-nfsv4-rfc3530bis-dot-x]
              Haynes, T. and D. Noveck, "NFSv4 Version 0 XDR
              Description", draft-ietf-nfsv4-rfc3530bis-dot-x-18 (work
              in progress), Aug 2013.

   [ISO.10646-1.1993]
              International Organization for Standardization,
              "Information Technology - Universal Multiple-octet coded
              Character Set (UCS) - Part 1: Architecture and Basic
              Multilingual Plane", ISO Standard 10646-1, May 1993.

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", March 1997.

Haynes & Noveck         Expires February 17, 2014             [Page 287]
Internet-Draft                    NFSv4                      August 2013

   [RFC2203]  Eisler, M., Chiu, A., and L. Ling, "RPCSEC_GSS Protocol
              Specification", RFC 2203, September 1997.

   [RFC2277]  Alvestrand, H., "IETF Policy on Character Sets and
              Languages", BCP 18, RFC 2277, January 1998.

   [RFC2743]  Linn, J., "Generic Security Service Application Program
              Interface Version 2, Update 1", RFC 2743, January 2000.

   [RFC5403]  Eisler, M., "RPCSEC_GSS Version 2", RFC 5403,
              February 2009.

   [RFC5531]  Thurlow, R., "RPC: Remote Procedure Call Protocol
              Specification Version 2", RFC 5531, May 2009.

   [RFC5665]  Eisler, M., Ed., "IANA Considerations for Remote Procedure
              Call (RPC) Network Identifiers and Universal Address
              Formats", RFC 5665, January 2010.

   [RFC5890]  Klensin, J., "Internationalized Domain Names in
              Applications (IDNA): Definitions and Document Framework",
              RFC 5890, August 2010.

   [RFC5891]  Klensin, J., "Internationalized Domain Names in
              Applications (IDNA): Protocol", RFC 5891, August 2010.

   [RFC6649]  Astrand, L. and T. Yu, "Deprecate DES, RC4-HMAC-EXP, and
              Other Weak Cryptographic Algorithms in Kerberos",
              RFC 6649, July 2012.

   [openg_symlink]
              The Open Group, "Section 3.372 of Chapter 3 of Base
              Definitions of The Open Group Base Specifications Issue 6,
              IEEE Std 1003.1, 2004 Edition, HTML Version
              (www.opengroup.org), ISBN 1931624232", 2004.

19.2.  Informative References

   [Chet]     Juszczak, C., "Improving the Performance and Correctness
              of an NFS Server", USENIX Conference Proceedings ,
              June 1990.

   [Floyd]    Floyd, S. and V. Jacobson, "The Synchronization of
              Periodic Routing Messages", IEEE/ACM Transactions on
              Networking 2(2), pp. 122-136, April 1994.

   [ISEG_errata]
              IESG, "IESG Processing of RFC Errata for the IETF Stream",

Haynes & Noveck         Expires February 17, 2014             [Page 288]
Internet-Draft                    NFSv4                      August 2013

              July 2008.

   [P1003.1e]
              Institute of Electrical and Electronics Engineers, Inc.,
              "IEEE Draft P1003.1e", 1997.

   [RFC0793]  Postel, J., "Transmission Control Protocol", STD 7,
              RFC 793, September 1981.

   [RFC1094]  Nowicki, B., "NFS: Network File System Protocol
              specification", RFC 1094, March 1989.

   [RFC1345]  Simonsen, K., "Character Mnemonics and Character Sets",
              RFC 1345, June 1992.

   [RFC1813]  Callaghan, B., Pawlowski, B., and P. Staubach, "NFS
              Version 3 Protocol Specification", RFC 1813, June 1995.

   [RFC1833]  Srinivasan, R., "Binding Protocols for ONC RPC Version 2",
              RFC 1833, August 1995.

   [RFC2054]  Callaghan, B., "WebNFS Client Specification", RFC 2054,
              October 1996.

   [RFC2055]  Callaghan, B., "WebNFS Server Specification", RFC 2055,
              October 1996.

   [RFC2224]  Callaghan, B., "NFS URL Scheme", RFC 2224, October 1997.

   [RFC2623]  Eisler, M., "NFS Version 2 and Version 3 Security Issues
              and the NFS Protocol's Use of RPCSEC_GSS and Kerberos V5",
              RFC 2623, June 1999.

   [RFC2624]  Shepler, S., "NFS Version 4 Design Considerations",
              RFC 2624, June 1999.

   [RFC2755]  Chiu, A., Eisler, M., and B. Callaghan, "Security
              Negotiation for WebNFS", RFC 2755, January 2000.

   [RFC3010]  Shepler, S., Callaghan, B., Robinson, D., Thurlow, R.,
              Beame, C., Eisler, M., and D. Noveck, "Network File System
              (NFS) version 4 Protocol", RFC 3010, December 2000.

   [RFC3232]  Reynolds, J., "Assigned Numbers: RFC 1700 is Replaced by
              an On-line Database", RFC 3232, January 2002.

   [RFC3454]  Hoffman, P. and M. Blanchet, "Preparation of
              Internationalized Strings ("stringprep")", RFC 3454,

Haynes & Noveck         Expires February 17, 2014             [Page 289]
Internet-Draft                    NFSv4                      August 2013

              December 2002.

   [RFC3530]  Shepler, S., Callaghan, B., Robinson, D., Thurlow, R.,
              Beame, C., Eisler, M., and D. Noveck, "Network File System
              (NFS) version 4 Protocol", RFC 3530, April 2003.

   [RFC4121]  Zhu, L., Jaganathan, K., and S. Hartman, "The Kerberos
              Version 5 Generic Security Service Application Program
              Interface (GSS-API) Mechanism: Version 2", RFC 4121,
              July 2005.

   [RFC4178]  Zhu, L., Leach, P., Jaganathan, K., and W. Ingersoll, "The
              Simple and Protected Generic Security Service Application
              Program Interface (GSS-API) Negotiation Mechanism",
              RFC 4178, October 2005.

   [RFC4340]  Kohler, E., Handley, M., and S. Floyd, "Datagram
              Congestion Control Protocol (DCCP)", RFC 4340, March 2006.

   [RFC4506]  Eisler, M., "XDR: External Data Representation Standard",
              RFC 4506, May 2006.

   [RFC4511]  Sermersheim, J., "Lightweight Directory Access Protocol
              (LDAP): The Protocol", RFC 4511, June 2006.

   [RFC5226]  Narten, T. and H. Alvestrand, "Guidelines for Writing an
              IANA Considerations Section in RFCs", BCP 26, RFC 5226,
              May 2008.

   [RFC5246]  Dierks, T. and E. Rescorla, "The Transport Layer Security
              (TLS) Protocol Version 1.2", RFC 5246, August 2008.

   [RFC5661]  Shepler, S., Eisler, M., and D. Noveck, "Network File
              System (NFS) Version 4 Minor Version 1 Protocol",
              RFC 5661, January 2010.

   [RFC5740]  Adamson, B., Bormann, C., Handley, M., and J. Macker,
              "Negative-acknowledgment (NACK)-Oriented Reliable
              Multicast (NORM) Transport Protocol", RFC 5740,
              November 2009.

   [fcntl]    The Open Group, "Section 'fcntl()' of System Interfaces of
              The Open Group Base Specifications Issue 6 IEEE Std
              1003.1, 2004 Edition, HTML Version (www.opengroup.org),
              ISBN 1931624232", 2004.

   [fsync]    The Open Group, "Section 'fsync()' of System Interfaces of
              The Open Group Base Specifications Issue 6 IEEE Std

Haynes & Noveck         Expires February 17, 2014             [Page 290]
Internet-Draft                    NFSv4                      August 2013

              1003.1, 2004 Edition, HTML Version (www.opengroup.org),
              ISBN 1931624232", 2004.

   [getpwnam]
              The Open Group, "Section 'getpwnam()' of System Interfaces
              of The Open Group Base Specifications Issue 6 IEEE Std
              1003.1, 2004 Edition, HTML Version (www.opengroup.org),
              ISBN 1931624232", 2004.

   [read_api]
              The Open Group, "Section 'read()' of System Interfaces of
              The Open Group Base Specifications Issue 6, IEEE Std
              1003.1, 2004 Edition", 2004.

   [readdir_api]
              The Open Group, "Section 'readdir()' of System Interfaces
              of The Open Group Base Specifications Issue 6, IEEE Std
              1003.1, 2004 Edition", 2004.

   [unlink]   The Open Group, "Section 'unlink()' of System Interfaces
              of The Open Group Base Specifications Issue 6 IEEE Std
              1003.1, 2004 Edition, HTML Version (www.opengroup.org),
              ISBN 1931624232", 2004.

   [write_api]
              The Open Group, "Section 'write()' of System Interfaces of
              The Open Group Base Specifications Issue 6, IEEE Std
              1003.1, 2004 Edition", 2004.

   [xnfs]     The Open Group, "Protocols for Interworking: XNFS, Version
              3W, ISBN 1-85912-184-5", February 1998.

Appendix A.  Acknowledgments

   A bis is certainly built on the shoulders of the first attempt.
   Spencer Shepler, Brent Callaghan, David Robinson, Robert Thurlow,
   Carl Beame, Mike Eisler, and David Noveck are responsible for a great
   deal of the effort in this work.

   Rob Thurlow clarified how a client should contact a new server if a
   migration has occurred.

   David Black, Nico Williams, Mike Eisler, Trond Myklebust, and James
   Lentini read many drafts of Section 12 and contributed numerous
   useful suggestions, without which the necessary revision of that
   section for this document would not have been possible.

Haynes & Noveck         Expires February 17, 2014             [Page 291]
Internet-Draft                    NFSv4                      August 2013

   Peter Staubach read almost all of the drafts of Section 12 leading to
   the published result and his numerous comments were always useful and
   contributed substantially to improving the quality of the final
   result.

   James Lentini graciously read the rewrite of Section 8 and his
   comments were vital in improving the quality of that effort.

   Rob Thurlow, Sorin Faibish, James Lentini, Bruce Fields, and Trond
   Myklebust were faithful attendants of the biweekly triage meeting and
   accepted many an action item.

   Bruce Fields was a good sounding board for both the Third Edge
   Condition and Courtesy Locks in general.  He was also the leading
   advocate of stamping out backport issues from [RFC5661].

   Marcel Telka was a champion of straightening out the difference
   between a lock-owner and an open-owner.  He has also been diligent in
   reviewing the final document.

   Benjamin Kaduk reminded us that DES is dead and Nico Williams helped
   us close the lid on the coffin.

Appendix B.  RFC Editor Notes

   [RFC Editor: please remove this section prior to publishing this
   document as an RFC]

   [RFC Editor: prior to publishing this document as an RFC, please
   replace all occurrences of RFCNFSv4XDR with RFCxxxx where xxxx is the
   RFC number assigned to the XDR document.]

   [RFC Editor: Please note that there is also a reference entry that
   needs to be modified for the companion document.]

Authors' Addresses

   Thomas Haynes (editor)
   NetApp
   495 E Java Dr
   Sunnyvale, CA  95054
   USA

   Phone: +1 408 419 3018
   Email: thomas@netapp.com

Haynes & Noveck         Expires February 17, 2014             [Page 292]
Internet-Draft                    NFSv4                      August 2013

   David Noveck (editor)
   EMC Corporation
   228 South Street
   Hopkinton, MA  01748
   US

   Phone: +1 508 249 5748
   Email: david.noveck@emc.com

Haynes & Noveck         Expires February 17, 2014             [Page 293]