tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Gloss.     Arch.     IMS     UICC    |    Misc.    |    search     info

RFC 5661

 
 
 

Network File System (NFS) Version 4 Minor Version 1 Protocol

Part 14 of 20, p. 391 to 423
Prev RFC Part       Next RFC Part

 


prevText      Top      Up      ToC       Page 391 
16.  NFSv4.1 Procedures

   Both procedures, NULL and COMPOUND, MUST be implemented.

Top      Up      ToC       Page 392 
16.1.  Procedure 0: NULL - No Operation

16.1.1.  ARGUMENTS

   void;

16.1.2.  RESULTS

   void;

16.1.3.  DESCRIPTION

   This is the standard NULL procedure with the standard void argument
   and 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.

16.1.4.  ERRORS

   None.

16.2.  Procedure 1: COMPOUND - Compound Operations

16.2.1.  ARGUMENTS

   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, /* Mandatory not-to-implement */
    OP_OPEN_DOWNGRADE      = 21,
    OP_PUTFH               = 22,

Top      Up      ToC       Page 393 
    OP_PUTPUBFH            = 23,
    OP_PUTROOTFH           = 24,
    OP_READ                = 25,
    OP_READDIR             = 26,
    OP_READLINK            = 27,
    OP_REMOVE              = 28,
    OP_RENAME              = 29,
    OP_RENEW               = 30, /* Mandatory not-to-implement */
    OP_RESTOREFH           = 31,
    OP_SAVEFH              = 32,
    OP_SECINFO             = 33,
    OP_SETATTR             = 34,
    OP_SETCLIENTID         = 35, /* Mandatory not-to-implement */
    OP_SETCLIENTID_CONFIRM = 36, /* Mandatory not-to-implement */
    OP_VERIFY              = 37,
    OP_WRITE               = 38,
    OP_RELEASE_LOCKOWNER   = 39, /* Mandatory not-to-implement */

   /* new operations for NFSv4.1 */
    OP_BACKCHANNEL_CTL     = 40,
    OP_BIND_CONN_TO_SESSION = 41,
    OP_EXCHANGE_ID         = 42,
    OP_CREATE_SESSION      = 43,
    OP_DESTROY_SESSION     = 44,
    OP_FREE_STATEID        = 45,
    OP_GET_DIR_DELEGATION  = 46,
    OP_GETDEVICEINFO       = 47,
    OP_GETDEVICELIST       = 48,
    OP_LAYOUTCOMMIT        = 49,
    OP_LAYOUTGET           = 50,
    OP_LAYOUTRETURN        = 51,
    OP_SECINFO_NO_NAME     = 52,
    OP_SEQUENCE            = 53,
    OP_SET_SSV             = 54,
    OP_TEST_STATEID        = 55,
    OP_WANT_DELEGATION     = 56,
    OP_DESTROY_CLIENTID    = 57,
    OP_RECLAIM_COMPLETE    = 58,
    OP_ILLEGAL             = 10044
   };

Top      Up      ToC       Page 394 
   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;

    /* Not for NFSv4.1 */
    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;

    /* Not for NFSv4.1 */
    case OP_RENEW:         RENEW4args oprenew;

    case OP_RESTOREFH:     void;
    case OP_SAVEFH:        void;
    case OP_SECINFO:       SECINFO4args opsecinfo;
    case OP_SETATTR:       SETATTR4args opsetattr;

    /* Not for NFSv4.1 */
    case OP_SETCLIENTID: SETCLIENTID4args opsetclientid;

Top      Up      ToC       Page 395 
    /* Not for NFSv4.1 */
    case OP_SETCLIENTID_CONFIRM: SETCLIENTID_CONFIRM4args
                                   opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4args opverify;
    case OP_WRITE:         WRITE4args opwrite;

    /* Not for NFSv4.1 */
    case OP_RELEASE_LOCKOWNER:
                           RELEASE_LOCKOWNER4args
                           oprelease_lockowner;

    /* Operations new to NFSv4.1 */
    case OP_BACKCHANNEL_CTL:
                           BACKCHANNEL_CTL4args opbackchannel_ctl;

    case OP_BIND_CONN_TO_SESSION:
                           BIND_CONN_TO_SESSION4args
                           opbind_conn_to_session;

    case OP_EXCHANGE_ID:   EXCHANGE_ID4args opexchange_id;

    case OP_CREATE_SESSION:
                           CREATE_SESSION4args opcreate_session;

    case OP_DESTROY_SESSION:
                           DESTROY_SESSION4args opdestroy_session;

    case OP_FREE_STATEID:  FREE_STATEID4args opfree_stateid;

    case OP_GET_DIR_DELEGATION:
                           GET_DIR_DELEGATION4args
                                   opget_dir_delegation;

    case OP_GETDEVICEINFO: GETDEVICEINFO4args opgetdeviceinfo;
    case OP_GETDEVICELIST: GETDEVICELIST4args opgetdevicelist;
    case OP_LAYOUTCOMMIT:  LAYOUTCOMMIT4args oplayoutcommit;
    case OP_LAYOUTGET:     LAYOUTGET4args oplayoutget;
    case OP_LAYOUTRETURN:  LAYOUTRETURN4args oplayoutreturn;

    case OP_SECINFO_NO_NAME:
                           SECINFO_NO_NAME4args opsecinfo_no_name;

    case OP_SEQUENCE:      SEQUENCE4args opsequence;
    case OP_SET_SSV:       SET_SSV4args opset_ssv;
    case OP_TEST_STATEID:  TEST_STATEID4args optest_stateid;

    case OP_WANT_DELEGATION:
                           WANT_DELEGATION4args opwant_delegation;

Top      Up      ToC       Page 396 
    case OP_DESTROY_CLIENTID:
                           DESTROY_CLIENTID4args
                                   opdestroy_clientid;

    case OP_RECLAIM_COMPLETE:
                           RECLAIM_COMPLETE4args
                                   opreclaim_complete;

    /* Operations not new to NFSv4.1 */
    case OP_ILLEGAL:       void;
   };


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

16.2.2.  RESULTS

   union nfs_resop4 switch (nfs_opnum4 resop) {
    case OP_ACCESS:        ACCESS4res opaccess;
    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;
    /* Not for NFSv4.1 */
    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;

Top      Up      ToC       Page 397 
    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;
    /* Not for NFSv4.1 */
    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;
    /* Not for NFSv4.1 */
    case OP_SETCLIENTID: SETCLIENTID4res opsetclientid;

    /* Not for NFSv4.1 */
    case OP_SETCLIENTID_CONFIRM:
                           SETCLIENTID_CONFIRM4res
                                   opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4res opverify;
    case OP_WRITE:         WRITE4res opwrite;

    /* Not for NFSv4.1 */
    case OP_RELEASE_LOCKOWNER:
                           RELEASE_LOCKOWNER4res
                                   oprelease_lockowner;

    /* Operations new to NFSv4.1 */

    case OP_BACKCHANNEL_CTL:
                           BACKCHANNEL_CTL4res
                                   opbackchannel_ctl;

    case OP_BIND_CONN_TO_SESSION:
                           BIND_CONN_TO_SESSION4res
                                    opbind_conn_to_session;

    case OP_EXCHANGE_ID:   EXCHANGE_ID4res opexchange_id;

    case OP_CREATE_SESSION:
                           CREATE_SESSION4res
                                   opcreate_session;

    case OP_DESTROY_SESSION:
                           DESTROY_SESSION4res
                                   opdestroy_session;

Top      Up      ToC       Page 398 
    case OP_FREE_STATEID:  FREE_STATEID4res
                                   opfree_stateid;

    case OP_GET_DIR_DELEGATION:
                           GET_DIR_DELEGATION4res
                                   opget_dir_delegation;

    case OP_GETDEVICEINFO: GETDEVICEINFO4res
                                   opgetdeviceinfo;

    case OP_GETDEVICELIST: GETDEVICELIST4res
                                   opgetdevicelist;

    case OP_LAYOUTCOMMIT:  LAYOUTCOMMIT4res oplayoutcommit;
    case OP_LAYOUTGET:     LAYOUTGET4res oplayoutget;
    case OP_LAYOUTRETURN:  LAYOUTRETURN4res oplayoutreturn;

    case OP_SECINFO_NO_NAME:
                           SECINFO_NO_NAME4res
                                   opsecinfo_no_name;

    case OP_SEQUENCE:      SEQUENCE4res opsequence;
    case OP_SET_SSV:       SET_SSV4res opset_ssv;
    case OP_TEST_STATEID:  TEST_STATEID4res optest_stateid;

    case OP_WANT_DELEGATION:
                           WANT_DELEGATION4res
                                   opwant_delegation;

    case OP_DESTROY_CLIENTID:

                           DESTROY_CLIENTID4res
                                   opdestroy_clientid;

    case OP_RECLAIM_COMPLETE:
                           RECLAIM_COMPLETE4res
                                   opreclaim_complete;

    /* Operations not new to NFSv4.1 */
    case OP_ILLEGAL:       ILLEGAL4res opillegal;
   };


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

Top      Up      ToC       Page 399 
16.2.3.  DESCRIPTION

   The COMPOUND procedure is used to combine one or more NFSv4
   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 until
   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.  See Section 2.10.6.4 for a
   more detailed discussion.

   The server will generally choose between two methods of decoding the
   client's request.  The first would be the traditional one-pass XDR
   decode.  If there is an XDR decoding error in this case, the 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 the individual operations; the most interesting is the decode
   of attributes.  In this case, the server may encounter an XDR decode
   error during the second pass.  If it does, the server would return
   the error NFS4ERR_BADXDR to signify the decode error.

   The COMPOUND arguments contain a "minorversion" field.  For NFSv4.1,
   the value for this field is 1.  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 zero and one are not defined for the COMPOUND
   procedure.  Operation 2 is not defined and is reserved for future
   definition and use with minor versioning.  If the server receives an
   operation array that contains operation 2 and the minorversion field
   has a value of 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

Top      Up      ToC       Page 400 
   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 be 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.

16.2.3.1.  Current Filehandle and Stateid

   The COMPOUND procedure offers a simple environment for the execution
   of the operations specified by the client.  The first two relate to
   the filehandle while the second two relate to the current stateid.

16.2.3.1.1.  Current Filehandle

   The current and saved filehandles are used throughout the protocol.
   Most operations implicitly use the current filehandle as an 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 2

Top      Up      ToC       Page 401 
   In this example, the PUTFH (Section 18.19) 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 18.21) and PUTPUBFH (Section 18.20) 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 operation 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.

16.2.3.1.2.  Current Stateid

   With NFSv4.1, additions of a current stateid and a saved stateid have
   been made to the COMPOUND processing environment; this allows for the
   passing of stateids between operations.  There are no changes to the
   syntax of the protocol, only changes to the semantics of a few
   operations.

   A "current stateid" is the stateid that is associated with the
   current filehandle.  The current stateid may only be changed by an
   operation that modifies the current filehandle or returns a stateid.

   If an operation returns a stateid, it MUST set the current stateid to
   the returned value.  If an operation sets the current filehandle but
   does not return a stateid, the current stateid MUST be set to the
   all-zeros special stateid, i.e., (seqid, other) = (0, 0).  If an
   operation uses a stateid as an argument but does not return a
   stateid, the current stateid MUST NOT be changed.  For example,
   PUTFH, PUTROOTFH, and PUTPUBFH will change the current server state
   from {ocfh, (osid)} to {cfh, (0, 0)}, while LOCK will change the
   current state from {cfh, (osid} to {cfh, (nsid)}.  Operations like
   LOOKUP that transform a current filehandle and component name into a
   new current filehandle will also change the current state to {0, 0}.
   The SAVEFH and RESTOREFH operations will save and restore both the
   current filehandle and the current stateid as a set.

Top      Up      ToC       Page 402 
   The following example is the common case of a simple READ operation
   with a normal stateid showing that the PUTFH initializes the current
   stateid to (0, 0).  The subsequent READ with stateid (sid1) leaves
   the current stateid unchanged.

       PUTFH fh1                             - -> {fh1, (0, 0)}
       READ (sid1), 0, 1024      {fh1, (0, 0)} -> {fh1, (0, 0)}

                                 Figure 3

   This next example performs an OPEN with the root filehandle and, as a
   result, generates stateid (sid1).  The next operation specifies the
   READ with the argument stateid set such that (seqid, other) are equal
   to (1, 0), but the current stateid set by the previous operation is
   actually used when the operation is evaluated.  This allows correct
   interaction with any existing, potentially conflicting, locks.

       PUTROOTFH                             - -> {fh1, (0, 0)}
       OPEN "compA"              {fh1, (0, 0)} -> {fh2, (sid1)}
       READ (1, 0), 0, 1024      {fh2, (sid1)} -> {fh2, (sid1)}
       CLOSE (1, 0)              {fh2, (sid1)} -> {fh2, (sid2)}

                                 Figure 4

   This next example is similar to the second in how it passes the
   stateid sid2 generated by the LOCK operation to the next READ
   operation.  This allows the client to explicitly surround a single
   I/O operation with a lock and its appropriate stateid to guarantee
   correctness with other client locks.  The example also shows how
   SAVEFH and RESTOREFH can save and later reuse a filehandle and
   stateid, passing them as the current filehandle and stateid to a READ
   operation.

       PUTFH fh1                             - -> {fh1, (0, 0)}
       LOCK 0, 1024, (sid1)      {fh1, (sid1)} -> {fh1, (sid2)}
       READ (1, 0), 0, 1024      {fh1, (sid2)} -> {fh1, (sid2)}
       LOCKU 0, 1024, (1, 0)     {fh1, (sid2)} -> {fh1, (sid3)}
       SAVEFH                    {fh1, (sid3)} -> {fh1, (sid3)}

       PUTFH fh2                 {fh1, (sid3)} -> {fh2, (0, 0)}
       WRITE (1, 0), 0, 1024     {fh2, (0, 0)} -> {fh2, (0, 0)}

       RESTOREFH                 {fh2, (0, 0)} -> {fh1, (sid3)}
       READ (1, 0), 1024, 1024   {fh1, (sid3)} -> {fh1, (sid3)}

                                 Figure 5

Top      Up      ToC       Page 403 
   The final example shows a disallowed use of the current stateid.  The
   client is attempting to implicitly pass an anonymous special stateid,
   (0,0), to the READ operation.  The server MUST return
   NFS4ERR_BAD_STATEID in the reply to the READ operation.

       PUTFH fh1                             - -> {fh1, (0, 0)}
       READ (1, 0), 0, 1024      {fh1, (0, 0)} -> NFS4ERR_BAD_STATEID

                                 Figure 6

16.2.4.  ERRORS

   COMPOUND will of course return every error that each operation on the
   fore channel can return (see Table 6).  However, if COMPOUND returns
   zero operations, obviously the error returned by COMPOUND has nothing
   to do with an error returned by an operation.  The list of errors
   COMPOUND will return if it processes zero operations include:

                          COMPOUND Error Returns

   +------------------------------+------------------------------------+
   | Error                        | Notes                              |
   +------------------------------+------------------------------------+
   | NFS4ERR_BADCHAR              | The tag argument has a character   |
   |                              | the replier does not support.      |
   | NFS4ERR_BADXDR               |                                    |
   | NFS4ERR_DELAY                |                                    |
   | NFS4ERR_INVAL                | The tag argument is not in UTF-8   |
   |                              | encoding.                          |
   | NFS4ERR_MINOR_VERS_MISMATCH  |                                    |
   | NFS4ERR_SERVERFAULT          |                                    |
   | NFS4ERR_TOO_MANY_OPS         |                                    |
   | NFS4ERR_REP_TOO_BIG          |                                    |
   | NFS4ERR_REP_TOO_BIG_TO_CACHE |                                    |
   | NFS4ERR_REQ_TOO_BIG          |                                    |
   +------------------------------+------------------------------------+

                                  Table 9

17.  Operations: REQUIRED, RECOMMENDED, or OPTIONAL

   The following tables summarize the operations of the NFSv4.1 protocol
   and the corresponding designation of REQUIRED, RECOMMENDED, and
   OPTIONAL to implement or MUST NOT implement.  The designation of MUST
   NOT implement is reserved for those operations that were defined in
   NFSv4.0 and MUST NOT be implemented in NFSv4.1.

Top      Up      ToC       Page 404 
   For the most part, the REQUIRED, RECOMMENDED, or OPTIONAL designation
   for operations sent by the client is for the server implementation.
   The client is generally required to implement the operations needed
   for the operating environment for which it serves.  For example, a
   read-only NFSv4.1 client would have no need to implement the WRITE
   operation and is not required to do so.

   The REQUIRED or OPTIONAL designation for callback operations sent by
   the server is for both the client and server.  Generally, the client
   has the option of creating the backchannel and sending the operations
   on the fore channel that will be a catalyst for the server sending
   callback operations.  A partial exception is CB_RECALL_SLOT; the only
   way the client can avoid supporting this operation is by not creating
   a backchannel.

   Since this is a summary of the operations and their designation,
   there are subtleties that are not presented here.  Therefore, if
   there is a question of the requirements of implementation, the
   operation descriptions themselves must be consulted along with other
   relevant explanatory text within this specification.

   The abbreviations used in the second and third columns of the table
   are defined as follows.

   REQ  REQUIRED to implement

   REC  RECOMMEND to implement

   OPT  OPTIONAL to implement

   MNI  MUST NOT implement

   For the NFSv4.1 features that are OPTIONAL, the operations that
   support those features are OPTIONAL, and the server would return
   NFS4ERR_NOTSUPP in response to the client's use of those operations.
   If an OPTIONAL feature is supported, it is possible that a set of
   operations related to the feature become REQUIRED to implement.  The
   third column of the table designates the feature(s) and if the
   operation is REQUIRED or OPTIONAL in the presence of support for the
   feature.

   The OPTIONAL features identified and their abbreviations are as
   follows:

   pNFS  Parallel NFS

   FDELG  File Delegations

Top      Up      ToC       Page 405 
   DDELG  Directory Delegations

                                Operations

   +----------------------+------------+--------------+----------------+
   | Operation            | REQ, REC,  | Feature      | Definition     |
   |                      | OPT, or    | (REQ, REC,   |                |
   |                      | MNI        | or OPT)      |                |
   +----------------------+------------+--------------+----------------+
   | ACCESS               | REQ        |              | Section 18.1   |
   | BACKCHANNEL_CTL      | REQ        |              | Section 18.33  |
   | BIND_CONN_TO_SESSION | REQ        |              | Section 18.34  |
   | CLOSE                | REQ        |              | Section 18.2   |
   | COMMIT               | REQ        |              | Section 18.3   |
   | CREATE               | REQ        |              | Section 18.4   |
   | CREATE_SESSION       | REQ        |              | Section 18.36  |
   | DELEGPURGE           | OPT        | FDELG (REQ)  | Section 18.5   |
   | DELEGRETURN          | OPT        | FDELG,       | Section 18.6   |
   |                      |            | DDELG, pNFS  |                |
   |                      |            | (REQ)        |                |
   | DESTROY_CLIENTID     | REQ        |              | Section 18.50  |
   | DESTROY_SESSION      | REQ        |              | Section 18.37  |
   | EXCHANGE_ID          | REQ        |              | Section 18.35  |
   | FREE_STATEID         | REQ        |              | Section 18.38  |
   | GETATTR              | REQ        |              | Section 18.7   |
   | GETDEVICEINFO        | OPT        | pNFS (REQ)   | Section 18.40  |
   | GETDEVICELIST        | OPT        | pNFS (OPT)   | Section 18.41  |
   | GETFH                | REQ        |              | Section 18.8   |
   | GET_DIR_DELEGATION   | OPT        | DDELG (REQ)  | Section 18.39  |
   | LAYOUTCOMMIT         | OPT        | pNFS (REQ)   | Section 18.42  |
   | LAYOUTGET            | OPT        | pNFS (REQ)   | Section 18.43  |
   | LAYOUTRETURN         | OPT        | pNFS (REQ)   | Section 18.44  |
   | LINK                 | OPT        |              | Section 18.9   |
   | LOCK                 | REQ        |              | Section 18.10  |
   | LOCKT                | REQ        |              | Section 18.11  |
   | LOCKU                | REQ        |              | Section 18.12  |
   | LOOKUP               | REQ        |              | Section 18.13  |
   | LOOKUPP              | REQ        |              | Section 18.14  |
   | NVERIFY              | REQ        |              | Section 18.15  |
   | OPEN                 | REQ        |              | Section 18.16  |
   | OPENATTR             | OPT        |              | Section 18.17  |
   | OPEN_CONFIRM         | MNI        |              | N/A            |
   | OPEN_DOWNGRADE       | REQ        |              | Section 18.18  |
   | PUTFH                | REQ        |              | Section 18.19  |
   | PUTPUBFH             | REQ        |              | Section 18.20  |
   | PUTROOTFH            | REQ        |              | Section 18.21  |
   | READ                 | REQ        |              | Section 18.22  |
   | READDIR              | REQ        |              | Section 18.23  |

Top      Up      ToC       Page 406 
   | READLINK             | OPT        |              | Section 18.24  |
   | RECLAIM_COMPLETE     | REQ        |              | Section 18.51  |
   | RELEASE_LOCKOWNER    | MNI        |              | N/A            |
   | REMOVE               | REQ        |              | Section 18.25  |
   | RENAME               | REQ        |              | Section 18.26  |
   | RENEW                | MNI        |              | N/A            |
   | RESTOREFH            | REQ        |              | Section 18.27  |
   | SAVEFH               | REQ        |              | Section 18.28  |
   | SECINFO              | REQ        |              | Section 18.29  |
   | SECINFO_NO_NAME      | REC        | pNFS file    | Section 18.45, |
   |                      |            | layout (REQ) | Section 13.12  |
   | SEQUENCE             | REQ        |              | Section 18.46  |
   | SETATTR              | REQ        |              | Section 18.30  |
   | SETCLIENTID          | MNI        |              | N/A            |
   | SETCLIENTID_CONFIRM  | MNI        |              | N/A            |
   | SET_SSV              | REQ        |              | Section 18.47  |
   | TEST_STATEID         | REQ        |              | Section 18.48  |
   | VERIFY               | REQ        |              | Section 18.31  |
   | WANT_DELEGATION      | OPT        | FDELG (OPT)  | Section 18.49  |
   | WRITE                | REQ        |              | Section 18.32  |
   +----------------------+------------+--------------+----------------+

Top      Up      ToC       Page 407 
                            Callback Operations

   +-------------------------+-----------+-------------+---------------+
   | Operation               | REQ, REC, | Feature     | Definition    |
   |                         | OPT, or   | (REQ, REC,  |               |
   |                         | MNI       | or OPT)     |               |
   +-------------------------+-----------+-------------+---------------+
   | CB_GETATTR              | OPT       | FDELG (REQ) | Section 20.1  |
   | CB_LAYOUTRECALL         | OPT       | pNFS (REQ)  | Section 20.3  |
   | CB_NOTIFY               | OPT       | DDELG (REQ) | Section 20.4  |
   | CB_NOTIFY_DEVICEID      | OPT       | pNFS (OPT)  | Section 20.12 |
   | CB_NOTIFY_LOCK          | OPT       |             | Section 20.11 |
   | CB_PUSH_DELEG           | OPT       | FDELG (OPT) | Section 20.5  |
   | CB_RECALL               | OPT       | FDELG,      | Section 20.2  |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   | CB_RECALL_ANY           | OPT       | FDELG,      | Section 20.6  |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   | CB_RECALL_SLOT          | REQ       |             | Section 20.8  |
   | CB_RECALLABLE_OBJ_AVAIL | OPT       | DDELG, pNFS | Section 20.7  |
   |                         |           | (REQ)       |               |
   | CB_SEQUENCE             | OPT       | FDELG,      | Section 20.9  |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   | CB_WANTS_CANCELLED      | OPT       | FDELG,      | Section 20.10 |
   |                         |           | DDELG, pNFS |               |
   |                         |           | (REQ)       |               |
   +-------------------------+-----------+-------------+---------------+

18.  NFSv4.1 Operations

18.1.  Operation 3: ACCESS - Check Access Rights

18.1.1.  ARGUMENTS


   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;
   };

Top      Up      ToC       Page 408 
18.1.2.  RESULTS

   struct ACCESS4resok {
           uint32_t        supported;
           uint32_t        access;
   };

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


18.1.3.  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 reply's supported and access fields MUST NOT contain
   more values than originally set in the request's access field.  For
   example, if the client sends an ACCESS operation with just the
   ACCESS4_READ value set and the server supports this value, the server
   MUST NOT set more than ACCESS4_READ in the supported field even if it
   could have reliably checked other values.

   The reply's access field MUST NOT contain more values than the
   supported field.

   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
   do 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.

Top      Up      ToC       Page 409 
   ACCESS4_LOOKUP  Look up a name in a directory (no meaning for non-
      directory objects).

   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 a regular file (no meaning for a directory).

   On success, the current filehandle retains its value.

   ACCESS4_EXECUTE is a challenging semantic to implement because NFS
   provides remote file access, not remote execution.  This leads to the
   following:

   o  Whether or not a regular file is executable ought to be the
      responsibility of the NFS client and not the server.  And yet the
      ACCESS operation is specified to seemingly require a server to own
      that responsibility.

   o  When a client executes a regular file, it has to read the file
      from the server.  Strictly speaking, the server should not allow
      the client to read a file being executed unless the user has read
      permissions on the file.  Requiring explicit read permissions on
      executable files in order to access them over NFS is not going to
      be acceptable to some users and storage administrators.
      Historically, NFS servers have allowed a user to READ a file if
      the user has execute access to the file.

   As a practical example, the UNIX specification [52] states that an
   implementation claiming conformance to UNIX may indicate in the
   access() programming interface's result that a privileged user has
   execute rights, even if no execute permission bits are set on the
   regular file's attributes.  It is possible to claim conformance to
   the UNIX specification and instead not indicate execute rights in
   that situation, which is true for some operating environments.
   Suppose the operating environments of the client and server are
   implementing the access() semantics for privileged users differently,
   and the ACCESS operation implementations of the client and server
   follow their respective access() semantics.  This can cause undesired
   behavior:

   o  Suppose the client's access() interface returns X_OK if the user
      is privileged and no execute permission bits are set on the
      regular file's attribute, and the server's access() interface does

Top      Up      ToC       Page 410 
      not return X_OK in that situation.  Then the client will be unable
      to execute files stored on the NFS server that could be executed
      if stored on a non-NFS file system.

   o  Suppose the client's access() interface does not return X_OK if
      the user is privileged, and no execute permission bits are set on
      the regular file's attribute, and the server's access() interface
      does return X_OK in that situation.  Then:

      *  The client will be able to execute files stored on the NFS
         server that could be executed if stored on a non-NFS file
         system, unless the client's execution subsystem also checks for
         execute permission bits.

      *  Even if the execution subsystem is checking for execute
         permission bits, there are more potential issues.  For example,
         suppose the client is invoking access() to build a "path search
         table" of all executable files in the user's "search path",
         where the path is a list of directories each containing
         executable files.  Suppose there are two files each in separate
         directories of the search path, such that files have the same
         component name.  In the first directory the file has no execute
         permission bits set, and in the second directory the file has
         execute bits set.  The path search table will indicate that the
         first directory has the executable file, but the execute
         subsystem will fail to execute it.  The command shell might
         fail to try the second file in the second directory.  And even
         if it did, this is a potential performance issue.  Clearly, the
         desired outcome for the client is for the path search table to
         not contain the first file.

   To deal with the problems described above, the "smart client, stupid
   server" principle is used.  The client owns overall responsibility
   for determining execute access and relies on the server to parse the
   execution permissions within the file's mode, acl, and dacl
   attributes.  The rules for the client and server follow:

   o  If the client is sending ACCESS in order to determine if the user
      can read the file, the client SHOULD set ACCESS4_READ in the
      request's access field.

   o  If the client's operating environment only grants execution to the
      user if the user has execute access according to the execute
      permissions in the mode, acl, and dacl attributes, then if the
      client wants to determine execute access, the client SHOULD send
      an ACCESS request with ACCESS4_EXECUTE bit set in the request's
      access field.

Top      Up      ToC       Page 411 
   o  If the client's operating environment grants execution to the user
      even if the user does not have execute access according to the
      execute permissions in the mode, acl, and dacl attributes, then if
      the client wants to determine execute access, it SHOULD send an
      ACCESS request with both the ACCESS4_EXECUTE and ACCESS4_READ bits
      set in the request's access field.  This way, if any read or
      execute permission grants the user read or execute access (or if
      the server interprets the user as privileged), as indicated by the
      presence of ACCESS4_EXECUTE and/or ACCESS4_READ in the reply's
      access field, the client will be able to grant the user execute
      access to the file.

   o  If the server supports execute permission bits, or some other
      method for denoting executability (e.g., the suffix of the name of
      the file might indicate execute), it MUST check only execute
      permissions, not read permissions, when determining whether or not
      the reply will have ACCESS4_EXECUTE set in the access field.  The
      server MUST NOT also examine read permission bits when determining
      whether or not the reply will have ACCESS4_EXECUTE set in the
      access field.  Even if the server's operating environment would
      grant execute access to the user (e.g., the user is privileged),
      the server MUST NOT reply with ACCESS4_EXECUTE set in reply's
      access field unless there is at least one execute permission bit
      set in the mode, acl, or dacl attributes.  In the case of acl and
      dacl, the "one execute permission bit" MUST be an ACE4_EXECUTE bit
      set in an ALLOW ACE.

   o  If the server does not support execute permission bits or some
      other method for denoting executability, it MUST NOT set
      ACCESS4_EXECUTE in the reply's supported and access fields.  If
      the client set ACCESS4_EXECUTE in the ACCESS request's access
      field, and ACCESS4_EXECUTE is not set in the reply's supported
      field, then the client will have to send an ACCESS request with
      the ACCESS4_READ bit set in the request's access field.

   o  If the server supports read permission bits, it MUST only check
      for read permissions in the mode, acl, and dacl attributes when it
      receives an ACCESS request with ACCESS4_READ set in the access
      field.  The server MUST NOT also examine execute permission bits
      when determining whether the reply will have ACCESS4_READ set in
      the access field or not.

   Note that if the ACCESS reply has ACCESS4_READ or ACCESS_EXECUTE set,
   then the user also has permissions to OPEN (Section 18.16) or READ
   (Section 18.22) the file.  In other words, if the client sends an
   ACCESS request with the ACCESS4_READ and ACCESS_EXECUTE set in the
   access field (or two separate requests, one with ACCESS4_READ set and
   the other with ACCESS4_EXECUTE set), and the reply has just

Top      Up      ToC       Page 412 
   ACCESS4_EXECUTE set in the access field (or just one reply has
   ACCESS4_EXECUTE set), then the user has authorization to OPEN or READ
   the file.

18.1.4.  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.1 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 that will result in an access failure.  The OPEN operation
   provides a point where the server can verify access to the file
   object and a method to return that information to the client.  The
   ACCESS operation is still useful for directory operations or for use
   in the case that the UNIX interface 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 afterwards.  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
   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.

Top      Up      ToC       Page 413 
18.2.  Operation 4: CLOSE - Close File

18.2.1.  ARGUMENTS

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


18.2.2.  RESULTS

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


18.2.3.  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 are only those associated with the supplied
   stateid.  State associated with other OPENs is not affected.

   If byte-range locks are held, the client SHOULD release all locks
   before sending 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.

   The argument seqid MAY have any value, and the server MUST ignore
   seqid.

   On success, the current filehandle retains its value.

   The server MAY require that the combination of principal, security
   flavor, and, if applicable, GSS mechanism that sent the OPEN request
   also be the one to CLOSE the file.  This might not be possible if
   credentials for the principal are no longer available.  The server
   MAY allow the machine credential or SSV credential (see
   Section 18.35) to send CLOSE.

Top      Up      ToC       Page 414 
18.2.4.  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.  To help find any uses of
   this stateid by clients, the server SHOULD return the invalid special
   stateid (the "other" value is zero and the "seqid" field is
   NFS4_UINT32_MAX, see Section 8.2.3).

   A CLOSE operation may make delegations grantable where they were not
   previously.  Servers may choose to respond immediately if there are
   pending delegation want requests or may respond to the situation at a
   later time.

18.3.  Operation 5: COMMIT - Commit Cached Data

18.3.1.  ARGUMENTS

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

18.3.2.  RESULTS

   struct COMMIT4resok {
           verifier4       writeverf;
   };

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

Top      Up      ToC       Page 415 
18.3.3.  DESCRIPTION

   The COMMIT operation forces or flushes uncommitted, modified data to
   stable storage for the file specified by the current filehandle.  The
   flushed data is that which was previously written with one or more
   WRITE operations that had the "committed" field of their results
   field set to UNSTABLE4.

   The offset specifies the position within the file where the flush is
   to begin.  An offset value of zero means to flush data starting at
   the beginning of the file.  The count specifies the number of bytes
   of data to flush.  If the count is zero, a flush from the 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 between the initial WRITE operations and the
   COMMIT.  The client does this by comparing the write verifier
   returned from the initial WRITE operations 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 restarted; however, other events at the server may result in
   uncommitted data loss as well.

   On success, the current filehandle retains its value.

18.3.4.  IMPLEMENTATION

   The COMMIT operation is similar in operation and semantics to the
   POSIX fsync() [25] system interface 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 the 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 zero and count zero, it should do the equivalent of applying

Top      Up      ToC       Page 416 
   fsync() to the entire file.  Otherwise, it should arrange to have the
   modified 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
   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 modified data
   based on the offset and count, and flushes any modified metadata
   associated with the file.  It then returns the status of the flush
   and the write verifier.  The second 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 zero and count of zero, 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 (via the WRITE operation) by the client
   with the "committed" field in the result of WRITE 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 the "committed" field in the result 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 differs from that previously
   returned by the server, the client will need to retransmit all of the
   buffers containing uncommitted 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 be sent in a WRITE request with the
   FILE_SYNC4 stable parameter.  If there is more than one buffer, it
   might be worthwhile retransmitting all of the buffers in WRITE
   operations 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.  However, if the server repeatably returns
   from COMMIT a verifier that differs from that returned by WRITE, the
   only way to ensure progress is to retransmit all of the buffers with
   WRITE requests with the FILE_SYNC4 stable parameter.

Top      Up      ToC       Page 417 
   The above description applies to page-cache-based systems as well as
   buffer-cache-based systems.  In the former systems, the virtual
   memory system will need to be modified instead of the buffer cache.

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

18.4.1.  ARGUMENTS

   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;
   };

18.4.2.  RESULTS

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

   union CREATE4res switch (nfsstat4 status) {
    case NFS4_OK:
            /* new CURRENTFH: created object */
            CREATE4resok resok4;
    default:
            void;
   };

Top      Up      ToC       Page 418 
18.4.3.  DESCRIPTION

   The CREATE operation creates a file object other than an ordinary
   file in a directory with a given name.  The OPEN operation MUST be
   used to create a regular file or a named attribute.

   The current filehandle must be a directory: an object of type NF4DIR.
   If the current filehandle is an attribute directory (type
   NF4ATTRDIR), the error NFS4ERR_WRONG_TYPE is returned.  If the
   current file handle designates any other type of object, the error
   NFS4ERR_NOTDIR results.

   The objname specifies the name for the new object.  The objtype
   determines the type of object to be created: directory, symlink, etc.
   If the object type specified is that of an ordinary file, a named
   attribute, or a named attribute directory, the error NFS4ERR_BADTYPE
   results.

   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 data type, the server will indicate if the before
   and after change attributes were obtained atomically with respect to
   the file object creation.

   If the objname has a length of 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

Top      Up      ToC       Page 419 
   (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 [26] that has a group identifier
   for every user identifier), inherited from the directory in which the
   object is created, or whatever else the server's operating
   environment or file system semantics dictate.  This applies to the
   OPEN operation too.

   Conversely, it is possible that the client will specify in
   createattrs an owner attribute, 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 NFS4ERR_PERM.  This applies to the OPEN operation too.

   If the current filehandle designates a directory for which another
   client holds a directory delegation, then, unless the delegation is
   such that the situation can be resolved by sending a notification,
   the delegation MUST be recalled, and the CREATE operation MUST NOT
   proceed until the delegation is returned or revoked.  Except where
   this happens very quickly, one or more NFS4ERR_DELAY errors will be
   returned to requests made while delegation remains outstanding.

   When the current filehandle designates a directory for which one or
   more directory delegations exist, then, when those delegations
   request such notifications, NOTIFY4_ADD_ENTRY will be generated as a
   result of this operation.

   If the capability FSCHARSET_CAP4_ALLOWS_ONLY_UTF8 is set
   (Section 14.4), and a symbolic link is being created, then the
   content of the symbolic link MUST be in UTF-8 encoding.

18.4.4.  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.

18.5.  Operation 7: DELEGPURGE - Purge Delegations Awaiting Recovery

18.5.1.  ARGUMENTS

   struct DELEGPURGE4args {
           clientid4       clientid;
   };

Top      Up      ToC       Page 420 
18.5.2.  RESULTS

   struct DELEGPURGE4res {
           nfsstat4        status;
   };

18.5.3.  DESCRIPTION

   This operation purges all of the delegations awaiting recovery for a
   given client.  This is useful for clients that 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.

   The client is NOT specified by the clientid field of the request.
   The client SHOULD set the client field to zero, and the server MUST
   ignore the clientid field.  Instead, the server MUST derive the
   client ID from the value of the session ID in the arguments of the
   SEQUENCE operation that precedes DELEGPURGE in the COMPOUND request.

   The DELEGPURGE operation should be used by clients that record
   delegation information on stable storage on the client.  In this
   case, after the client recovers all delegations it knows of, it
   should immediately send a DELEGPURGE operation.  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 which make requests that conflict with the unrecovered
   delegations.  The set of delegations known to the server and the
   client might be different.  The reason for this is that after sending
   a request that resulted in a delegation, the client might experience
   a failure before it both received the delegation and committed the
   delegation to the client's stable storage.

   The server MAY support DELEGPURGE, but if it does not, it MUST NOT
   support CLAIM_DELEGATE_PREV and MUST NOT support CLAIM_DELEG_PREV_FH.

18.6.  Operation 8: DELEGRETURN - Return Delegation

18.6.1.  ARGUMENTS

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

Top      Up      ToC       Page 421 
18.6.2.  RESULTS

   struct DELEGRETURN4res {
           nfsstat4        status;
   };

18.6.3.  DESCRIPTION

   The DELEGRETURN operation returns the delegation represented by the
   current filehandle and stateid.

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

   The server MAY require that the principal, security flavor, and if
   applicable, the GSS mechanism, combination that acquired the
   delegation also be the one to send DELEGRETURN on the file.  This
   might not be possible if credentials for the principal are no longer
   available.  The server MAY allow the machine credential or SSV
   credential (see Section 18.35) to send DELEGRETURN.

18.7.  Operation 9: GETATTR - Get Attributes

18.7.1.  ARGUMENTS

   struct GETATTR4args {
           /* CURRENT_FH: object */
           bitmap4         attr_request;
   };

18.7.2.  RESULTS

   struct GETATTR4resok {
           fattr4          obj_attributes;
   };

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

Top      Up      ToC       Page 422 
18.7.3.  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 that it was able to return, which will
   include all attributes requested by the client that are attributes
   supported by the server for the target file system.  This bitmap is
   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 for the target
   file system.  If the server does not support a particular attribute
   on the target file system, 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 that are absent should be treated as having support for
   a very small set of attributes as described in Section 11.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
   Section 5.6, for all file systems, with the exception of absent file
   systems.

   On success, the current filehandle retains its value.

18.7.4.  IMPLEMENTATION

   Suppose there is an OPEN_DELEGATE_WRITE delegation held by another
   client for the 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.

Top      Up      ToC       Page 423 
   o  The OPEN_DELEGATE_WRITE delegation is revoked.

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

18.8.  Operation 10: GETFH - Get Current Filehandle

18.8.1.  ARGUMENTS

   /* CURRENT_FH: */
   void;

18.8.2.  RESULTS

   struct GETFH4resok {
           nfs_fh4         object;
   };

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

18.8.3.  DESCRIPTION

   This operation returns the current filehandle value.

   On success, the current filehandle retains its value.

   As described in Section 2.10.6.4, GETFH is REQUIRED or RECOMMENDED to
   immediately follow certain operations, and servers are free to reject
   such operations if the client fails to insert GETFH in the request as
   REQUIRED or RECOMMENDED.  Section 18.16.4.1 provides additional
   justification for why GETFH MUST follow OPEN.

18.8.4.  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 look up a directory entry and obtain
   its filehandle, then the following request is needed.

      PUTFH (directory filehandle)
      LOOKUP (entry name)
      GETFH


Next RFC Part