Network File System (NFS) version 4 Protocol
RFC 3530
Document | Type |
RFC
- Proposed Standard
(April 2003)
Errata
IPR
Obsoleted by RFC 7530
Obsoletes RFC 3010
|
|
---|---|---|---|
Authors | Carl Beame , Robert Thurlow , Brent Callaghan , David Robinson , David Noveck , Mike Eisler , Spencer Shepler | ||
Last updated | 2020-01-21 | ||
RFC stream | Internet Engineering Task Force (IETF) | ||
Formats | |||
Additional resources | Mailing list discussion | ||
IESG | Responsible AD | Scott O. Bradner | |
Send notices to | (None) |
RFC 3530
#x27;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. Shepler, et al. Standards Track [Page 214] RFC 3530 NFS version 4 Protocol April 2003 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: 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. Shepler, et al. Standards Track [Page 215] RFC 3530 NFS version 4 Protocol April 2003 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. 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 clientid and setclientid_confirm verifier. The client should then send the SETCLIENTID_CONFIRM to confirm the clientid. 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. Shepler, et al. Standards Track [Page 216] RFC 3530 NFS version 4 Protocol April 2003 ERRORS NFS4ERR_BADXDR NFS4ERR_CLID_INUSE NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE_CLIENTID 14.2.35. Operation 37: VERIFY - Verify Same Attributes SYNOPSIS (cfh), fattr -> - ARGUMENT struct VERIFY4args { /* CURRENT_FH: object */ fattr4 obj_attributes; }; RESULT struct VERIFY4res { nfsstat4 status; }; 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. 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) Shepler, et al. Standards Track [Page 217] RFC 3530 NFS version 4 Protocol April 2003 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 filesystem 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. ERRORS NFS4ERR_ACCESS NFS4ERR_ATTRNOTSUPP NFS4ERR_BADCHAR NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_FHEXPIRED NFS4ERR_INVAL NFS4ERR_MOVED NFS4ERR_NOFILEHANDLE NFS4ERR_NOT_SAME NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE 14.2.36. Operation 38: WRITE - Write to File SYNOPSIS (cfh), stateid, offset, stable, data -> count, committed, writeverf ARGUMENT enum stable_how4 { UNSTABLE4 = 0, DATA_SYNC4 = 1, FILE_SYNC4 = 2 }; struct WRITE4args { /* CURRENT_FH: file */ stateid4 stateid; offset4 offset; Shepler, et al. Standards Track [Page 218] RFC 3530 NFS version 4 Protocol April 2003 stable_how4 stable; opaque data<>; }; RESULT struct WRITE4resok { count4 count; stable_how4 committed; verifier4 writeverf; }; union WRITE4res switch (nfsstat4 status) { case NFS4_OK: WRITE4resok resok4; default: void; }; 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 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 filesystem 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 Shepler, et al. Standards Track [Page 219] RFC 3530 NFS version 4 Protocol April 2003 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 record lock or share reservation request. The stateid is used by the server to verify that the associated share reservation and any record 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 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 NFS version 4 protocol service and must be unique between instances of the NFS version 4 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 Shepler, et al. Standards Track [Page 220] RFC 3530 NFS version 4 Protocol April 2003 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. 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.). 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 NFS version 4 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). Shepler, et al. Standards Track [Page 221] RFC 3530 NFS version 4 Protocol April 2003 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 record lock via the LOCK operation before re-attempting the WRITE. When the WRITE completes, the client should release the record lock via LOCKU. 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. ERRORS NFS4ERR_ACCESS NFS4ERR_ADMIN_REVOKED NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_DELAY NFS4ERR_DQUOT NFS4ERR_EXPIRED Shepler, et al. Standards Track [Page 222] RFC 3530 NFS version 4 Protocol April 2003 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 14.2.37. Operation 39: RELEASE_LOCKOWNER - Release Lockowner State SYNOPSIS lockowner -> () ARGUMENT struct RELEASE_LOCKOWNER4args { lock_owner4 lock_owner; }; RESULT struct RELEASE_LOCKOWNER4res { nfsstat4 status; }; DESCRIPTION This operation is used to notify the server that the lock_owner is no longer in use by the client. 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. Shepler, et al. Standards Track [Page 223] RFC 3530 NFS version 4 Protocol April 2003 IMPLEMENTATION The client may choose to use this operation to ease the amount of server state that is held. Depending on 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 a lock_owner as long as the associated file is open. Therefore, if the client knows for certain that the lock_owner will no longer be used under the context of the associated open_owner4, it should use RELEASE_LOCKOWNER. ERRORS NFS4ERR_ADMIN_REVOKED NFS4ERR_BADXDR NFS4ERR_EXPIRED NFS4ERR_LEASE_MOVED NFS4ERR_LOCKS_HELD NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT NFS4ERR_STALE_CLIENTID 14.2.38. Operation 10044: ILLEGAL - Illegal operation SYNOPSIS <null> -> () ARGUMENT void; RESULT struct ILLEGAL4res { nfsstat4 status; }; DESCRIPTION This operation is a placeholder for encoding a result to handle the case of the client sending an operation code within COMPOUND that is not supported. See the COMPOUND procedure description for more details. The status field of ILLEGAL4res MUST be set to NFS4ERR_OP_ILLEGAL. Shepler, et al. Standards Track [Page 224] RFC 3530 NFS version 4 Protocol April 2003 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. ERRORS NFS4ERR_OP_ILLEGAL 15. NFS version 4 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. 15.1. Procedure 0: CB_NULL - No Operation SYNOPSIS <null> ARGUMENT void; RESULT void; 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. ERRORS None. Shepler, et al. Standards Track [Page 225] RFC 3530 NFS version 4 Protocol April 2003 15.2. Procedure 1: CB_COMPOUND - Compound Operations SYNOPSIS compoundargs -> compoundres ARGUMENT enum nfs_cb_opnum4 { OP_CB_GETATTR = 3, OP_CB_RECALL = 4, OP_CB_ILLEGAL = 10044 }; 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 opcbillegal; }; struct CB_COMPOUND4args { utf8str_cs tag; uint32_t minorversion; uint32_t callback_ident; nfs_cb_argop4 argarray<>; }; RESULT union nfs_cb_resop4 switch (unsigned resop){ case OP_CB_GETATTR: CB_GETATTR4res opcbgetattr; case OP_CB_RECALL: CB_RECALL4res opcbrecall; }; struct CB_COMPOUND4res { nfsstat4 status; utf8str_cs tag; nfs_cb_resop4 resarray<>; }; 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. Shepler, et al. Standards Track [Page 226] RFC 3530 NFS version 4 Protocol April 2003 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 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 the section "Procedure 1: COMPOUND - Compound Operations". 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. 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. ERRORS NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_OP_ILLEGAL NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT Shepler, et al. Standards Track [Page 227] RFC 3530 NFS version 4 Protocol April 2003 15.2.1. Operation 3: CB_GETATTR - Get Attributes SYNOPSIS fh, attr_request -> attrmask, attr_vals ARGUMENT struct CB_GETATTR4args { nfs_fh4 fh; bitmap4 attr_request; }; RESULT struct CB_GETATTR4resok { fattr4 obj_attributes; }; union CB_GETATTR4res switch (nfsstat4 status) { case NFS4_OK: CB_GETATTR4resok resok4; default: void; }; DESCRIPTION The CB_GETATTR operation is used by the server to obtain the current modified state of a file that has been write delegated. The attributes size and change are the only ones guaranteed to be serviced by the client. See the section "Handling of CB_GETATTR" 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 write open delegation, an NFS4ERR_BADHANDLE error is returned. 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). Shepler, et al. Standards Track [Page 228] RFC 3530 NFS version 4 Protocol April 2003 ERRORS NFS4ERR_BADHANDLE NFS4ERR_BADXDR NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT 15.2.2. Operation 4: CB_RECALL - Recall an Open Delegation SYNOPSIS stateid, truncate, fh -> () ARGUMENT struct CB_RECALL4args { stateid4 stateid; bool truncate; nfs_fh4 fh; }; RESULT struct CB_RECALL4res { nfsstat4 status; }; 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. Shepler, et al. Standards Track [Page 229] RFC 3530 NFS version 4 Protocol April 2003 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. ERRORS NFS4ERR_BADHANDLE NFS4ERR_BAD_STATEID NFS4ERR_BADXDR NFS4ERR_RESOURCE NFS4ERR_SERVERFAULT 15.2.3. Operation 10044: CB_ILLEGAL - Illegal Callback Operation SYNOPSIS <null> -> () ARGUMENT void; RESULT struct CB_ILLEGAL4res { nfsstat4 status; }; DESCRIPTION This operation is a placeholder for encoding a result to handle the case of the client sending an operation code within COMPOUND that is not supported. See the COMPOUND procedure description for more details. The status field of CB_ILLEGAL4res MUST be set to NFS4ERR_OP_ILLEGAL. 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 Shepler, et al. Standards Track [Page 230] RFC 3530 NFS version 4 Protocol April 2003 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. ERRORS NFS4ERR_OP_ILLEGAL 16. 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 discussed as part of the section on "RPC and Security Flavor". Note that while NFSv4 mandates an end to end mutual authentication model, the "classic" model of machine authentication via IP address checking and AUTH_SYS identification can still be supported with the caveat that the AUTH_SYS flavor is neither MANDATORY nor RECOMMENDED by this specification, 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 NFS version 4 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. Shepler, et al. Standards Track [Page 231] RFC 3530 NFS version 4 Protocol April 2003 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 definitely 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 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 the section "Client ID" for further discussion. 17. IANA Considerations 17.1. Named Attribute Definition The NFS version 4 protocol provides for the association of named attributes to files. 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. Even though the name space is not specifically controlled to prevent collisions, an IANA registry has been created for the registration of NFS version 4 named attributes. Registration will be achieved through the publication of an Informational RFC and will require not only the name of the attribute but the syntax and semantics of the named attribute contents; the intent is to promote 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. 17.2. ONC RPC Network Identifiers (netids) The section "Structured Data Types" discussed the r_netid field and the corresponding r_addr field of a clientaddr4 structure. The NFS version 4 protocol depends on the syntax and semantics of these Shepler, et al. Standards Track [Page 232] RFC 3530 NFS version 4 Protocol April 2003 fields to effectively communicate callback information between client and server. Therefore, an IANA registry has been created to include the values defined in this document and to allow for future expansion based on transport usage/availability. Additions to this ONC RPC Network Identifier registry must be done with the publication of an RFC. The initial values for this registry are as follows (some of this text is replicated from section 2.2 for clarity): The Network Identifier (or r_netid for short) is used to specify a transport protocol and associated universal address (or r_addr for short). The syntax of the Network Identifier is a US-ASCII string. The initial definitions for r_netid are: "tcp" - TCP over IP version 4 "udp" - UDP over IP version 4 "tcp6" - TCP over IP version 6 "udp6" - UDP over IP version 6 Note: the '"' marks are used for delimiting the strings for this document and are not part of the Network Identifier string. For the "tcp" and "udp" Network Identifiers the Universal Address or r_addr (for IPv4) is a US-ASCII string and is of the form: h1.h2.h3.h4.p1.p2 The prefix, "h1.h2.h3.h4", is the standard textual form for representing an IPv4 address, which is always four octets long. Assuming big-endian ordering, h1, h2, h3, and h4, are respectively, the first through fourth octets each converted to ASCII-decimal. Assuming big-endian ordering, p1 and p2 are, respectively, the first and second octets each converted to ASCII-decimal. For example, if a host, in big-endian order, has an address of 0x0A010307 and there is a service listening on, in big endian order, port 0x020F (decimal 527), then complete universal address is "10.1.3.7.2.15". For the "tcp6" and "udp6" Network Identifiers the Universal Address or r_addr (for IPv6) is a US-ASCII string and is of the form: x1:x2:x3:x4:x5:x6:x7:x8.p1.p2 Shepler, et al. Standards Track [Page 233] RFC 3530 NFS version 4 Protocol April 2003 The suffix "p1.p2" is the service port, and is computed the same way as with universal addresses for "tcp" and "udp". The prefix, "x1:x2:x3:x4:x5:x6:x7:x8", is the standard textual form for representing an IPv6 address as defined in Section 2.2 of [RFC2373]. Additionally, the two alternative forms specified in Section 2.2 of [RFC2373] are also acceptable. As mentioned, the registration of new Network Identifiers will require the publication of an Information RFC with similar detail as listed above for the Network Identifier itself and corresponding Universal Address. 18. RPC definition file /* * Copyright (C) The Internet Society (1998,1999,2000,2001,2002). * All Rights Reserved. */ /* * nfs4_prot.x * */ %#pragma ident "%W%" /* * Basic typedefs for RFC 1832 data type definitions */ typedef int int32_t; typedef unsigned int uint32_t; typedef hyper int64_t; typedef unsigned hyper uint64_t; /* * Sizes */ const NFS4_FHSIZE = 128; const NFS4_VERIFIER_SIZE = 8; const NFS4_OPAQUE_LIMIT = 1024; /* * File types */ enum nfs_ftype4 { NF4REG = 1, /* Regular File */ NF4DIR = 2, /* Directory */ NF4BLK = 3, /* Special File - block device */ Shepler, et al. Standards Track [Page 234] RFC 3530 NFS version 4 Protocol April 2003 NF4CHR = 4, /* Special File - character device */ NF4LNK = 5, /* Symbolic Link */ NF4SOCK = 6, /* Special File - socket */ NF4FIFO = 7, /* Special File - fifo */ NF4ATTRDIR = 8, /* Attribute Directory */ NF4NAMEDATTR = 9 /* Named Attribute */ }; /* * Error status */ enum nfsstat4 { NFS4_OK = 0, /* everything is okay */ NFS4ERR_PERM = 1, /* caller not privileged */ NFS4ERR_NOENT = 2, /* no such file/directory */ NFS4ERR_IO = 5, /* hard I/O error */ NFS4ERR_NXIO = 6, /* no such device */ NFS4ERR_ACCESS = 13, /* access denied */ NFS4ERR_EXIST = 17, /* file already exists */ NFS4ERR_XDEV = 18, /* different filesystems */ /* Unused/reserved 19 */ NFS4ERR_NOTDIR = 20, /* should be a directory */ NFS4ERR_ISDIR = 21, /* should not be directory */ NFS4ERR_INVAL = 22, /* invalid argument */ NFS4ERR_FBIG = 27, /* file exceeds server max */ NFS4ERR_NOSPC = 28, /* no space on filesystem */ NFS4ERR_ROFS = 30, /* read-only filesystem */ NFS4ERR_MLINK = 31, /* too many hard links */ NFS4ERR_NAMETOOLONG = 63, /* name exceeds server max */ NFS4ERR_NOTEMPTY = 66, /* directory not empty */ NFS4ERR_DQUOT = 69, /* hard quota limit reached*/ NFS4ERR_STALE = 70, /* file no longer exists */ NFS4ERR_BADHANDLE = 10001,/* Illegal filehandle */ NFS4ERR_BAD_COOKIE = 10003,/* READDIR cookie is stale */ NFS4ERR_NOTSUPP = 10004,/* operation not supported */ NFS4ERR_TOOSMALL = 10005,/* response limit exceeded */ NFS4ERR_SERVERFAULT = 10006,/* undefined server error */ NFS4ERR_BADTYPE = 10007,/* type invalid for CREATE */ NFS4ERR_DELAY = 10008,/* file "busy" - retry */ NFS4ERR_SAME = 10009,/* nverify says attrs same */ NFS4ERR_DENIED = 10010,/* lock unavailable */ NFS4ERR_EXPIRED = 10011,/* lock lease expired */ NFS4ERR_LOCKED = 10012,/* I/O failed due to lock */ NFS4ERR_GRACE = 10013,/* in grace period */ NFS4ERR_FHEXPIRED = 10014,/* filehandle expired */ NFS4ERR_SHARE_DENIED = 10015,/* share reserve denied */ NFS4ERR_WRONGSEC = 10016,/* wrong security flavor */ NFS4ERR_CLID_INUSE = 10017,/* clientid in use */ Shepler, et al. Standards Track [Page 235] RFC 3530 NFS version 4 Protocol April 2003 NFS4ERR_RESOURCE = 10018,/* resource exhaustion */ NFS4ERR_MOVED = 10019,/* filesystem relocated */ NFS4ERR_NOFILEHANDLE = 10020,/* current FH is not set */ NFS4ERR_MINOR_VERS_MISMATCH = 10021,/* minor vers not supp */ NFS4ERR_STALE_CLIENTID = 10022,/* server has rebooted */ NFS4ERR_STALE_STATEID = 10023,/* server has rebooted */ NFS4ERR_OLD_STATEID = 10024,/* state is out of sync */ NFS4ERR_BAD_STATEID = 10025,/* incorrect stateid */ NFS4ERR_BAD_SEQID = 10026,/* request is out of seq. */ NFS4ERR_NOT_SAME = 10027,/* verify - attrs not same */ NFS4ERR_LOCK_RANGE = 10028,/* lock range not supported*/ NFS4ERR_SYMLINK = 10029,/* should be file/directory*/ NFS4ERR_RESTOREFH = 10030,/* no saved filehandle */ NFS4ERR_LEASE_MOVED = 10031,/* some filesystem moved */ NFS4ERR_ATTRNOTSUPP = 10032,/* recommended attr not sup*/ NFS4ERR_NO_GRACE = 10033,/* reclaim outside of grace*/ NFS4ERR_RECLAIM_BAD = 10034,/* reclaim error at server */ NFS4ERR_RECLAIM_CONFLICT = 10035,/* conflict on reclaim */ NFS4ERR_BADXDR = 10036,/* XDR decode failed */ NFS4ERR_LOCKS_HELD = 10037,/* file locks held at CLOSE*/ NFS4ERR_OPENMODE = 10038,/* conflict in OPEN and I/O*/ NFS4ERR_BADOWNER = 10039,/* owner translation bad */ NFS4ERR_BADCHAR = 10040,/* utf-8 char not supported*/ NFS4ERR_BADNAME = 10041,/* name not supported */ NFS4ERR_BAD_RANGE = 10042,/* lock range not supported*/ NFS4ERR_LOCK_NOTSUPP = 10043,/* no atomic up/downgrade */ NFS4ERR_OP_ILLEGAL = 10044,/* undefined operation */ NFS4ERR_DEADLOCK = 10045,/* file locking deadlock */ NFS4ERR_FILE_OPEN = 10046,/* open file blocks op. */ NFS4ERR_ADMIN_REVOKED = 10047,/* lockowner state revoked */ NFS4ERR_CB_PATH_DOWN = 10048 /* callback path down */ }; /* * Basic data types */ typedef uint32_t bitmap4<>; typedef uint64_t offset4; typedef uint32_t count4; typedef uint64_t length4; typedef uint64_t clientid4; typedef uint32_t seqid4; typedef opaque utf8string<>; typedef utf8string utf8str_cis; typedef utf8string utf8str_cs; typedef utf8string utf8str_mixed; typedef utf8str_cs component4; typedef component4 pathname4<>; Shepler, et al. Standards Track [Page 236] RFC 3530 NFS version 4 Protocol April 2003 typedef uint64_t nfs_lockid4; typedef uint64_t nfs_cookie4; typedef utf8str_cs linktext4; typedef opaque sec_oid4<>; typedef uint32_t qop4; typedef uint32_t mode4; typedef uint64_t changeid4; typedef opaque verifier4[NFS4_VERIFIER_SIZE]; /* * Timeval */ struct nfstime4 { int64_t seconds; uint32_t nseconds; }; enum time_how4 { SET_TO_SERVER_TIME4 = 0, SET_TO_CLIENT_TIME4 = 1 }; union settime4 switch (time_how4 set_it) { case SET_TO_CLIENT_TIME4: nfstime4 time; default: void; }; /* * File access handle */ typedef opaque nfs_fh4<NFS4_FHSIZE>; /* * File attribute definitions */ /* * FSID structure for major/minor */ struct fsid4 { uint64_t major; uint64_t minor; }; /* Shepler, et al. Standards Track [Page 237] RFC 3530 NFS version 4 Protocol April 2003 * Filesystem locations attribute for relocation/migration */ struct fs_location4 { utf8str_cis server<>; pathname4 rootpath; }; struct fs_locations4 { pathname4 fs_root; fs_location4 locations<>; }; /* * Various Access Control Entry definitions */ /* * Mask that indicates which Access Control Entries are supported. * Values for the fattr4_aclsupport attribute. */ const ACL4_SUPPORT_ALLOW_ACL = 0x00000001; const ACL4_SUPPORT_DENY_ACL = 0x00000002; const ACL4_SUPPORT_AUDIT_ACL = 0x00000004; const ACL4_SUPPORT_ALARM_ACL = 0x00000008; typedef uint32_t acetype4; /* * acetype4 values, others can be added as needed. */ const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000; const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001; const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002; const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003; /* * ACE flag */ typedef uint32_t aceflag4; /* * ACE flag values */ const ACE4_FILE_INHERIT_ACE = 0x00000001; const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002; const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004; const ACE4_INHERIT_ONLY_ACE = 0x00000008; Shepler, et al. Standards Track [Page 238] RFC 3530 NFS version 4 Protocol April 2003 const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010; const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020; const ACE4_IDENTIFIER_GROUP = 0x00000040; /* * ACE mask */ typedef uint32_t acemask4; /* * ACE mask values */ const ACE4_READ_DATA = 0x00000001; const ACE4_LIST_DIRECTORY = 0x00000001; const ACE4_WRITE_DATA = 0x00000002; const ACE4_ADD_FILE = 0x00000002; const ACE4_APPEND_DATA = 0x00000004; const ACE4_ADD_SUBDIRECTORY = 0x00000004; const ACE4_READ_NAMED_ATTRS = 0x00000008; const ACE4_WRITE_NAMED_ATTRS = 0x00000010; const ACE4_EXECUTE = 0x00000020; const ACE4_DELETE_CHILD = 0x00000040; const ACE4_READ_ATTRIBUTES = 0x00000080; const ACE4_WRITE_ATTRIBUTES = 0x00000100; const ACE4_DELETE = 0x00010000; const ACE4_READ_ACL = 0x00020000; const ACE4_WRITE_ACL = 0x00040000; const ACE4_WRITE_OWNER = 0x00080000; const ACE4_SYNCHRONIZE = 0x00100000; /* * ACE4_GENERIC_READ -- defined as combination of * ACE4_READ_ACL | * ACE4_READ_DATA | * ACE4_READ_ATTRIBUTES | * ACE4_SYNCHRONIZE */ const ACE4_GENERIC_READ = 0x00120081; /* * ACE4_GENERIC_WRITE -- defined as combination of * ACE4_READ_ACL | * ACE4_WRITE_DATA | * ACE4_WRITE_ATTRIBUTES | * ACE4_WRITE_ACL | Shepler, et al. Standards Track [Page 239] RFC 3530 NFS version 4 Protocol April 2003 * ACE4_APPEND_DATA | * ACE4_SYNCHRONIZE */ const ACE4_GENERIC_WRITE = 0x00160106; /* * ACE4_GENERIC_EXECUTE -- defined as combination of * ACE4_READ_ACL * ACE4_READ_ATTRIBUTES * ACE4_EXECUTE * ACE4_SYNCHRONIZE */ const ACE4_GENERIC_EXECUTE = 0x001200A0; /* * Access Control Entry definition */ struct nfsace4 { acetype4 type; aceflag4 flag; acemask4 access_mask; utf8str_mixed who; }; /* * Field definitions for the fattr4_mode attribute */ const MODE4_SUID = 0x800; /* set user id on execution */ const MODE4_SGID = 0x400; /* set group id on execution */ const MODE4_SVTX = 0x200; /* save text even after use */ const MODE4_RUSR = 0x100; /* read permission: owner */ const MODE4_WUSR = 0x080; /* write permission: owner */ const MODE4_XUSR = 0x040; /* execute permission: owner */ const MODE4_RGRP = 0x020; /* read permission: group */ const MODE4_WGRP = 0x010; /* write permission: group */ const MODE4_XGRP = 0x008; /* execute permission: group */ const MODE4_ROTH = 0x004; /* read permission: other */ const MODE4_WOTH = 0x002; /* write permission: other */ const MODE4_XOTH = 0x001; /* execute permission: other */ /* * Special data/attribute associated with * file types NF4BLK and NF4CHR. */ struct specdata4 { uint32_t specdata1; /* major device number */ Shepler, et al. Standards Track [Page 240] RFC 3530 NFS version 4 Protocol April 2003 uint32_t specdata2; /* minor device number */ }; /* * Values for fattr4_fh_expire_type */ const FH4_PERSISTENT = 0x00000000; const FH4_NOEXPIRE_WITH_OPEN = 0x00000001; const FH4_VOLATILE_ANY = 0x00000002; const FH4_VOL_MIGRATION = 0x00000004; const FH4_VOL_RENAME = 0x00000008; typedef bitmap4 fattr4_supported_attrs; typedef nfs_ftype4 fattr4_type; typedef uint32_t fattr4_fh_expire_type; typedef changeid4 fattr4_change; typedef uint64_t fattr4_size; typedef bool fattr4_link_support; typedef bool fattr4_symlink_support; typedef bool fattr4_named_attr; typedef fsid4 fattr4_fsid; typedef bool fattr4_unique_handles; typedef uint32_t fattr4_lease_time; typedef nfsstat4 fattr4_rdattr_error; typedef nfsace4 fattr4_acl<>; typedef uint32_t fattr4_aclsupport; typedef bool fattr4_archive; typedef bool fattr4_cansettime; typedef bool fattr4_case_insensitive; typedef bool fattr4_case_preserving; typedef bool fattr4_chown_restricted; typedef uint64_t fattr4_fileid; typedef uint64_t fattr4_files_avail; typedef nfs_fh4 fattr4_filehandle; typedef uint64_t fattr4_files_free; typedef uint64_t fattr4_files_total; typedef fs_locations4 fattr4_fs_locations; typedef bool fattr4_hidden; typedef bool fattr4_homogeneous; typedef uint64_t fattr4_maxfilesize; typedef uint32_t fattr4_maxlink; typedef uint32_t fattr4_maxname; typedef uint64_t fattr4_maxread; typedef uint64_t fattr4_maxwrite; typedef utf8str_cs fattr4_mimetype; typedef mode4 fattr4_mode; Shepler, et al. Standards Track [Page 241] RFC 3530 NFS version 4 Protocol April 2003 typedef uint64_t fattr4_mounted_on_fileid; typedef bool fattr4_no_trunc; typedef uint32_t fattr4_numlinks; typedef utf8str_mixed fattr4_owner; typedef utf8str_mixed fattr4_owner_group; typedef uint64_t fattr4_quota_avail_hard; typedef uint64_t fattr4_quota_avail_soft; typedef uint64_t fattr4_quota_used; typedef specdata4 fattr4_rawdev; typedef uint64_t fattr4_space_avail; typedef uint64_t fattr4_space_free; typedef uint64_t fattr4_space_total; typedef uint64_t fattr4_space_used; typedef bool fattr4_system; typedef nfstime4 fattr4_time_access; typedef settime4 fattr4_time_access_set; typedef nfstime4 fattr4_time_backup; typedef nfstime4 fattr4_time_create; typedef nfstime4 fattr4_time_delta; typedef nfstime4 fattr4_time_metadata; typedef nfstime4 fattr4_time_modify; typedef settime4 fattr4_time_modify_set; /* * Mandatory Attributes */ const FATTR4_SUPPORTED_ATTRS = 0; const FATTR4_TYPE = 1; const FATTR4_FH_EXPIRE_TYPE = 2; const FATTR4_CHANGE = 3; const FATTR4_SIZE = 4; const FATTR4_LINK_SUPPORT = 5; const FATTR4_SYMLINK_SUPPORT = 6; const FATTR4_NAMED_ATTR = 7; const FATTR4_FSID = 8; const FATTR4_UNIQUE_HANDLES = 9; const FATTR4_LEASE_TIME = 10; const FATTR4_RDATTR_ERROR = 11; const FATTR4_FILEHANDLE = 19; /* * Recommended Attributes */ const FATTR4_ACL = 12; const FATTR4_ACLSUPPORT = 13; const FATTR4_ARCHIVE = 14; const FATTR4_CANSETTIME = 15; Shepler, et al. Standards Track [Page 242] RFC 3530 NFS version 4 Protocol April 2003 const FATTR4_CASE_INSENSITIVE = 16; const FATTR4_CASE_PRESERVING = 17; const FATTR4_CHOWN_RESTRICTED = 18; const FATTR4_FILEID = 20; const FATTR4_FILES_AVAIL = 21; const FATTR4_FILES_FREE = 22; const FATTR4_FILES_TOTAL = 23; const FATTR4_FS_LOCATIONS = 24; const FATTR4_HIDDEN = 25; const FATTR4_HOMOGENEOUS = 26; const FATTR4_MAXFILESIZE = 27; const FATTR4_MAXLINK = 28; const FATTR4_MAXNAME = 29; const FATTR4_MAXREAD = 30; const FATTR4_MAXWRITE = 31; const FATTR4_MIMETYPE = 32; const FATTR4_MODE = 33; const FATTR4_NO_TRUNC = 34; const FATTR4_NUMLINKS = 35; const FATTR4_OWNER = 36; const FATTR4_OWNER_GROUP = 37; const FATTR4_QUOTA_AVAIL_HARD = 38; const FATTR4_QUOTA_AVAIL_SOFT = 39; const FATTR4_QUOTA_USED = 40; const FATTR4_RAWDEV = 41; const FATTR4_SPACE_AVAIL = 42; const FATTR4_SPACE_FREE = 43; const FATTR4_SPACE_TOTAL = 44; const FATTR4_SPACE_USED = 45; const FATTR4_SYSTEM = 46; const FATTR4_TIME_ACCESS = 47; const FATTR4_TIME_ACCESS_SET = 48; const FATTR4_TIME_BACKUP = 49; const FATTR4_TIME_CREATE = 50; const FATTR4_TIME_DELTA = 51; const FATTR4_TIME_METADATA = 52; const FATTR4_TIME_MODIFY = 53; const FATTR4_TIME_MODIFY_SET = 54; const FATTR4_MOUNTED_ON_FILEID = 55; typedef opaque attrlist4<>; /* * File attribute container */ struct fattr4 { bitmap4 attrmask; attrlist4 attr_vals; Shepler, et al. Standards Track [Page 243] RFC 3530 NFS version 4 Protocol April 2003 }; /* * Change info for the client */ struct change_info4 { bool atomic; changeid4 before; changeid4 after; }; struct clientaddr4 { /* see struct rpcb in RFC 1833 */ string r_netid<>; /* network id */ string r_addr<>; /* universal address */ }; /* * Callback program info as provided by the client */ struct cb_client4 { uint32_t cb_program; clientaddr4 cb_location; }; /* * Stateid */ struct stateid4 { uint32_t seqid; opaque other[12]; }; /* * Client ID */ struct nfs_client_id4 { verifier4 verifier; opaque id<NFS4_OPAQUE_LIMIT>; }; struct open_owner4 { clientid4 clientid; opaque owner<NFS4_OPAQUE_LIMIT>; }; struct lock_owner4 { clientid4 clientid; Shepler, et al. Standards Track [Page 244] RFC 3530 NFS version 4 Protocol April 2003 opaque owner<NFS4_OPAQUE_LIMIT>; }; enum nfs_lock_type4 { READ_LT = 1, WRITE_LT = 2, READW_LT = 3, /* blocking read */ WRITEW_LT = 4 /* blocking write */ }; /* * ACCESS: Check access permission */ 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; }; struct ACCESS4resok { uint32_t supported; uint32_t access; }; union ACCESS4res switch (nfsstat4 status) { case NFS4_OK: ACCESS4resok resok4; default: void; }; /* * CLOSE: Close a file and release share reservations */ struct CLOSE4args { /* CURRENT_FH: object */ seqid4 seqid; stateid4 open_stateid; }; union CLOSE4res switch (nfsstat4 status) { case NFS4_OK: Shepler, et al. Standards Track [Page 245] RFC 3530 NFS version 4 Protocol April 2003 stateid4 open_stateid; default: void; }; /* * COMMIT: Commit cached data on server to stable storage */ struct COMMIT4args { /* CURRENT_FH: file */ offset4 offset; count4 count; }; struct COMMIT4resok { verifier4 writeverf; }; union COMMIT4res switch (nfsstat4 status) { case NFS4_OK: COMMIT4resok resok4; default: void; }; /* * CREATE: Create a non-regular file */ 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; Shepler, et al. Standards Track [Page 246] RFC 3530 NFS version 4 Protocol April 2003 }; struct CREATE4resok { change_info4 cinfo; bitmap4 attrset; /* attributes set */ }; union CREATE4res switch (nfsstat4 status) { case NFS4_OK: CREATE4resok resok4; default: void; }; /* * DELEGPURGE: Purge Delegations Awaiting Recovery */ struct DELEGPURGE4args { clientid4 clientid; }; struct DELEGPURGE4res { nfsstat4 status; }; /* * DELEGRETURN: Return a delegation */ struct DELEGRETURN4args { /* CURRENT_FH: delegated file */ stateid4 deleg_stateid; }; struct DELEGRETURN4res { nfsstat4 status; }; /* * GETATTR: Get file attributes */ struct GETATTR4args { /* CURRENT_FH: directory or file */ bitmap4 attr_request; }; struct GETATTR4resok { fattr4 obj_attributes; }; Shepler, et al. Standards Track [Page 247] RFC 3530 NFS version 4 Protocol April 2003 union GETATTR4res switch (nfsstat4 status) { case NFS4_OK: GETATTR4resok resok4; default: void; }; /* * GETFH: Get current filehandle */ struct GETFH4resok { nfs_fh4 object; }; union GETFH4res switch (nfsstat4 status) { case NFS4_OK: GETFH4resok resok4; default: void; }; /* * LINK: Create link to an object */ struct LINK4args { /* SAVED_FH: source object */ /* CURRENT_FH: target directory */ component4 newname; }; struct LINK4resok { change_info4 cinfo; }; union LINK4res switch (nfsstat4 status) { case NFS4_OK: LINK4resok resok4; default: void; }; /* * For LOCK, transition from open_owner to new lock_owner */ struct open_to_lock_owner4 { seqid4 open_seqid; stateid4 open_stateid; seqid4 lock_seqid; Shepler, et al. Standards Track [Page 248] RFC 3530 NFS version 4 Protocol April 2003 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; }; 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; Shepler, et al. Standards Track [Page 249] RFC 3530 NFS version 4 Protocol April 2003 }; struct LOCKT4args { /* CURRENT_FH: file */ nfs_lock_type4 locktype; offset4 offset; length4 length; lock_owner4 owner; }; union LOCKT4res switch (nfsstat4 status) { case NFS4ERR_DENIED: LOCK4denied denied; case NFS4_OK: void; default: void; }; struct LOCKU4args { /* CURRENT_FH: file */ nfs_lock_type4 locktype; seqid4 seqid; stateid4 lock_stateid; offset4 offset; length4 length; }; union LOCKU4res switch (nfsstat4 status) { case NFS4_OK: stateid4 lock_stateid; default: void; }; /* * LOOKUP: Lookup filename */ struct LOOKUP4args { /* CURRENT_FH: directory */ component4 objname; }; struct LOOKUP4res { /* CURRENT_FH: object */ nfsstat4 status; }; Shepler, et al. Standards Track [Page 250] RFC 3530 NFS version 4 Protocol April 2003 /* * LOOKUPP: Lookup parent directory */ struct LOOKUPP4res { /* CURRENT_FH: directory */ nfsstat4 status; }; /* * NVERIFY: Verify attributes different */ struct NVERIFY4args { /* CURRENT_FH: object */ fattr4 obj_attributes; }; struct NVERIFY4res { nfsstat4 status; }; /* * 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; }; Shepler, et al. Standards Track [Page 251] RFC 3530 NFS version 4 Protocol April 2003 /* 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; } ; /* * Share Access and Deny constants for open argument */ const OPEN4_SHARE_ACCESS_READ = 0x00000001; const OPEN4_SHARE_ACCESS_WRITE = 0x00000002; const OPEN4_SHARE_ACCESS_BOTH = 0x00000003; const OPEN4_SHARE_DENY_NONE = 0x00000000; const OPEN4_SHARE_DENY_READ = 0x00000001; const OPEN4_SHARE_DENY_WRITE = 0x00000002; const OPEN4_SHARE_DENY_BOTH = 0x00000003; 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; Shepler, et al. Standards Track [Page 252] RFC 3530 NFS version 4 Protocol April 2003 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; /* * 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; }; Shepler, et al. Standards Track [Page 253] RFC 3530 NFS version 4 Protocol April 2003 struct open_read_delegation4 { stateid4 stateid; /* Stateid for delegation*/ bool recall; /* Pre-recalled flag for delegations obtained by reclaim (CLAIM_PREVIOUS) */ 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 */ Shepler, et al. Standards Track [Page 254] RFC 3530 NFS version 4 Protocol April 2003 change_info4 cinfo; /* Directory Change Info */ uint32_t rflags; /* Result flags */ 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; }; /* * OPENATTR: open named attributes directory */ struct OPENATTR4args { /* CURRENT_FH: object */ bool createdir; }; struct OPENATTR4res { /* CURRENT_FH: named attr directory */ nfsstat4 status; }; /* * OPEN_CONFIRM: confirm the open */ struct OPEN_CONFIRM4args { /* CURRENT_FH: opened file */ stateid4 open_stateid; seqid4 seqid; }; struct OPEN_CONFIRM4resok { stateid4 open_stateid; }; union OPEN_CONFIRM4res switch (nfsstat4 status) { case NFS4_OK: OPEN_CONFIRM4resok resok4; default: void; }; Shepler, et al. Standards Track [Page 255] RFC 3530 NFS version 4 Protocol April 2003 /* * OPEN_DOWNGRADE: downgrade the access/deny for a file */ struct OPEN_DOWNGRADE4args { /* CURRENT_FH: opened file */ stateid4 open_stateid; seqid4 seqid; uint32_t share_access; uint32_t share_deny; }; struct OPEN_DOWNGRADE4resok { stateid4 open_stateid; }; union OPEN_DOWNGRADE4res switch(nfsstat4 status) { case NFS4_OK: OPEN_DOWNGRADE4resok resok4; default: void; }; /* * PUTFH: Set current filehandle */ struct PUTFH4args { nfs_fh4 object; }; struct PUTFH4res { /* CURRENT_FH: */ nfsstat4 status; }; /* * PUTPUBFH: Set public filehandle */ struct PUTPUBFH4res { /* CURRENT_FH: public fh */ nfsstat4 status; }; /* * PUTROOTFH: Set root filehandle */ struct PUTROOTFH4res { /* CURRENT_FH: root fh */ Shepler, et al. Standards Track [Page 256] RFC 3530 NFS version 4 Protocol April 2003 nfsstat4 status; }; /* * READ: Read from file */ struct READ4args { /* CURRENT_FH: file */ stateid4 stateid; offset4 offset; count4 count; }; struct READ4resok { bool eof; opaque data<>; }; union READ4res switch (nfsstat4 status) { case NFS4_OK: READ4resok resok4; default: void; }; /* * READDIR: Read directory */ struct READDIR4args { /* CURRENT_FH: directory */ nfs_cookie4 cookie; verifier4 cookieverf; count4 dircount; count4 maxcount; bitmap4 attr_request; }; struct entry4 { nfs_cookie4 cookie; component4 name; fattr4 attrs; entry4 *nextentry; }; struct dirlist4 { entry4 *entries; bool eof; }; Shepler, et al. Standards Track [Page 257] RFC 3530 NFS version 4 Protocol April 2003 struct READDIR4resok { verifier4 cookieverf; dirlist4 reply; }; union READDIR4res switch (nfsstat4 status) { case NFS4_OK: READDIR4resok resok4; default: void; }; /* * READLINK: Read symbolic link */ struct READLINK4resok { linktext4 link; }; union READLINK4res switch (nfsstat4 status) { case NFS4_OK: READLINK4resok resok4; default: void; }; /* * REMOVE: Remove filesystem object */ struct REMOVE4args { /* CURRENT_FH: directory */ component4 target; }; struct REMOVE4resok { change_info4 cinfo; }; union REMOVE4res switch (nfsstat4 status) { case NFS4_OK: REMOVE4resok resok4; default: void; }; /* Shepler, et al. Standards Track [Page 258] RFC 3530 NFS version 4 Protocol April 2003 * RENAME: Rename directory entry */ struct RENAME4args { /* SAVED_FH: source directory */ component4 oldname; /* CURRENT_FH: target directory */ component4 newname; }; struct RENAME4resok { change_info4 source_cinfo; change_info4 target_cinfo; }; union RENAME4res switch (nfsstat4 status) { case NFS4_OK: RENAME4resok resok4; default: void; }; /* * RENEW: Renew a Lease */ struct RENEW4args { clientid4 clientid; }; struct RENEW4res { nfsstat4 status; }; /* * RESTOREFH: Restore saved filehandle */ struct RESTOREFH4res { /* CURRENT_FH: value of saved fh */ nfsstat4 status; }; /* * SAVEFH: Save current filehandle */ struct SAVEFH4res { /* SAVED_FH: value of current fh */ nfsstat4 status; Shepler, et al. Standards Track [Page 259] RFC 3530 NFS version 4 Protocol April 2003 }; /* * SECINFO: Obtain Available Security Mechanisms */ struct SECINFO4args { /* CURRENT_FH: directory */ component4 name; }; /* * 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; }; /* * SETATTR: Set attributes */ struct SETATTR4args { /* CURRENT_FH: target object */ Shepler, et al. Standards Track [Page 260] RFC 3530 NFS version 4 Protocol April 2003 stateid4 stateid; fattr4 obj_attributes; }; struct SETATTR4res { nfsstat4 status; bitmap4 attrsset; }; /* * SETCLIENTID */ struct SETCLIENTID4args { nfs_client_id4 client; cb_client4 callback; uint32_t callback_ident; }; 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; }; struct SETCLIENTID_CONFIRM4args { clientid4 clientid; verifier4 setclientid_confirm; }; struct SETCLIENTID_CONFIRM4res { nfsstat4 status; }; /* * VERIFY: Verify attributes same */ struct VERIFY4args { /* CURRENT_FH: object */ fattr4 obj_attributes; Shepler, et al. Standards Track [Page 261] RFC 3530 NFS version 4 Protocol April 2003 }; struct VERIFY4res { nfsstat4 status; }; /* * WRITE: Write to file */ 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<>; }; struct WRITE4resok { count4 count; stable_how4 committed; verifier4 writeverf; }; union WRITE4res switch (nfsstat4 status) { case NFS4_OK: WRITE4resok resok4; default: void; }; /* * RELEASE_LOCKOWNER: Notify server to release lockowner */ struct RELEASE_LOCKOWNER4args { lock_owner4 lock_owner; }; struct RELEASE_LOCKOWNER4res { nfsstat4 status; }; /* Shepler, et al. Standards Track [Page 262] RFC 3530 NFS version 4 Protocol April 2003 * ILLEGAL: Response for illegal operation numbers */ struct ILLEGAL4res { nfsstat4 status; }; /* * Operation arrays */ enum nfs_opnum4 { OP_ACCESS = 3, OP_CLOSE = 4, OP_COMMIT = 5, OP_CREATE = 6, OP_DELEGPURGE = 7, OP_DELEGRETURN = 8, OP_GETATTR = 9, OP_GETFH = 10, OP_LINK = 11, OP_LOCK = 12, OP_LOCKT = 13, OP_LOCKU = 14, OP_LOOKUP = 15, OP_LOOKUPP = 16, OP_NVERIFY = 17, OP_OPEN = 18, OP_OPENATTR = 19, OP_OPEN_CONFIRM = 20, OP_OPEN_DOWNGRADE = 21, OP_PUTFH = 22, OP_PUTPUBFH = 23, OP_PUTROOTFH = 24, OP_READ = 25, OP_READDIR = 26, OP_READLINK = 27, OP_REMOVE = 28, OP_RENAME = 29, OP_RENEW = 30, OP_RESTOREFH = 31, OP_SAVEFH = 32, OP_SECINFO = 33, OP_SETATTR = 34, OP_SETCLIENTID = 35, OP_SETCLIENTID_CONFIRM = 36, OP_VERIFY = 37, OP_WRITE = 38, OP_RELEASE_LOCKOWNER = 39, Shepler, et al. Standards Track [Page 263] RFC 3530 NFS version 4 Protocol April 2003 OP_ILLEGAL = 10044 }; union nfs_argop4 switch (nfs_opnum4 argop) { case OP_ACCESS: ACCESS4args opaccess; case OP_CLOSE: CLOSE4args opclose; case OP_COMMIT: COMMIT4args opcommit; case OP_CREATE: CREATE4args opcreate; case OP_DELEGPURGE: DELEGPURGE4args opdelegpurge; case OP_DELEGRETURN: DELEGRETURN4args opdelegreturn; case OP_GETATTR: GETATTR4args opgetattr; case OP_GETFH: void; case OP_LINK: LINK4args oplink; case OP_LOCK: LOCK4args oplock; case OP_LOCKT: LOCKT4args oplockt; case OP_LOCKU: LOCKU4args oplocku; case OP_LOOKUP: LOOKUP4args oplookup; case OP_LOOKUPP: void; case OP_NVERIFY: NVERIFY4args opnverify; case OP_OPEN: OPEN4args opopen; case OP_OPENATTR: OPENATTR4args opopenattr; case OP_OPEN_CONFIRM: OPEN_CONFIRM4args opopen_confirm; case OP_OPEN_DOWNGRADE: OPEN_DOWNGRADE4args opopen_downgrade; case OP_PUTFH: PUTFH4args opputfh; case OP_PUTPUBFH: void; case OP_PUTROOTFH: void; case OP_READ: READ4args opread; case OP_READDIR: READDIR4args opreaddir; case OP_READLINK: void; case OP_REMOVE: REMOVE4args opremove; case OP_RENAME: RENAME4args oprename; case OP_RENEW: RENEW4args oprenew; case OP_RESTOREFH: void; case OP_SAVEFH: void; case OP_SECINFO: SECINFO4args opsecinfo; case OP_SETATTR: SETATTR4args opsetattr; case OP_SETCLIENTID: SETCLIENTID4args opsetclientid; case OP_SETCLIENTID_CONFIRM: SETCLIENTID_CONFIRM4args opsetclientid_confirm; case OP_VERIFY: VERIFY4args opverify; case OP_WRITE: WRITE4args opwrite; case OP_RELEASE_LOCKOWNER: RELEASE_LOCKOWNER4args oprelease_lockowner; case OP_ILLEGAL: void; }; union nfs_resop4 switch (nfs_opnum4 resop){ case OP_ACCESS: ACCESS4res opaccess; Shepler, et al. Standards Track [Page 264] RFC 3530 NFS version 4 Protocol April 2003 case OP_CLOSE: CLOSE4res opclose; case OP_COMMIT: COMMIT4res opcommit; case OP_CREATE: CREATE4res opcreate; case OP_DELEGPURGE: DELEGPURGE4res opdelegpurge; case OP_DELEGRETURN: DELEGRETURN4res opdelegreturn; case OP_GETATTR: GETATTR4res opgetattr; case OP_GETFH: GETFH4res opgetfh; case OP_LINK: LINK4res oplink; case OP_LOCK: LOCK4res oplock; case OP_LOCKT: LOCKT4res oplockt; case OP_LOCKU: LOCKU4res oplocku; case OP_LOOKUP: LOOKUP4res oplookup; case OP_LOOKUPP: LOOKUPP4res oplookupp; case OP_NVERIFY: NVERIFY4res opnverify; case OP_OPEN: OPEN4res opopen; case OP_OPENATTR: OPENATTR4res opopenattr; case OP_OPEN_CONFIRM: OPEN_CONFIRM4res opopen_confirm; case OP_OPEN_DOWNGRADE: OPEN_DOWNGRADE4res opopen_downgrade; case OP_PUTFH: PUTFH4res opputfh; case OP_PUTPUBFH: PUTPUBFH4res opputpubfh; case OP_PUTROOTFH: PUTROOTFH4res opputrootfh; case OP_READ: READ4res opread; case OP_READDIR: READDIR4res opreaddir; case OP_READLINK: READLINK4res opreadlink; case OP_REMOVE: REMOVE4res opremove; case OP_RENAME: RENAME4res oprename; case OP_RENEW: RENEW4res oprenew; case OP_RESTOREFH: RESTOREFH4res oprestorefh; case OP_SAVEFH: SAVEFH4res opsavefh; case OP_SECINFO: SECINFO4res opsecinfo; case OP_SETATTR: SETATTR4res opsetattr; case OP_SETCLIENTID: SETCLIENTID4res opsetclientid; case OP_SETCLIENTID_CONFIRM: SETCLIENTID_CONFIRM4res opsetclientid_confirm; case OP_VERIFY: VERIFY4res opverify; case OP_WRITE: WRITE4res opwrite; case OP_RELEASE_LOCKOWNER: RELEASE_LOCKOWNER4res oprelease_lockowner; case OP_ILLEGAL: ILLEGAL4res opillegal; }; struct COMPOUND4args { utf8str_cs tag; uint32_t minorversion; nfs_argop4 argarray<>; }; struct COMPOUND4res { Shepler, et al. Standards Track [Page 265] RFC 3530 NFS version 4 Protocol April 2003 nfsstat4 status; utf8str_cs tag; nfs_resop4 resarray<>; }; /* * Remote file service routines */ program NFS4_PROGRAM { version NFS_V4 { void NFSPROC4_NULL(void) = 0; COMPOUND4res NFSPROC4_COMPOUND(COMPOUND4args) = 1; } = 4; } = 100003; /* * NFS4 Callback Procedure Definitions and Program */ /* * CB_GETATTR: Get Current Attributes */ struct CB_GETATTR4args { nfs_fh4 fh; bitmap4 attr_request; }; struct CB_GETATTR4resok { fattr4 obj_attributes; }; union CB_GETATTR4res switch (nfsstat4 status) { case NFS4_OK: CB_GETATTR4resok resok4; default: void; }; /* * CB_RECALL: Recall an Open Delegation */ struct CB_RECALL4args { Shepler, et al. Standards Track [Page 266] RFC 3530 NFS version 4 Protocol April 2003 stateid4 stateid; bool truncate; nfs_fh4 fh; }; struct CB_RECALL4res { nfsstat4 status; }; /* * CB_ILLEGAL: Response for illegal operation numbers */ struct CB_ILLEGAL4res { nfsstat4 status; }; /* * Various definitions for CB_COMPOUND */ enum nfs_cb_opnum4 { OP_CB_GETATTR = 3, OP_CB_RECALL = 4, OP_CB_ILLEGAL = 10044 }; 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; }; 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_COMPOUND4args { utf8str_cs tag; uint32_t minorversion; uint32_t callback_ident; nfs_cb_argop4 argarray<>; }; struct CB_COMPOUND4res { nfsstat4 status; utf8str_cs tag; nfs_cb_resop4 resarray<>; Shepler, et al. Standards Track [Page 267] RFC 3530 NFS version 4 Protocol April 2003 }; /* * Program number is in the transient range since the client * will assign the exact transient program number and provide * that to the server via the SETCLIENTID operation. */ program NFS4_CALLBACK { version NFS_CB { void CB_NULL(void) = 0; CB_COMPOUND4res CB_COMPOUND(CB_COMPOUND4args) = 1; } = 1; } = 0x40000000; 19. Acknowledgements The authors thank and acknowledge: Neil Brown for his extensive review and comments of various documents. Rick Macklem at the University of Guelph, Mike Frisch, Sergey Klyushin, and Dan Trufasiu of Hummingbird Ltd., and Andy Adamson, Bruce Fields, Jim Rees, and Kendrick Smith from the CITI organization at the University of Michigan, for their implementation efforts and feedback on the protocol specification. Mike Kupfer for his review of the file locking and ACL mechanisms. Alan Yoder for his input to ACL mechanisms. Peter Astrand for his close review of the protocol specification. Ran Atkinson for his constant reminder that users do matter. 20. Normative References [ISO10646] "ISO/IEC 10646-1:1993. International Standard -- Information technology -- Universal Multiple-Octet Coded Character Set (UCS) -- Part 1: Architecture and Basic Multilingual Plane." [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, September 1981. [RFC1831] Srinivasan, R., "RPC: Remote Procedure Call Protocol Specification Version 2", RFC 1831, August 1995. Shepler, et al. Standards Track [Page 268] RFC 3530 NFS version 4 Protocol April 2003 [RFC1832] Srinivasan, R., "XDR: External Data Representation Standard", RFC 1832, August 1995. [RFC2373] Hinden, R. and S. Deering, "IP Version 6 Addressing Architecture", RFC 2373, July 1998. [RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC 1964, June 1996. [RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism (SPKM)", RFC 2025, October 1996. [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. [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 19, RFC 2277, January 1998. [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC 2279, January 1998. [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. [RFC2743] Linn, J., "Generic Security Service Application Program Interface, Version 2, Update 1", RFC 2743, January 2000. [RFC2847] Eisler, M., "LIPKEY - A Low Infrastructure Public Key Mechanism Using SPKM", RFC 2847, June 2000. [RFC3010] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame, C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC 3010, December 2000. Shepler, et al. Standards Track [Page 269] RFC 3530 NFS version 4 Protocol April 2003 [RFC3454] Hoffman, P. and P. Blanchet, "Preparation of Internationalized Strings ("stringprep")", RFC 3454, December 2002. [Unicode1] The Unicode Consortium, "The Unicode Standard, Version 3.0", Addison-Wesley Developers Press, Reading, MA, 2000. ISBN 0-201-61633-5. More information available at: http://www.unicode.org/ [Unicode2] "Unsupported Scripts" Unicode, Inc., The Unicode Consortium, P.O. Box 700519, San Jose, CA 95710-0519 USA, September 1999. http://www.unicode.org/unicode/standard/ unsupported.html 21. Informative References [Floyd] S. Floyd, V. Jacobson, "The Synchronization of Periodic Routing Messages," IEEE/ACM Transactions on Networking, 2(2), pp. 122- 136, April 1994. [Gray] C. Gray, D. Cheriton, "Leases: An Efficient Fault-Tolerant Mechanism for Distributed File Cache Consistency," Proceedings of the Twelfth Symposium on Operating Systems Principles, p. 202-210, December 1989. [Juszczak] Juszczak, Chet, "Improving the Performance and Correctness of an NFS Server," USENIX Conference Proceedings, USENIX Association, Berkeley, CA, June 1990, pages 53-63. Describes reply cache implementation that avoids work in the server by handling duplicate requests. More important, though listed as a side-effect, the reply cache aids in the avoidance of destructive non- idempotent operation re-application -- improving correctness. Shepler, et al. Standards Track [Page 270] RFC 3530 NFS version 4 Protocol April 2003 [Kazar] Kazar, Michael Leon, "Synchronization and Caching Issues in the Andrew File System," USENIX Conference Proceedings, USENIX Association, Berkeley, CA, Dallas Winter 1988, pages 27-36. A description of the cache consistency scheme in AFS. Contrasted with other distributed file systems. [Macklem] Macklem, Rick, "Lessons Learned Tuning the 4.3BSD Reno Implementation of the NFS Protocol," Winter USENIX Conference Proceedings, USENIX Association, Berkeley, CA, January 1991. Describes performance work in tuning the 4.3BSD Reno NFS implementation. Describes performance improvement (reduced CPU loading) through elimination of data copies. [Mogul] Mogul, Jeffrey C., "A Recovery Protocol for Spritely NFS," USENIX File System Workshop Proceedings, Ann Arbor, MI, USENIX Association, Berkeley, CA, May 1992. Second paper on Spritely NFS proposes a lease-based scheme for recovering state of consistency protocol. [Nowicki] Nowicki, Bill, "Transport Issues in the Network File System," ACM SIGCOMM newsletter Computer Communication Review, April 1989. A brief description of the basis for the dynamic retransmission work. [Pawlowski] Pawlowski, Brian, Ron Hixon, Mark Stein, Joseph Tumminaro, "Network Computing in the UNIX and IBM Mainframe Environment," Uniforum `89 Conf. Proc., (1989) Description of an NFS server implementation for IBM's MVS operating system. [RFC1094] Sun Microsystems, Inc., "NFS: Network File System Protocol Specification", RFC 1094, March 1989. [RFC1345] Simonsen, K., "Character Mnemonics & Character Sets", RFC 1345, June 1992. Shepler, et al. Standards Track [Page 271] RFC 3530 NFS version 4 Protocol April 2003 [RFC1813] Callaghan, B., Pawlowski, B. and P. Staubach, "NFS Version 3 Protocol Specification", RFC 1813, June 1995. [RFC3232] Reynolds, J., Editor, "Assigned Numbers: RFC 1700 is Replaced by an On-line Database", RFC 3232, January 2002. [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. [RFC2152] Goldsmith, D. and M. Davis, "UTF-7 A Mail- Safe Transformation Format of Unicode", RFC 2152, May 1997. [RFC2224] Callaghan, B., "NFS URL Scheme", RFC 2224, October 1997. [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, June 2000. [Sandberg] Sandberg, R., D. Goldberg, S. Kleiman, D. Walsh, B. Lyon, "Design and Implementation of the Sun Network Filesystem," USENIX Conference Proceedings, USENIX Association, Berkeley, CA, Summer 1985. The basic paper describing the SunOS implementation of the NFS version 2 protocol, and discusses the goals, protocol specification and trade- offs. Shepler, et al. Standards Track [Page 272] RFC 3530 NFS version 4 Protocol April 2003 [Srinivasan] Srinivasan, V., Jeffrey C. Mogul, "Spritely NFS: Implementation and Performance of Cache Consistency Protocols", WRL Research Report 89/5, Digital Equipment Corporation Western Research Laboratory, 100 Hamilton Ave., Palo Alto, CA, 94301, May 1989. This paper analyzes the effect of applying a Sprite-like consistency protocol applied to standard NFS. The issues of recovery in a stateful environment are covered in [Mogul]. [XNFS] The Open Group, Protocols for Interworking: XNFS, Version 3W, The Open Group, 1010 El Camino Real Suite 380, Menlo Park, CA 94025, ISBN 1-85912-184-5, February 1998. HTML version available: http://www.opengroup.org 22. Authors' Information 22.1. Editor's Address Spencer Shepler Sun Microsystems, Inc. 7808 Moonflower Drive Austin, Texas 78750 Phone: +1 512-349-9376 EMail: spencer.shepler@sun.com Shepler, et al. Standards Track [Page 273] RFC 3530 NFS version 4 Protocol April 2003 22.2. Authors' Addresses Carl Beame Hummingbird Ltd. EMail: beame@bws.com Brent Callaghan Sun Microsystems, Inc. 17 Network Circle Menlo Park, CA 94025 Phone: +1 650-786-5067 EMail: brent.callaghan@sun.com Mike Eisler 5765 Chase Point Circle Colorado Springs, CO 80919 Phone: +1 719-599-9026 EMail: mike@eisler.com David Noveck Network Appliance 375 Totten Pond Road Waltham, MA 02451 Phone: +1 781-768-5347 EMail: dnoveck@netapp.com David Robinson Sun Microsystems, Inc. 5300 Riata Park Court Austin, TX 78727 Phone: +1 650-786-5088 EMail: david.robinson@sun.com Robert Thurlow Sun Microsystems, Inc. 500 Eldorado Blvd. Broomfield, CO 80021 Phone: +1 650-786-5096 EMail: robert.thurlow@sun.com Shepler, et al. Standards Track [Page 274] RFC 3530 NFS version 4 Protocol April 2003 23. Full Copyright Statement Copyright (C) The Internet Society (2003). All Rights Reserved. This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English. The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns. This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Acknowledgement Funding for the RFC Editor function is currently provided by the Internet Society. Shepler, et al. Standards Track [Page 275]