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 |
GENART Telechat review
(of
-33)
by Elwyn Davies
Almost ready
SECDIR Last Call review
(of
-25)
by Yoav Nir
Has issues
|
||
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]