Skip to main content

NFS version 4 Protocol
draft-ietf-nfsv4-07

The information below is for an old version of the document that is already published as an RFC.
Document Type
This is an older version of an Internet-Draft that was ultimately published as RFC 3010.
Authors Carl Beame , David Robinson , Brent Callaghan , David Noveck , Robert Thurlow , Mike Eisler , Spencer Shepler
Last updated 2020-01-21 (Latest revision 2000-06-16)
RFC stream Internet Engineering Task Force (IETF)
Intended RFC status Proposed Standard
Formats
Additional resources Mailing list discussion
Stream WG state (None)
Document shepherd (None)
IESG IESG state Became RFC 3010 (Proposed Standard)
Consensus boilerplate Unknown
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-ietf-nfsv4-07

14.2.6.  Operation 8: DELEGRETURN - Return Delegation

   SYNOPSIS

     stateid ->

   ARGUMENT

     struct DELEGRETURN4args {
             stateid4        stateid;
     };

   RESULT

     struct DELEGRETURN4res {
             nfsstat4        status;
     };

   DESCRIPTION

     Returns the delegation represented by the given stateid.

   ERRORS

     NFS4ERR_BAD_STATEID
     NFS4ERR_OLD_STATEID
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE_STATEID

Expires: December 2000                                        [Page 121]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.7.  Operation 9: GETATTR - Get Attributes

   SYNOPSIS

     (cfh), attrbits -> attrbits, attrvals

   ARGUMENT

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

   RESULT

     struct GETATTR4resok {
             fattr4          obj_attributes;
     };

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

   DESCRIPTION

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

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

     All servers must support the mandatory attributes as specified in
     the section "File Attributes".

     On success, the current filehandle retains its value.

Expires: December 2000                                        [Page 122]
Draft Specification      NFS version 4 Protocol                June 2000

   IMPLEMENTATION

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_DELAY
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 123]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.8.  Operation 10: GETFH - Get Current Filehandle

   SYNOPSIS

     (cfh) -> filehandle

   ARGUMENT

     /* CURRENT_FH: */
     void;

   RESULT

     struct GETFH4resok {
             nfs_fh4         object;
     };

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

   DESCRIPTION

     This operation returns the current filehandle value.

     On success, the current filehandle retains its value.

   IMPLEMENTATION

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

             PUTFH  (directory filehandle)
             LOOKUP (entry name)
             GETFH

   ERRORS

     NFS4ERR_BADHANDLE
     NFS4ERR_FHEXPIRED
     NFS4ERR_MOVED

Expires: December 2000                                        [Page 124]
Draft Specification      NFS version 4 Protocol                June 2000

     NFS4ERR_NOFILEHANDLE
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 125]
Draft Specification      NFS version 4 Protocol                June 2000

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

   SYNOPSIS

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

   ARGUMENT

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

   RESULT

     struct LINK4resok {
             change_info4    cinfo;
     };

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

   DESCRIPTION

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

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

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

   IMPLEMENTATION

Expires: December 2000                                        [Page 126]
Draft Specification      NFS version 4 Protocol                June 2000

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

     The comments under RENAME regarding object and target residing on
     the same file system apply here as well. The comments regarding the
     target name applies as well.

     Note that symbolic links are created with the CREATE operation.

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_DELAY
     NFS4ERR_DQUOT
     NFS4ERR_EXIST
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_ISDIR
     NFS4ERR_MLINK
     NFS4ERR_MOVED
     NFS4ERR_NAMETOOLONG
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOSPC
     NFS4ERR_NOTDIR
     NFS4ERR_NOTSUPP
     NFS4ERR_RESOURCE
     NFS4ERR_ROFS
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC
     NFS4ERR_XDEV

Expires: December 2000                                        [Page 127]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.10.  Operation 12: LOCK - Create Lock

   SYNOPSIS

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

   ARGUMENT

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

     struct LOCK4args {
             /* CURRENT_FH: file */
             nfs_lock_type4  locktype;
             seqid4          seqid;
             bool            reclaim;
             stateid4        stateid;
             offset4         offset;
             length4         length;
     };

   RESULT

     struct LOCK4denied {
             nfs_lockowner4  owner;
             offset4         offset;
             length4         length;
     };

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

   DESCRIPTION

     The LOCK operation requests a record lock for the byte range
     specified by the offset and length parameters.  The lock type is
     also specified to be one of the nfs4_lock_types.  If this is a

Expires: December 2000                                        [Page 128]
Draft Specification      NFS version 4 Protocol                June 2000

     reclaim request, the reclaim parameter will be TRUE;

     Bytes in a file may be locked even if those bytes are not currently
     allocated to the file.  To lock the file from a specific offset
     through the end-of-file (no matter how long the file actually is)
     use a length field with all bits set to 1 (one).  To lock the
     entire file, use an offset of 0 (zero) and a length with all bits
     set to 1.  A length of 0 is reserved and should not be used.

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

     On success, the current filehandle retains its value.

   IMPLEMENTATION

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

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_BAD_SEQID
     NFS4ERR_BAD_STATEID
     NFS4ERR_DELAY
     NFS4ERR_DENIED
     NFS4ERR_EXPIRED
     NFS4ERR_FHEXPIRED
     NFS4ERR_GRACE
     NFS4ERR_INVAL
     NFS4ERR_ISDIR
     NFS4ERR_LEASE_MOVED
     NFS4ERR_LOCK_RANGE
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_OLD_STATEID
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_STALE_CLIENTID
     NFS4ERR_STALE_STATEID
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 129]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.11.  Operation 13: LOCKT - Test For Lock

   SYNOPSIS

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

   ARGUMENT

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

   RESULT

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

   DESCRIPTION

     The LOCKT operation tests the lock as specified in the arguments.
     If a conflicting lock exists, the owner, offset, and length of the
     conflicting lock are returned; if no lock is held, nothing other
     than NFS4_OK is returned.

     On success, the current filehandle retains its value.

   IMPLEMENTATION

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

     LOCKT uses nfs_lockowner4 instead of a stateid4, as LOCK does, to
     identify the owner so that the client does not have to open the

Expires: December 2000                                        [Page 130]
Draft Specification      NFS version 4 Protocol                June 2000

     file to test for the existence of a lock.

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_DELAY
     NFS4ERR_DENIED
     NFS4ERR_FHEXPIRED
     NFS4ERR_GRACE
     NFS4ERR_INVAL
     NFS4ERR_ISDIR
     NFS4ERR_LEASE_MOVED
     NFS4ERR_LOCK_RANGE
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_STALE_CLIENTID
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 131]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.12.  Operation 14: LOCKU - Unlock File

   SYNOPSIS

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

   ARGUMENT

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

   RESULT

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

   DESCRIPTION

     The LOCKU operation unlocks the record lock specified by the
     parameters.

     On success, the current filehandle retains its value.

   IMPLEMENTATION

     The File Locking section contains a full description of this and
     the other file locking procedures.

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_BAD_SEQID
     NFS4ERR_BAD_STATEID
     NFS4ERR_EXPIRED
     NFS4ERR_FHEXPIRED
     NFS4ERR_GRACE

Expires: December 2000                                        [Page 132]
Draft Specification      NFS version 4 Protocol                June 2000

     NFS4ERR_INVAL
     NFS4ERR_LOCK_RANGE
     NFS4ERR_LEASE_MOVED
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_OLD_STATEID
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_STALE_CLIENTID
     NFS4ERR_STALE_STATEID

Expires: December 2000                                        [Page 133]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.13.  Operation 15: LOOKUP - Lookup Filename

   SYNOPSIS

     (cfh), filenames -> (cfh)

   ARGUMENT

     struct LOOKUP4args {
             /* CURRENT_FH: directory */
             pathname4       path;
     };

   RESULT

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

   DESCRIPTION

     This operation LOOKUPs or finds a file system object starting from
     the directory specified by the current filehandle.  LOOKUP
     evaluates the pathname contained in the array of names and obtains
     a new current filehandle from the final name.  All but the final
     name in the list must be the names of directories.

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

     If the path is a zero length array, if any component does not obey
     the UTF-8 definition, or if any component in the path is of zero
     length, the error NFS4ERR_INVAL will be returned.

   IMPLEMENTATION

     If the client prefers a partial evaluation of the path then a
     sequence of LOOKUP operations can be substituted e.g.

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

Expires: December 2000                                        [Page 134]
Draft Specification      NFS version 4 Protocol                June 2000

     or, if the client wishes to obtain the intermediate filehandles

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

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

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

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

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

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

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_MOVED
     NFS4ERR_NAMETOOLONG
     NFS4ERR_NOENT

Expires: December 2000                                        [Page 135]
Draft Specification      NFS version 4 Protocol                June 2000

     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOTDIR
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_SYMLINK
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 136]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.14.  Operation 16: LOOKUPP - Lookup Parent Directory

   SYNOPSIS

     (cfh) -> (cfh)

   ARGUMENT

     /* CURRENT_FH: object */
     void;

   RESULT

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

   DESCRIPTION

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

   IMPLEMENTATION

     As for LOOKUP, LOOKUPP will also cross mountpoints.

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

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_MOVED
     NFS4ERR_NOENT
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOTDIR
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE

Expires: December 2000                                        [Page 137]
Draft Specification      NFS version 4 Protocol                June 2000

     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 138]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.15.  Operation 17: NVERIFY - Verify Difference in Attributes

   SYNOPSIS

     (cfh), fattr -> -

   ARGUMENT

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

   RESULT

     struct NVERIFY4res {
             nfsstat4        status;
     };

   DESCRIPTION

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

     On success, the current filehandle retains its value.

   IMPLEMENTATION

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

             PUTFH  (public)
             LOOKUP "pub" "foo" "bar"
             NVERIFY attrbits attrs
             READ 0 32767

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

Expires: December 2000                                        [Page 139]
Draft Specification      NFS version 4 Protocol                June 2000

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_DELAY
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOTSUPP
     NFS4ERR_RESOURCE
     NFS4ERR_SAME
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 140]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.16.  Operation 18: OPEN - Open a Regular File

   SYNOPSIS

     (cfh), claim, openhow, owner, seqid, access, deny -> (cfh),
     stateid, cinfo, rflags, open_confirm, delegation

   ARGUMENT

     struct OPEN4args {
             open_claim4     claim;
             openflag4       openhow;
             nfs_lockowner4  owner;
             seqid4          seqid;
             uint32_t        share_access;
             uint32_t        share_deny;
     };

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

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

Expires: December 2000                                        [Page 141]
Draft Specification      NFS version 4 Protocol                June 2000

     struct nfs_modified_limit4 {
             uint32_t        num_blocks;
             uint32_t        bytes_per_block;
     };

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

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

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

     struct open_claim_delegate_cur4 {
             pathname4       file;
             stateid4        delegate_stateid;
     };

     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 */
              pathname4      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 */
              uint32_t        delegate_type;

      /*
       * Right to file based on a delegation granted by the server.
       * File is specified by name.

Expires: December 2000                                        [Page 142]
Draft Specification      NFS version 4 Protocol                June 2000

       */
      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 */
              pathname4      file_delegate_prev;
     };

   RESULT

     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;

Expires: December 2000                                        [Page 143]
Draft Specification      NFS version 4 Protocol                June 2000

             case OPEN_DELEGATE_WRITE:
                     open_write_delegation4 write;
     };

     const OPEN4_RESULT_MLOCK        = 0x00000001;
     const OPEN4_RESULT_CONFIRM= 0x00000002;

     struct OPEN4resok {
             stateid4        stateid;        /* Stateid for open */
             change_info4    cinfo;          /* Directory Change Info */
             uint32_t        rflags;         /* Result flags */
             verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
             open_delegation4 delegation;    /* Info on any open
                                                delegation */
     };

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

   WARNING TO CLIENT IMPLEMENTORS

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

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

   DESCRIPTION

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

     UNCHECKED means that the file should be created if a file of that
     name does not exist and encountering an existing regular file of

Expires: December 2000                                        [Page 144]
Draft Specification      NFS version 4 Protocol                June 2000

     that name is not an error.  For this type of create, createattrs
     specifies the initial set of attributes for the file.  The set of
     attributes may includes any writable attribute valid for regular
     files.  When an UNCHECKED create encounters an existing file, the
     attributes specified by createattrs is not used, except that when
     an object_size of zero is specified, the existing file is
     truncated.  If GUARDED is specified, the server checks for the
     presence of a duplicate object by name before performing the
     create.  If a duplicate exists, an error of NFS4ERR_EXIST is
     returned as the status.  If the object does not exist, the request
     is performed as described for UNCHECKED.

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

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

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

     The OPEN procedure provides for DOS SHARE capability with the use
     of the access and deny fields of the OPEN arguments.  The client
     specifies at OPEN the required access and deny modes.  For clients
     that do not directly support SHAREs (i.e. Unix), the expected deny
     value is DENY_NONE.  In the case that there is a existing SHARE
     reservation that conflicts with the OPEN request, the server
     returns the error NFS4ERR_DENIED.  For a complete SHARE request,
     the client must provide values for the owner and seqid fields for
     the OPEN argument.  For additional discussion of SHARE semantics
     see the section on 'Share Reservations'.

     In the case that the client is recovering state from a server
     failure, the reclaim field of the OPEN argument is used to signify
     that the request is meant to reclaim state previously held.

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

Expires: December 2000                                        [Page 145]
Draft Specification      NFS version 4 Protocol                June 2000

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

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

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

     CLAIM_DELEGATE_PREV
                           The client is claiming a delegation
                           granted to a previous client instance;
                           used after the client reboots.

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

     For any OPEN request, the server may return an open delegation,
     which allows further opens and closes to be handled locally on the
     client as described in the section Open Delegation.  Note that
     delegation is up to the server to decide.  The client should never
     assume that delegation will or will not be granted in a particular
     instance.  It should always be prepared for either case.  A partial
     exception is the reclaim (CLAIM_PREVIOUS) case, in which a
     delegation type is claimed.  In this case, delegation will always
     be granted, although the server may specify an immediate recall in
     the delegation structure.

     The rflags returned by a successful OPEN allow the server to return
     information governing how the open file is to be handled.
     OPEN4_RESULT_MLOCK indicates to the caller that mandatory locking
     is in effect for this file and the client should act appropriately
     with regard to data cached on the client.  OPEN4_RESULT_CONFIRM
     indicates that the client MUST execute an OPEN_CONFIRM operation
     before using the open file.

     If the file is a zero length array, if any component does not obey
     the UTF-8 definition, or if any component in the path is of zero
     length, the error NFS4ERR_INVAL will be returned.

     When an OPEN is done and the specified lockowner already has the
     resulting filehandle open, the result is to "OR" together the new
     share and deny status together with the existing status.  In this

Expires: December 2000                                        [Page 146]
Draft Specification      NFS version 4 Protocol                June 2000

     case, only a single CLOSE need be done, even though multiple OPEN's
     were completed.

   IMPLEMENTATION

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

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

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

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

     Once the client has performed a successful exclusive create, it
     must issue a SETATTR to set the correct object attributes.  Until
     it does so, it should not rely upon any of the object attributes,

Expires: December 2000                                        [Page 147]
Draft Specification      NFS version 4 Protocol                June 2000

     since the server implementation may need to overload object meta-
     data to store the verifier.  The subsequent SETATTR must not occur
     in the same COMPOUND request as the OPEN.  This separation will
     guarantee that the exclusive create mechanism will continue to
     function properly in the face of retransmission of the request.

     Use of the GUARDED attribute does not provide exactly-once
     semantics.  In particular, if a reply is lost and the server does
     not detect the retransmission of the request, the procedure can
     fail with NFS4ERR_EXIST, even though the create was performed
     successfully.

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

     If the final component provided to OPEN is a symbolic link, the
     error NFS4ERR_SYMLINK will be returned to the client.  If an
     intermediate component of the pathname provided to OPEN is a
     symbolic link, the error NFS4ERR_NOTDIR will be returned to the
     client.

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BAD_SEQID
     NFS4ERR_DELAY
     NFS4ERR_DQUOT
     NFS4ERR_EXIST
     NFS4ERR_FHEXPIRED
     NFS4ERR_GRACE
     NFS4ERR_IO
     NFS4ERR_LEASE_MOVED
     NFS4ERR_MOVED
     NFS4ERR_NAMETOOLONG
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOSPC
     NFS4ERR_NOTDIR
     NFS4ERR_NOTSUPP
     NFS4ERR_RESOURCE
     NFS4ERR_ROFS
     NFS4ERR_SERVERFAULT
     NFS4ERR_SHARE_DENIED
     NFS4ERR_STALE_CLIENTID
     NFS4ERR_SYMLINK

Expires: December 2000                                        [Page 148]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.17.  Operation 19: OPENATTR - Open Named Attribute Directory

   SYNOPSIS

     (cfh) -> (cfh)

   ARGUMENT

     /* CURRENT_FH: file or directory */
     void;

   RESULT

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

   DESCRIPTION

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

   IMPLEMENTATION

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

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_DELAY
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_MOVED
     NFS4ERR_NOENT
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOTSUPP

Expires: December 2000                                        [Page 149]
Draft Specification      NFS version 4 Protocol                June 2000

     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 150]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.18.  Operation 20: OPEN_CONFIRM - Confirm Open

   SYNOPSIS

     (cfh), seqid, open_confirm-> stateid

   ARGUMENT

     struct OPEN_CONFIRM4args {
             /* CURRENT_FH: opened file */
             seqid4          seqid;
             verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
     };

   RESULT

     struct OPEN_CONFIRM4resok {
             stateid4        stateid;
     };

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

   DESCRIPTION

     This operation is used to confirm the sequence id usage for the
     first time that a nfs_lockowner is used by a client.  The OPEN
     operation returns a opaque confirmation verifier that is then
     passed to this operation along with the next sequence id for the
     nfs_lockowner.  The sequence id passed to the OPEN_CONFIRM must be
     1 (one) greater than the seqid passed to the OPEN operation from
     which the open_confirm value was obtained.  If the server receives
     an unexpected sequence id with respect to the original open, then
     the server assumes that the client will not confirm the original
     OPEN and all state associated with the original OPEN is released by
     the server.

     On success, the current filehandle retains its value.

   IMPLEMENTATION

     A given client might generate many nfs_lockowner data structures
     for a given clientid.  The client will periodically either dispose
     of its nfs_lockowners or stop using them for indefinite periods of

Expires: December 2000                                        [Page 151]
Draft Specification      NFS version 4 Protocol                June 2000

     time.  The latter situation is why the NFS version 4 protocol does
     not have a an explicit operation to exit an nfs_lockowner: such an
     operation is of no use in that situation.  Instead, to avoid
     unbounded memory use, the server needs to implement a strategy for
     disposing of nfs_lockowners that have no current lock, open, or
     delegation state for any files and have not been used recently.
     The time period used to determine when to dispose of nfs_lockowners
     is an implementation choice.  The time period should certainly be
     no less than the lease time plus any grace period the server wishes
     to implement beyond a lease time.  The OPEN_CONFIRM operation
     allows the server to safely dispose of unused nfs_lockowner data
     structures.

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

     A lazy server implementation might require confirmation for every
     nfs_lockowner for which it has no record.  However, this is not
     necessary until the server records the fact that it has disposed of
     one nfs_lockowner for the given clientid.

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

     Second, the client sends another OPEN request with a sequence id
     that is incorrect for the nfs_lockowner (out of sequence).  In this
     case, the server assumes the second OPEN request is valid and the
     first one is a replay.  The server cancels the OPEN state of the
     first OPEN request, establishes an unconfirmed OPEN state for the
     second OPEN request, and responds to the second OPEN request with
     an indication that an OPEN_CONFIRM is needed.  The process then
     repeats itself.  While there is a potential for a denial of service
     attack on the client, it is mitigated if the client and server
     require the use of a security flavor based on Kerberos V5, LIPKEY,
     or some other flavor that uses cryptography.

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

     Third, neither of the two aforementioned events occur for the
     nfs_lockowner within the lease period.  In this case, the OPEN

Expires: December 2000                                        [Page 152]
Draft Specification      NFS version 4 Protocol                June 2000

     state is cancelled and disposal of the nfs_lockowner can occur.

   ERRORS

     NFS4ERR_BADHANDLE
     NFS4ERR_BAD_SEQID
     NFS4ERR_EXPIRED
     NFS4ERR_FHEXPIRED
     NFS4ERR_GRACE
     NFS4ERR_INVAL
     NFS4ERR_MOVED
     NFS4ERR_NOENT
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOTSUPP
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 153]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.19.  Operation 21: OPEN_DOWNGRADE - Reduce Open File Access

   SYNOPSIS

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

   ARGUMENT

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

   RESULT

     struct OPEN_DOWNGRADE4resok {
             stateid4        stateid;
     };

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

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

   The access and deny bits specified in this operation replace the
   current ones for the specified open file.  If either the access or
   the deny mode specified includes bits not in effect for the open, the
   error NFS4ERR_INVAL should be returned.  Since access and deny bits
   are subsets of those already granted, it is not possible for this
   request to be denied because of conflicting share reservations.

   On success, the current filehandle retains its value.

   ERRORS

     NFS4ERR_BADHANDLE

Expires: December 2000                                        [Page 154]
Draft Specification      NFS version 4 Protocol                June 2000

     NFS4ERR_BAD_SEQID
     NFS4ERR_BAD_STATEID
     NFS4ERR_EXPIRED
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_OLD_STATEID
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_STALE_STATEID

Expires: December 2000                                        [Page 155]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.20.  Operation 22: PUTFH - Set Current Filehandle

   SYNOPSIS

     filehandle -> (cfh)

   ARGUMENT

     struct PUTFH4args {
             nfs4_fh         object;
     };

   RESULT

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

   DESCRIPTION

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

   IMPLEMENTATION

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

   ERRORS

     NFS4ERR_BADHANDLE
     NFS4ERR_FHEXPIRED
     NFS4ERR_MOVED
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 156]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.21.  Operation 23: PUTPUBFH - Set Public Filehandle

   SYNOPSIS

     - -> (cfh)

   ARGUMENT

     void;

   RESULT

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

   DESCRIPTION

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

   IMPLEMENTATION

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

   ERRORS

     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 157]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.22.  Operation 24: PUTROOTFH - Set Root Filehandle

   SYNOPSIS

     - -> (cfh)

   ARGUMENT

     void;

   RESULT

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

   DESCRIPTION

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

   IMPLEMENTATION

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

   ERRORS

     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 158]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.23.  Operation 25: READ - Read from File

   SYNOPSIS

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

   ARGUMENT

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

   RESULT

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

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

   DESCRIPTION

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

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

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

     The stateid value for a READ request represents a value returned

Expires: December 2000                                        [Page 159]
Draft Specification      NFS version 4 Protocol                June 2000

     from a previous record lock or share reservation request.  Used by
     the server to verify that the associated lock is still valid and to
     update lease timeouts for the client.

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

     On success, the current filehandle retains its value.

   IMPLEMENTATION

     It is possible for the server to return fewer than count bytes of
     data.  If the server returns less than the count requested and eof
     set to FALSE, the client should issue another READ to get the
     remaining data.  A server may return less data than requested under
     several circumstances.  The file may have been truncated by another
     client or perhaps on the server itself, changing the file size from
     what the requesting client believes to be the case.  This would
     reduce the actual amount of data available to the client.  It is
     possible that the server may back off the transfer size and reduce
     the read request return.  Server resource exhaustion may also occur
     necessitating a smaller read return.

     If the file is locked the server will return an NFS4ERR_LOCKED
     error.  Since the lock may be of short duration, the client may
     choose to retransmit the READ request (with exponential backoff)
     until the operation succeeds.

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_BAD_STATEID
     NFS4ERR_DELAY
     NFS4ERR_DENIED
     NFS4ERR_EXPIRED
     NFS4ERR_FHEXPIRED
     NFS4ERR_GRACE
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_LOCKED
     NFS4ERR_LEASE_MOVED
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NXIO
     NFS4ERR_OLD_STATEID

Expires: December 2000                                        [Page 160]
Draft Specification      NFS version 4 Protocol                June 2000

     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_STALE_STATEID
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 161]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.24.  Operation 26: READDIR - Read Directory

   SYNOPSIS
      (cfh), cookie, cookieverf, dircount, maxcount, attrbits ->
      cookieverf { cookie, filename, attrbits, attributes }

   ARGUMENT

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

   RESULT

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

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

     struct READDIR4resok {
             verifier4       cookieverf;
             dirlist4        reply;
     };

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

   DESCRIPTION

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

Expires: December 2000                                        [Page 162]
Draft Specification      NFS version 4 Protocol                June 2000

     additional directory entries in a subsequent READDIR.

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

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

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

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

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

     On successful return, the server's response will provide a list of
     directory entries.  Each of these entries contains the name of the
     directory entry, a cookie value for that entry, and the associated
     attributes as requested.

     The cookie value is only meaningful to the server and is used as a
     "bookmark" for the directory entry.  As mentioned, this cookie is
     used by the client for subsequent READDIR operations so that it may
     continue reading a directory.  The cookie is similar in concept to
     a READ offset but should not be interpreted as such by the client.
     Ideally, the cookie value should not change if the directory is
     modified since the client may be caching these values.

     In some cases, the server may encounter an error while obtaining
     the attributes for a directory entry.  Instead of returning an
     error for the entire READDIR operation, the server can instead
     return the attribute 'fattr4_rdattr_error'.  With this, the server
     is able to communicate the failure to the client and not fail the
     entire operation in the instance of what might be a transient

Expires: December 2000                                        [Page 163]
Draft Specification      NFS version 4 Protocol                June 2000

     failure.  Obviously, the client must request the
     fattr4_rdattr_error attribute for this method to work properly.  If
     the client does not request the attribute, the server has no choice
     but to return failure for the entire READDIR operation.

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

     For READDIR arguments, cookie values of 1 and 2 should not be used
     and for READDIR results cookie values of 0, 1, and 2 should not
     returned.

     On success, the current filehandle retains its value.

   IMPLEMENTATION

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

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

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

Expires: December 2000                                        [Page 164]
Draft Specification      NFS version 4 Protocol                June 2000

     underlying directory has changed and the response is invalid from
     the client's context of its previous READDIR.

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

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_BAD_COOKIE
     NFS4ERR_DELAY
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOTDIR
     NFS4ERR_NOTSUPP
     NFS4ERR_READDIR_NOSPC
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_TOOSMALL
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 165]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.25.  Operation 27: READLINK - Read Symbolic Link

   SYNOPSIS

     (cfh) -> linktext

   ARGUMENT

     /* CURRENT_FH: symlink */
     void;

   RESULT

     struct READLINK4resok {
             linktext4       link;
     };

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

   DESCRIPTION

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

     On success, the current filehandle retains its value.

   IMPLEMENTATION

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

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

Expires: December 2000                                        [Page 166]
Draft Specification      NFS version 4 Protocol                June 2000

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_DELAY
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOTSUPP
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 167]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.26.  Operation 28: REMOVE - Remove Filesystem Object

   SYNOPSIS

     (cfh), filename -> change_info

   ARGUMENT

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

   RESULT

     struct REMOVE4resok {
             change_info4    cinfo;
     }

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

   DESCRIPTION

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

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

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

     On success, the current filehandle retains its value.

   IMPLEMENTATION

     NFS versions 2 and 3 required a different operator RMDIR for

Expires: December 2000                                        [Page 168]
Draft Specification      NFS version 4 Protocol                June 2000

     directory removal.  NFS version 4 REMOVE can be used to delete any
     directory entry independent of its file type.

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

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_DELAY
     NFS4ERR_FHEXPIRED
     NFS4ERR_IO
     NFS4ERR_MOVED
     NFS4ERR_NAMETOOLONG
     NFS4ERR_NOENT
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOTDIR
     NFS4ERR_NOTEMPTY
     NFS4ERR_NOTSUPP
     NFS4ERR_RESOURCE
     NFS4ERR_ROFS
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 169]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.27.  Operation 29: RENAME - Rename Directory Entry

   SYNOPSIS

     (sfh), oldname (cfh), newname -> source_change_info,
     target_change_info

   ARGUMENT

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

   RESULT

     struct RENAME4resok {
             change_info4    source_cinfo;
             change_info4    target_cinfo;
     };

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

   DESCRIPTION

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

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

     If oldname and newname both refer to the same file (they might be

Expires: December 2000                                        [Page 170]
Draft Specification      NFS version 4 Protocol                June 2000

     hard links of each other), then RENAME should perform no action and
     return success.

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

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

   IMPLEMENTATION

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

     A filehandle may or may not become stale or expire on a rename.
     However, server implementors are strongly encouraged to attempt to
     keep file handles from becoming stale or expiring in this fashion.

     On some servers, the filenames, "." and "..", are illegal as either
     oldname or newname.  In addition, neither oldname nor newname can
     be an alias for the source directory.  These servers will return
     the error, NFS4ERR_INVAL, in these cases.

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_DELAY
     NFS4ERR_DQUOT
     NFS4ERR_EXIST
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_ISDIR
     NFS4ERR_MOVED
     NFS4ERR_NAMETOOLONG
     NFS4ERR_NOENT
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOSPC
     NFS4ERR_NOTDIR
     NFS4ERR_NOTEMPTY
     NFS4ERR_NOTSUPP

Expires: December 2000                                        [Page 171]
Draft Specification      NFS version 4 Protocol                June 2000

     NFS4ERR_RESOURCE
     NFS4ERR_ROFS
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC
     NFS4ERR_XDEV

Expires: December 2000                                        [Page 172]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.28.  Operation 30: RENEW - Renew a Lease

   SYNOPSIS

     stateid -> ()

   ARGUMENT

     struct RENEW4args {
             stateid4        stateid;
     };

   RESULT

     struct RENEW4res {
             nfsstat4        status;
     };

   DESCRIPTION

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

     The stateid for RENEW may not be one of the special stateids
     consisting of all bits 0 (zero) or all bits 1.

   IMPLEMENTATION

   ERRORS

     NFS4ERR_BAD_STATEID
     NFS4ERR_EXPIRED
     NFS4ERR_GRACE
     NFS4ERR_INVAL
     NFS4ERR_LEASE_MOVED
     NFS4ERR_MOVED
     NFS4ERR_OLD_STATEID
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE_STATEID
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 173]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.29.  Operation 31: RESTOREFH - Restore Saved Filehandle

   SYNOPSIS

     (sfh) -> (cfh)

   ARGUMENT

     /* SAVED_FH: */
     void;

   RESULT

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

   DESCRIPTION

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

   IMPLEMENTATION

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

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

   ERRORS

     NFS4ERR_BADHANDLE
     NFS4ERR_FHEXPIRED
     NFS4ERR_MOVED

Expires: December 2000                                        [Page 174]
Draft Specification      NFS version 4 Protocol                June 2000

     NFS4ERR_NOFILEHANDLE
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 175]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.30.  Operation 32: SAVEFH - Save Current Filehandle

   SYNOPSIS

     (cfh) -> (sfh)

   ARGUMENT

     /* CURRENT_FH: */
     void;

   RESULT

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

   DESCRIPTION

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

     On success, the current filehandle retains its value.

   IMPLEMENTATION

   ERRORS

     NFS4ERR_BADHANDLE
     NFS4ERR_FHEXPIRED
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 176]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.31.  Operation 33: SECINFO - Obtain Available Security

   SYNOPSIS

     (cfh), name -> { secinfo }

   ARGUMENT

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

   RESULT

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

     struct secinfo4 {
             uint32_t flavor;
             opaque flavor_info<>;   /* null for AUTH_SYS, AUTH_NONE;
                                        contains rpcsec_gss_info for
                                        RPCSEC_GSS. */
     };

     typedef secinfo4 SECINFO4resok<>;

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

   DESCRIPTION

     The SECINFO operation is used by the client to obtain a list of
     valid RPC authentication flavors for a specific file handle, file
     name pair.  The result will contain an array which represents the

Expires: December 2000                                        [Page 177]
Draft Specification      NFS version 4 Protocol                June 2000

     security mechanisms available.  The array entries are represented
     by the secinfo4 structure.  The field 'flavor' will contain a value
     of AUTH_NONE, AUTH_SYS (as defined in [RFC1831]), or RPCSEC_GSS (as
     defined in [RFC2203]).

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

     On success, the current filehandle retains its value.

   IMPLEMENTATION

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

     It is recommended that the client issue the SECINFO call protected
     by a security triple that uses either rpc_gss_svc_integrity or
     rpc_gss_svc_privacy service. The use of rpc_gss_svc_none would
     allow an attacker in the middle to modify the SECINFO 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.

   ERRORS

     NFS4ERR_BADHANDLE
     NFS4ERR_FHEXPIRED
     NFS4ERR_MOVED
     NFS4ERR_NAMETOOLONG
     NFS4ERR_NOENT
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOTDIR
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 178]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.32.  Operation 34: SETATTR - Set Attributes

   SYNOPSIS

     (cfh), attrbits, attrvals -> -

   ARGUMENT

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

   RESULT

     struct SETATTR4res {
             nfsstat4        status;
             bitmap4         attrsset;
     };

   DESCRIPTION

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

     The stateid is necessary for SETATTRs that change the size of a
     file (modify the attribute object_size).  This stateid represents a
     record lock, share reservation, or delegation which must be valid
     for the SETATTR to modify the file data.  A valid stateid would
     always be specified.  When the file size is not changed, the
     special stateid consisting of all bits 0 (zero) should be used.

     On either success or failure of the operation, the server will
     return the attrsset bitmask to represent what (if any) attributes
     were successfully set.

     On success, the current filehandle retains its value.

   IMPLEMENTATION

     The file size attribute is used to request changes to the size of a
     file. A value of 0 (zero) causes the file to be truncated, a value
     less than the current size of the file causes data from new size to
     the end of the file to be discarded, and a size greater than the
     current size of the file causes logically zeroed data bytes to be
     added to the end of the file.  Servers are free to implement this

Expires: December 2000                                        [Page 179]
Draft Specification      NFS version 4 Protocol                June 2000

     using holes or actual zero data bytes. Clients should not make any
     assumptions regarding a server's implementation of this feature,
     beyond that the bytes returned will be zeroed.  Servers must
     support extending the file size via SETATTR.

     SETATTR is not guaranteed atomic.  A failed SETATTR may partially
     change a file's attributes.

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

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

     If the server cannot successfully set all the attributes it must
     return an NFS4ERR_INVAL error.  If the server can only support 32
     bit offsets and sizes, a SETATTR request to set the size of a file
     to larger than can be represented in 32 bits will be rejected with
     this same error.

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_BAD_STATEID
     NFS4ERR_DELAY
     NFS4ERR_DENIED
     NFS4ERR_DQUOT
     NFS4ERR_EXPIRED
     NFS4ERR_FBIG
     NFS4ERR_FHEXPIRED
     NFS4ERR_GRACE
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOSPC
     NFS4ERR_NOTSUPP
     NFS4ERR_OLD_STATEID
     NFS4ERR_PERM
     NFS4ERR_RESOURCE
     NFS4ERR_ROFS
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_STALE_STATEID
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 180]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.33.  Operation 35: SETCLIENTID - Negotiate Clientid

   SYNOPSIS

     client, callback -> clientid, setclientid_confirm

   ARGUMENT

     struct SETCLIENTID4args {
             nfs_client_id4  client;
             cb_client4      callback;
     };

   RESULT

     struct SETCLIENTID4resok {
             clientid4       clientid;
             verifier4       setclientid_confirm;
     };

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

   DESCRIPTION

     The SETCLIENTID operation introduces the ability of the client to
     notify the server of its intention to use a particular client
     identifier and verifier pair.  Upon successful completion the
     server will return a clientid which is used in subsequent file
     locking requests and a confirmation verifier.  The client will use
     the SETCLIENTID_CONFIRM operation to return the verifier to the
     server.  At that point, the client may use the clientid in
     subsequent operations that require an nfs_lockowner.

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

   IMPLEMENTATION

     The server takes the verifier and client identification supplied in

Expires: December 2000                                        [Page 181]
Draft Specification      NFS version 4 Protocol                June 2000

     the nfs_client_id4 and searches for a match of the client
     identification.  If no match is found the server saves the
     principal/uid information along with the verifier and client
     identification and returns a unique clientid that is used as a
     shorthand reference to the supplied information.

     If the server finds matching client identification and a
     corresponding match in principal/uid, the server releases all
     locking state for the client and returns a new clientid.

     The principal, or principal to user-identifier mapping is taken
     from the credential presented in the RPC.  As mentioned, the server
     will use the credential and associated principal for the matching
     with existing clientids.  If the client is a traditional host-based
     client like a Unix NFS client, then the credential presented may be
     the host credential.  If the client is a user level client or
     lightweight client, the credential used may be the end user's
     credential.  The client should take care in choosing an appropriate
     credential since denial of service attacks could be attempted by a
     rogue client that has access to the credential.

   ERRORS

     NFS4ERR_CLID_INUSE
     NFS4ERR_INVAL
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT

Expires: December 2000                                        [Page 182]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.34.  Operation 36: SETCLIENTID_CONFIRM - Confirm Clientid

   SYNOPSIS

     setclientid_confirm -> -

   ARGUMENT

     struct SETCLIENTID_CONFIRM4args {
             verifier4       setclientid_confirm;
     };

   RESULT

     struct SETCLIENTID_CONFIRM4res {
             nfsstat4        status;
     };

   DESCRIPTION

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

   IMPLEMENTATION

     The client must use the SETCLIENTID_CONFIRM operation to confirm
     its use of client identifier.  If the server is holding state for a
     client which has presented a new verifier via SETCLIENTID, then the
     state will not be released, as described in the section "Client
     Failure and Recovery", until a valid SETCLIENTID_CONFIRM is
     received.  Upon successful confirmation the server will release the
     previous state held on behalf of the client.  The server should
     choose a confirmation cookie value that is reasonably unique for
     the client.

   ERRORS

     NFS4ERR_CLID_INUSE
     NFS4ERR_INVAL
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE_CLIENTID

Expires: December 2000                                        [Page 183]
Draft Specification      NFS version 4 Protocol                June 2000

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)

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

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

Expires: December 2000                                        [Page 184]
Draft Specification      NFS version 4 Protocol                June 2000

     client.

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_DELAY
     NFS4ERR_FHEXPIRED
     NFS4ERR_INVAL
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOTSUPP
     NFS4ERR_NOT_SAME
     NFS4ERR_RESOURCE
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 185]
Draft Specification      NFS version 4 Protocol                June 2000

14.2.36.  Operation 38: WRITE - Write to File

   SYNOPSIS

     (cfh), offset, count, stability, stateid, data -> count, committed,
     verifier

   ARGUMENT

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

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

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

Expires: December 2000                                        [Page 186]
Draft Specification      NFS version 4 Protocol                June 2000

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

     The stateid returned from a previous record lock or share
     reservation request is provided as part of the argument.  The
     stateid is used by the server to verify that the associated lock is
     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, verf.  The
     write verifier is a cookie that the client can use to determine
     whether the server has changed 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

Expires: December 2000                                        [Page 187]
Draft Specification      NFS version 4 Protocol                June 2000

     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.

     On success, the current filehandle retains its value.

   IMPLEMENTATION

     It is possible for the server to write fewer than count bytes of
     data.  In this case, the server should not return an error unless
     no data was written at all.  If the server writes less than count
     bytes, 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.

Expires: December 2000                                        [Page 188]
Draft Specification      NFS version 4 Protocol                June 2000

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

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

     Some implementations may return NFS4ERR_NOSPC instead of
     NFS4ERR_DQUOT when a user's quota is exceeded.

   ERRORS

     NFS4ERR_ACCES
     NFS4ERR_BADHANDLE
     NFS4ERR_BAD_STATEID
     NFS4ERR_DELAY
     NFS4ERR_DENIED
     NFS4ERR_DQUOT
     NFS4ERR_EXPIRED
     NFS4ERR_FBIG
     NFS4ERR_FHEXPIRED
     NFS4ERR_GRACE
     NFS4ERR_INVAL
     NFS4ERR_IO
     NFS4ERR_LEASE_MOVED
     NFS4ERR_LOCKED
     NFS4ERR_MOVED
     NFS4ERR_NOFILEHANDLE
     NFS4ERR_NOSPC
     NFS4ERR_OLD_STATEID
     NFS4ERR_RESOURCE
     NFS4ERR_ROFS
     NFS4ERR_SERVERFAULT
     NFS4ERR_STALE
     NFS4ERR_STALE_STATEID
     NFS4ERR_WRONGSEC

Expires: December 2000                                        [Page 189]
Draft Specification      NFS version 4 Protocol                June 2000

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.

Expires: December 2000                                        [Page 190]
Draft Specification      NFS version 4 Protocol                June 2000

15.2.  Procedure 1: CB_COMPOUND - Compound Operations

   SYNOPSIS

     compoundargs -> compoundres

   ARGUMENT

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

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

     struct CB_COMPOUND4args {
             utf8string      tag;
             uint32_t        minorversion;
             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;
             utf8string      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.

     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

Expires: December 2000                                        [Page 191]
Draft Specification      NFS version 4 Protocol                June 2000

     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.

   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_RESOURCE

Expires: December 2000                                        [Page 192]
Draft Specification      NFS version 4 Protocol                June 2000

15.2.1.  Operation 3: CB_GETATTR - Get Attributes

   SYNOPSIS

     fh, attrbits -> attrbits, attrvals

   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 to obtain the attributes modified
     by an open delegate to allow the server to respond to GETATTR
     requests for a file which is the subject of an open delegation.

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

   IMPLEMENTATION

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

   ERRORS

     NFS4ERR_BADHANDLE
     NFS4ERR_RESOURCE

Expires: December 2000                                        [Page 193]
Draft Specification      NFS version 4 Protocol                June 2000

15.2.2.  Operation 4: CB_RECALL - Recall an Open Delegation

   SYNOPSIS

     stateid, truncate, fh -> status

   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.

   IMPLEMENTATION

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

   ERRORS

     NFS4ERR_BADHANDLE
     NFS4ERR_BAD_STATEID

Expires: December 2000                                        [Page 194]
Draft Specification      NFS version 4 Protocol                June 2000

     NFS4ERR_RESOURCE

Expires: December 2000                                        [Page 195]
Draft Specification      NFS version 4 Protocol                June 2000

16.  Security Considerations

   The major security feature to consider is the authentication of the
   user making the request of NFS service.  Consideration should also be
   given to the integrity and privacy of this NFS request.  These
   specific issues are discussed as part of the section on "RPC and
   Security Flavor".

Expires: December 2000                                        [Page 196]
Draft Specification      NFS version 4 Protocol                June 2000

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; the
   application developer or system vendor is allowed to define the
   attribute, its semantics, and the associated name.  Even though this
   name space will not be specifically controlled to prevent collisions,
   the application developer or system vendor is strongly encouraged to
   provide the name assignment and associated semantics for attributes
   via an Informational RFC.  This will provide for interoperability
   where common interests exist.

Expires: December 2000                                        [Page 197]
Draft Specification      NFS version 4 Protocol                June 2000

18.  RPC definition file

   /*
    *  Copyright (C) The Internet Society (1998,1999,2000).
    *  All Rights Reserved.
    */

   /*
    *      nfs4_prot.x
    *
    */

   %#pragma ident  "@(#)nfs4_prot.x        1.97    00/06/12"

   /*
    * 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;

   /*
    * File types
    */
   enum nfs_ftype4 {
           NF4REG          = 1,    /* Regular File */
           NF4DIR          = 2,    /* Directory */
           NF4BLK          = 3,    /* Special File - block device */
           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,
           NFS4ERR_PERM            = 1,
           NFS4ERR_NOENT           = 2,
           NFS4ERR_IO              = 5,
           NFS4ERR_NXIO            = 6,

Expires: December 2000                                        [Page 198]
Draft Specification      NFS version 4 Protocol                June 2000

           NFS4ERR_ACCES           = 13,
           NFS4ERR_EXIST           = 17,
           NFS4ERR_XDEV            = 18,
           NFS4ERR_NODEV           = 19,
           NFS4ERR_NOTDIR          = 20,
           NFS4ERR_ISDIR           = 21,
           NFS4ERR_INVAL           = 22,
           NFS4ERR_FBIG            = 27,
           NFS4ERR_NOSPC           = 28,
           NFS4ERR_ROFS            = 30,
           NFS4ERR_MLINK           = 31,
           NFS4ERR_NAMETOOLONG     = 63,
           NFS4ERR_NOTEMPTY        = 66,
           NFS4ERR_DQUOT           = 69,
           NFS4ERR_STALE           = 70,
           NFS4ERR_BADHANDLE       = 10001,
           NFS4ERR_BAD_COOKIE      = 10003,
           NFS4ERR_NOTSUPP         = 10004,
           NFS4ERR_TOOSMALL        = 10005,
           NFS4ERR_SERVERFAULT     = 10006,
           NFS4ERR_BADTYPE         = 10007,
           NFS4ERR_DELAY           = 10008,
           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,/* file handle expired     */
           NFS4ERR_SHARE_DENIED    = 10015,/* share reserve denied    */
           NFS4ERR_WRONGSEC        = 10016,/* wrong security flavor   */
           NFS4ERR_CLID_INUSE      = 10017,/* clientid in use         */
           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,
           NFS4ERR_STALE_STATEID   = 10023,
           NFS4ERR_OLD_STATEID     = 10024,
           NFS4ERR_BAD_STATEID     = 10025,
           NFS4ERR_BAD_SEQID       = 10026,
           NFS4ERR_NOT_SAME        = 10027,/* verify - attrs not same */
           NFS4ERR_LOCK_RANGE      = 10028,
           NFS4ERR_SYMLINK         = 10029,
           NFS4ERR_READDIR_NOSPC   = 10030,
           NFS4ERR_LEASE_MOVED     = 10031
   };

   /*
    * Basic data types
    */
   typedef uint32_t        bitmap4<>;
   typedef uint64_t        offset4;

Expires: December 2000                                        [Page 199]
Draft Specification      NFS version 4 Protocol                June 2000

   typedef uint32_t        count4;
   typedef uint64_t        length4;
   typedef uint64_t        clientid4;
   typedef uint64_t        stateid4;
   typedef uint32_t        seqid4;
   typedef opaque          utf8string<>;
   typedef utf8string      component4;
   typedef component4      pathname4<>;
   typedef uint64_t        nfs_lockid4;
   typedef uint64_t        nfs_cookie4;
   typedef utf8string      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;

Expires: December 2000                                        [Page 200]
Draft Specification      NFS version 4 Protocol                June 2000

           uint64_t        minor;
   };

   /*
    * Filesystem locations attribute for relocation/migration
    */
   struct fs_location4 {
           utf8string      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;

Expires: December 2000                                        [Page 201]
Draft Specification      NFS version 4 Protocol                June 2000

   const ACE4_INHERIT_ONLY_ACE             = 0x00000008;
   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 |
    *      ACE4_APPEND_DATA |
    *      ACE4_SYNCHRONIZE
    */

Expires: December 2000                                        [Page 202]
Draft Specification      NFS version 4 Protocol                June 2000

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

   /*
    * Special data/attribute associated with
    * file types NF4BLK and NF4CHR.
    */
   struct specdata4 {
           uint32_t        specdata1;
           uint32_t        specdata2;
   };

   /*
    * 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;

Expires: December 2000                                        [Page 203]
Draft Specification      NFS version 4 Protocol                June 2000

   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 utf8string      fattr4_mimetype;
   typedef mode4           fattr4_mode;
   typedef bool            fattr4_no_trunc;
   typedef uint32_t        fattr4_numlinks;
   typedef utf8string      fattr4_owner;
   typedef utf8string      fattr4_owner_group;
   typedef uint64_t        fattr4_quota_hard;
   typedef uint64_t        fattr4_quota_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;

Expires: December 2000                                        [Page 204]
Draft Specification      NFS version 4 Protocol                June 2000

   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;

   /*
    * Recommended Attributes
    */
   const FATTR4_ACL                = 12;
   const FATTR4_ACLSUPPORT         = 13;
   const FATTR4_ARCHIVE            = 14;
   const FATTR4_CANSETTIME         = 15;
   const FATTR4_CASE_INSENSITIVE   = 16;
   const FATTR4_CASE_PRESERVING    = 17;
   const FATTR4_CHOWN_RESTRICTED   = 18;
   const FATTR4_FILEHANDLE         = 19;
   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_HARD         = 38;
   const FATTR4_QUOTA_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;

Expires: December 2000                                        [Page 205]
Draft Specification      NFS version 4 Protocol                June 2000

   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;

   typedef opaque  attrlist4<>;

   /*
    * File attribute container
    */
   struct fattr4 {
           bitmap4         attrmask;
           attrlist4       attr_vals;
   };

   /*
    * 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 {
           unsigned int    cb_program;
           clientaddr4     cb_location;
   };

   /*
    * Client ID
    */
   struct nfs_client_id4 {
           verifier4       verifier;
           opaque          id<>;
   };

   struct nfs_lockowner4 {
           clientid4       clientid;
           opaque          owner<>;

Expires: December 2000                                        [Page 206]
Draft Specification      NFS version 4 Protocol                June 2000

   };

   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 locks
    */
   struct CLOSE4args {
           /* CURRENT_FH: object */
           seqid4          seqid;
           stateid4        stateid;
   };

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

Expires: December 2000                                        [Page 207]
Draft Specification      NFS version 4 Protocol                June 2000

   /*
    * 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 file
    */
   union createtype4 switch (nfs_ftype4 type) {
    case NF4LNK:
            linktext4      linkdata;
    case NF4BLK:
    case NF4CHR:
            specdata4      devdata;
    case NF4SOCK:
    case NF4FIFO:
    case NF4DIR:
            void;
   };

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

   struct CREATE4resok {
           change_info4     cinfo;
   };

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

Expires: December 2000                                        [Page 208]
Draft Specification      NFS version 4 Protocol                June 2000

   /*
    * DELEGPURGE: Purge Delegations Awaiting Recovery
    */
   struct DELEGPURGE4args {
           clientid4       clientid;
   };

   struct DELEGPURGE4res {
           nfsstat4        status;
   };

   /*
    * DELEGRETURN: Return a delegation
    */
   struct DELEGRETURN4args {
           stateid4        stateid;
   };

   struct DELEGRETURN4res {
           nfsstat4        status;
   };

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

   struct GETATTR4resok {
           fattr4          obj_attributes;
   };

   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:

Expires: December 2000                                        [Page 209]
Draft Specification      NFS version 4 Protocol                June 2000

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

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

   struct LOCK4denied {
           nfs_lockowner4  owner;
           offset4         offset;
           length4         length;
   };

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

   struct LOCKT4args {

Expires: December 2000                                        [Page 210]
Draft Specification      NFS version 4 Protocol                June 2000

           /* CURRENT_FH: file */
           nfs_lock_type4  locktype;
           nfs_lockowner4  owner;
           offset4         offset;
           length4         length;
   };

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

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

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

   /*
    * LOOKUP: Lookup filename
    */
   struct LOOKUP4args {
           /* CURRENT_FH: directory */
           pathname4       path;
   };

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

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

Expires: December 2000                                        [Page 211]
Draft Specification      NFS version 4 Protocol                June 2000

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

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

Expires: December 2000                                        [Page 212]
Draft Specification      NFS version 4 Protocol                June 2000

   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 {
           pathname4       file;
           stateid4        delegate_stateid;
   };

   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 */
           pathname4       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.
     */

Expires: December 2000                                        [Page 213]
Draft Specification      NFS version 4 Protocol                June 2000

    case CLAIM_PREVIOUS:
           /* CURRENT_FH: file being reclaimed */
           uint32_t        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 */
           pathname4       file_delegate_prev;
   };

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

   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

Expires: December 2000                                        [Page 214]
Draft Specification      NFS version 4 Protocol                June 2000

                                              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
    */
   /* Mandatory locking is in effect for this file. */
   const OPEN4_RESULT_MLOCK        = 0x00000001;
   /* Client must confirm open */
   const OPEN4_RESULT_CONFIRM      = 0x00000002;

   struct OPEN4resok {
           stateid4        stateid;        /* Stateid for open */
           change_info4    cinfo;          /* Directory Change Info */
           uint32_t        rflags;         /* Result flags */
           verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
           open_delegation4 delegation;    /* Info on any open
                                              delegation */
   };

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

   /*
    * OPENATTR: open named attributes directory
    */
   struct OPENATTR4res {
           /* CURRENT_FH: name attr directory*/
           nfsstat4        status;
   };

Expires: December 2000                                        [Page 215]
Draft Specification      NFS version 4 Protocol                June 2000

   /*
    * OPEN_CONFIRM: confirm the open
    */
   struct OPEN_CONFIRM4args {
           /* CURRENT_FH: opened file */
           seqid4          seqid;
           verifier4       open_confirm;   /* OPEN_CONFIRM verifier */
   };

   struct OPEN_CONFIRM4resok {
           stateid4        stateid;
   };

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

   /*
    * OPEN_DOWNGRADE: downgrade the access/deny for a file
    */
   struct OPEN_DOWNGRADE4args {
           /* CURRENT_FH: opened file */
           stateid4        stateid;
           seqid4          seqid;
           uint32_t        share_access;
           uint32_t        share_deny;
   };

   struct OPEN_DOWNGRADE4resok {
              stateid4        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;

Expires: December 2000                                        [Page 216]
Draft Specification      NFS version 4 Protocol                June 2000

   };

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

   /*
    * PUTROOTFH: Set root filehandle
    */
   struct PUTROOTFH4res {
           /* CURRENT_FH: root fh */
           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;
   };

Expires: December 2000                                        [Page 217]
Draft Specification      NFS version 4 Protocol                June 2000

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

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

   struct READDIR4resok {
           verifier4       cookieverf;
           dirlist4        reply;
   };

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

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

Expires: December 2000                                        [Page 218]
Draft Specification      NFS version 4 Protocol                June 2000

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

   /*
    * 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 {
           stateid4        stateid;
   };

   struct RENEW4res {
           nfsstat4        status;
   };

   /*
    * RESTOREFH: Restore saved filehandle
    */

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

   /*
    * SAVEFH: Save current filehandle
    */

Expires: December 2000                                        [Page 219]
Draft Specification      NFS version 4 Protocol                June 2000

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

   /*
    * SECINFO: Obtain Available Security Mechanisms
    */
   struct SECINFO4args {
           /* CURRENT_FH: */
           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;
   };

   struct secinfo4 {
           uint32_t        flavor;
           /* null for AUTH_SYS, AUTH_NONE;
              contains rpcsec_gss_info for
              RPCSEC_GSS. */
           opaque          flavor_info<>;
   };

   typedef secinfo4 SECINFO4resok<>;

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

   /*
    * SETATTR: Set attributes
    */
   struct SETATTR4args {
           /* CURRENT_FH: target object */
           stateid4        stateid;
           fattr4          obj_attributes;

Expires: December 2000                                        [Page 220]
Draft Specification      NFS version 4 Protocol                June 2000

   };

   struct SETATTR4res {
           nfsstat4        status;
           bitmap4         attrsset;
   };

   /*
    * SETCLIENTID
    */
   struct SETCLIENTID4args {
           nfs_client_id4  client;
           cb_client4      callback;
   };

   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 {
           verifier4       setclientid_confirm;
   };

   struct SETCLIENTID_CONFIRM4res {
           nfsstat4        status;
   };

   /*
    * VERIFY: Verify attributes same
    */
   struct VERIFY4args {
           /* CURRENT_FH: object */
           fattr4          obj_attributes;
   };

   struct VERIFY4res {
           nfsstat4        status;
   };

   /*
    * WRITE: Write to file
    */

Expires: December 2000                                        [Page 221]
Draft Specification      NFS version 4 Protocol                June 2000

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

   /*
    * 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,

Expires: December 2000                                        [Page 222]
Draft Specification      NFS version 4 Protocol                June 2000

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

   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:         LOCK4args oplockt;
    case OP_LOCKU:         LOCK4args oplocku;
    case OP_LOOKUP:        LOOKUP4args oplookup;
    case OP_LOOKUPP:       void;
    case OP_NVERIFY:       NVERIFY4args opnverify;
    case OP_OPEN:          OPEN4args opopen;
    case OP_OPENATTR:      void;
    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;

Expires: December 2000                                        [Page 223]
Draft Specification      NFS version 4 Protocol                June 2000

    case OP_SETCLIENTID_CONFIRM:   SETCLIENTID_CONFIRM4args
                                           opsetclientid_confirm;
    case OP_VERIFY:        VERIFY4args opverify;
    case OP_WRITE:         WRITE4args opwrite;
   };

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

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

Expires: December 2000                                        [Page 224]
Draft Specification      NFS version 4 Protocol                June 2000

   struct COMPOUND4res {
           nfsstat4 status;
           utf8string      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 {
           stateid4        stateid;
           bool            truncate;
           nfs_fh4         fh;

Expires: December 2000                                        [Page 225]
Draft Specification      NFS version 4 Protocol                June 2000

   };

   struct CB_RECALL4res {
           nfsstat4        status;
   };

   /*
    * Various definitions for CB_COMPOUND
    */
   enum nfs_cb_opnum4 {
           OP_CB_GETATTR           = 3,
           OP_CB_RECALL            = 4
   };

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

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

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

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

   /*
    * 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;
   } = 40000000;

Expires: December 2000                                        [Page 226]
Draft Specification      NFS version 4 Protocol                June 2000

19.  Bibliography

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

   [ISO10646]
   "ISO/IEC 10646-1:1993. International Standard -- Information
   technology -- Universal Multiple-Octet Coded Character Set (UCS) --
   Part 1: Architecture and Basic Multilingual Plane."

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

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

Expires: December 2000                                        [Page 227]
Draft Specification      NFS version 4 Protocol                June 2000

   [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", RFC1094, March 1989.

   http://www.ietf.org/rfc/rfc1094.txt

   [RFC1345]
   Simonsen, K., "Character Mnemonics & Character Sets", RFC1345,
   Rationel Almen Planlaegning, June 1992.

   http://www.ietf.org/rfc/rfc1345.txt

   [RFC1700]
   Reynolds, J., Postel, J., "Assigned Numbers", RFC1700, ISI, October
   1994

   http://www.ietf.org/rfc/rfc1700.txt

   [RFC1813]
   Callaghan, B., Pawlowski, B., Staubach, P., "NFS Version 3 Protocol
   Specification", RFC1813, Sun Microsystems, Inc., June 1995.

   http://www.ietf.org/rfc/rfc1813.txt

   [RFC1831]
   Srinivasan, R., "RPC: Remote Procedure Call Protocol Specification
   Version 2", RFC1831, Sun Microsystems, Inc., August 1995.

   http://www.ietf.org/rfc/rfc1831.txt

   [RFC1832]
   Srinivasan, R., "XDR: External Data Representation Standard",
   RFC1832, Sun Microsystems, Inc., August 1995.

Expires: December 2000                                        [Page 228]
Draft Specification      NFS version 4 Protocol                June 2000

   http://www.ietf.org/rfc/rfc1832.txt

   [RFC1833]
   Srinivasan, R., "Binding Protocols for ONC RPC Version 2", RFC1833,
   Sun Microsystems, Inc., August 1995.

   http://www.ietf.org/rfc/rfc1833.txt

   [RFC2025]
   Adams, C., "The Simple Public-Key GSS-API Mechanism (SPKM)", RFC2025,
   Bell-Northern Research, October 1996.

   http://www.ietf.org/rfc/rfc2026.txt

   [RFC2054]
   Callaghan, B., "WebNFS Client Specification", RFC2054, Sun
   Microsystems, Inc., October 1996

   http://www.ietf.org/rfc/rfc2054.txt

   [RFC2055]
   Callaghan, B., "WebNFS Server Specification", RFC2055, Sun
   Microsystems, Inc., October 1996

   http://www.ietf.org/rfc/rfc2055.txt

   [RFC2078]
   Linn, J., "Generic Security Service Application Program Interface,
   Version 2", RFC2078, OpenVision Technologies, January 1997.

   http://www.ietf.org/rfc/rfc2078.txt

   [RFC2152]
   Goldsmith, D., "UTF-7 A Mail-Safe Transformation Format of Unicode",
   RFC2152, Apple Computer, Inc., May 1997

   http://www.ietf.org/rfc/rfc2152.txt

   [RFC2203]
   Eisler, M., Chiu, A., Ling, L., "RPCSEC_GSS Protocol Specification",
   RFC2203, Sun Microsystems, Inc., August 1995.

   http://www.ietf.org/rfc/rfc2203.txt

Expires: December 2000                                        [Page 229]
Draft Specification      NFS version 4 Protocol                June 2000

   [RFC2277]
   Alvestrand, H., "IETF Policy on Character Sets and Languages",
   RFC2277, UNINETT, January 1998.

   http://www.ietf.org/rfc/rfc2277.txt

   [RFC2279]
   Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC2279,
   Alis Technologies, January 1998.

   http://www.ietf.org/rfc/rfc2279.txt

   [RFC2623]
   Eisler, M., "NFS Version 2 and Version 3 Security Issues and the NFS
   Protocol's Use of RPCSEC_GSS and Kerberos V5", RFC2623, Sun
   Microsystems, June 1999

   http://www.ietf.org/rfc/rfc2623.txt

   [RFC2624]
   Shepler, S., "NFS Version 4 Design Considerations", RFC2624, Sun
   Microsystems, June 1999

   http://www.ietf.org/rfc/rfc2624.txt

   [RFC2847]
   Eisler, M., "LIPKEY - A Low Infrastructure Public Key Mechanism Using
   SPKM", RFC2847, Sun Microsystems, June 2000

   http://www.ietf.org/internet-drafts/draft-ietf-cat-lipkey-03.txt

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

   [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

Expires: December 2000                                        [Page 230]
Draft Specification      NFS version 4 Protocol                June 2000

   covered in [Mogul].

   [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

   [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

Expires: December 2000                                        [Page 231]
Draft Specification      NFS version 4 Protocol                June 2000

20.  Authors

20.1.  Editor's Address

   Spencer Shepler
   Sun Microsystems, Inc.
   7808 Moonflower Drive
   Austin, Texas 78750

   Phone: +1 512-349-9376
   E-mail: shepler@eng.sun.com

20.2.  Authors' Addresses

   Carl Beame
   Hummingbird Ltd.

   E-mail: beame@bws.com

   Brent Callaghan
   Sun Microsystems, Inc.
   901 San Antonio Road
   Palo Alto, CA 94303

   Phone: +1 650-786-5067
   E-mail: brent.callaghan@eng.sun.com

   Mike Eisler
   5565 Wilson Road
   Colorado Springs, CO 80919

   Phone: +1 719-599-9026
   E-mail: mike@eisler.com

   Dave Noveck
   Network Appliance
   200 West Street
   Waltham, MA  02451

   Phone: +1 781-861-9291
   E-mail: dave.noveck@netapp.com

   David Robinson
   Sun Microsystems, Inc.
   901 San Antonio Road
   Palo Alto, CA 94303

Expires: December 2000                                        [Page 232]
Draft Specification      NFS version 4 Protocol                June 2000

   Phone: +1 650-786-5088
   E-mail: david.robinson@eng.sun.com

   Robert Thurlow
   Sun Microsystems, Inc.
   901 San Antonio Road
   Palo Alto, CA 94303

   Phone: +1 650-786-5096
   E-mail: robert.thurlow@eng.sun.com

20.3.  Acknowledgements

   The author thanks and acknowledges:

   Neil Brown for his extensive review and comments of various drafts.

Expires: December 2000                                        [Page 233]
Draft Specification      NFS version 4 Protocol                June 2000

21.  Full Copyright Statement

   "Copyright (C) The Internet Society (2000).  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."

Expires: December 2000                                        [Page 234]